diff --git a/Jamfile b/Jamfile index 929c395efa..9a446f8ad0 100644 --- a/Jamfile +++ b/Jamfile @@ -173,7 +173,11 @@ SubDir HAIKU_TOP ; UserBuildConfigRulePostBuildTargets ; # specify the Haiku image and network boot archive contents -include [ FDirName $(HAIKU_BUILD_RULES_DIR) HaikuImage ] ; +if $(TARGET_ARCH) = x86_64 { + include [ FDirName $(HAIKU_BUILD_RULES_DIR) Haiku64Image ] ; +} else { + include [ FDirName $(HAIKU_BUILD_RULES_DIR) HaikuImage ] ; +} include [ FDirName $(HAIKU_BUILD_RULES_DIR) NetBootArchive ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) FloppyBootImage ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) CDBootImage ] ; diff --git a/Jamrules b/Jamrules index c8f6182603..711d802298 100644 --- a/Jamrules +++ b/Jamrules @@ -44,6 +44,7 @@ include [ FDirName $(HAIKU_BUILD_RULES_DIR) DocumentationRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) FileRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) HeadersRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) KernelRules ] ; +include [ FDirName $(HAIKU_BUILD_RULES_DIR) BootRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) ImageRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) CDRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) MainBuildRules ] ; diff --git a/build/jam/BootRules b/build/jam/BootRules new file mode 100644 index 0000000000..fde7d54313 --- /dev/null +++ b/build/jam/BootRules @@ -0,0 +1,129 @@ + +rule SetupBoot +{ + # Usage SetupBoot : : ; + # + # - Ideally sources, otherwise HDRSEARCH can not be + # set for the sources and the sources some header + # dependencies might be missing. + + local sources = [ FGristFiles $(1) ] ; + local objects = $(sources:S=$(SUFOBJ)) ; + + # add private kernel headers + if $(3) != false { + SourceSysHdrs $(sources) : $(TARGET_PRIVATE_KERNEL_HEADERS) ; + } + + local object ; + for object in $(objects) { + # add boot flags for the object + ObjectCcFlags $(object) : $(TARGET_BOOT_CCFLAGS) $(2) ; + ObjectC++Flags $(object) : $(TARGET_BOOT_C++FLAGS) $(2) ; + ObjectDefines $(object) : $(TARGET_KERNEL_DEFINES) ; + ASFLAGS on $(object) = $(TARGET_BOOT_CCFLAGS) ; + + # override warning flags + TARGET_WARNING_CCFLAGS on $(object) = $(TARGET_KERNEL_WARNING_CCFLAGS) ; + TARGET_WARNING_C++FLAGS on $(object) + = $(TARGET_KERNEL_WARNING_C++FLAGS) ; + } +} + +rule BootObjects +{ + SetupBoot $(1) : $(2) ; + Objects $(1) ; +} + +rule BootLd +{ + # BootLd : : : ; + + LINK on $(1) = $(TARGET_LD) ; + + LINKFLAGS on $(1) = $(4) ; + if $(3) { LINKFLAGS on $(1) += --script=$(3) ; } + + # Remove any preset LINKLIBS, but link against libgcc.a. Linking against + # libsupc++ is opt-out. + local libs ; + if ! [ on $(1) return HAIKU_NO_LIBSUPC++ ] { + libs += $(TARGET_BOOT_LIBSUPC++) ; + } + LINKLIBS on $(1) = $(libs) $(TARGET_BOOT_LIBGCC) ; + + # TODO: Do we really want to invoke SetupBoot here? The objects should + # have been compiled with BootObjects anyway, so we're doing that twice. + SetupBoot $(2) ; + + # Show that we depend on the libraries we need + LocalClean clean : $(1) ; + LocalDepends all : $(1) ; + Depends $(1) : $(2) ; + + MakeLocateDebug $(1) ; + + on $(1) XRes $(1) : $(RESFILES) ; + if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] { + SetType $(1) ; + MimeSet $(1) ; + SetVersion $(1) ; + } +} + +actions BootLd bind VERSION_SCRIPT +{ + $(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) \ + --version-script=$(VERSION_SCRIPT) +} + +rule BootMergeObject +{ + # BootMergeObject : : : ; + # Compiles source files and merges the object files to an object file. + # : Name of the object file to create. No grist will be added. + # : Sources to be compiled. Grist will be added. + # : Additional flags for compilation. + # : Object files or static libraries to be merged. No grist + # will be added. + # + + SetupBoot $(2) : $(3) ; + Objects $(2) ; + MergeObjectFromObjects $(1) : $(2:S=$(SUFOBJ)) : $(4) ; + LINKFLAGS on $(1) += $(TARGET_BOOT_LINKFLAGS) ; +} + +rule BootStaticLibrary +{ + # Usage BootStaticLibrary : : ; + # This is designed to take a set of sources and libraries and create + # a file called lib.a + + SetupBoot $(2) : $(3) : false ; + Library $(1) : $(2) ; +} + +rule BootStaticLibraryObjects +{ + # Usage BootStaticLibrary : ; + # This is designed to take a set of sources and libraries and create + # a file called + + # Show that we depend on the libraries we need + SetupBoot $(2) ; + LocalClean clean : $(1) ; + LocalDepends all : $(1) ; + Depends $(1) : $(2) ; + + MakeLocateDebug $(1) ; +} + +actions BootStaticLibraryObjects +{ + # Force recreation of the archive to avoid build errors caused by + # stale dependencies after renaming or deleting object files. + $(RM) "$(1)" + $(HAIKU_AR) -r "$(1)" "$(2)" ; +} diff --git a/build/jam/BuildSetup b/build/jam/BuildSetup index 5864f70723..a03fec254e 100644 --- a/build/jam/BuildSetup +++ b/build/jam/BuildSetup @@ -159,10 +159,13 @@ if $(HAIKU_GCC_VERSION[1]) = 2 { HAIKU_C++ ?= $(HAIKU_CC) ; HAIKU_LINK = $(HAIKU_CC) ; HAIKU_LINKFLAGS = $(HAIKU_GCC_BASE_FLAGS) ; +HAIKU_BOOT_LINKFLAGS = ; HAIKU_HDRS = [ FStandardHeaders ] ; HAIKU_KERNEL_CCFLAGS = $(HAIKU_CCFLAGS) $(HAIKU_GCC_BASE_FLAGS) ; HAIKU_KERNEL_C++FLAGS = $(HAIKU_C++FLAGS) $(HAIKU_GCC_BASE_FLAGS) ; +HAIKU_BOOT_CCFLAGS = $(HAIKU_CCFLAGS) $(HAIKU_GCC_BASE_FLAGS) ; +HAIKU_BOOT_C++FLAGS = $(HAIKU_C++FLAGS) $(HAIKU_GCC_BASE_FLAGS) ; HAIKU_CCFLAGS += $(HAIKU_GCC_BASE_FLAGS) -nostdinc ; HAIKU_C++FLAGS += $(HAIKU_GCC_BASE_FLAGS) -nostdinc ; HAIKU_DEFINES = __HAIKU__ ; @@ -190,7 +193,7 @@ switch $(HAIKU_DISTRO_COMPATIBILITY) { # analyze the gcc machine spec to determine HAIKU_CPU switch $(HAIKU_GCC_MACHINE) { case i?86-* : HAIKU_CPU = x86 ; - case x86_64-* : HAIKU_CPU = x86_64 ; + case x86_64-* : HAIKU_CPU = x86_64 ; case powerpc-* : HAIKU_CPU = ppc ; case m68k-* : HAIKU_CPU = m68k ; case mipsel-* : HAIKU_CPU = mipsel ; @@ -249,12 +252,15 @@ switch $(HAIKU_CPU) { } case x86_64 : { - HAIKU_DEFINES += __x86_64__ ; + # x86_64 completely shares the x86 bootloader. HAIKU_BOOT_PLATFORM = bios_ia32 ; HAIKU_BOOT_FLOPPY_IMAGE_SIZE = 2880 ; # in kB # offset in floppy image (>= sizeof(haiku_loader)) HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET = 300 ; # in kB + # x86_64 kernel source is under arch/x86. + HAIKU_KERNEL_ARCH = x86 ; + # yasm is required for target arch x86_64 if ! $(HAIKU_YASM) { Exit "HAIKU_YASM not set. Please re-run configure." ; @@ -304,6 +310,7 @@ HAIKU_ARCH ?= $(HAIKU_CPU) ; HAIKU_ARCH_MACRO_DEFINE = ARCH_$(HAIKU_ARCH) ; HAIKU_DEFINES += $(HAIKU_ARCH_MACRO_DEFINE) ; HAIKU_DEFINES += BOOT_ARCHIVE_IMAGE_OFFSET=$(HAIKU_BOOT_ARCHIVE_IMAGE_OFFSET) ; +HAIKU_KERNEL_ARCH ?= $(HAIKU_ARCH) ; HAIKU_ATA_STACK ?= 1 ; # directories @@ -329,8 +336,11 @@ HAIKU_ASFLAGS = ; HAIKU_KERNEL_CCFLAGS += -finline -fno-builtin ; HAIKU_KERNEL_C++FLAGS += -finline -fno-builtin -fno-exceptions ; HAIKU_KERNEL_DEFINES += _KERNEL_MODE ; +HAIKU_BOOT_CCFLAGS += -finline -fno-builtin ; +HAIKU_BOOT_C++FLAGS += -finline -fno-builtin -fno-exceptions ; if $(HAIKU_GCC_VERSION[1]) >= 3 { + HAIKU_BOOT_C++FLAGS += -fno-use-cxa-atexit ; HAIKU_KERNEL_C++FLAGS += -fno-use-cxa-atexit ; } @@ -340,11 +350,14 @@ if $(HAIKU_GCC_VERSION[1]) >= 4 { if $(HAIKU_GCC_VERSION[2]) >= 3 { HAIKU_KERNEL_CCFLAGS += -ffreestanding ; HAIKU_KERNEL_C++FLAGS += -ffreestanding ; + HAIKU_BOOT_CCFLAGS += -ffreestanding ; + HAIKU_BOOT_C++FLAGS += -ffreestanding ; } } HAIKU_KERNEL_PIC_CCFLAGS = -fno-pic ; HAIKU_KERNEL_PIC_LINKFLAGS = ; +HAIKU_KERNEL_ADDON_LINKFLAGS = ; switch $(HAIKU_ARCH) { case ppc : @@ -377,6 +390,23 @@ switch $(HAIKU_ARCH) { } case x86_64 : { + # Kernel lives in the top 2GB of the address space, use kernel code + # model. + HAIKU_KERNEL_PIC_CCFLAGS += -mcmodel=kernel ; + + # Disable the red zone, which cannot be used in kernel code due to + # interrupts, and always enable the frame pointer so stack traces are + # correct. + HAIKU_KERNEL_CCFLAGS += -mno-red-zone -fno-omit-frame-pointer ; + HAIKU_KERNEL_C++FLAGS += -mno-red-zone -fno-omit-frame-pointer ; + HAIKU_KERNEL_PIC_LINKFLAGS += -z max-page-size=0x1000 ; + HAIKU_KERNEL_ADDON_LINKFLAGS += -z max-page-size=0x1000 ; + + # Bootloader is 32-bit. + HAIKU_BOOT_LINKFLAGS += -m elf_i386_haiku ; + HAIKU_BOOT_CCFLAGS += -m32 -march=pentium ; + HAIKU_BOOT_C++FLAGS += -m32 -march=pentium ; + # Enable use of the gcc built-in atomic functions instead of atomic_*(). # The former are inlined and have thus less overhead. HAIKU_DEFINES += B_USE_BUILTIN_ATOMIC_FUNCTIONS ; @@ -439,7 +469,7 @@ HAIKU_PRIVATE_SYSTEM_HEADERS = HAIKU_PRIVATE_KERNEL_HEADERS = [ PrivateHeaders $(DOT) kernel libroot shared kernel/boot/platform/$(HAIKU_BOOT_PLATFORM) ] - [ ArchHeaders $(HAIKU_ARCH) ] + [ ArchHeaders $(HAIKU_KERNEL_ARCH) ] [ FDirName $(HAIKU_COMMON_DEBUG_OBJECT_DIR) system kernel ] $(HAIKU_PRIVATE_SYSTEM_HEADERS) ; @@ -957,9 +987,9 @@ if $(TARGET_PLATFORM) != haiku { # specified TARGET_PLATFORM. local buildVars = - ARCH CPU GCC_VERSION + ARCH CPU GCC_VERSION KERNEL_ARCH - AR CC C++ LD OBJCOPY RANLIB + AR CC C++ LD OBJCOPY RANLIB ELFEDIT INCLUDES_SEPARATOR LOCAL_INCLUDES_OPTION SYSTEM_INCLUDES_OPTION @@ -968,7 +998,8 @@ local buildVars = KERNEL_DEFINES KERNEL_CCFLAGS KERNEL_C++FLAGS - KERNEL_PIC_CCFLAGS KERNEL_PIC_LINKFLAGS + KERNEL_PIC_CCFLAGS KERNEL_PIC_LINKFLAGS KERNEL_ADDON_LINKFLAGS + BOOT_CCFLAGS BOOT_C++FLAGS BOOT_LINKFLAGS WARNING_CCFLAGS WARNING_C++FLAGS KERNEL_WARNING_CCFLAGS KERNEL_WARNING_C++FLAGS @@ -1005,6 +1036,11 @@ if $(TARGET_PLATFORM) = haiku { TARGET_GCC_LIBGCC = $(HAIKU_GCC_LIBGCC) ; TARGET_GCC_LIBGCC_OBJECTS = $(HAIKU_GCC_LIBGCC_OBJECTS) ; + TARGET_KERNEL_LIBGCC = $(HAIKU_KERNEL_LIBGCC) ; + TARGET_KERNEL_LIBSUPC++ = $(HAIKU_KERNEL_LIBSUPC++) ; + TARGET_BOOT_LIBGCC = $(HAIKU_BOOT_LIBGCC) ; + TARGET_BOOT_LIBSUPC++ = $(HAIKU_BOOT_LIBSUPC++) ; + TARGET_BOOT_PLATFORM ?= $(HAIKU_BOOT_PLATFORM) ; TARGET_BOOT_BOARD ?= $(HAIKU_BOOT_BOARD) ; @@ -1021,6 +1057,11 @@ if $(TARGET_PLATFORM) = haiku { TARGET_GCC_LIBGCC = ; TARGET_GCC_LIBGCC_OBJECTS = ; + TARGET_KERNEL_LIBGCC = ; + TARGET_KERNEL_LIBSUPC++ = ; + TARGET_BOOT_LIBGCC = ; + TARGET_BOOT_LIBSUPC++ = ; + TARGET_BOOT_PLATFORM = ; TARGET_BOOT_BOARD = ; diff --git a/build/jam/FloppyBootImage b/build/jam/FloppyBootImage index 3c792844a7..7ecd4872c0 100644 --- a/build/jam/FloppyBootImage +++ b/build/jam/FloppyBootImage @@ -4,7 +4,7 @@ local X86_ONLY = ; local PPC_ONLY = ; local ARM_ONLY = ; -if $(TARGET_ARCH) = x86 { +if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 { X86_ONLY = "" ; } else if $(TARGET_ARCH) = ppc { X86_ONLY = ; @@ -55,41 +55,77 @@ SYSTEM_ADD_ONS_BUS_MANAGERS = $(X86_ONLY)acpi $(ATA_ONLY)ata config_manager dpc SYSTEM_ADD_ONS_FILE_SYSTEMS = bfs iso9660 attribute_overlay write_overlay ; -# modules -AddFilesToFloppyBootArchive system add-ons kernel bus_managers - : $(SYSTEM_ADD_ONS_BUS_MANAGERS) ; -AddFilesToFloppyBootArchive system add-ons kernel busses ide - : generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata it8211 ; -AddFilesToFloppyBootArchive system add-ons kernel busses scsi - : ahci ; -AddFilesToFloppyBootArchive system add-ons kernel console : vga_text ; -AddFilesToFloppyBootArchive system add-ons kernel file_systems - : $(SYSTEM_ADD_ONS_FILE_SYSTEMS) ; -AddFilesToFloppyBootArchive system add-ons kernel generic - : $(ATA_ONLY)ata_adapter $(IDE_ONLY)ide_adapter locked_pool scsi_periph ; -AddFilesToFloppyBootArchive system add-ons kernel partitioning_systems - : intel session ; -AddFilesToFloppyBootArchive system add-ons kernel interrupt_controllers - : $(PPC_ONLY)openpic ; +if $(TARGET_ARCH) = x86_64 { + AddFilesToFloppyBootArchive system add-ons kernel bus_managers + : ata config_manager dpc pci isa scsi $(USB_ONLY)usb ; + AddFilesToFloppyBootArchive system add-ons kernel busses ata + : generic_ide_pci legacy_sata ; + AddFilesToFloppyBootArchive system add-ons kernel busses scsi + : ahci ; + AddFilesToFloppyBootArchive system add-ons kernel file_systems + : $(SYSTEM_ADD_ONS_FILE_SYSTEMS) ; + AddFilesToFloppyBootArchive system add-ons kernel generic + : ata_adapter locked_pool scsi_periph ; + AddFilesToFloppyBootArchive system add-ons kernel partitioning_systems + : intel session ; -if $(USB_BOOT) = 1 { - AddFilesToFloppyBootArchive system add-ons kernel busses usb - : uhci ohci ehci ; -} + if $(USB_BOOT) = 1 { + AddFilesToFloppyBootArchive system add-ons kernel busses usb + : uhci ohci ehci ; + } -if $(TARGET_ARCH) = x86 { AddFilesToFloppyBootArchive system add-ons kernel cpu : generic_x86 ; -} -# drivers -AddNewDriversToFloppyBootArchive disk scsi : scsi_cd scsi_disk ; -AddNewDriversToFloppyBootArchive disk : $(ARM_ONLY)norflash ; -if $(USB_BOOT) = 1 { - AddDriversToFloppyBootArchive disk usb : usb_disk ; -} -if $(NET_BOOT) = 1 { - AddDriversToFloppyBootArchive disk virtual : remote_disk ; - AddDriversToFloppyBootArchive net : $(SYSTEM_ADD_ONS_DRIVERS_NET) ; + AddNewDriversToFloppyBootArchive disk scsi : scsi_cd scsi_disk ; + if $(USB_BOOT) = 1 { + AddDriversToFloppyBootArchive disk usb : usb_disk ; + } +} else { + # modules + AddFilesToFloppyBootArchive system add-ons kernel bus_managers + : $(SYSTEM_ADD_ONS_BUS_MANAGERS) ; + + if $(HAIKU_ATA_STACK) = 1 { + AddFilesToFloppyBootArchive system add-ons kernel busses ata + : generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata + it8211 ; + } else { + AddFilesToFloppyBootArchive system add-ons kernel busses ide + : generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata + it8211 ; + } + + AddFilesToFloppyBootArchive system add-ons kernel busses scsi + : ahci ; + AddFilesToFloppyBootArchive system add-ons kernel console : vga_text ; + AddFilesToFloppyBootArchive system add-ons kernel file_systems + : $(SYSTEM_ADD_ONS_FILE_SYSTEMS) ; + AddFilesToFloppyBootArchive system add-ons kernel generic + : $(ATA_ONLY)ata_adapter $(IDE_ONLY)ide_adapter locked_pool scsi_periph ; + AddFilesToFloppyBootArchive system add-ons kernel partitioning_systems + : intel session ; + AddFilesToFloppyBootArchive system add-ons kernel interrupt_controllers + : $(PPC_ONLY)openpic ; + + if $(USB_BOOT) = 1 { + AddFilesToFloppyBootArchive system add-ons kernel busses usb + : uhci ohci ehci ; + } + + if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 { + AddFilesToFloppyBootArchive system add-ons kernel cpu : generic_x86 ; + } + + # drivers + AddNewDriversToFloppyBootArchive disk scsi : scsi_cd scsi_disk ; + AddNewDriversToFloppyBootArchive disk : $(ARM_ONLY)norflash ; + if $(USB_BOOT) = 1 { + AddDriversToFloppyBootArchive disk usb : usb_disk ; + } + if $(NET_BOOT) = 1 { + AddDriversToFloppyBootArchive disk virtual : remote_disk ; + AddDriversToFloppyBootArchive net : $(SYSTEM_ADD_ONS_DRIVERS_NET) ; + } } # kernel @@ -118,19 +154,30 @@ if $(NET_BOOT) = 1 { } # boot module links -AddBootModuleSymlinksToFloppyBootArchive - $(SYSTEM_ADD_ONS_BUS_MANAGERS) - $(PPC_ONLY)openpic - $(ATA_ONLY)ata_adapter $(IDE_ONLY)ide_adapter locked_pool scsi_periph - $(X86_ONLY)generic_x86 - ahci generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata - it8211 - $(USB_ONLY)uhci $(USB_ONLY)ohci $(USB_ONLY)ehci - scsi_cd scsi_disk $(USB_ONLY)usb_disk $(ARM_ONLY)norflash - intel session - $(SYSTEM_ADD_ONS_FILE_SYSTEMS) - $(BOOT_ADD_ONS_NET) -; +if $(TARGET_ARCH) = x86_64 { + AddBootModuleSymlinksToFloppyBootArchive + ata dpc config_manager pci scsi $(USB_ONLY)usb ata_adapter locked_pool + scsi_periph generic_x86 ahci generic_ide_pci legacy_sata + $(USB_ONLY)uhci $(USB_ONLY)ohci $(USB_ONLY)ehci + scsi_cd scsi_disk $(USB_ONLY)usb_disk + intel session + $(SYSTEM_ADD_ONS_FILE_SYSTEMS) + ; +} else { + AddBootModuleSymlinksToFloppyBootArchive + $(SYSTEM_ADD_ONS_BUS_MANAGERS) + $(PPC_ONLY)openpic + $(ATA_ONLY)ata_adapter $(IDE_ONLY)ide_adapter locked_pool scsi_periph + $(X86_ONLY)generic_x86 + ahci generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata + it8211 + $(USB_ONLY)uhci $(USB_ONLY)ohci $(USB_ONLY)ehci + scsi_cd scsi_disk $(USB_ONLY)usb_disk $(ARM_ONLY)norflash + intel session + $(SYSTEM_ADD_ONS_FILE_SYSTEMS) + $(BOOT_ADD_ONS_NET) + ; +} #pragma mark - Build The Archive diff --git a/build/jam/Haiku64Image b/build/jam/Haiku64Image new file mode 100644 index 0000000000..7e1611f11e --- /dev/null +++ b/build/jam/Haiku64Image @@ -0,0 +1,593 @@ +# This file defines what ends up on the Haiku image (respectively in the Haiku +# installation directory) and it executes the rules building the image +# (respectively installing the files in the installation directory). + +# This is only temporary while x86_64 is still a work in progress, so I can +# easily add things to the image as I port them. + +local GPL_ONLY = ; +if $(HAIKU_INCLUDE_GPL_ADDONS) = 1 { + GPL_ONLY = "" ; +} + +#HACK: remove when old ide code is removed! +local ATA_ONLY = ; +local IDE_ONLY = ; +if $(HAIKU_ATA_STACK) = 1 { + ATA_ONLY = "" ; +} else { + IDE_ONLY = "" ; +} + +SYSTEM_BIN = "[" addattr base64 basename bash beep cal cat catattr checkfs + chgrp chmod chown chroot cksum clear clockconfig cmp collectcatkeys comm + compress copyattr cp csplit cut date dd diff diff3 dircolors dirname df du + dumpcatalog echo eject env error expand expr factor false find finddir + fmt fold fortune gawk gdb gzip gzexe getlimits grep groups head hostname id + ifconfig install isvolume join kernel_debugger kill less lessecho + lesskey link linkcatkeys listdev ln locale locate logger logname ls + makebootable md5sum mimeset mkdir mkfifo mkfs mktemp mount mountvolume + mv nl nohup notify nproc od paste patch pathchk ping pr printenv printf + ps ptx pwd query rc readlink ReadOnlyBootPrompt rm rmattr rmdir safemode + sdiff seq sha1sum shred shuf sleep sort split stat strace stty su sum sync + sysinfo tac tail tee test timeout touch tr true truncate tsort tty unexpand + uname uniq unlink unmount unzip updatedb waitfor wc wget whoami xargs + xres yes zdiff zforce zgrep zip zipcloak zipgrep zipnote zipsplit + zmore znew +; + +SYSTEM_APPS = AboutSystem DriveSetup Installer NetworkStatus ProcessController + StyledEdit Terminal +; + +SYSTEM_PREFERENCES = Appearance Backgrounds Deskbar FileTypes + Keyboard Keymap Locale Mouse Network Notifications Screen Time Touchpad + Tracker VirtualMemory +; + +SYSTEM_DEMOS = ; + +SYSTEM_LIBS = libbe.so libbnetapi.so libdebug.so libnetwork.so + libroot.so libroot-addon-icu.so + libtextencoding.so libtiff.so libtracker.so libtranslation.so + $(HAIKU_SHARED_LIBSTDC++) $(HAIKU_SHARED_LIBSUPC++) +; + +PRIVATE_SYSTEM_LIBS = + $(HAIKU_JPEG_CURRENT_LIB) + $(HAIKU_LIBPNG_CURRENT_LIB) + $(HAIKU_ZLIB_CURRENT_LIB) + $(HAIKU_FREETYPE_CURRENT_LIB) + libilmimf.so +; + +SYSTEM_SERVERS = app_server debug_server input_server mount_server + net_server notification_server registrar syslog_daemon +; + +SYSTEM_NETWORK_DEVICES = ethernet loopback ; +SYSTEM_NETWORK_DATALINK_PROTOCOLS = ethernet_frame arp loopback_frame + ipv6_datagram ; +SYSTEM_NETWORK_PROTOCOLS = ipv4 tcp udp icmp unix icmp6 ipv6 ; + +SYSTEM_ADD_ONS_ACCELERANTS = vesa.accelerant ; +SYSTEM_ADD_ONS_TRANSLATORS = BMPTranslator EXRTranslator GIFTranslator + HVIFTranslator ICOTranslator JPEGTranslator JPEG2000Translator + PCXTranslator PNGTranslator PPMTranslator + RAWTranslator RTFTranslator SGITranslator STXTTranslator TGATranslator + TIFFTranslator WebPTranslator WonderBrushTranslator +; + +SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = vesa ; +SYSTEM_ADD_ONS_DRIVERS_NET = 3com atheros813x ar81xx attansic_l1 attansic_l2 + broadcom440x broadcom570x dec21xxx etherpci ipro100 ipro1000 jmicron2x0 + marvell_yukon nforce pcnet pegasus rtl8139 rtl81xx sis19x sis900 syskonnect + via_rhine wb840 +; + +SYSTEM_ADD_ONS_BUS_MANAGERS = $(ATA_ONLY)ata pci ps2 isa scsi config_manager + usb ; +SYSTEM_ADD_ONS_FILE_SYSTEMS = bfs iso9660 attribute_overlay write_overlay ; + +# modules +AddFilesToHaikuImage system add-ons kernel bus_managers + : $(SYSTEM_ADD_ONS_BUS_MANAGERS) ; + +if $(HAIKU_ATA_STACK) = 1 { + AddFilesToHaikuImage system add-ons kernel busses ata + : generic_ide_pci legacy_sata ; +} + +AddFilesToHaikuImage system add-ons kernel busses scsi + : ahci ; +AddFilesToHaikuImage system add-ons kernel busses usb + : uhci ohci ehci ; +AddFilesToHaikuImage system add-ons kernel debugger + : demangle invalidate_on_exit usb_keyboard ; +AddFilesToHaikuImage system add-ons kernel file_systems + : $(SYSTEM_ADD_ONS_FILE_SYSTEMS) ; +AddFilesToHaikuImage system add-ons kernel generic + : $(ATA_ONLY)ata_adapter bios dpc locked_pool scsi_periph tty ; +AddFilesToHaikuImage system add-ons kernel partitioning_systems + : intel session ; + +AddFilesToHaikuImage system add-ons kernel cpu : generic_x86 ; + +# drivers +AddNewDriversToHaikuImage disk scsi : scsi_cd scsi_disk ; + +# legacy drivers +AddDriversToHaikuImage : console dprintf null + random tty zero ; +AddDriversToHaikuImage graphics : $(SYSTEM_ADD_ONS_DRIVERS_GRAPHICS) ; +AddDriversToHaikuImage disk usb : usb_disk ; +AddDriversToHaikuImage input : ps2_hid usb_hid ; +AddDriversToHaikuImage net : $(SYSTEM_ADD_ONS_DRIVERS_NET) ; + +# kernel +AddFilesToHaikuImage system : kernel_$(TARGET_ARCH) ; + +# libs +AddLibrariesToHaikuHybridImage system lib + : $(SYSTEM_LIBS) $(PRIVATE_SYSTEM_LIBS) ; + +# libfreetype.so links to the current freetype lib +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_FREETYPE_CURRENT_LIB:BS) + : $(HAIKU_FREETYPE_CURRENT_LINK) : : true ; +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_FREETYPE_CURRENT_LINK) + : libfreetype.so : : true ; + +# libpng.so links to the current libpng +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_LIBPNG_CURRENT_LIB:BS) + : $(HAIKU_LIBPNG_CURRENT_LINK) : : true ; +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_LIBPNG_CURRENT_LINK) + : libpng.so : : true ; + +# libjpeg.so links to the current libjpeg +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_JPEG_CURRENT_LIB:BS) + : $(HAIKU_JPEG_CURRENT_LINK) : : true ; +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_JPEG_CURRENT_LINK) + : libjpeg.so : : true ; + +# zlib.so links to the current zlib +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_ZLIB_CURRENT_LIB:BS) + : $(HAIKU_ZLIB_CURRENT_LINK) : : true ; +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_ZLIB_CURRENT_LINK) + : libz.so : : true ; + +# servers +AddFilesToHaikuImage system servers : $(SYSTEM_SERVERS) ; + +# apps +AddFilesToHaikuImage system : runtime_loader Deskbar Tracker ; +AddFilesToHaikuImage system bin : $(SYSTEM_BIN) consoled ; +AddFilesToHaikuImage system apps : $(SYSTEM_APPS) ; +AddFilesToHaikuImage system preferences : $(SYSTEM_PREFERENCES) ; +AddFilesToHaikuImage system demos : $(SYSTEM_DEMOS) ; + +SEARCH on which = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToHaikuImage system bin : which ; +SEARCH on installoptionalpackage = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToHaikuImage system bin : installoptionalpackage ; +SEARCH on install-wifi-firmwares.sh = [ FDirName $(HAIKU_TOP) data bin ] ; +AddFilesToHaikuImage system bin : install-wifi-firmwares.sh ; + +# Add the files to be used by installoptionalpackage. +AddDirectoryToHaikuImage common data optional-packages ; +local optional-pkg-files = OptionalBuildFeatures OptionalPackageDependencies + OptionalPackages OptionalLibPackages ; +for name in $(optional-pkg-files) { + local file = [ FDirName $(HAIKU_TOP) build jam $(name) ] ; + AddFilesToHaikuImage common data optional-packages : $(file) ; +} +AddInstalledPackagesFileToHaikuImage ; + +AddSymlinkToHaikuImage system bin : bash : sh ; +AddSymlinkToHaikuImage system bin : trash : untrash ; + +AddSymlinkToHaikuImage home Desktop : /boot/home : Home ; + +# Mailbox folders and symlink +AddDirectoryToHaikuImage home mail draft ; +AddDirectoryToHaikuImage home mail in ; +AddDirectoryToHaikuImage home mail out ; + +AddSymlinkToHaikuImage home config : settings/deskbar : be ; +# Deskbar Application links +AddDirectoryToHaikuImage home config settings deskbar Applications ; +DESKBAR_APPLICATIONS = DriveSetup Installer StyledEdit Terminal ; +local linkTarget ; +for linkTarget in $(DESKBAR_APPLICATIONS) { + AddSymlinkToHaikuImage home config settings deskbar Applications + : /boot/system/apps/$(linkTarget) : $(linkTarget) ; +} + +# Deskbar Desktop applets links +AddDirectoryToHaikuImage home config settings deskbar Desktop\ applets ; +DESKBAR_DESKTOP_APPLETS = NetworkStatus ProcessController ; +for linkTarget in $(DESKBAR_DESKTOP_APPLETS) { + AddSymlinkToHaikuImage home config settings deskbar Desktop\ applets + : /boot/system/apps/$(linkTarget) : $(linkTarget) ; +} + +# Deskbar Preferences links +AddDirectoryToHaikuImage home config settings deskbar Preferences ; +DESKBAR_PREFERENCES = $(SYSTEM_PREFERENCES:B) ; +for linkTarget in $(DESKBAR_PREFERENCES) { + AddSymlinkToHaikuImage home config settings deskbar Preferences + : /boot/system/preferences/$(linkTarget) + : $(linkTarget) ; +} + +AddSymlinkToHaikuImage system bin : less : more ; +AddSymlinkToHaikuImage system bin : gzip : gunzip ; +AddSymlinkToHaikuImage system bin : gzip : zcat ; +AddSymlinkToHaikuImage system bin : zdiff : zcmp ; +AddSymlinkToHaikuImage system bin : unzip : zipinfo ; +AddSymlinkToHaikuImage system bin : gawk : awk ; +AddSymlinkToHaikuImage system bin : grep : egrep ; +AddSymlinkToHaikuImage system bin : grep : fgrep ; + + +# scripts and data files +local bootScripts = Bootscript Bootscript.cd SetupEnvironment Netscript + InstallerInitScript InstallerFinishScript ; +SEARCH on $(bootScripts) = [ FDirName $(HAIKU_TOP) data system boot ] ; +AddFilesToHaikuImage system boot : $(bootScripts) ; + +local userBootScripts = UserBootscript UserSetupEnvironment.sample ; +SEARCH on $(userBootScripts) = [ FDirName $(HAIKU_TOP) data config boot ] ; +AddFilesToHaikuImage home config boot : $(userBootScripts) ; + +# Add boot launch directory +AddDirectoryToHaikuImage home config boot launch ; + +local logoArtwork = + $(HAIKU_INCLUDE_TRADEMARKS)"HAIKU logo - white on blue - big.png" + $(HAIKU_INCLUDE_TRADEMARKS)"HAIKU logo - white on blue - normal.png" ; +SEARCH on $(logoArtwork) = [ FDirName $(HAIKU_TOP) data artwork ] ; +AddFilesToHaikuImage system data artwork : $(logoArtwork) ; + +local etcDir = [ FDirName $(HAIKU_TOP) data etc ] ; +local etcFiles = inputrc profile ; +etcFiles = $(etcFiles:G=etc) ; +SEARCH on $(etcFiles) = [ FDirName $(etcDir) ] ; +etcFiles += termcap sysless sysless.in ; +AddFilesToHaikuImage common etc : $(etcFiles) ; + +local profileFiles = [ Glob $(etcDir)/profile.d : *.sh ] ; +profileFiles = $(profileFiles:G=profile-d) ; +AddDirectoryToHaikuImage common etc profile.d ; +AddFilesToHaikuImage common etc profile.d : $(profileFiles) ; + +local fortuneFiles = [ Glob $(HAIKU_TOP)/data/system/data/fortunes + : [a-zA-Z0-9]* ] ; +fortuneFiles = $(fortuneFiles:G=data!fortunes) ; +AddFilesToHaikuImage system data fortunes : $(fortuneFiles) ; + +local fontDir = [ FDirName $(HAIKU_TOP) data system data fonts ] ; +local psFonts = [ Glob $(fontDir)/psfonts : *.afm *.pfb ] ; +local ttFonts = [ Glob $(fontDir)/ttfonts : *.ttf ] ; +AddFilesToHaikuImage system data fonts psfonts : $(psFonts) ; +AddFilesToHaikuImage system data fonts ttfonts : $(ttFonts) ; + +local keymapFiles = [ Glob [ FDirName $(HAIKU_TOP) src data keymaps ] + : *.keymap ] ; +keymapFiles = $(keymapFiles:BG=keymap) ; +AddFilesToHaikuImage system data Keymaps : $(keymapFiles) ; +AddSymlinkToHaikuImage system data Keymaps : Swedish : Finnish ; +AddSymlinkToHaikuImage system data Keymaps : Slovene : Croatian ; +AddSymlinkToHaikuImage system data Keymaps : US-International : Brazilian ; + +# Copy keyboard layout files to the image one-by-one. +local keyboardLayoutsDir + = [ FDirName $(HAIKU_TOP) data system data KeyboardLayouts ] ; +local keyboardLayoutFiles = + "Generic 104-key" + "Generic 105-key International" + "Kinesis Advantage" + "Kinesis Ergo Elan International" + "TypeMatrix 2030" ; +keyboardLayoutFiles = $(keyboardLayoutFiles:G=keyboard-layout) ; +SEARCH on $(keyboardLayoutFiles) = $(keyboardLayoutsDir) ; +AddFilesToHaikuImage system data KeyboardLayouts + : $(keyboardLayoutFiles) ; + +# Add Apple Aluminum keyboard layout files to the image in an Apple Aluminum +# subdirectory. The subdirectory is turned into a submenu in the Layout menu +# of the Keymap preference app. +local appleAluminumDir + = [ FDirName $(HAIKU_TOP) data system data KeyboardLayouts + Apple\ Aluminum ] ; +local appleAluminumFiles = + "Apple Aluminium Extended International" + "Apple Aluminium International" + "Apple Aluminum (US)" + "Apple Aluminum Extended (US)" ; +appleAluminumFiles = $(appleAluminumFiles:G=keyboard-layout) ; +SEARCH on $(appleAluminumFiles) = $(appleAluminumDir) ; +AddFilesToHaikuImage system data KeyboardLayouts Apple\ Aluminum + : $(appleAluminumFiles) ; + +# Add ThinkPad keyboard layout files to the image in a ThinkPad +# subdirectory. The subdirectory is turned into a submenu in the Layout menu +# of the Keymap preference app. +local thinkpadDir + = [ FDirName $(HAIKU_TOP) data system data KeyboardLayouts ThinkPad ] ; +local thinkPadFiles = + "ThinkPad (US)" + "ThinkPad International" + "ThinkPad T400s (US)" + "ThinkPad T400s International" + "ThinkPad X1 (US)" + "ThinkPad X1 International" + "ThinkPad X100e (US)" + "ThinkPad X100e International" ; +thinkPadFiles = $(thinkPadFiles:G=keyboard-layout) ; +SEARCH on $(thinkPadFiles) = $(thinkpadDir) ; +AddFilesToHaikuImage system data KeyboardLayouts ThinkPad + : $(thinkPadFiles) ; + +local driverSettingsFiles = kernel ; +SEARCH on $(driverSettingsFiles) + = [ FDirName $(HAIKU_TOP) data settings kernel drivers ] ; +AddFilesToHaikuImage home config settings kernel drivers + : $(driverSettingsFiles) ; + +# post install scripts and fresh install indicator file +local postInstallFiles = add_catalog_entry_attributes.sh + default_deskbar_items.sh mime_update.sh ; +postInstallFiles = $(postInstallFiles:G=post-install) ; +SEARCH on $(postInstallFiles) + = [ FDirName $(HAIKU_TOP) data common boot post_install ] ; +SEARCH on fresh_install + = [ FDirName $(HAIKU_TOP) data common settings ] ; +AddFilesToHaikuImage common boot post_install : $(postInstallFiles) ; +AddFilesToHaikuImage common settings : fresh_install ; + +# boot loader +AddFilesToHaikuImage system : haiku_loader ; + +# boot module links +AddBootModuleSymlinksToHaikuImage + $(ATA_ONLY)ata pci config_manager dpc scsi usb $(ATA_ONLY)ata_adapter + locked_pool scsi_periph ahci generic_ide_pci legacy_sata + uhci ohci ehci + scsi_cd scsi_disk usb_disk + intel + bfs +; + +# add-ons +AddFilesToHaikuImage system add-ons accelerants + : $(SYSTEM_ADD_ONS_ACCELERANTS) ; + +AddFilesToHaikuHybridImage system add-ons Translators + : $(SYSTEM_ADD_ONS_TRANSLATORS) : : true ; +AddFilesToHaikuImage system add-ons input_server devices + : keyboard mouse tablet wacom ; +AddFilesToHaikuImage system add-ons kernel network + : notifications stack ; +AddFilesToHaikuImage system add-ons kernel network devices + : $(SYSTEM_NETWORK_DEVICES) ; +AddFilesToHaikuImage system add-ons kernel network datalink_protocols + : $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ; +AddFilesToHaikuImage system add-ons kernel network protocols + : $(SYSTEM_NETWORK_PROTOCOLS) ; + +AddFilesToHaikuImage system add-ons disk_systems + : intel bfs ; + +# create directories that will remain empty +AddDirectoryToHaikuImage common bin ; +AddDirectoryToHaikuImage common include ; +AddDirectoryToHaikuImage common lib ; +AddDirectoryToHaikuImage home Desktop ; +AddDirectoryToHaikuImage home config bin ; +AddDirectoryToHaikuImage home config lib ; +AddDirectoryToHaikuImage home mail ; +AddDirectoryToHaikuImage common var empty ; +AddDirectoryToHaikuImage common var log ; +AddDirectoryToHaikuImage common cache tmp ; + +AddDirectoryToHaikuImage home config add-ons kernel drivers bin ; +AddDirectoryToHaikuImage home config add-ons kernel drivers dev ; +AddDirectoryToHaikuImage home config add-ons input_server devices ; +AddDirectoryToHaikuImage home config add-ons input_server filters ; +AddDirectoryToHaikuImage home config add-ons input_server methods ; +AddDirectoryToHaikuImage home config add-ons media plugins ; +AddDirectoryToHaikuImage home config add-ons Tracker ; +AddDirectoryToHaikuImage home config add-ons Print ; +AddDirectoryToHaikuImage home config add-ons Screen\ Savers ; +AddDirectoryToHaikuImage home config add-ons Translators ; +AddDirectoryToHaikuImage system data synth ; +AddDirectoryToHaikuImage system add-ons input_server methods ; + +# licenses +CopyDirectoryToHaikuImage system data + : [ FDirName $(HAIKU_TOP) data system data licenses ] + : licenses : -x .svn ; + +# Copy documentation as per DiskUsage's license requirement. +CopyDirectoryToHaikuImage system documentation + : [ FDirName $(HAIKU_TOP) docs apps diskusage ] + : diskusage : -x .svn ; + + +#pragma mark - Optional Packages + + +HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS = ; + +include [ FDirName $(HAIKU_BUILD_RULES_DIR) OptionalPackages ] ; +include [ FDirName $(HAIKU_BUILD_RULES_DIR) OptionalTestPackages ] ; +include [ FDirName $(HAIKU_BUILD_RULES_DIR) OptionalLibPackages ] ; + +local optionalPackageDescriptions ; +if $(HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS) { + optionalPackageDescriptions = optional_package_descriptions ; + MakeLocate $(optionalPackageDescriptions) + : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ; + + Depends $(optionalPackageDescriptions) + : $(HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS) ; + + actions together BuildOptionalPackageDescriptions + { + cat $(2) > $(1) + } + + BuildOptionalPackageDescriptions $(optionalPackageDescriptions) + : $(HAIKU_IMAGE_OPTIONAL_PACKAGE_DESCRIPTIONS) ; +} + + +#pragma mark - User/Group Setup + + +# add the root user and the root and users groups +AddUserToHaikuImage $(HAIKU_ROOT_USER_NAME:E=baron) : 0 : 0 : /boot/home + : /bin/bash : $(HAIKU_ROOT_USER_REAL_NAME:E="Root User") ; +AddGroupToHaikuImage root : 0 : ; +AddGroupToHaikuImage users : 100 : ; + + +#pragma mark - Host Name + + +if $(HAIKU_IMAGE_HOST_NAME) { + actions BuildHaikuImageHostnameFile + { + echo "$(HAIKU_IMAGE_HOST_NAME)" > $(1) + } + + local file = hostname ; + Always $(file) ; + MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ; + BuildHaikuImageHostnameFile $(file) ; + AddFilesToHaikuImage common settings network : $(file) ; +} + + +#pragma mark - Build The Image + + +# Execute pre-image user config rules. +UserBuildConfigRulePreImage ; + +# Set image name and directory defaults and locate the image. +HAIKU_IMAGE_NAME ?= $(HAIKU_DEFAULT_IMAGE_NAME) ; +HAIKU_IMAGE_DIR ?= $(HAIKU_DEFAULT_IMAGE_DIR) ; +HAIKU_IMAGE = $(HAIKU_IMAGE_NAME) ; +HAIKU_IMAGE_SIZE ?= $(HAIKU_DEFAULT_IMAGE_SIZE) ; # 300 MB +HAIKU_IMAGE_LABEL ?= $(HAIKU_DEFAULT_IMAGE_LABEL) ; +MakeLocate $(HAIKU_IMAGE) : $(HAIKU_IMAGE_DIR) ; + +# Set the default installation directory. +HAIKU_INSTALL_DIR ?= $(HAIKU_DEFAULT_INSTALL_DIR) ; + +# the pseudo target all image contents is attached to +NotFile $(HAIKU_IMAGE_CONTAINER_NAME) ; + +# prepare the script that initializes the shell variables +HAIKU_IMAGE_INIT_VARIABLES_SCRIPT = haiku.image-init-vars ; +local script = $(HAIKU_IMAGE_INIT_VARIABLES_SCRIPT) ; +MakeLocate $(script) : $(HAIKU_OUTPUT_DIR) ; +Always $(script) ; + +AddVariableToScript $(script) : sourceDir : $(HAIKU_TOP) ; +AddVariableToScript $(script) : outputDir : $(HAIKU_OUTPUT_DIR) ; +AddVariableToScript $(script) : tmpDir : $(HAIKU_TMP_DIR) ; +AddVariableToScript $(script) : installDir : $(HAIKU_INSTALL_DIR) ; +#AddVariableToScript $(script) : isImage : 1 ; +AddVariableToScript $(script) : imageSize : $(HAIKU_IMAGE_SIZE) ; +AddVariableToScript $(script) : imageLabel : $(HAIKU_IMAGE_LABEL) ; +AddVariableToScript $(script) : addBuildCompatibilityLibDir + : $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) ; +AddVariableToScript $(script) : dontClearImage : $(HAIKU_DONT_CLEAR_IMAGE) ; +AddVariableToScript $(script) : updateOnly : [ IsUpdateHaikuImageOnly ] ; +AddVariableToScript $(script) : stripOptionalPackageDebugSymbols + : $(HAIKU_STRIP_DEBUG_FROM_OPTIONAL_PACKAGES) ; +AddTargetVariableToScript $(script) : addattr ; +AddTargetVariableToScript $(script) : bfs_shell : bfsShell ; +AddTargetVariableToScript $(script) : fs_shell_command : fsShellCommand ; +AddTargetVariableToScript $(script) : copyattr ; +AddTargetVariableToScript $(script) : create_image : createImage ; +AddTargetVariableToScript $(script) : makebootable ; +AddTargetVariableToScript $(script) : rc ; +AddTargetVariableToScript $(script) : resattr ; +AddTargetVariableToScript $(script) : unzip ; +AddTargetVariableToScript $(script) : vmdkimage ; +if $(HOST_RM_ATTRS_TARGET) { + AddTargetVariableToScript $(script) : $(HOST_RM_ATTRS_TARGET) : rmAttrs ; +} else { + AddVariableToScript $(script) : rmAttrs : rm ; +} +if $(optionalPackageDescriptions) { + AddTargetVariableToScript $(script) : $(optionalPackageDescriptions) + : optionalPackageDescriptions ; +} + + +# create the other scripts +HAIKU_IMAGE_MAKE_DIRS_SCRIPT = haiku.image-make-dirs ; +HAIKU_IMAGE_COPY_FILES_SCRIPT = haiku.image-copy-files ; +HAIKU_IMAGE_EXTRACT_FILES_SCRIPT = haiku.image-extract-files ; +MakeLocate $(HAIKU_IMAGE_MAKE_DIRS_SCRIPT) $(HAIKU_IMAGE_COPY_FILES_SCRIPT) + $(HAIKU_IMAGE_EXTRACT_FILES_SCRIPT) : $(HAIKU_OUTPUT_DIR) ; + +CreateHaikuImageMakeDirectoriesScript $(HAIKU_IMAGE_MAKE_DIRS_SCRIPT) ; +CreateHaikuImageCopyFilesScript $(HAIKU_IMAGE_COPY_FILES_SCRIPT) ; +CreateHaikuImageExtractFilesScript $(HAIKU_IMAGE_EXTRACT_FILES_SCRIPT) ; + +# Convenience wrapper rule around BuildHaikuImage. +rule _BuildHaikuImage image : isImage : isVMwareImage +{ + # _BuildHaikuImage : : ; + # + + # build the image + # HAIKU_IMAGE_EARLY_USER_SCRIPTS, HAIKU_IMAGE_LATE_USER_SCRIPTS can be + # specified by the user. + BuildHaikuImage $(image) : + $(HAIKU_IMAGE_INIT_VARIABLES_SCRIPT) + $(HAIKU_IMAGE_EARLY_USER_SCRIPTS) + $(HAIKU_IMAGE_MAKE_DIRS_SCRIPT) + $(HAIKU_IMAGE_COPY_FILES_SCRIPT) + $(HAIKU_IMAGE_EXTRACT_FILES_SCRIPT) + $(HAIKU_IMAGE_LATE_USER_SCRIPTS) + : $(isImage) + : $(isVMwareImage) + ; + + # remove the scripts we have generated + RmTemps $(image) : + $(HAIKU_IMAGE_INIT_VARIABLES_SCRIPT) + $(HAIKU_IMAGE_MAKE_DIRS_SCRIPT) + $(HAIKU_IMAGE_COPY_FILES_SCRIPT) + $(HAIKU_IMAGE_EXTRACT_FILES_SCRIPT) + ; +} + +# build the image +_BuildHaikuImage $(HAIKU_IMAGE) : true ; +NotFile haiku-image ; +Depends haiku-image : $(HAIKU_IMAGE) ; + + +# install Haiku into a directory +NotFile install-haiku ; +_BuildHaikuImage install-haiku : 0 ; + + +# build the VMware image +HAIKU_VMWARE_IMAGE_NAME ?= $(HAIKU_DEFAULT_VMWARE_IMAGE_NAME) ; +HAIKU_VMWARE_IMAGE = $(HAIKU_VMWARE_IMAGE_NAME) ; +MakeLocate $(HAIKU_VMWARE_IMAGE) : $(HAIKU_IMAGE_DIR) ; + +_BuildHaikuImage $(HAIKU_VMWARE_IMAGE) : true : true ; +NotFile haiku-vmware-image ; +Depends haiku-vmware-image : $(HAIKU_VMWARE_IMAGE) ; + +# Execute post-image user config rules. +UserBuildConfigRulePostImage ; diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index b4b6fd85a0..b04d140172 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -5,6 +5,7 @@ local X86_ONLY = ; local PPC_ONLY = ; local M68K_ONLY = ; +local ARM_ONLY = ; if $(TARGET_ARCH) = x86 { X86_ONLY = "" ; } else if $(TARGET_ARCH) = ppc { @@ -86,8 +87,8 @@ SYSTEM_DEMOS = BSnow Chart Clock Cortex FontDemo $(X86_ONLY)GLTeapot SYSTEM_LIBS = libbe.so libbsd.so libbnetapi.so libdebug.so libdevice.so - libgame.so $(X86_ONLY)libGL.so libgnu.so - libmail.so libmedia.so libmidi.so libmidi2.so + libgame.so $(X86_ONLY)libGL.so $(X86_ONLY)libglut.so + libgnu.so libmail.so libmedia.so libmidi.so libmidi2.so libnetwork.so libroot.so libroot-addon-icu.so libscreensaver.so @@ -246,8 +247,8 @@ AddFilesToHaikuImage system add-ons kernel debugger AddFilesToHaikuImage system add-ons kernel file_systems : $(SYSTEM_ADD_ONS_FILE_SYSTEMS) ; AddFilesToHaikuImage system add-ons kernel generic - : $(ATA_ONLY)ata_adapter dpc $(IDE_ONLY)ide_adapter locked_pool mpu401 - scsi_periph tty ; + : $(ATA_ONLY)ata_adapter $(X86_ONLY)bios dpc $(IDE_ONLY)ide_adapter + locked_pool mpu401 scsi_periph tty ; #$(X86_ONLY)cpuidle ; AddFilesToHaikuImage system add-ons kernel partitioning_systems : amiga_rdb apple efi_gpt intel session ; AddFilesToHaikuImage system add-ons kernel interrupt_controllers @@ -261,6 +262,7 @@ if $(TARGET_ARCH) = x86 { AddNewDriversToHaikuImage disk scsi : scsi_cd scsi_disk ; AddNewDriversToHaikuImage power : $(X86_ONLY)enhanced_speedstep ; AddNewDriversToHaikuImage power : $(X86_ONLY)acpi_battery ; +#AddNewDriversToHaikuImage power : $(X86_ONLY)x86_cpuidle ; # legacy drivers AddDriversToHaikuImage : console dprintf null @@ -305,9 +307,8 @@ if $(HAIKU_GCC_VERSION[1]) = 2 { } -# libGL.so has GLU (like BeOS) *and* GLUT API built-in -SYSTEM_LIBS_LIBGL_ALIASES - = libGLU.so libglut.so ; +# libGL.so has GLU (like BeOS) built-in +SYSTEM_LIBS_LIBGL_ALIASES = libGLU.so ; if $(TARGET_ARCH) = x86 { local lib ; diff --git a/build/jam/KernelRules b/build/jam/KernelRules index 25b2260bf1..0ea34e8c59 100644 --- a/build/jam/KernelRules +++ b/build/jam/KernelRules @@ -48,9 +48,9 @@ rule KernelLd # libsupc++ is opt-out. local libs ; if ! [ on $(1) return HAIKU_NO_LIBSUPC++ ] { - libs += $(TARGET_STATIC_LIBSUPC++) ; + libs += $(TARGET_KERNEL_LIBSUPC++) ; } - LINKLIBS on $(1) = $(libs) $(TARGET_GCC_LIBGCC) ; + LINKLIBS on $(1) = $(libs) $(TARGET_KERNEL_LIBGCC) ; # TODO: Do we really want to invoke SetupKernel here? The objects should # have been compiled with KernelObjects anyway, so we're doing that twice. @@ -77,6 +77,24 @@ actions KernelLd bind VERSION_SCRIPT --version-script=$(VERSION_SCRIPT) } +rule KernelSo target : source +{ + # KernelSo : + + Depends $(target) : copyattr $(source) ; + + MakeLocateDebug $(1) ; + KernelSo1 $(target) : copyattr $(source) ; +} + +actions KernelSo1 +{ + $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) + + $(2[1]) --data $(2[2]) $(1) && + $(HAIKU_ELFEDIT) --output-type dyn $(1) +} + rule KernelAddon { # KernelAddon : : : ; @@ -117,7 +135,7 @@ rule KernelAddon # compile and link SetupKernel $(sources) : $(TARGET_KERNEL_PIC_FLAGS) : false ; local linkFlags = -nostdlib -Xlinker --no-undefined - -Xlinker -soname=\"$(target:G=)\" ; + -Xlinker -soname=\"$(target:G=)\" $(TARGET_KERNEL_ADDON_LINKFLAGS) ; LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] $(linkFlags) ; Main $(target) : $(sources) ; LinkAgainst $(target) : $(libs) $(kernel) ; diff --git a/build/jam/OptionalBuildFeatures b/build/jam/OptionalBuildFeatures index ca0097acf9..f83c2e76a9 100644 --- a/build/jam/OptionalBuildFeatures +++ b/build/jam/OptionalBuildFeatures @@ -69,12 +69,20 @@ if $(HAIKU_BUILD_FEATURE_SSL) { HAIKU_ICU_GCC_2_PACKAGE = icu-4.8.1.1-r1a4-x86-gcc2-2012-08-29.zip ; HAIKU_ICU_GCC_4_PACKAGE = icu-4.8.1.1-r1a4-x86-gcc4-2012-08-29.zip ; HAIKU_ICU_PPC_PACKAGE = icu-4.8.1-ppc-2011-08-20.zip ; +HAIKU_ICU_ARM_PACKAGE = icu-4.8.1.1-arm-2012-11-16.zip ; +HAIKU_ICU_X86_64_PACKAGE = icu-4.8.1.1-x86_64-2012-07-30.zip ; -if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { +if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = arm || $(TARGET_ARCH) = x86_64 { local icu_package ; if $(TARGET_ARCH) = ppc { icu_package = $(HAIKU_ICU_PPC_PACKAGE) ; HAIKU_ICU_DEVEL_PACKAGE = icu-devel-4.8.1-ppc-2011-12-19.zip ; + } else if $(TARGET_ARCH) = arm { + icu_package = $(HAIKU_ICU_ARM_PACKAGE) ; + HAIKU_ICU_DEVEL_PACKAGE = icu-devel-4.8.1.1-arm-2012-11-16.zip ; + } else if $(TARGET_ARCH) = x86_64 { + icu_package = $(HAIKU_ICU_X86_64_PACKAGE) ; + HAIKU_ICU_DEVEL_PACKAGE = icu-devel-4.8.1.1-x86_64-2012-07-30.zip ; } else if $(HAIKU_GCC_VERSION[1]) = 2 { icu_package = $(HAIKU_ICU_GCC_2_PACKAGE) ; HAIKU_ICU_DEVEL_PACKAGE = icu-devel-4.8.1.1-x86-gcc2-2011-12-20.zip ; @@ -209,8 +217,7 @@ if $(TARGET_ARCH) = x86 { local galliumObjects ; local zipFile ; if $(HAIKU_GCC_VERSION[1]) >= 4 { - HAIKU_MESA_FILE = mesa-8.1devel-x86-gcc4-2012-06-07.zip ; - #HAIKU_MESA_FILE = mesa-8.1develdbg-x86-gcc4-2012-06-07.zip ; + HAIKU_MESA_FILE = mesa-9.0-x86-gcc4-2012-11-17.zip ; glslObject = lib.haiku/libglsl.a ; galliumObjects = lib.haiku/libgallium.a ; } else { @@ -401,9 +408,11 @@ if $(TARGET_ARCH) = x86 { # Freetype local freetypeBaseURL = $(baseURL)/lib ; -if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { +if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 { if $(TARGET_ARCH) = ppc { HAIKU_FREETYPE_FILE = freetype-2.4.9-ppc-gcc4-2012-06-26.zip ; + } else if $(TARGET_ARCH) = x86_64 { + HAIKU_FREETYPE_FILE = freetype-2.4.9-x86_64-2012-08-04.zip ; } else if $(HAIKU_GCC_VERSION[1]) >= 4 { HAIKU_FREETYPE_FILE = freetype-2.4.9-r1a4-x86-gcc4-2012-09-02.zip ; } else { @@ -529,9 +538,11 @@ if $(HAIKU_BUILD_FEATURE_WEBKIT) { # libpng local libpngBaseURL = $(baseURL)/lib ; -if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { +if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 { if $(TARGET_ARCH) = ppc { HAIKU_LIBPNG_FILE = libpng-1.5.12-ppc-gcc4-2012-08-27.zip ; + } else if $(TARGET_ARCH) = x86_64 { + HAIKU_LIBPNG_FILE = libpng-1.5.12-x86_64-2012-11-18.zip ; } else if $(HAIKU_GCC_VERSION[1]) >= 4 { HAIKU_LIBPNG_FILE = libpng-1.5.12-x86-gcc4-2012-08-23.zip ; } else { @@ -569,9 +580,11 @@ if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { # jpeg local jpegBaseURL = $(baseURL)/lib ; -if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { +if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 { if $(TARGET_ARCH) = ppc { HAIKU_JPEG_FILE = jpeg-8d-ppc-gcc4-2012-08-27.zip ; + } else if $(TARGET_ARCH) = x86_64 { + HAIKU_JPEG_FILE = jpeg-8d-x86_64-2012-11-18.zip ; } else if $(HAIKU_GCC_VERSION[1]) >= 4 { HAIKU_JPEG_FILE = jpeg-8d-x86-gcc4-2012-08-23.zip ; } else { @@ -609,9 +622,11 @@ if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { # zlib local zlibBaseURL = $(baseURL)/lib ; -if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { +if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 { if $(TARGET_ARCH) = ppc { HAIKU_ZLIB_FILE = zlib-1.2.7-ppc-gcc4-2012-10-30.zip ; + } else if $(TARGET_ARCH) = x86_64 { + HAIKU_ZLIB_FILE = zlib-1.2.7-x86_64-2012-11-18.zip ; } else if $(HAIKU_GCC_VERSION[1]) >= 4 { HAIKU_ZLIB_FILE = zlib-1.2.7-x86-gcc4-2012-10-30.zip ; } else { diff --git a/build/jam/OptionalPackages b/build/jam/OptionalPackages index 3875fc71df..b4574e425a 100644 --- a/build/jam/OptionalPackages +++ b/build/jam/OptionalPackages @@ -355,18 +355,25 @@ if [ IsOptionalHaikuImagePackageAdded BurnItNow ] { # Bzip if [ IsOptionalHaikuImagePackageAdded Bzip ] { - if $(TARGET_ARCH) != x86 { - Echo "No optional package Bzip available for $(TARGET_ARCH)" ; - } else if $(HAIKU_GCC_VERSION[1]) >= 4 { + if $(TARGET_ARCH) = x86 { + if $(HAIKU_GCC_VERSION[1]) >= 4 { + InstallOptionalHaikuImagePackage + bzip2-1.0.6-r1a4-x86-gcc4-2012-08-30.zip + : $(baseURL)/bzip2-1.0.6-r1a4-x86-gcc4-2012-08-30.zip + : : true ; + } else { + InstallOptionalHaikuImagePackage + bzip2-1.0.6-r1a4-x86-gcc2-2012-08-27.zip + : $(baseURL)/bzip2-1.0.6-r1a4-x86-gcc2-2012-08-27.zip + : : true ; + } + } else if $(TARGET_ARCH) = x86_64 { InstallOptionalHaikuImagePackage - bzip2-1.0.6-r1a4-x86-gcc4-2012-08-30.zip - : $(baseURL)/bzip2-1.0.6-r1a4-x86-gcc4-2012-08-30.zip + bzip2-1.0.6-x86_64-2012-08-16.zip + : $(baseURL)/bzip2-1.0.6-x86_64-2012-08-16.zip : : true ; } else { - InstallOptionalHaikuImagePackage - bzip2-1.0.6-r1a4-x86-gcc2-2012-08-27.zip - : $(baseURL)/bzip2-1.0.6-r1a4-x86-gcc2-2012-08-27.zip - : : true ; + Echo "No optional package Bzip available for $(TARGET_ARCH)" ; } } @@ -609,125 +616,181 @@ if [ IsOptionalHaikuImagePackageAdded DemoPackage_Video ] { # Development -if [ IsOptionalHaikuImagePackageAdded Development ] && $(TARGET_ARCH) = x86 { - AddFilesToHaikuImage system apps : Debugger ; - AddSymlinkToHaikuImage home config settings deskbar Applications - : /boot/system/apps/Debugger : Debugger ; - # autotools - if $(HAIKU_GCC_VERSION[1]) >= 4 { +if [ IsOptionalHaikuImagePackageAdded Development ] { + if $(TARGET_ARCH) = x86 { + AddFilesToHaikuImage system apps : Debugger ; + AddSymlinkToHaikuImage home config settings deskbar Applications + : /boot/system/apps/Debugger : Debugger ; + # autotools + if $(HAIKU_GCC_VERSION[1]) >= 4 { + InstallOptionalHaikuImagePackage + autoconf-2.68-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/autoconf-2.68-r1a4-x86-gcc4-2012-08-28.zip + : : true ; + InstallOptionalHaikuImagePackage + automake-1.11.1-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/automake-1.11.1-r1a4-x86-gcc4-2012-08-28.zip + : : true ; + InstallOptionalHaikuImagePackage + libtool-2.4-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/libtool-2.4-r1a4-x86-gcc4-2012-08-28.zip + : : true ; + InstallOptionalHaikuImagePackage + texinfo-4.13a-r1a4-x86-gcc4-2012-08-30.zip + : $(baseURL)/texinfo-4.13a-r1a4-x86-gcc4-2012-08-30.zip + : : true ; + } else { + InstallOptionalHaikuImagePackage + autoconf-2.68-r1a4-x86-gcc2-2012-08-26.zip + : $(baseURL)/autoconf-2.68-r1a4-x86-gcc2-2012-08-26.zip + : : true ; + InstallOptionalHaikuImagePackage + automake-1.11.1-r1a4-x86-gcc2-2012-08-26.zip + : $(baseURL)/automake-1.11.1-r1a4-x86-gcc2-2012-08-26.zip + : : true ; + InstallOptionalHaikuImagePackage + libtool-2.4-r1a4-x86-gcc2-2012-08-26.zip + : $(baseURL)/libtool-2.4-r1a4-x86-gcc2-2012-08-26.zip + : : true ; + InstallOptionalHaikuImagePackage + texinfo-4.13a-r1a4-x86-gcc2-2012-08-28.zip + : $(baseURL)/texinfo-4.13a-r1a4-x86-gcc2-2012-08-28.zip + : : true ; + } + } else if $(TARGET_ARCH) = x86_64 { InstallOptionalHaikuImagePackage - autoconf-2.68-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/autoconf-2.68-r1a4-x86-gcc4-2012-08-28.zip + autoconf-2.69-x86_64-2012-08-17.zip + : $(baseURL)/autoconf-2.69-x86_64-2012-08-17.zip : : true ; InstallOptionalHaikuImagePackage - automake-1.11.1-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/automake-1.11.1-r1a4-x86-gcc4-2012-08-28.zip + automake-1.12.2-x86_64-2012-08-17.zip + : $(baseURL)/automake-1.12.2-x86_64-2012-08-17.zip : : true ; InstallOptionalHaikuImagePackage - libtool-2.4-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/libtool-2.4-r1a4-x86-gcc4-2012-08-28.zip + libtool-2.4.2-x86_64-2012-08-17.zip + : $(baseURL)/libtool-2.4.2-x86_64-2012-08-17.zip : : true ; InstallOptionalHaikuImagePackage - texinfo-4.13a-r1a4-x86-gcc4-2012-08-30.zip - : $(baseURL)/texinfo-4.13a-r1a4-x86-gcc4-2012-08-30.zip - : : true ; - } else { - InstallOptionalHaikuImagePackage - autoconf-2.68-r1a4-x86-gcc2-2012-08-26.zip - : $(baseURL)/autoconf-2.68-r1a4-x86-gcc2-2012-08-26.zip - : : true ; - InstallOptionalHaikuImagePackage - automake-1.11.1-r1a4-x86-gcc2-2012-08-26.zip - : $(baseURL)/automake-1.11.1-r1a4-x86-gcc2-2012-08-26.zip - : : true ; - InstallOptionalHaikuImagePackage - libtool-2.4-r1a4-x86-gcc2-2012-08-26.zip - : $(baseURL)/libtool-2.4-r1a4-x86-gcc2-2012-08-26.zip - : : true ; - InstallOptionalHaikuImagePackage - texinfo-4.13a-r1a4-x86-gcc2-2012-08-28.zip - : $(baseURL)/texinfo-4.13a-r1a4-x86-gcc2-2012-08-28.zip + texinfo-4.13a-x86_64-2012-08-17.zip + : $(baseURL)/texinfo-4.13a-x86_64-2012-08-17.zip : : true ; } } # DevelopmentBase -if [ IsOptionalHaikuImagePackageAdded DevelopmentBase ] - && $(TARGET_ARCH) = x86 { - # gcc and binutils - if $(HAIKU_GCC_VERSION[1]) = 2 || $(isHybridBuild) { +if [ IsOptionalHaikuImagePackageAdded DevelopmentBase ] { + if $(TARGET_ARCH) = x86 { + # gcc and binutils + if $(HAIKU_GCC_VERSION[1]) = 2 || $(isHybridBuild) { + InstallOptionalHaikuImagePackage + gcc-2.95.3-r1a4-x86-gcc2-2012-11-01.zip + : $(baseURL)/gcc-2.95.3-r1a4-x86-gcc2-2012-11-01.zip ; + } + + if $(HAIKU_GCC_VERSION[1]) = 2 { + # symlink to the appropriate system/lib[/gcc2] folder + AddSymlinkToHaikuHybridImage + develop abi x86 gcc2 tools gcc-2.95.3-haiku-121101 lib + : /system/lib libstdc++.r4.so : : true ; + } + + if $(HAIKU_GCC_VERSION[1]) = 4 || $(isHybridBuild) { + InstallOptionalHaikuImagePackage + gcc-4.6.3-r1a4-x86-gcc4-2012-11-01.zip + : $(baseURL)/gcc-4.6.3-r1a4-x86-gcc4-2012-11-01.zip ; + } + + if $(HAIKU_GCC_VERSION[1]) = 4 { + # symlink cpp to g++'s headers + AddSymlinkToHaikuHybridImage develop abi x86 gcc4 headers + : ../tools/current/include/g++ : cpp ; + + # symlink to the appropriate system/lib[/gcc4] folder + local libs = libstdc++.so libsupc++.so ; + for lib in $(libs) { + AddSymlinkToHaikuHybridImage + develop abi x86 gcc4 tools gcc-4.6.3-haiku-121101 lib + : /system/lib $(lib) : : true ; + } + } + + # other commonly used tools + if $(HAIKU_GCC_VERSION[1]) >= 4 { + InstallOptionalHaikuImagePackage + bison-2.4.3-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/bison-2.4.3-r1a4-x86-gcc4-2012-08-28.zip ; + InstallOptionalHaikuImagePackage + m4-1.4.16-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/m4-1.4.16-r1a4-x86-gcc4-2012-08-28.zip ; + InstallOptionalHaikuImagePackage + flex-2.5.35-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/flex-2.5.35-r1a4-x86-gcc4-2012-08-28.zip ; + InstallOptionalHaikuImagePackage + jam-2.5-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/jam-2.5-r1a4-x86-gcc4-2012-08-28.zip ; + InstallOptionalHaikuImagePackage + mkdepend-1.7-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/mkdepend-1.7-r1a4-x86-gcc4-2012-08-28.zip ; + InstallOptionalHaikuImagePackage + make-3.82-r1a4-x86-gcc4-2012-08-28.zip + : $(baseURL)/make-3.82-r1a4-x86-gcc4-2012-08-28.zip ; + } else { + InstallOptionalHaikuImagePackage + bison-2.4.3-r1a4-x86-gcc2-2012-08-26.zip + : $(baseURL)/bison-2.4.3-r1a4-x86-gcc2-2012-08-26.zip ; + InstallOptionalHaikuImagePackage + m4-1.4.16-r1a4-x86-gcc2-2012-08-26.zip + : $(baseURL)/m4-1.4.16-r1a4-x86-gcc2-2012-08-26.zip ; + InstallOptionalHaikuImagePackage + flex-2.5.35-r1a4-x86-gcc2-2012-09-10.zip + : $(baseURL)/flex-2.5.35-r1a4-x86-gcc2-2012-09-10.zip ; + InstallOptionalHaikuImagePackage + jam-2.5-r1a4-x86-gcc2-2012-08-27.zip + : $(baseURL)/jam-2.5-r1a4-x86-gcc2-2012-08-27.zip ; + InstallOptionalHaikuImagePackage + mkdepend-1.7-r1a4-x86-gcc2-2012-08-26.zip + : $(baseURL)/mkdepend-1.7-r1a4-x86-gcc2-2012-08-26.zip ; + InstallOptionalHaikuImagePackage + make-3.82-r1a4-x86-gcc2-2012-08-26.zip + : $(baseURL)/make-3.82-r1a4-x86-gcc2-2012-08-26.zip ; + } + } else if $(TARGET_ARCH) = x86_64 { + # gcc and binutils InstallOptionalHaikuImagePackage - gcc-2.95.3-r1a4-x86-gcc2-2012-11-01.zip - : $(baseURL)/gcc-2.95.3-r1a4-x86-gcc2-2012-11-01.zip ; - } + gcc-4.6.2-x86_64-2012-08-16.zip + : $(baseURL)/gcc-4.6.2-x86_64-2012-08-16.zip ; - if $(HAIKU_GCC_VERSION[1]) = 2 { - # symlink to the appropriate system/lib[/gcc2] folder - AddSymlinkToHaikuHybridImage - develop abi x86 gcc2 tools gcc-2.95.3-haiku-121101 lib - : /system/lib libstdc++.r4.so : : true ; - } - - if $(HAIKU_GCC_VERSION[1]) = 4 || $(isHybridBuild) { - InstallOptionalHaikuImagePackage - gcc-4.6.3-r1a4-x86-gcc4-2012-11-01.zip - : $(baseURL)/gcc-4.6.3-r1a4-x86-gcc4-2012-11-01.zip ; - } - - if $(HAIKU_GCC_VERSION[1]) = 4 { # symlink cpp to g++'s headers - AddSymlinkToHaikuHybridImage develop abi x86 gcc4 headers + AddSymlinkToHaikuHybridImage develop abi x86_64 gcc4 headers : ../tools/current/include/g++ : cpp ; # symlink to the appropriate system/lib[/gcc4] folder local libs = libstdc++.so libsupc++.so ; for lib in $(libs) { AddSymlinkToHaikuHybridImage - develop abi x86 gcc4 tools gcc-4.6.3-haiku-121101 lib + develop abi x86_64 gcc4 tools gcc-4.6.2-haiku-120816 lib : /system/lib $(lib) : : true ; } - } - # other commonly used tools - if $(HAIKU_GCC_VERSION[1]) >= 4 { InstallOptionalHaikuImagePackage - bison-2.4.3-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/bison-2.4.3-r1a4-x86-gcc4-2012-08-28.zip ; + bison-2.5-x86_64-2012-08-12.zip + : $(baseURL)/bison-2.5-x86_64-2012-08-12.zip ; InstallOptionalHaikuImagePackage - m4-1.4.16-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/m4-1.4.16-r1a4-x86-gcc4-2012-08-28.zip ; + m4-1.4.16-x86_64-2012-08-12.zip + : $(baseURL)/m4-1.4.16-x86_64-2012-08-12.zip ; InstallOptionalHaikuImagePackage - flex-2.5.35-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/flex-2.5.35-r1a4-x86-gcc4-2012-08-28.zip ; + flex-2.5.35-x86_64-2012-08-18.zip + : $(baseURL)/flex-2.5.35-x86_64-2012-08-18.zip ; InstallOptionalHaikuImagePackage - jam-2.5-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/jam-2.5-r1a4-x86-gcc4-2012-08-28.zip ; + jam-2.5-x86_64-2012-08-12.zip + : $(baseURL)/jam-2.5-x86_64-2012-08-12.zip ; InstallOptionalHaikuImagePackage - mkdepend-1.7-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/mkdepend-1.7-r1a4-x86-gcc4-2012-08-28.zip ; + mkdepend-1.7-x86_64-2012-08-14.zip + : $(baseURL)/mkdepend-1.7-x86_64-2012-08-14.zip ; InstallOptionalHaikuImagePackage - make-3.82-r1a4-x86-gcc4-2012-08-28.zip - : $(baseURL)/make-3.82-r1a4-x86-gcc4-2012-08-28.zip ; - } else { - InstallOptionalHaikuImagePackage - bison-2.4.3-r1a4-x86-gcc2-2012-08-26.zip - : $(baseURL)/bison-2.4.3-r1a4-x86-gcc2-2012-08-26.zip ; - InstallOptionalHaikuImagePackage - m4-1.4.16-r1a4-x86-gcc2-2012-08-26.zip - : $(baseURL)/m4-1.4.16-r1a4-x86-gcc2-2012-08-26.zip ; - InstallOptionalHaikuImagePackage - flex-2.5.35-r1a4-x86-gcc2-2012-09-10.zip - : $(baseURL)/flex-2.5.35-r1a4-x86-gcc2-2012-09-10.zip ; - InstallOptionalHaikuImagePackage - jam-2.5-r1a4-x86-gcc2-2012-08-27.zip - : $(baseURL)/jam-2.5-r1a4-x86-gcc2-2012-08-27.zip ; - InstallOptionalHaikuImagePackage - mkdepend-1.7-r1a4-x86-gcc2-2012-08-26.zip - : $(baseURL)/mkdepend-1.7-r1a4-x86-gcc2-2012-08-26.zip ; - InstallOptionalHaikuImagePackage - make-3.82-r1a4-x86-gcc2-2012-08-26.zip - : $(baseURL)/make-3.82-r1a4-x86-gcc2-2012-08-26.zip ; + make-3.82-x86_64-2012-08-11.zip + : $(baseURL)/make-3.82-x86_64-2012-08-11.zip ; } } @@ -754,7 +817,8 @@ if [ IsOptionalHaikuImagePackageAdded DevelopmentJava ] { # DevelopmentMin -if [ IsOptionalHaikuImagePackageAdded DevelopmentMin ] && $(TARGET_ARCH) = x86 { +if [ IsOptionalHaikuImagePackageAdded DevelopmentMin ] + && ( $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 ) { if ! ( $(HAIKU_GCC_VERSION[1]) in 2 4 ) { Exit "Optional package DevelopmentMin: Unsupported GCC version:" $(HAIKU_GCC_VERSION[1]) ; @@ -988,9 +1052,7 @@ if [ IsOptionalHaikuImagePackageAdded friss ] { # GetText if [ IsOptionalHaikuImagePackageAdded GetText ] { - if $(TARGET_ARCH) != x86 { - Echo "No optional package GetText available for $(TARGET_ARCH)" ; - } else { + if $(TARGET_ARCH) = x86 { if $(HAIKU_GCC_VERSION[1]) >= 4 { InstallOptionalHaikuImagePackage gettext-0.18.1.1-r1a4-x86-gcc4-2012-08-30.zip @@ -1002,6 +1064,13 @@ if [ IsOptionalHaikuImagePackageAdded GetText ] { : $(baseURL)/gettext-0.18.1.1-r1a4-x86-gcc2-2012-08-28.zip : : true ; } + } else if $(TARGET_ARCH) = x86_64 { + InstallOptionalHaikuImagePackage + gettext-0.18.1.1-x86_64-2012-08-17.zip + : $(baseURL)/gettext-0.18.1.1-x86_64-2012-08-17.zip + : : true ; + } else { + Echo "No optional package GetText available for $(TARGET_ARCH)" ; } } @@ -1100,9 +1169,7 @@ if [ IsOptionalHaikuImagePackageAdded HGrep ] { # ICU if [ IsOptionalHaikuImagePackageAdded ICU ] { - if $(TARGET_ARCH) != x86 { - Echo "No optional package ICU available for $(TARGET_ARCH)" ; - } else { + if $(TARGET_ARCH) = x86 { if $(HAIKU_GCC_VERSION[1]) = 2 { # unzip gcc2 InstallOptionalHaikuImagePackage $(HAIKU_ICU_GCC_2_PACKAGE) @@ -1126,6 +1193,16 @@ if [ IsOptionalHaikuImagePackageAdded ICU ] { : system lib gcc2 ; } } + } else if $(TARGET_ARCH) = arm { + InstallOptionalHaikuImagePackage $(HAIKU_ICU_ARM_PACKAGE) + : $(baseURL)/(HAIKU_ICU_ARM_PACKAGE) + : system lib ; + } else if $(TARGET_ARCH) = x86_64 { + InstallOptionalHaikuImagePackage $(HAIKU_ICU_X86_64_PACKAGE) + : $(baseURL)/$(HAIKU_ICU_X86_64_PACKAGE) + : system lib ; + } else { + Echo "No optional package ICU available for $(TARGET_ARCH)" ; } } @@ -1374,9 +1451,7 @@ if [ IsOptionalHaikuImagePackageAdded Mercurial ] { # Nano if [ IsOptionalHaikuImagePackageAdded Nano ] { - if $(TARGET_ARCH) != x86 { - Echo "No optional package Nano available for $(TARGET_ARCH)" ; - } else { + if $(TARGET_ARCH) = x86 { if $(HAIKU_GCC_VERSION[1]) >= 4 { InstallOptionalHaikuImagePackage nano-2.2.6-r1a4-x86-gcc4-2012-08-30.zip @@ -1386,6 +1461,12 @@ if [ IsOptionalHaikuImagePackageAdded Nano ] { nano-2.2.6-r1a4-x86-gcc2-2012-08-28.zip : $(baseURL)/nano-2.2.6-r1a4-x86-gcc2-2012-08-28.zip ; } + } else if $(TARGET_ARCH) = x86_64 { + InstallOptionalHaikuImagePackage + nano-2.3.1-x86_64-2012-08-17.zip + : $(baseURL)/nano-2.3.1-x86_64-2012-08-17.zip ; + } else { + Echo "No optional package Nano available for $(TARGET_ARCH)" ; } } @@ -1627,9 +1708,7 @@ if [ IsOptionalHaikuImagePackageAdded Pe ] { # Perl if [ IsOptionalHaikuImagePackageAdded Perl ] { - if $(TARGET_ARCH) != x86 { - Echo "No optional package Perl available for $(TARGET_ARCH)" ; - } else { + if $(TARGET_ARCH) = x86 { if $(HAIKU_GCC_VERSION[1]) >= 4 { InstallOptionalHaikuImagePackage perl-5.10.1-r1a4-x86-gcc4-2012-10-17.zip @@ -1641,6 +1720,13 @@ if [ IsOptionalHaikuImagePackageAdded Perl ] { : $(baseURL)/perl-5.10.1-r1a4-x86-gcc2-2012-08-27.zip : : true ; } + } else if $(TARGET_ARCH) = x86_64 { + InstallOptionalHaikuImagePackage + perl-5.10.1-x86_64-2012-08-17.zip + : $(baseURL)/perl-5.10.1-x86_64-2012-08-17.zip + : : true ; + } else { + Echo "No optional package Perl available for $(TARGET_ARCH)" ; } } @@ -1719,16 +1805,22 @@ if [ IsOptionalHaikuImagePackageAdded Ruby ] { # Sed if [ IsOptionalHaikuImagePackageAdded Sed ] { - if $(TARGET_ARCH) != x86 { - Echo "No optional package Sed available for $(TARGET_ARCH)" ; - } else if $(HAIKU_GCC_VERSION[1]) >= 4 { + if $(TARGET_ARCH) = x86 { + if $(HAIKU_GCC_VERSION[1]) >= 4 { + InstallOptionalHaikuImagePackage + sed-4.2.1-r1a4-x86-gcc4-2012-08-31.zip + : $(baseURL)/sed-4.2.1-r1a4-x86-gcc4-2012-08-31.zip ; + } else { + InstallOptionalHaikuImagePackage + sed-4.2.1-r1a4-x86-gcc2-2012-08-27.zip + : $(baseURL)/sed-4.2.1-r1a4-x86-gcc2-2012-08-27.zip ; + } + } else if $(TARGET_ARCH) = x86_64 { InstallOptionalHaikuImagePackage - sed-4.2.1-r1a4-x86-gcc4-2012-08-31.zip - : $(baseURL)/sed-4.2.1-r1a4-x86-gcc4-2012-08-31.zip ; + sed-4.2.1-x86_64-2012-08-14.zip + : $(baseURL)/sed-4.2.1-x86_64-2012-08-14.zip ; } else { - InstallOptionalHaikuImagePackage - sed-4.2.1-r1a4-x86-gcc2-2012-08-27.zip - : $(baseURL)/sed-4.2.1-r1a4-x86-gcc2-2012-08-27.zip ; + Echo "No optional package Sed available for $(TARGET_ARCH)" ; } } @@ -1789,9 +1881,7 @@ if [ IsOptionalHaikuImagePackageAdded TagLib ] { # Tar if [ IsOptionalHaikuImagePackageAdded Tar ] { - if $(TARGET_ARCH) != x86 { - Echo "No optional package Tar available for $(TARGET_ARCH)" ; - } else { + if $(TARGET_ARCH) = x86 { if $(HAIKU_GCC_VERSION[1]) >= 4 { InstallOptionalHaikuImagePackage tar-1.26-r1a4-x86-gcc4-2012-09-03.zip @@ -1801,6 +1891,12 @@ if [ IsOptionalHaikuImagePackageAdded Tar ] { tar-1.26-r1a4-x86-gcc2-2012-08-29.zip : $(baseURL)/tar-1.26-r1a4-x86-gcc2-2012-08-29.zip ; } + } else if $(TARGET_ARCH) = x86_64 { + InstallOptionalHaikuImagePackage + tar-1.26-x86_64-2012-08-12.zip + : $(baseURL)/tar-1.26-x86_64-2012-08-12.zip ; + } else { + Echo "No optional package Tar available for $(TARGET_ARCH)" ; } } diff --git a/build/scripts/build_cross_tools_gcc4 b/build/scripts/build_cross_tools_gcc4 index 320420f8ea..3f5a99696d 100755 --- a/build/scripts/build_cross_tools_gcc4 +++ b/build/scripts/build_cross_tools_gcc4 @@ -33,6 +33,7 @@ x86_64-*) # failure binutilsConfigureArgs="" gccConfigureArgs="" + kernelCcFlags="-mno-red-zone" ;; m68k-*) binutilsConfigureArgs="--enable-multilib" @@ -45,6 +46,7 @@ arm-*) *) binutilsConfigureArgs="--disable-multilib" gccConfigureArgs="--disable-multilib" + kernelCcFlags= ;; esac @@ -101,13 +103,14 @@ installDir=$haikuOutputDir/cross-tools objDir=$haikuOutputDir/cross-tools-build binutilsObjDir=$objDir/binutils gccObjDir=$objDir/gcc +stdcxxObjDir=$objDir/stdcxx tmpIncludeDir=$objDir/sysincludes tmpLibDir=$objDir/syslibs rm -rf $installDir $objDir -mkdir -p $installDir $objDir $binutilsObjDir $gccObjDir $tmpIncludeDir \ - $tmpLibDir || exit 1 +mkdir -p $installDir $objDir $binutilsObjDir $gccObjDir $stdcxxObjDir \ + $tmpIncludeDir $tmpLibDir || exit 1 mkdir -p $installDir/lib/gcc/$haikuMachine/$gccVersion # force the POSIX locale, as the build (makeinfo) might choke otherwise @@ -165,6 +168,28 @@ $MAKE $additionalMakeArgs install || { exit 1 } +# build libraries for the kernel if the target arch requires it +if [ -n "$kernelCcFlags" ]; then + $MAKE -C $haikuMachine/libgcc clean + $MAKE -C $haikuMachine/libgcc CFLAGS="-g -O2 $kernelCcFlags" || { + echo "Error: Building kernel libgcc failed." >&2 + exit 1 + } + + cp $haikuMachine/libgcc/libgcc.a \ + $installDir/$haikuMachine/lib/libgcc-kernel.a || exit 1 + + $MAKE -C $haikuMachine/libstdc++-v3/libsupc++ clean + $MAKE -C $haikuMachine/libstdc++-v3/libsupc++ CFLAGS="-g -O2 $kernelCcFlags" \ + CXXFLAGS="-g -O2 $kernelCcFlags" || { + echo "Error: Building kernel libsupc++ failed." >&2 + exit 1 + } + + cp $haikuMachine/libstdc++-v3/libsupc++/.libs/libsupc++.a \ + $installDir/$haikuMachine/lib/libsupc++-kernel.a || exit 1 +fi + # cleanup # remove the system headers from the installation dir diff --git a/configure b/configure index fb2b95e921..f0df8ebabf 100755 --- a/configure +++ b/configure @@ -188,6 +188,17 @@ standard_gcc_settings() HAIKU_STATIC_LIBSUPCXX=`$HAIKU_CC -print-file-name=libsupc++.a` HAIKU_SHARED_LIBSUPCXX=`$HAIKU_CC -print-file-name=libsupc++.so` + # If the architecture has separate runtime libraries for the + # kernel, use them. + HAIKU_KERNEL_LIBGCC=`$HAIKU_CC -print-file-name=libgcc-kernel.a` + if [ $HAIKU_KERNEL_LIBGCC = libgcc-kernel.a ]; then + HAIKU_KERNEL_LIBGCC=$HAIKU_GCC_LIBGCC + fi + HAIKU_KERNEL_LIBSUPCXX=`$HAIKU_CC -print-file-name=libsupc++-kernel.a` + if [ $HAIKU_KERNEL_LIBSUPCXX = libsupc++-kernel.a ]; then + HAIKU_KERNEL_LIBSUPCXX=$HAIKU_STATIC_LIBSUPCXX + fi + local headers if [ -d $gccdir/../../../../$HAIKU_GCC_MACHINE/include/c++/$HAIKU_GCC_RAW_VERSION ]; then headers=$gccdir/../../../../$HAIKU_GCC_MACHINE/include/c++/$HAIKU_GCC_RAW_VERSION @@ -240,6 +251,21 @@ standard_gcc_settings() echo "Please download it from www.haiku-os.org..."; exit 1; fi + + HAIKU_KERNEL_LIBGCC=$HAIKU_GCC_LIBGCC + HAIKU_KERNEL_LIBSUPCXX= + ;; + esac + + case $HAIKU_GCC_MACHINE in + x86_64-*) + # Boot loader is 32-bit, need the 32-bit libs. + HAIKU_BOOT_LIBGCC=`$HAIKU_CC -m32 -print-libgcc-file-name` + HAIKU_BOOT_LIBSUPCXX=`$HAIKU_CC -m32 -print-file-name=libsupc++.a` + ;; + *) + HAIKU_BOOT_LIBGCC=$HAIKU_GCC_LIBGCC + HAIKU_BOOT_LIBSUPCXX=$HAIKU_STATIC_LIBSUPCXX ;; esac } @@ -336,6 +362,7 @@ set_default_value HAIKU_CC gcc set_default_value HAIKU_LD ld set_default_value HAIKU_OBJCOPY objcopy set_default_value HAIKU_RANLIB ranlib +set_default_value HAIKU_ELFEDIT elfedit set_default_value HAIKU_YASM yasm set_default_value HAIKU_CPPFLAGS "" set_default_value HAIKU_CCFLAGS "" @@ -392,7 +419,7 @@ while [ $# -gt 0 ] ; do buildCrossToolsScript="${buildCrossToolsScript}_gcc4" case "$2" in x86) HAIKU_GCC_MACHINE=i586-pc-haiku;; - x86_64) HAIKU_GCC_MACHINE=x86_64-pc-haiku; targetArch=x86_64;; + x86_64) HAIKU_GCC_MACHINE=x86_64-unknown-haiku; targetArch=x86_64;; ppc) HAIKU_GCC_MACHINE=powerpc-apple-haiku; targetArch=ppc;; m68k) HAIKU_GCC_MACHINE=m68k-unknown-haiku; targetArch=m68k;; arm) HAIKU_GCC_MACHINE=arm-unknown-haiku; targetArch=arm;; @@ -507,6 +534,15 @@ fi # prepare gcc settings standard_gcc_settings +# cross tools for gcc4 builds +if [ -n "$crossToolsPrefix" ]; then + case $HAIKU_GCC_RAW_VERSION in + 4.*) + get_build_tool_path ELFEDIT elfedit + ;; + esac +fi + # check whether the Haiku compiler really targets Haiku or BeOS case "$HAIKU_GCC_MACHINE" in *-*-haiku) ;; @@ -552,6 +588,11 @@ HAIKU_STATIC_LIBSUPC++ ?= ${HAIKU_STATIC_LIBSUPCXX} ; HAIKU_SHARED_LIBSUPC++ ?= ${HAIKU_SHARED_LIBSUPCXX} ; HAIKU_C++_HEADERS_DIR ?= ${HAIKU_CXX_HEADERS_DIR} ; +HAIKU_KERNEL_LIBGCC ?= ${HAIKU_KERNEL_LIBGCC} ; +HAIKU_KERNEL_LIBSUPC++ ?= ${HAIKU_KERNEL_LIBSUPCXX} ; +HAIKU_BOOT_LIBGCC ?= ${HAIKU_BOOT_LIBGCC} ; +HAIKU_BOOT_LIBSUPC++ ?= ${HAIKU_BOOT_LIBSUPCXX} ; + HAIKU_BUILD_ATTRIBUTES_DIR ?= ${HAIKU_BUILD_ATTRIBUTES_DIR} ; HAIKU_AR ?= ${HAIKU_AR} ; @@ -559,6 +600,7 @@ HAIKU_CC ?= ${HAIKU_CC} ; HAIKU_LD ?= ${HAIKU_LD} ; HAIKU_OBJCOPY ?= ${HAIKU_OBJCOPY} ; HAIKU_RANLIB ?= ${HAIKU_RANLIB} ; +HAIKU_ELFEDIT ?= ${HAIKU_ELFEDIT} ; HAIKU_YASM ?= ${HAIKU_YASM} ; HAIKU_CPPFLAGS ?= ${HAIKU_CPPFLAGS} ; HAIKU_CCFLAGS ?= ${HAIKU_CCFLAGS} ; diff --git a/data/system/boot/Bootscript b/data/system/boot/Bootscript index 04a73bf6e6..3a52cb2ea2 100644 --- a/data/system/boot/Bootscript +++ b/data/system/boot/Bootscript @@ -96,6 +96,12 @@ fi # We must wait for the app_server and registrar to be ready launch $SERVERS/registrar _roster_thread_ # launch registrar +# If app_server doesn't exist, just run consoled. +if [ ! -f "/boot/$SERVERS/app_server" ]; then + /bin/consoled + exit +fi + launch $SERVERS/debug_server # launch debug_server # Init Network diff --git a/data/system/boot/SetupEnvironment b/data/system/boot/SetupEnvironment index e8d57bd652..f7392e7d00 100644 --- a/data/system/boot/SetupEnvironment +++ b/data/system/boot/SetupEnvironment @@ -17,7 +17,7 @@ BeMac|BeBox) BE_HOST_CPU=ppc ;; *) - BE_HOST_CPU=unknown + BE_HOST_CPU=`uname -m` esac BELIBRARIES="$BUILDHOME/abi/current/library-paths/common:$BUILDHOME/lib/$BE_HOST_CPU" diff --git a/headers/config/types.h b/headers/config/types.h index 84209791b5..13f1dc0ac4 100644 --- a/headers/config/types.h +++ b/headers/config/types.h @@ -20,8 +20,13 @@ typedef signed short __haiku_std_int16; typedef unsigned short __haiku_std_uint16; typedef signed int __haiku_std_int32; typedef unsigned int __haiku_std_uint32; +#ifdef __HAIKU_ARCH_64_BIT +typedef signed long __haiku_std_int64; +typedef unsigned long __haiku_std_uint64; +#else typedef signed long long __haiku_std_int64; typedef unsigned long long __haiku_std_uint64; +#endif typedef __haiku_std_int8 __haiku_int8; typedef __haiku_std_uint8 __haiku_uint8; @@ -38,17 +43,12 @@ typedef __haiku_std_int64 __haiku_int64; typedef __haiku_std_uint64 __haiku_uint64; /* address types */ -#ifdef __HAIKU_ARCH_64_BIT - typedef __haiku_int64 __haiku_saddr_t; - typedef __haiku_uint64 __haiku_addr_t; -#else - typedef __haiku_int32 __haiku_saddr_t; - typedef __haiku_uint32 __haiku_addr_t; -#endif +typedef signed long int __haiku_saddr_t; +typedef unsigned long int __haiku_addr_t; #ifdef __HAIKU_ARCH_PHYSICAL_64_BIT - typedef __haiku_int64 __haiku_phys_saddr_t; - typedef __haiku_uint64 __haiku_phys_addr_t; + typedef __haiku_int64 __haiku_phys_saddr_t; + typedef __haiku_uint64 __haiku_phys_addr_t; #else typedef __haiku_int32 __haiku_phys_saddr_t; typedef __haiku_uint32 __haiku_phys_addr_t; @@ -76,20 +76,20 @@ typedef __haiku_std_uint64 __haiku_uint64; /* printf()/scanf() format prefixes */ #define __HAIKU_STD_PRI_PREFIX_32 "" -#define __HAIKU_STD_PRI_PREFIX_64 "ll" +#ifdef __HAIKU_ARCH_64_BIT +# define __HAIKU_STD_PRI_PREFIX_64 "l" +#else +# define __HAIKU_STD_PRI_PREFIX_64 "ll" +#endif #ifdef __HAIKU_BEOS_COMPATIBLE_TYPES -# define __HAIKU_PRI_PREFIX_32 "l" +# define __HAIKU_PRI_PREFIX_32 "l" #else -# define __HAIKU_PRI_PREFIX_32 __HAIKU_STD_PRI_PREFIX_32 +# define __HAIKU_PRI_PREFIX_32 __HAIKU_STD_PRI_PREFIX_32 #endif -#define __HAIKU_PRI_PREFIX_64 __HAIKU_STD_PRI_PREFIX_64 +#define __HAIKU_PRI_PREFIX_64 __HAIKU_STD_PRI_PREFIX_64 -#ifdef __HAIKU_ARCH_64_BIT -# define __HAIKU_PRI_PREFIX_ADDR __HAIKU_PRI_PREFIX_64 -#else -# define __HAIKU_PRI_PREFIX_ADDR __HAIKU_PRI_PREFIX_32 -#endif +#define __HAIKU_PRI_PREFIX_ADDR "l" #ifdef __HAIKU_ARCH_PHYSICAL_64_BIT # define __HAIKU_PRI_PREFIX_PHYS_ADDR __HAIKU_PRI_PREFIX_64 diff --git a/headers/libs/x86emu/x86emu.h b/headers/libs/x86emu/x86emu.h new file mode 100644 index 0000000000..501dd913c9 --- /dev/null +++ b/headers/libs/x86emu/x86emu.h @@ -0,0 +1,197 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for public specific functions. +* Any application linking against us should only +* include this header +* +****************************************************************************/ + +#ifndef __X86EMU_X86EMU_H +#define __X86EMU_X86EMU_H + +#ifdef SCITECH +#include "scitech.h" +#define X86API _ASMAPI +#define X86APIP _ASMAPIP +typedef int X86EMU_pioAddr; +#else +#include "x86emu/types.h" +#define X86API +#define X86APIP * +#endif +#include "x86emu/regs.h" + +/*---------------------- Macros and type definitions ----------------------*/ + +#ifdef PACK +#pragma PACK /* Don't pack structs with function pointers! */ +#endif + +/**************************************************************************** +REMARKS: +Data structure containing ponters to programmed I/O functions used by the +emulator. This is used so that the user program can hook all programmed +I/O for the emulator to handled as necessary by the user program. By +default the emulator contains simple functions that do not do access the +hardware in any way. To allow the emualtor access the hardware, you will +need to override the programmed I/O functions using the X86EMU_setupPioFuncs +function. + +HEADER: +x86emu.h + +MEMBERS: +inb - Function to read a byte from an I/O port +inw - Function to read a word from an I/O port +inl - Function to read a dword from an I/O port +outb - Function to write a byte to an I/O port +outw - Function to write a word to an I/O port +outl - Function to write a dword to an I/O port +****************************************************************************/ +typedef struct { + u8(X86APIP inb) (X86EMU_pioAddr addr); + u16(X86APIP inw) (X86EMU_pioAddr addr); + u32(X86APIP inl) (X86EMU_pioAddr addr); + void (X86APIP outb) (X86EMU_pioAddr addr, u8 val); + void (X86APIP outw) (X86EMU_pioAddr addr, u16 val); + void (X86APIP outl) (X86EMU_pioAddr addr, u32 val); +} X86EMU_pioFuncs; + +/**************************************************************************** +REMARKS: +Data structure containing ponters to memory access functions used by the +emulator. This is used so that the user program can hook all memory +access functions as necessary for the emulator. By default the emulator +contains simple functions that only access the internal memory of the +emulator. If you need specialised functions to handle access to different +types of memory (ie: hardware framebuffer accesses and BIOS memory access +etc), you will need to override this using the X86EMU_setupMemFuncs +function. + +HEADER: +x86emu.h + +MEMBERS: +rdb - Function to read a byte from an address +rdw - Function to read a word from an address +rdl - Function to read a dword from an address +wrb - Function to write a byte to an address +wrw - Function to write a word to an address +wrl - Function to write a dword to an address +****************************************************************************/ +typedef struct { + u8(X86APIP rdb) (u32 addr); + u16(X86APIP rdw) (u32 addr); + u32(X86APIP rdl) (u32 addr); + void (X86APIP wrb) (u32 addr, u8 val); + void (X86APIP wrw) (u32 addr, u16 val); + void (X86APIP wrl) (u32 addr, u32 val); +} X86EMU_memFuncs; + +/**************************************************************************** + Here are the default memory read and write + function in case they are needed as fallbacks. +***************************************************************************/ +extern u8 X86API rdb(u32 addr); +extern u16 X86API rdw(u32 addr); +extern u32 X86API rdl(u32 addr); +extern void X86API wrb(u32 addr, u8 val); +extern void X86API wrw(u32 addr, u16 val); +extern void X86API wrl(u32 addr, u32 val); + +#ifdef END_PACK +#pragma END_PACK +#endif + +/*--------------------- type definitions -----------------------------------*/ + +typedef void (X86APIP X86EMU_intrFuncs) (int num); +extern X86EMU_intrFuncs _X86EMU_intrTab[256]; + +/*-------------------------- Function Prototypes --------------------------*/ + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + + void X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs); + void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs); + void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]); + void X86EMU_prepareForInt(int num); + +/* decode.c */ + + void X86EMU_exec(void); + void X86EMU_halt_sys(void); + +#ifdef DEBUG +#define HALT_SYS() \ + printk("halt_sys: file %s, line %d\n", __FILE__, __LINE__), \ + X86EMU_halt_sys() +#else +#define HALT_SYS() X86EMU_halt_sys() +#endif + +/* Debug options */ + +#define DEBUG_DECODE_F 0x000001 /* print decoded instruction */ +#define DEBUG_TRACE_F 0x000002 /* dump regs before/after execution */ +#define DEBUG_STEP_F 0x000004 +#define DEBUG_DISASSEMBLE_F 0x000008 +#define DEBUG_BREAK_F 0x000010 +#define DEBUG_SVC_F 0x000020 +#define DEBUG_SAVE_IP_CS_F 0x000040 +#define DEBUG_FS_F 0x000080 +#define DEBUG_PROC_F 0x000100 +#define DEBUG_SYSINT_F 0x000200 /* bios system interrupts. */ +#define DEBUG_TRACECALL_F 0x000400 +#define DEBUG_INSTRUMENT_F 0x000800 +#define DEBUG_MEM_TRACE_F 0x001000 +#define DEBUG_IO_TRACE_F 0x002000 +#define DEBUG_TRACECALL_REGS_F 0x004000 +#define DEBUG_DECODE_NOPRINT_F 0x008000 +#define DEBUG_EXIT 0x010000 +#define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F) + + void X86EMU_trace_regs(void); + void X86EMU_trace_xregs(void); + void X86EMU_dump_memory(u16 seg, u16 off, u32 amt); + int X86EMU_trace_on(void); + int X86EMU_trace_off(void); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif +#endif /* __X86EMU_X86EMU_H */ diff --git a/headers/libs/x86emu/x86emu/debug.h b/headers/libs/x86emu/x86emu/debug.h new file mode 100644 index 0000000000..385b804dd7 --- /dev/null +++ b/headers/libs/x86emu/x86emu/debug.h @@ -0,0 +1,209 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for debug definitions. +* +****************************************************************************/ + +#ifndef __X86EMU_DEBUG_H +#define __X86EMU_DEBUG_H + +/*---------------------- Macros and type definitions ----------------------*/ + +/* checks to be enabled for "runtime" */ + +#define CHECK_IP_FETCH_F 0x1 +#define CHECK_SP_ACCESS_F 0x2 +#define CHECK_MEM_ACCESS_F 0x4 /*using regular linear pointer */ +#define CHECK_DATA_ACCESS_F 0x8 /*using segment:offset */ + +#ifdef DEBUG +#define CHECK_IP_FETCH() (M.x86.check & CHECK_IP_FETCH_F) +#define CHECK_SP_ACCESS() (M.x86.check & CHECK_SP_ACCESS_F) +#define CHECK_MEM_ACCESS() (M.x86.check & CHECK_MEM_ACCESS_F) +#define CHECK_DATA_ACCESS() (M.x86.check & CHECK_DATA_ACCESS_F) +#else +#define CHECK_IP_FETCH() +#define CHECK_SP_ACCESS() +#define CHECK_MEM_ACCESS() +#define CHECK_DATA_ACCESS() +#endif + +#ifdef DEBUG +#define DEBUG_INSTRUMENT() (M.x86.debug & DEBUG_INSTRUMENT_F) +#define DEBUG_DECODE() (M.x86.debug & DEBUG_DECODE_F) +#define DEBUG_TRACE() (M.x86.debug & DEBUG_TRACE_F) +#define DEBUG_STEP() (M.x86.debug & DEBUG_STEP_F) +#define DEBUG_DISASSEMBLE() (M.x86.debug & DEBUG_DISASSEMBLE_F) +#define DEBUG_BREAK() (M.x86.debug & DEBUG_BREAK_F) +#define DEBUG_SVC() (M.x86.debug & DEBUG_SVC_F) +#define DEBUG_SAVE_IP_CS() (M.x86.debug & DEBUG_SAVE_IP_CS_F) + +#define DEBUG_FS() (M.x86.debug & DEBUG_FS_F) +#define DEBUG_PROC() (M.x86.debug & DEBUG_PROC_F) +#define DEBUG_SYSINT() (M.x86.debug & DEBUG_SYSINT_F) +#define DEBUG_TRACECALL() (M.x86.debug & DEBUG_TRACECALL_F) +#define DEBUG_TRACECALLREGS() (M.x86.debug & DEBUG_TRACECALL_REGS_F) +#define DEBUG_SYS() (M.x86.debug & DEBUG_SYS_F) +#define DEBUG_MEM_TRACE() (M.x86.debug & DEBUG_MEM_TRACE_F) +#define DEBUG_IO_TRACE() (M.x86.debug & DEBUG_IO_TRACE_F) +#define DEBUG_DECODE_NOPRINT() (M.x86.debug & DEBUG_DECODE_NOPRINT_F) +#else +#define DEBUG_INSTRUMENT() 0 +#define DEBUG_DECODE() 0 +#define DEBUG_TRACE() 0 +#define DEBUG_STEP() 0 +#define DEBUG_DISASSEMBLE() 0 +#define DEBUG_BREAK() 0 +#define DEBUG_SVC() 0 +#define DEBUG_SAVE_IP_CS() 0 +#define DEBUG_FS() 0 +#define DEBUG_PROC() 0 +#define DEBUG_SYSINT() 0 +#define DEBUG_TRACECALL() 0 +#define DEBUG_TRACECALLREGS() 0 +#define DEBUG_SYS() 0 +#define DEBUG_MEM_TRACE() 0 +#define DEBUG_IO_TRACE() 0 +#define DEBUG_DECODE_NOPRINT() 0 +#endif + +#ifdef DEBUG + +#define DECODE_PRINTF(x) if (DEBUG_DECODE()) \ + x86emu_decode_printf(x) +#define DECODE_PRINTF2(x,y) if (DEBUG_DECODE()) \ + x86emu_decode_printf2(x,y) + +/* + * The following allow us to look at the bytes of an instruction. The + * first INCR_INSTRN_LEN, is called everytime bytes are consumed in + * the decoding process. The SAVE_IP_CS is called initially when the + * major opcode of the instruction is accessed. + */ +#define INC_DECODED_INST_LEN(x) \ + if (DEBUG_DECODE()) \ + x86emu_inc_decoded_inst_len(x) + +#define SAVE_IP_CS(x,y) \ + if (DEBUG_DECODE() | DEBUG_TRACECALL() | DEBUG_BREAK() \ + | DEBUG_IO_TRACE() | DEBUG_SAVE_IP_CS()) { \ + M.x86.saved_cs = x; \ + M.x86.saved_ip = y; \ + } +#else +#define INC_DECODED_INST_LEN(x) +#define DECODE_PRINTF(x) +#define DECODE_PRINTF2(x,y) +#define SAVE_IP_CS(x,y) +#endif + +#ifdef DEBUG +#define TRACE_REGS() \ + if (DEBUG_DISASSEMBLE()) { \ + x86emu_just_disassemble(); \ + goto EndOfTheInstructionProcedure; \ + } \ + if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs() +#else +#define TRACE_REGS() +#endif + +#ifdef DEBUG +#define SINGLE_STEP() if (DEBUG_STEP()) x86emu_single_step() +#else +#define SINGLE_STEP() +#endif + +#define TRACE_AND_STEP() \ + TRACE_REGS(); \ + SINGLE_STEP() + +#ifdef DEBUG +#define START_OF_INSTR() +#define END_OF_INSTR() EndOfTheInstructionProcedure: x86emu_end_instr(); +#define END_OF_INSTR_NO_TRACE() x86emu_end_instr(); +#else +#define START_OF_INSTR() +#define END_OF_INSTR() +#define END_OF_INSTR_NO_TRACE() +#endif + +#ifdef DEBUG +#define CALL_TRACE(u,v,w,x,s) \ + if (DEBUG_TRACECALLREGS()) \ + x86emu_dump_regs(); \ + if (DEBUG_TRACECALL()) \ + printk("%04x:%04x: CALL %s%04x:%04x\n", u , v, s, w, x); +#define RETURN_TRACE(n,u,v) \ + if (DEBUG_TRACECALLREGS()) \ + x86emu_dump_regs(); \ + if (DEBUG_TRACECALL()) \ + printk("%04x:%04x: %s\n",u,v,n); +#else +#define CALL_TRACE(u,v,w,x,s) +#define RETURN_TRACE(n,u,v) +#endif + +#ifdef DEBUG +#define DB(x) x +#else +#define DB(x) +#endif + +/*-------------------------- Function Prototypes --------------------------*/ + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + + extern void x86emu_inc_decoded_inst_len(int x); + extern void x86emu_decode_printf(const char *x); + extern void x86emu_decode_printf2(const char *x, int y); + extern void x86emu_just_disassemble(void); + extern void x86emu_single_step(void); + extern void x86emu_end_instr(void); + extern void x86emu_dump_regs(void); + extern void x86emu_dump_xregs(void); + extern void x86emu_print_int_vect(u16 iv); + extern void x86emu_instrument_instruction(void); + extern void x86emu_check_ip_access(void); + extern void x86emu_check_sp_access(void); + extern void x86emu_check_mem_access(u32 p); + extern void x86emu_check_data_access(uint s, uint o); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif +#endif /* __X86EMU_DEBUG_H */ diff --git a/headers/libs/x86emu/x86emu/decode.h b/headers/libs/x86emu/x86emu/decode.h new file mode 100644 index 0000000000..49a1f7b540 --- /dev/null +++ b/headers/libs/x86emu/x86emu/decode.h @@ -0,0 +1,87 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for instruction decoding logic. +* +****************************************************************************/ + +#ifndef __X86EMU_DECODE_H +#define __X86EMU_DECODE_H + +/*---------------------- Macros and type definitions ----------------------*/ + +/* Instruction Decoding Stuff */ + +#define FETCH_DECODE_MODRM(mod,rh,rl) fetch_decode_modrm(&mod,&rh,&rl) +#define DECODE_RM_BYTE_REGISTER(r) decode_rm_byte_register(r) +#define DECODE_RM_WORD_REGISTER(r) decode_rm_word_register(r) +#define DECODE_RM_LONG_REGISTER(r) decode_rm_long_register(r) +#define DECODE_CLEAR_SEGOVR() M.x86.mode &= ~SYSMODE_CLRMASK + +/*-------------------------- Function Prototypes --------------------------*/ + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + + void x86emu_intr_raise(u8 type); + void fetch_decode_modrm(int *mod, int *regh, int *regl); + u8 fetch_byte_imm(void); + u16 fetch_word_imm(void); + u32 fetch_long_imm(void); + u8 fetch_data_byte(uint offset); + u8 fetch_data_byte_abs(uint segment, uint offset); + u16 fetch_data_word(uint offset); + u16 fetch_data_word_abs(uint segment, uint offset); + u32 fetch_data_long(uint offset); + u32 fetch_data_long_abs(uint segment, uint offset); + void store_data_byte(uint offset, u8 val); + void store_data_byte_abs(uint segment, uint offset, u8 val); + void store_data_word(uint offset, u16 val); + void store_data_word_abs(uint segment, uint offset, u16 val); + void store_data_long(uint offset, u32 val); + void store_data_long_abs(uint segment, uint offset, u32 val); + u8 *decode_rm_byte_register(int reg); + u16 *decode_rm_word_register(int reg); + u32 *decode_rm_long_register(int reg); + u16 *decode_rm_seg_register(int reg); + u32 decode_rm00_address(int rm); + u32 decode_rm01_address(int rm); + u32 decode_rm10_address(int rm); + u32 decode_sib_address(int sib, int mod); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif +#endif /* __X86EMU_DECODE_H */ diff --git a/headers/libs/x86emu/x86emu/fpu.h b/headers/libs/x86emu/x86emu/fpu.h new file mode 100644 index 0000000000..1c114987f0 --- /dev/null +++ b/headers/libs/x86emu/x86emu/fpu.h @@ -0,0 +1,60 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for FPU instruction decoding. +* +****************************************************************************/ + +#ifndef __X86EMU_FPU_H +#define __X86EMU_FPU_H + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + +/* these have to be defined, whether 8087 support compiled in or not. */ + + extern void x86emuOp_esc_coprocess_d8(u8 op1); + extern void x86emuOp_esc_coprocess_d9(u8 op1); + extern void x86emuOp_esc_coprocess_da(u8 op1); + extern void x86emuOp_esc_coprocess_db(u8 op1); + extern void x86emuOp_esc_coprocess_dc(u8 op1); + extern void x86emuOp_esc_coprocess_dd(u8 op1); + extern void x86emuOp_esc_coprocess_de(u8 op1); + extern void x86emuOp_esc_coprocess_df(u8 op1); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif +#endif /* __X86EMU_FPU_H */ diff --git a/headers/libs/x86emu/x86emu/fpu_regs.h b/headers/libs/x86emu/x86emu/fpu_regs.h new file mode 100644 index 0000000000..5a780e69c0 --- /dev/null +++ b/headers/libs/x86emu/x86emu/fpu_regs.h @@ -0,0 +1,119 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for FPU register definitions. +* +****************************************************************************/ + +#ifndef __X86EMU_FPU_REGS_H +#define __X86EMU_FPU_REGS_H + +#ifdef X86_FPU_SUPPORT + +#ifdef PACK +#pragma PACK +#endif + +/* Basic 8087 register can hold any of the following values: */ + +union x86_fpu_reg_u { + s8 tenbytes[10]; + double dval; + float fval; + s16 sval; + s32 lval; +}; + +struct x86_fpu_reg { + union x86_fpu_reg_u reg; + char tag; +}; + +/* + * Since we are not going to worry about the problems of aliasing + * registers, every time a register is modified, its result type is + * set in the tag fields for that register. If some operation + * attempts to access the type in a way inconsistent with its current + * storage format, then we flag the operation. If common, we'll + * attempt the conversion. + */ + +#define X86_FPU_VALID 0x80 +#define X86_FPU_REGTYP(r) ((r) & 0x7F) + +#define X86_FPU_WORD 0x0 +#define X86_FPU_SHORT 0x1 +#define X86_FPU_LONG 0x2 +#define X86_FPU_FLOAT 0x3 +#define X86_FPU_DOUBLE 0x4 +#define X86_FPU_LDBL 0x5 +#define X86_FPU_BSD 0x6 + +#define X86_FPU_STKTOP 0 + +struct x86_fpu_registers { + struct x86_fpu_reg x86_fpu_stack[8]; + int x86_fpu_flags; + int x86_fpu_config; /* rounding modes, etc. */ + short x86_fpu_tos, x86_fpu_bos; +}; + +#ifdef END_PACK +#pragma END_PACK +#endif + +/* + * There are two versions of the following macro. + * + * One version is for opcode D9, for which there are more than 32 + * instructions encoded in the second byte of the opcode. + * + * The other version, deals with all the other 7 i87 opcodes, for + * which there are only 32 strings needed to describe the + * instructions. + */ + +#endif /* X86_FPU_SUPPORT */ + +#ifdef DEBUG +#define DECODE_PRINTINSTR32(t,mod,rh,rl) \ + DECODE_PRINTF(t[(mod<<3)+(rh)]); +#define DECODE_PRINTINSTR256(t,mod,rh,rl) \ + DECODE_PRINTF(t[(mod<<6)+(rh<<3)+(rl)]); +#else +#define DECODE_PRINTINSTR32(t,mod,rh,rl) +#define DECODE_PRINTINSTR256(t,mod,rh,rl) +#endif + +#endif /* __X86EMU_FPU_REGS_H */ diff --git a/headers/libs/x86emu/x86emu/ops.h b/headers/libs/x86emu/x86emu/ops.h new file mode 100644 index 0000000000..1bc07a4e1d --- /dev/null +++ b/headers/libs/x86emu/x86emu/ops.h @@ -0,0 +1,45 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for operand decoding functions. +* +****************************************************************************/ + +#ifndef __X86EMU_OPS_H +#define __X86EMU_OPS_H + +extern void (*x86emu_optab[0x100]) (u8 op1); +extern void (*x86emu_optab2[0x100]) (u8 op2); + +#endif /* __X86EMU_OPS_H */ diff --git a/headers/libs/x86emu/x86emu/prim_asm.h b/headers/libs/x86emu/x86emu/prim_asm.h new file mode 100644 index 0000000000..aca132bf1c --- /dev/null +++ b/headers/libs/x86emu/x86emu/prim_asm.h @@ -0,0 +1,1053 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: Watcom C++ 10.6 or later +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Inline assembler versions of the primitive operand +* functions for faster performance. At the moment this is +* x86 inline assembler, but these functions could be replaced +* with native inline assembler for each supported processor +* platform. +* +****************************************************************************/ + +#ifndef __X86EMU_PRIM_ASM_H +#define __X86EMU_PRIM_ASM_H + +#ifdef __WATCOMC__ + +#ifndef VALIDATE +#define __HAVE_INLINE_ASSEMBLER__ +#endif + +u32 get_flags_asm(void); + +#pragma aux get_flags_asm = \ + "pushf" \ + "pop eax" \ + value [eax] \ + modify exact [eax]; + +u16 aaa_word_asm(u32 * flags, u16 d); + +#pragma aux aaa_word_asm = \ + "push [edi]" \ + "popf" \ + "aaa" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] \ + value [ax] \ + modify exact [ax]; + +u16 aas_word_asm(u32 * flags, u16 d); + +#pragma aux aas_word_asm = \ + "push [edi]" \ + "popf" \ + "aas" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] \ + value [ax] \ + modify exact [ax]; + +u16 aad_word_asm(u32 * flags, u16 d); + +#pragma aux aad_word_asm = \ + "push [edi]" \ + "popf" \ + "aad" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] \ + value [ax] \ + modify exact [ax]; + +u16 aam_word_asm(u32 * flags, u8 d); + +#pragma aux aam_word_asm = \ + "push [edi]" \ + "popf" \ + "aam" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] \ + value [ax] \ + modify exact [ax]; + +u8 adc_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux adc_byte_asm = \ + "push [edi]" \ + "popf" \ + "adc al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + value [al] \ + modify exact [al bl]; + +u16 adc_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux adc_word_asm = \ + "push [edi]" \ + "popf" \ + "adc ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + value [ax] \ + modify exact [ax bx]; + +u32 adc_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux adc_long_asm = \ + "push [edi]" \ + "popf" \ + "adc eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + value [eax] \ + modify exact [eax ebx]; + +u8 add_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux add_byte_asm = \ + "push [edi]" \ + "popf" \ + "add al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + value [al] \ + modify exact [al bl]; + +u16 add_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux add_word_asm = \ + "push [edi]" \ + "popf" \ + "add ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + value [ax] \ + modify exact [ax bx]; + +u32 add_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux add_long_asm = \ + "push [edi]" \ + "popf" \ + "add eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + value [eax] \ + modify exact [eax ebx]; + +u8 and_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux and_byte_asm = \ + "push [edi]" \ + "popf" \ + "and al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + value [al] \ + modify exact [al bl]; + +u16 and_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux and_word_asm = \ + "push [edi]" \ + "popf" \ + "and ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + value [ax] \ + modify exact [ax bx]; + +u32 and_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux and_long_asm = \ + "push [edi]" \ + "popf" \ + "and eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + value [eax] \ + modify exact [eax ebx]; + +u8 cmp_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux cmp_byte_asm = \ + "push [edi]" \ + "popf" \ + "cmp al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + value [al] \ + modify exact [al bl]; + +u16 cmp_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux cmp_word_asm = \ + "push [edi]" \ + "popf" \ + "cmp ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + value [ax] \ + modify exact [ax bx]; + +u32 cmp_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux cmp_long_asm = \ + "push [edi]" \ + "popf" \ + "cmp eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + value [eax] \ + modify exact [eax ebx]; + +u8 daa_byte_asm(u32 * flags, u8 d); + +#pragma aux daa_byte_asm = \ + "push [edi]" \ + "popf" \ + "daa" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] \ + value [al] \ + modify exact [al]; + +u8 das_byte_asm(u32 * flags, u8 d); + +#pragma aux das_byte_asm = \ + "push [edi]" \ + "popf" \ + "das" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] \ + value [al] \ + modify exact [al]; + +u8 dec_byte_asm(u32 * flags, u8 d); + +#pragma aux dec_byte_asm = \ + "push [edi]" \ + "popf" \ + "dec al" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] \ + value [al] \ + modify exact [al]; + +u16 dec_word_asm(u32 * flags, u16 d); + +#pragma aux dec_word_asm = \ + "push [edi]" \ + "popf" \ + "dec ax" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] \ + value [ax] \ + modify exact [ax]; + +u32 dec_long_asm(u32 * flags, u32 d); + +#pragma aux dec_long_asm = \ + "push [edi]" \ + "popf" \ + "dec eax" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] \ + value [eax] \ + modify exact [eax]; + +u8 inc_byte_asm(u32 * flags, u8 d); + +#pragma aux inc_byte_asm = \ + "push [edi]" \ + "popf" \ + "inc al" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] \ + value [al] \ + modify exact [al]; + +u16 inc_word_asm(u32 * flags, u16 d); + +#pragma aux inc_word_asm = \ + "push [edi]" \ + "popf" \ + "inc ax" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] \ + value [ax] \ + modify exact [ax]; + +u32 inc_long_asm(u32 * flags, u32 d); + +#pragma aux inc_long_asm = \ + "push [edi]" \ + "popf" \ + "inc eax" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] \ + value [eax] \ + modify exact [eax]; + +u8 or_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux or_byte_asm = \ + "push [edi]" \ + "popf" \ + "or al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + value [al] \ + modify exact [al bl]; + +u16 or_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux or_word_asm = \ + "push [edi]" \ + "popf" \ + "or ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + value [ax] \ + modify exact [ax bx]; + +u32 or_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux or_long_asm = \ + "push [edi]" \ + "popf" \ + "or eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + value [eax] \ + modify exact [eax ebx]; + +u8 neg_byte_asm(u32 * flags, u8 d); + +#pragma aux neg_byte_asm = \ + "push [edi]" \ + "popf" \ + "neg al" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] \ + value [al] \ + modify exact [al]; + +u16 neg_word_asm(u32 * flags, u16 d); + +#pragma aux neg_word_asm = \ + "push [edi]" \ + "popf" \ + "neg ax" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] \ + value [ax] \ + modify exact [ax]; + +u32 neg_long_asm(u32 * flags, u32 d); + +#pragma aux neg_long_asm = \ + "push [edi]" \ + "popf" \ + "neg eax" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] \ + value [eax] \ + modify exact [eax]; + +u8 not_byte_asm(u32 * flags, u8 d); + +#pragma aux not_byte_asm = \ + "push [edi]" \ + "popf" \ + "not al" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] \ + value [al] \ + modify exact [al]; + +u16 not_word_asm(u32 * flags, u16 d); + +#pragma aux not_word_asm = \ + "push [edi]" \ + "popf" \ + "not ax" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] \ + value [ax] \ + modify exact [ax]; + +u32 not_long_asm(u32 * flags, u32 d); + +#pragma aux not_long_asm = \ + "push [edi]" \ + "popf" \ + "not eax" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] \ + value [eax] \ + modify exact [eax]; + +u8 rcl_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux rcl_byte_asm = \ + "push [edi]" \ + "popf" \ + "rcl al,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [cl] \ + value [al] \ + modify exact [al cl]; + +u16 rcl_word_asm(u32 * flags, u16 d, u8 s); + +#pragma aux rcl_word_asm = \ + "push [edi]" \ + "popf" \ + "rcl ax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [cl] \ + value [ax] \ + modify exact [ax cl]; + +u32 rcl_long_asm(u32 * flags, u32 d, u8 s); + +#pragma aux rcl_long_asm = \ + "push [edi]" \ + "popf" \ + "rcl eax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [cl] \ + value [eax] \ + modify exact [eax cl]; + +u8 rcr_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux rcr_byte_asm = \ + "push [edi]" \ + "popf" \ + "rcr al,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [cl] \ + value [al] \ + modify exact [al cl]; + +u16 rcr_word_asm(u32 * flags, u16 d, u8 s); + +#pragma aux rcr_word_asm = \ + "push [edi]" \ + "popf" \ + "rcr ax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [cl] \ + value [ax] \ + modify exact [ax cl]; + +u32 rcr_long_asm(u32 * flags, u32 d, u8 s); + +#pragma aux rcr_long_asm = \ + "push [edi]" \ + "popf" \ + "rcr eax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [cl] \ + value [eax] \ + modify exact [eax cl]; + +u8 rol_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux rol_byte_asm = \ + "push [edi]" \ + "popf" \ + "rol al,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [cl] \ + value [al] \ + modify exact [al cl]; + +u16 rol_word_asm(u32 * flags, u16 d, u8 s); + +#pragma aux rol_word_asm = \ + "push [edi]" \ + "popf" \ + "rol ax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [cl] \ + value [ax] \ + modify exact [ax cl]; + +u32 rol_long_asm(u32 * flags, u32 d, u8 s); + +#pragma aux rol_long_asm = \ + "push [edi]" \ + "popf" \ + "rol eax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [cl] \ + value [eax] \ + modify exact [eax cl]; + +u8 ror_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux ror_byte_asm = \ + "push [edi]" \ + "popf" \ + "ror al,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [cl] \ + value [al] \ + modify exact [al cl]; + +u16 ror_word_asm(u32 * flags, u16 d, u8 s); + +#pragma aux ror_word_asm = \ + "push [edi]" \ + "popf" \ + "ror ax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [cl] \ + value [ax] \ + modify exact [ax cl]; + +u32 ror_long_asm(u32 * flags, u32 d, u8 s); + +#pragma aux ror_long_asm = \ + "push [edi]" \ + "popf" \ + "ror eax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [cl] \ + value [eax] \ + modify exact [eax cl]; + +u8 shl_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux shl_byte_asm = \ + "push [edi]" \ + "popf" \ + "shl al,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [cl] \ + value [al] \ + modify exact [al cl]; + +u16 shl_word_asm(u32 * flags, u16 d, u8 s); + +#pragma aux shl_word_asm = \ + "push [edi]" \ + "popf" \ + "shl ax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [cl] \ + value [ax] \ + modify exact [ax cl]; + +u32 shl_long_asm(u32 * flags, u32 d, u8 s); + +#pragma aux shl_long_asm = \ + "push [edi]" \ + "popf" \ + "shl eax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [cl] \ + value [eax] \ + modify exact [eax cl]; + +u8 shr_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux shr_byte_asm = \ + "push [edi]" \ + "popf" \ + "shr al,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [cl] \ + value [al] \ + modify exact [al cl]; + +u16 shr_word_asm(u32 * flags, u16 d, u8 s); + +#pragma aux shr_word_asm = \ + "push [edi]" \ + "popf" \ + "shr ax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [cl] \ + value [ax] \ + modify exact [ax cl]; + +u32 shr_long_asm(u32 * flags, u32 d, u8 s); + +#pragma aux shr_long_asm = \ + "push [edi]" \ + "popf" \ + "shr eax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [cl] \ + value [eax] \ + modify exact [eax cl]; + +u8 sar_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux sar_byte_asm = \ + "push [edi]" \ + "popf" \ + "sar al,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [cl] \ + value [al] \ + modify exact [al cl]; + +u16 sar_word_asm(u32 * flags, u16 d, u8 s); + +#pragma aux sar_word_asm = \ + "push [edi]" \ + "popf" \ + "sar ax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [cl] \ + value [ax] \ + modify exact [ax cl]; + +u32 sar_long_asm(u32 * flags, u32 d, u8 s); + +#pragma aux sar_long_asm = \ + "push [edi]" \ + "popf" \ + "sar eax,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [cl] \ + value [eax] \ + modify exact [eax cl]; + +u16 shld_word_asm(u32 * flags, u16 d, u16 fill, u8 s); + +#pragma aux shld_word_asm = \ + "push [edi]" \ + "popf" \ + "shld ax,dx,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [dx] [cl] \ + value [ax] \ + modify exact [ax dx cl]; + +u32 shld_long_asm(u32 * flags, u32 d, u32 fill, u8 s); + +#pragma aux shld_long_asm = \ + "push [edi]" \ + "popf" \ + "shld eax,edx,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [edx] [cl] \ + value [eax] \ + modify exact [eax edx cl]; + +u16 shrd_word_asm(u32 * flags, u16 d, u16 fill, u8 s); + +#pragma aux shrd_word_asm = \ + "push [edi]" \ + "popf" \ + "shrd ax,dx,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [dx] [cl] \ + value [ax] \ + modify exact [ax dx cl]; + +u32 shrd_long_asm(u32 * flags, u32 d, u32 fill, u8 s); + +#pragma aux shrd_long_asm = \ + "push [edi]" \ + "popf" \ + "shrd eax,edx,cl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [edx] [cl] \ + value [eax] \ + modify exact [eax edx cl]; + +u8 sbb_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux sbb_byte_asm = \ + "push [edi]" \ + "popf" \ + "sbb al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + value [al] \ + modify exact [al bl]; + +u16 sbb_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux sbb_word_asm = \ + "push [edi]" \ + "popf" \ + "sbb ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + value [ax] \ + modify exact [ax bx]; + +u32 sbb_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux sbb_long_asm = \ + "push [edi]" \ + "popf" \ + "sbb eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + value [eax] \ + modify exact [eax ebx]; + +u8 sub_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux sub_byte_asm = \ + "push [edi]" \ + "popf" \ + "sub al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + value [al] \ + modify exact [al bl]; + +u16 sub_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux sub_word_asm = \ + "push [edi]" \ + "popf" \ + "sub ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + value [ax] \ + modify exact [ax bx]; + +u32 sub_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux sub_long_asm = \ + "push [edi]" \ + "popf" \ + "sub eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + value [eax] \ + modify exact [eax ebx]; + +void test_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux test_byte_asm = \ + "push [edi]" \ + "popf" \ + "test al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + modify exact [al bl]; + +void test_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux test_word_asm = \ + "push [edi]" \ + "popf" \ + "test ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + modify exact [ax bx]; + +void test_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux test_long_asm = \ + "push [edi]" \ + "popf" \ + "test eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + modify exact [eax ebx]; + +u8 xor_byte_asm(u32 * flags, u8 d, u8 s); + +#pragma aux xor_byte_asm = \ + "push [edi]" \ + "popf" \ + "xor al,bl" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [al] [bl] \ + value [al] \ + modify exact [al bl]; + +u16 xor_word_asm(u32 * flags, u16 d, u16 s); + +#pragma aux xor_word_asm = \ + "push [edi]" \ + "popf" \ + "xor ax,bx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [ax] [bx] \ + value [ax] \ + modify exact [ax bx]; + +u32 xor_long_asm(u32 * flags, u32 d, u32 s); + +#pragma aux xor_long_asm = \ + "push [edi]" \ + "popf" \ + "xor eax,ebx" \ + "pushf" \ + "pop [edi]" \ + parm [edi] [eax] [ebx] \ + value [eax] \ + modify exact [eax ebx]; + +void imul_byte_asm(u32 * flags, u16 * ax, u8 d, u8 s); + +#pragma aux imul_byte_asm = \ + "push [edi]" \ + "popf" \ + "imul bl" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],ax" \ + parm [edi] [esi] [al] [bl] \ + modify exact [esi ax bl]; + +void imul_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 d, u16 s); + +#pragma aux imul_word_asm = \ + "push [edi]" \ + "popf" \ + "imul bx" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],ax" \ + "mov [ecx],dx" \ + parm [edi] [esi] [ecx] [ax] [bx]\ + modify exact [esi edi ax bx dx]; + +void imul_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 d, u32 s); + +#pragma aux imul_long_asm = \ + "push [edi]" \ + "popf" \ + "imul ebx" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],eax" \ + "mov [ecx],edx" \ + parm [edi] [esi] [ecx] [eax] [ebx] \ + modify exact [esi edi eax ebx edx]; + +void mul_byte_asm(u32 * flags, u16 * ax, u8 d, u8 s); + +#pragma aux mul_byte_asm = \ + "push [edi]" \ + "popf" \ + "mul bl" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],ax" \ + parm [edi] [esi] [al] [bl] \ + modify exact [esi ax bl]; + +void mul_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 d, u16 s); + +#pragma aux mul_word_asm = \ + "push [edi]" \ + "popf" \ + "mul bx" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],ax" \ + "mov [ecx],dx" \ + parm [edi] [esi] [ecx] [ax] [bx]\ + modify exact [esi edi ax bx dx]; + +void mul_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 d, u32 s); + +#pragma aux mul_long_asm = \ + "push [edi]" \ + "popf" \ + "mul ebx" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],eax" \ + "mov [ecx],edx" \ + parm [edi] [esi] [ecx] [eax] [ebx] \ + modify exact [esi edi eax ebx edx]; + +void idiv_byte_asm(u32 * flags, u8 * al, u8 * ah, u16 d, u8 s); + +#pragma aux idiv_byte_asm = \ + "push [edi]" \ + "popf" \ + "idiv bl" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],al" \ + "mov [ecx],ah" \ + parm [edi] [esi] [ecx] [ax] [bl]\ + modify exact [esi edi ax bl]; + +void idiv_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 dlo, u16 dhi, u16 s); + +#pragma aux idiv_word_asm = \ + "push [edi]" \ + "popf" \ + "idiv bx" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],ax" \ + "mov [ecx],dx" \ + parm [edi] [esi] [ecx] [ax] [dx] [bx]\ + modify exact [esi edi ax dx bx]; + +void idiv_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 dlo, u32 dhi, u32 s); + +#pragma aux idiv_long_asm = \ + "push [edi]" \ + "popf" \ + "idiv ebx" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],eax" \ + "mov [ecx],edx" \ + parm [edi] [esi] [ecx] [eax] [edx] [ebx]\ + modify exact [esi edi eax edx ebx]; + +void div_byte_asm(u32 * flags, u8 * al, u8 * ah, u16 d, u8 s); + +#pragma aux div_byte_asm = \ + "push [edi]" \ + "popf" \ + "div bl" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],al" \ + "mov [ecx],ah" \ + parm [edi] [esi] [ecx] [ax] [bl]\ + modify exact [esi edi ax bl]; + +void div_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 dlo, u16 dhi, u16 s); + +#pragma aux div_word_asm = \ + "push [edi]" \ + "popf" \ + "div bx" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],ax" \ + "mov [ecx],dx" \ + parm [edi] [esi] [ecx] [ax] [dx] [bx]\ + modify exact [esi edi ax dx bx]; + +void div_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 dlo, u32 dhi, u32 s); + +#pragma aux div_long_asm = \ + "push [edi]" \ + "popf" \ + "div ebx" \ + "pushf" \ + "pop [edi]" \ + "mov [esi],eax" \ + "mov [ecx],edx" \ + parm [edi] [esi] [ecx] [eax] [edx] [ebx]\ + modify exact [esi edi eax edx ebx]; + +#endif + +#endif /* __X86EMU_PRIM_ASM_H */ diff --git a/headers/libs/x86emu/x86emu/prim_ops.h b/headers/libs/x86emu/x86emu/prim_ops.h new file mode 100644 index 0000000000..0f0e78d717 --- /dev/null +++ b/headers/libs/x86emu/x86emu/prim_ops.h @@ -0,0 +1,141 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for primitive operation functions. +* +****************************************************************************/ + +#ifndef __X86EMU_PRIM_OPS_H +#define __X86EMU_PRIM_OPS_H + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + + u16 aaa_word(u16 d); + u16 aas_word(u16 d); + u16 aad_word(u16 d); + u16 aam_word(u8 d); + u8 adc_byte(u8 d, u8 s); + u16 adc_word(u16 d, u16 s); + u32 adc_long(u32 d, u32 s); + u8 add_byte(u8 d, u8 s); + u16 add_word(u16 d, u16 s); + u32 add_long(u32 d, u32 s); + u8 and_byte(u8 d, u8 s); + u16 and_word(u16 d, u16 s); + u32 and_long(u32 d, u32 s); + u8 cmp_byte(u8 d, u8 s); + u16 cmp_word(u16 d, u16 s); + u32 cmp_long(u32 d, u32 s); + u8 daa_byte(u8 d); + u8 das_byte(u8 d); + u8 dec_byte(u8 d); + u16 dec_word(u16 d); + u32 dec_long(u32 d); + u8 inc_byte(u8 d); + u16 inc_word(u16 d); + u32 inc_long(u32 d); + u8 or_byte(u8 d, u8 s); + u16 or_word(u16 d, u16 s); + u32 or_long(u32 d, u32 s); + u8 neg_byte(u8 s); + u16 neg_word(u16 s); + u32 neg_long(u32 s); + u8 not_byte(u8 s); + u16 not_word(u16 s); + u32 not_long(u32 s); + u8 rcl_byte(u8 d, u8 s); + u16 rcl_word(u16 d, u8 s); + u32 rcl_long(u32 d, u8 s); + u8 rcr_byte(u8 d, u8 s); + u16 rcr_word(u16 d, u8 s); + u32 rcr_long(u32 d, u8 s); + u8 rol_byte(u8 d, u8 s); + u16 rol_word(u16 d, u8 s); + u32 rol_long(u32 d, u8 s); + u8 ror_byte(u8 d, u8 s); + u16 ror_word(u16 d, u8 s); + u32 ror_long(u32 d, u8 s); + u8 shl_byte(u8 d, u8 s); + u16 shl_word(u16 d, u8 s); + u32 shl_long(u32 d, u8 s); + u8 shr_byte(u8 d, u8 s); + u16 shr_word(u16 d, u8 s); + u32 shr_long(u32 d, u8 s); + u8 sar_byte(u8 d, u8 s); + u16 sar_word(u16 d, u8 s); + u32 sar_long(u32 d, u8 s); + u16 shld_word(u16 d, u16 fill, u8 s); + u32 shld_long(u32 d, u32 fill, u8 s); + u16 shrd_word(u16 d, u16 fill, u8 s); + u32 shrd_long(u32 d, u32 fill, u8 s); + u8 sbb_byte(u8 d, u8 s); + u16 sbb_word(u16 d, u16 s); + u32 sbb_long(u32 d, u32 s); + u8 sub_byte(u8 d, u8 s); + u16 sub_word(u16 d, u16 s); + u32 sub_long(u32 d, u32 s); + void test_byte(u8 d, u8 s); + void test_word(u16 d, u16 s); + void test_long(u32 d, u32 s); + u8 xor_byte(u8 d, u8 s); + u16 xor_word(u16 d, u16 s); + u32 xor_long(u32 d, u32 s); + void imul_byte(u8 s); + void imul_word(u16 s); + void imul_long(u32 s); + void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s); + void mul_byte(u8 s); + void mul_word(u16 s); + void mul_long(u32 s); + void idiv_byte(u8 s); + void idiv_word(u16 s); + void idiv_long(u32 s); + void div_byte(u8 s); + void div_word(u16 s); + void div_long(u32 s); + void ins(int size); + void outs(int size); + u16 mem_access_word(int addr); + void push_word(u16 w); + void push_long(u32 w); + u16 pop_word(void); + u32 pop_long(void); + void cpuid(void); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif +#endif /* __X86EMU_PRIM_OPS_H */ diff --git a/headers/libs/x86emu/x86emu/prim_x86_gcc.h b/headers/libs/x86emu/x86emu/prim_x86_gcc.h new file mode 100644 index 0000000000..646ec9defe --- /dev/null +++ b/headers/libs/x86emu/x86emu/prim_x86_gcc.h @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* Inline helpers for x86emu +* +* Copyright (C) 2008 Bart Trojanowski, Symbio Technologies, LLC +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: GNU C +* Environment: GCC on i386 or x86-64 +* Developer: Bart Trojanowski +* +* Description: This file defines a few x86 macros that can be used by the +* emulator to execute native instructions. +* +* For PIC vs non-PIC code refer to: +* http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well +* +****************************************************************************/ +#ifndef __X86EMU_PRIM_X86_GCC_H +#define __X86EMU_PRIM_X86_GCC_H + +#include "x86emu/types.h" + +#if !defined(__GNUC__) || !(defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__amd64__)) +#error This file is intended to be used by gcc on i386 or x86-64 system +#endif + +#if defined(__PIC__) && defined(__i386__) + +#define X86EMU_HAS_HW_CPUID 1 +static inline void +hw_cpuid(u32 * a, u32 * b, u32 * c, u32 * d) +{ + __asm__ __volatile__("pushl %%ebx \n\t" + "cpuid \n\t" + "movl %%ebx, %1 \n\t" + "popl %%ebx \n\t":"=a"(*a), "=r"(*b), + "=c"(*c), "=d"(*d) + :"a"(*a), "c"(*c) + :"cc"); +} + +#else /* ! (__PIC__ && __i386__) */ + +#define x86EMU_HAS_HW_CPUID 1 +static inline void +hw_cpuid(u32 * a, u32 * b, u32 * c, u32 * d) +{ + __asm__ __volatile__("cpuid":"=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) + :"a"(*a), "c"(*c) + :"cc"); +} + +#endif /* __PIC__ && __i386__ */ + +#endif /* __X86EMU_PRIM_X86_GCC_H */ diff --git a/headers/libs/x86emu/x86emu/regs.h b/headers/libs/x86emu/x86emu/regs.h new file mode 100644 index 0000000000..203a442adc --- /dev/null +++ b/headers/libs/x86emu/x86emu/regs.h @@ -0,0 +1,342 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for x86 register definitions. +* +****************************************************************************/ + +#ifndef __X86EMU_REGS_H +#define __X86EMU_REGS_H + +/*---------------------- Macros and type definitions ----------------------*/ + +#ifdef PACK +#pragma PACK +#endif + +/* + * General EAX, EBX, ECX, EDX type registers. Note that for + * portability, and speed, the issue of byte swapping is not addressed + * in the registers. All registers are stored in the default format + * available on the host machine. The only critical issue is that the + * registers should line up EXACTLY in the same manner as they do in + * the 386. That is: + * + * EAX & 0xff === AL + * EAX & 0xffff == AX + * + * etc. The result is that alot of the calculations can then be + * done using the native instruction set fully. + */ + +#ifdef __BIG_ENDIAN__ + +typedef struct { + u32 e_reg; +} I32_reg_t; + +typedef struct { + u16 filler0, x_reg; +} I16_reg_t; + +typedef struct { + u8 filler0, filler1, h_reg, l_reg; +} I8_reg_t; + +#else /* !__BIG_ENDIAN__ */ + +typedef struct { + u32 e_reg; +} I32_reg_t; + +typedef struct { + u16 x_reg; +} I16_reg_t; + +typedef struct { + u8 l_reg, h_reg; +} I8_reg_t; + +#endif /* BIG_ENDIAN */ + +typedef union { + I32_reg_t I32_reg; + I16_reg_t I16_reg; + I8_reg_t I8_reg; +} i386_general_register; + +struct i386_general_regs { + i386_general_register A, B, C, D; +}; + +typedef struct i386_general_regs Gen_reg_t; + +struct i386_special_regs { + i386_general_register SP, BP, SI, DI, IP; + u32 FLAGS; +}; + +/* + * Segment registers here represent the 16 bit quantities + * CS, DS, ES, SS. + */ + +struct i386_segment_regs { + u16 CS, DS, SS, ES, FS, GS; +}; + +/* 8 bit registers */ +#define R_AH gen.A.I8_reg.h_reg +#define R_AL gen.A.I8_reg.l_reg +#define R_BH gen.B.I8_reg.h_reg +#define R_BL gen.B.I8_reg.l_reg +#define R_CH gen.C.I8_reg.h_reg +#define R_CL gen.C.I8_reg.l_reg +#define R_DH gen.D.I8_reg.h_reg +#define R_DL gen.D.I8_reg.l_reg + +/* 16 bit registers */ +#define R_AX gen.A.I16_reg.x_reg +#define R_BX gen.B.I16_reg.x_reg +#define R_CX gen.C.I16_reg.x_reg +#define R_DX gen.D.I16_reg.x_reg + +/* 32 bit extended registers */ +#define R_EAX gen.A.I32_reg.e_reg +#define R_EBX gen.B.I32_reg.e_reg +#define R_ECX gen.C.I32_reg.e_reg +#define R_EDX gen.D.I32_reg.e_reg + +/* special registers */ +#define R_SP spc.SP.I16_reg.x_reg +#define R_BP spc.BP.I16_reg.x_reg +#define R_SI spc.SI.I16_reg.x_reg +#define R_DI spc.DI.I16_reg.x_reg +#define R_IP spc.IP.I16_reg.x_reg +#define R_FLG spc.FLAGS + +/* special registers */ +#define R_SP spc.SP.I16_reg.x_reg +#define R_BP spc.BP.I16_reg.x_reg +#define R_SI spc.SI.I16_reg.x_reg +#define R_DI spc.DI.I16_reg.x_reg +#define R_IP spc.IP.I16_reg.x_reg +#define R_FLG spc.FLAGS + +/* special registers */ +#define R_ESP spc.SP.I32_reg.e_reg +#define R_EBP spc.BP.I32_reg.e_reg +#define R_ESI spc.SI.I32_reg.e_reg +#define R_EDI spc.DI.I32_reg.e_reg +#define R_EIP spc.IP.I32_reg.e_reg +#define R_EFLG spc.FLAGS + +/* segment registers */ +#define R_CS seg.CS +#define R_DS seg.DS +#define R_SS seg.SS +#define R_ES seg.ES +#define R_FS seg.FS +#define R_GS seg.GS + +/* flag conditions */ +#define FB_CF 0x0001 /* CARRY flag */ +#define FB_PF 0x0004 /* PARITY flag */ +#define FB_AF 0x0010 /* AUX flag */ +#define FB_ZF 0x0040 /* ZERO flag */ +#define FB_SF 0x0080 /* SIGN flag */ +#define FB_TF 0x0100 /* TRAP flag */ +#define FB_IF 0x0200 /* INTERRUPT ENABLE flag */ +#define FB_DF 0x0400 /* DIR flag */ +#define FB_OF 0x0800 /* OVERFLOW flag */ + +/* 80286 and above always have bit#1 set */ +#define F_ALWAYS_ON (0x0002) /* flag bits always on */ + +/* + * Define a mask for only those flag bits we will ever pass back + * (via PUSHF) + */ +#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF) + +/* following bits masked in to a 16bit quantity */ + +#define F_CF 0x0001 /* CARRY flag */ +#define F_PF 0x0004 /* PARITY flag */ +#define F_AF 0x0010 /* AUX flag */ +#define F_ZF 0x0040 /* ZERO flag */ +#define F_SF 0x0080 /* SIGN flag */ +#define F_TF 0x0100 /* TRAP flag */ +#define F_IF 0x0200 /* INTERRUPT ENABLE flag */ +#define F_DF 0x0400 /* DIR flag */ +#define F_OF 0x0800 /* OVERFLOW flag */ + +#define TOGGLE_FLAG(flag) (M.x86.R_FLG ^= (flag)) +#define SET_FLAG(flag) (M.x86.R_FLG |= (flag)) +#define CLEAR_FLAG(flag) (M.x86.R_FLG &= ~(flag)) +#define ACCESS_FLAG(flag) (M.x86.R_FLG & (flag)) +#define CLEARALL_FLAG(m) (M.x86.R_FLG = 0) + +#define CONDITIONAL_SET_FLAG(COND,FLAG) \ + if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG) + +#define F_PF_CALC 0x010000 /* PARITY flag has been calced */ +#define F_ZF_CALC 0x020000 /* ZERO flag has been calced */ +#define F_SF_CALC 0x040000 /* SIGN flag has been calced */ + +#define F_ALL_CALC 0xff0000 /* All have been calced */ + +/* + * Emulator machine state. + * Segment usage control. + */ +#define SYSMODE_SEG_DS_SS 0x00000001 +#define SYSMODE_SEGOVR_CS 0x00000002 +#define SYSMODE_SEGOVR_DS 0x00000004 +#define SYSMODE_SEGOVR_ES 0x00000008 +#define SYSMODE_SEGOVR_FS 0x00000010 +#define SYSMODE_SEGOVR_GS 0x00000020 +#define SYSMODE_SEGOVR_SS 0x00000040 +#define SYSMODE_PREFIX_REPE 0x00000080 +#define SYSMODE_PREFIX_REPNE 0x00000100 +#define SYSMODE_PREFIX_DATA 0x00000200 +#define SYSMODE_PREFIX_ADDR 0x00000400 +#define SYSMODE_INTR_PENDING 0x10000000 +#define SYSMODE_EXTRN_INTR 0x20000000 +#define SYSMODE_HALTED 0x40000000 + +#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS | \ + SYSMODE_SEGOVR_CS | \ + SYSMODE_SEGOVR_DS | \ + SYSMODE_SEGOVR_ES | \ + SYSMODE_SEGOVR_FS | \ + SYSMODE_SEGOVR_GS | \ + SYSMODE_SEGOVR_SS) +#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS | \ + SYSMODE_SEGOVR_CS | \ + SYSMODE_SEGOVR_DS | \ + SYSMODE_SEGOVR_ES | \ + SYSMODE_SEGOVR_FS | \ + SYSMODE_SEGOVR_GS | \ + SYSMODE_SEGOVR_SS | \ + SYSMODE_PREFIX_DATA | \ + SYSMODE_PREFIX_ADDR) + +#define INTR_SYNCH 0x1 +#define INTR_ASYNCH 0x2 +#define INTR_HALTED 0x4 + +typedef struct { + struct i386_general_regs gen; + struct i386_special_regs spc; + struct i386_segment_regs seg; + /* + * MODE contains information on: + * REPE prefix 2 bits repe,repne + * SEGMENT overrides 5 bits normal,DS,SS,CS,ES + * Delayed flag set 3 bits (zero, signed, parity) + * reserved 6 bits + * interrupt # 8 bits instruction raised interrupt + * BIOS video segregs 4 bits + * Interrupt Pending 1 bits + * Extern interrupt 1 bits + * Halted 1 bits + */ + u32 mode; + volatile int intr; /* mask of pending interrupts */ + int debug; +#ifdef DEBUG + int check; + u16 saved_ip; + u16 saved_cs; + int enc_pos; + int enc_str_pos; + char decode_buf[32]; /* encoded byte stream */ + char decoded_buf[256]; /* disassembled strings */ +#endif + u8 intno; + u8 __pad[3]; +} X86EMU_regs; + +/**************************************************************************** +REMARKS: +Structure maintaining the emulator machine state. + +MEMBERS: +mem_base - Base real mode memory for the emulator +mem_size - Size of the real mode memory block for the emulator +private - private data pointer +x86 - X86 registers +****************************************************************************/ +typedef struct { + unsigned long mem_base; + unsigned long mem_size; +#ifdef __cplusplus + void *_private; +#else + void *private; +#endif + X86EMU_regs x86; +} X86EMU_sysEnv; + +#ifdef END_PACK +#pragma END_PACK +#endif + +/*----------------------------- Global Variables --------------------------*/ + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + +/* Global emulator machine state. + * + * We keep it global to avoid pointer dereferences in the code for speed. + */ + + extern X86EMU_sysEnv _X86EMU_env; +#define M _X86EMU_env + +/*-------------------------- Function Prototypes --------------------------*/ + +/* Function to log information at runtime */ + +#include +#define printk(fmt...) dprintf(fmt) +// void printk(const char *fmt, ...); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif +#endif /* __X86EMU_REGS_H */ diff --git a/headers/libs/x86emu/x86emu/types.h b/headers/libs/x86emu/x86emu/types.h new file mode 100644 index 0000000000..5a6ef01f8b --- /dev/null +++ b/headers/libs/x86emu/x86emu/types.h @@ -0,0 +1,80 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for x86 emulator type definitions. +* +****************************************************************************/ + +#ifndef __X86EMU_TYPES_H +#define __X86EMU_TYPES_H + +#ifndef NO_SYS_HEADERS +#include +#endif + +/* + * The following kludge is an attempt to work around typedef conflicts with + * . + */ +#define u8 x86emuu8 +#define u16 x86emuu16 +#define u32 x86emuu32 +#define u64 x86emuu64 +#define s8 x86emus8 +#define s16 x86emus16 +#define s32 x86emus32 +#define s64 x86emus64 +#define uint x86emuuint +#define sint x86emusint + +/*---------------------- Macros and type definitions ----------------------*/ + +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +typedef unsigned int uint; +typedef int sint; + +typedef u16 X86EMU_pioAddr; + +#endif /* __X86EMU_TYPES_H */ diff --git a/headers/libs/x86emu/x86emu/x86emui.h b/headers/libs/x86emu/x86emu/x86emui.h new file mode 100644 index 0000000000..f11dc102ff --- /dev/null +++ b/headers/libs/x86emu/x86emu/x86emui.h @@ -0,0 +1,100 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: Header file for system specific functions. These functions +* are always compiled and linked in the OS depedent libraries, +* and never in a binary portable driver. +* +****************************************************************************/ + +#ifndef __X86EMU_X86EMUI_H +#define __X86EMU_X86EMUI_H + +/* If we are compiling in C++ mode, we can compile some functions as + * inline to increase performance (however the code size increases quite + * dramatically in this case). + */ + +#if defined(__cplusplus) && !defined(_NO_INLINE) +#define _INLINE inline +#else +#define _INLINE static +#endif + +/* Get rid of unused parameters in C++ compilation mode */ + +#ifdef __cplusplus +#define X86EMU_UNUSED(v) +#else +#define X86EMU_UNUSED(v) v +#endif + +#include "x86emu.h" +#include "x86emu/regs.h" +#include "x86emu/debug.h" +#include "x86emu/decode.h" +#include "x86emu/ops.h" +#include "x86emu/prim_ops.h" +#include "x86emu/fpu.h" +#include "x86emu/fpu_regs.h" + +#ifndef NO_SYS_HEADERS +#include +#include +#include +#endif +/*--------------------------- Inline Functions ----------------------------*/ + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + + extern u8(X86APIP sys_rdb) (u32 addr); + extern u16(X86APIP sys_rdw) (u32 addr); + extern u32(X86APIP sys_rdl) (u32 addr); + extern void (X86APIP sys_wrb) (u32 addr, u8 val); + extern void (X86APIP sys_wrw) (u32 addr, u16 val); + extern void (X86APIP sys_wrl) (u32 addr, u32 val); + + extern u8(X86APIP sys_inb) (X86EMU_pioAddr addr); + extern u16(X86APIP sys_inw) (X86EMU_pioAddr addr); + extern u32(X86APIP sys_inl) (X86EMU_pioAddr addr); + extern void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val); + extern void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val); + extern void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif +#endif /* __X86EMU_X86EMUI_H */ diff --git a/headers/os/arch/x86_64/arch_debugger.h b/headers/os/arch/x86_64/arch_debugger.h new file mode 100644 index 0000000000..59b27c3ba3 --- /dev/null +++ b/headers/os/arch/x86_64/arch_debugger.h @@ -0,0 +1,69 @@ +/* + * Copyright 2005-2012, Haiku Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef _ARCH_X86_64_DEBUGGER_H +#define _ARCH_X86_64_DEBUGGER_H + + +typedef struct x86_64_fp_register { + uint8 value[10]; + uint8 reserved[6]; +} x86_64_fp_register; + + +typedef struct x86_64_xmm_register { + uint8 value[16]; +} x86_64_xmm_register; + + +typedef struct x86_64_extended_registers { + uint16 control; + uint16 status; + uint8 tag; + uint8 reserved1; + uint16 opcode; + uint64 instruction_pointer; + uint64 data_pointer; + uint32 mxcsr; + uint32 mxcsr_mask; + union { + x86_64_fp_register fp_registers[8]; // st0-st7 + x86_64_fp_register mmx_registers[8]; // mm0-mm7 + }; + x86_64_xmm_register xmm_registers[16]; // xmm0-xmm15 + uint8 reserved2[96]; // 416 - 512 +} x86_64_extended_registers; + + +struct x86_64_debug_cpu_state { + x86_64_extended_registers extended_registers; + + uint64 gs; + uint64 fs; + uint64 es; + uint64 ds; + uint64 r15; + uint64 r14; + uint64 r13; + uint64 r12; + uint64 r11; + uint64 r10; + uint64 r9; + uint64 r8; + uint64 rbp; + uint64 rsi; + uint64 rdi; + uint64 rdx; + uint64 rcx; + uint64 rbx; + uint64 rax; + uint64 rip; + uint64 cs; + uint64 rflags; + uint64 rsp; + uint64 ss; +} __attribute__((aligned(16))); + + +#endif // _ARCH_X86_64_DEBUGGER_H diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index 221c649f49..66ce0d0128 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -133,6 +133,7 @@ typedef struct acpi_data { enum { ACPI_ALLOCATE_BUFFER = -1, + ACPI_ALLOCATE_LOCAL_BUFFER = -2, }; @@ -261,6 +262,10 @@ struct acpi_module_info { /* Table Access */ status_t (*get_table)(const char *signature, uint32 instance, void **tableHeader); + + /* Register Access */ + status_t (*read_bit_register)(uint32 regid, uint32 *val); + status_t (*write_bit_register)(uint32 regid, uint32 val); }; diff --git a/headers/os/drivers/ISA.h b/headers/os/drivers/ISA.h index 812e04b0c1..2b0f5df592 100644 --- a/headers/os/drivers/ISA.h +++ b/headers/os/drivers/ISA.h @@ -57,7 +57,7 @@ typedef struct isa_module_info { isa_dma_entry *table, /* -> caller-supplied scatter/gather table */ long num_entries /* max # entries in table */ ); - long (*start_isa_dma) ( + status_t (*start_isa_dma) ( long channel, /* dma channel to use */ void *buf, /* buffer to transfer */ long transfer_count, /* # transfers */ @@ -70,8 +70,8 @@ typedef struct isa_module_info { uchar mode, /* mode flags */ uchar emode /* extended mode flags */ ); - long (*lock_isa_dma_channel) (long channel); - long (*unlock_isa_dma_channel) (long channel); + status_t (*lock_isa_dma_channel) (long channel); + status_t (*unlock_isa_dma_channel) (long channel); } isa_module_info; #define B_ISA_MODULE_NAME "bus_managers/isa/v1" diff --git a/headers/os/drivers/PCI.h b/headers/os/drivers/PCI.h index 84535da8af..ef0b50653c 100644 --- a/headers/os/drivers/PCI.h +++ b/headers/os/drivers/PCI.h @@ -44,15 +44,15 @@ typedef struct pci_info { uchar reserved; /* filler, for alignment */ union { struct { - ulong cardbus_cis; /* CardBus CIS pointer */ + uint32 cardbus_cis; /* CardBus CIS pointer */ ushort subsystem_id; /* subsystem (add-in card) id */ ushort subsystem_vendor_id; /* subsystem (add-in card) vendor id */ - ulong rom_base; /* rom base address, viewed from host */ - ulong rom_base_pci; /* rom base addr, viewed from pci */ - ulong rom_size; /* rom size */ - ulong base_registers[6]; /* base registers, viewed from host */ - ulong base_registers_pci[6]; /* base registers, viewed from pci */ - ulong base_register_sizes[6]; /* size of what base regs point to */ + uint32 rom_base; /* rom base address, viewed from host */ + uint32 rom_base_pci; /* rom base addr, viewed from pci */ + uint32 rom_size; /* rom size */ + uint32 base_registers[6]; /* base registers, viewed from host */ + uint32 base_registers_pci[6]; /* base registers, viewed from pci */ + uint32 base_register_sizes[6]; /* size of what base regs point to */ uchar base_register_flags[6]; /* flags from base address fields */ uchar interrupt_line; /* interrupt line */ uchar interrupt_pin; /* interrupt pin */ @@ -60,9 +60,9 @@ typedef struct pci_info { uchar max_latency; /* how often PCI access needed */ } h0; struct { - ulong base_registers[2]; /* base registers, viewed from host */ - ulong base_registers_pci[2]; /* base registers, viewed from pci */ - ulong base_register_sizes[2]; /* size of what base regs point to */ + uint32 base_registers[2]; /* base registers, viewed from host */ + uint32 base_registers_pci[2]; /* base registers, viewed from pci */ + uint32 base_register_sizes[2]; /* size of what base regs point to */ uchar base_register_flags[2]; /* flags from base address fields */ uchar primary_bus; uchar secondary_bus; @@ -75,12 +75,12 @@ typedef struct pci_info { ushort memory_limit; ushort prefetchable_memory_base; ushort prefetchable_memory_limit; - ulong prefetchable_memory_base_upper32; - ulong prefetchable_memory_limit_upper32; + uint32 prefetchable_memory_base_upper32; + uint32 prefetchable_memory_limit_upper32; ushort io_base_upper16; ushort io_limit_upper16; - ulong rom_base; /* rom base address, viewed from host */ - ulong rom_base_pci; /* rom base addr, viewed from pci */ + uint32 rom_base; /* rom base address, viewed from host */ + uint32 rom_base_pci; /* rom base addr, viewed from pci */ uchar interrupt_line; /* interrupt line */ uchar interrupt_pin; /* interrupt pin */ ushort bridge_control; @@ -98,14 +98,14 @@ typedef struct pci_info { uchar subordinate_bus; uchar secondary_latency; ushort reserved; - ulong memory_base; - ulong memory_limit; - ulong memory_base_upper32; - ulong memory_limit_upper32; - ulong io_base; - ulong io_limit; - ulong io_base_upper32; - ulong io_limit_upper32; + uint32 memory_base; + uint32 memory_limit; + uint32 memory_base_upper32; + uint32 memory_limit_upper32; + uint32 io_base; + uint32 io_limit; + uint32 io_base_upper32; + uint32 io_limit_upper32; ushort secondary_status; ushort bridge_control; #endif /* __HAIKU_PCI_BUS_MANAGER_TESTING */ diff --git a/headers/os/drivers/bios.h b/headers/os/drivers/bios.h new file mode 100644 index 0000000000..c756649eb1 --- /dev/null +++ b/headers/os/drivers/bios.h @@ -0,0 +1,73 @@ +/* + * Copyright 2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _BIOS_MODULE_H_ +#define _BIOS_MODULE_H_ + + +#include +#include + + +/*! BIOS call interface. + + This module provides a mechanism to call PC BIOS interrupts (e.g. to use + the VESA BIOS). + + Basic usage is as follows: + - Call bios_module_info::prepare(). This sets up memory mappings and + obtains exclusive access to the BIOS (only 1 thread is able to use the + BIOS at a time). + - Allocate memory for data that will be passed to BIOS interrupts using + bios_module_info::allocate_mem(). This returns a virtual address, to + get the physical address to pass to the BIOS use + bios_module_info::physical_address(). + - Call the BIOS with bios_module_info::interrupt(). + - Get the virtual location of any physical addresses returned using + bios_module_info::virtual_address(). + - Release the BIOS and free created memory mappings with + bios_module_info::finish(). + +*/ + + +// Cookie for the BIOS module functions. +typedef struct BIOSState bios_state; + + +// Registers to pass to a BIOS interrupt. +struct bios_regs { + uint32 eax; + uint32 ebx; + uint32 ecx; + uint32 edx; + uint32 edi; + uint32 esi; + uint32 ebp; + uint32 eflags; + uint32 ds; + uint32 es; + uint32 fs; + uint32 gs; +}; + + +struct bios_module_info { + module_info info; + + status_t (*prepare)(bios_state** _state); + status_t (*interrupt)(bios_state* state, uint8 vector, bios_regs* regs); + void (*finish)(bios_state* state); + + // Memory management methods. + void* (*allocate_mem)(bios_state* state, size_t size); + uint32 (*physical_address)(bios_state* state, void* virtualAddress); + void* (*virtual_address)(bios_state* state, uint32 physicalAddress); +}; + + +#define B_BIOS_MODULE_NAME "generic/bios/v1" + + +#endif // _BIOS_MODULE_H_ diff --git a/headers/os/drivers/cpuidle.h b/headers/os/drivers/cpuidle.h new file mode 100644 index 0000000000..7649cdadab --- /dev/null +++ b/headers/os/drivers/cpuidle.h @@ -0,0 +1,57 @@ +/* + * Copyright 2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _CPUIDLE_MODULE_H +#define _CPUIDLE_MODULE_H + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CPUIDLE_CSTATE_MAX 8 +#define CSTATE_NAME_LENGTH 32 +#define B_CPUIDLE_MODULE_NAME "generic/cpuidle/v1" + + +struct CpuidleStat { + uint64 usageCount; + bigtime_t usageTime; +}; + + +struct CpuidleInfo { + int32 cstateSleep; + CpuidleStat stats[CPUIDLE_CSTATE_MAX]; +}; + +struct CpuidleDevice; + +struct CpuidleCstate { + char name[CSTATE_NAME_LENGTH]; + int32 latency; + int32 (*EnterIdle)(int32 state, CpuidleDevice *device); + void *pData; +}; + + +struct CpuidleDevice { + CpuidleCstate cStates[CPUIDLE_CSTATE_MAX]; + int32 cStateCount; +}; + + +struct CpuidleModuleInfo { + module_info info; + status_t (*AddDevice)(CpuidleDevice *device); +}; + + +#ifdef __cplusplus +} +#endif + +#endif // _CPUIDLE_MODULE_H diff --git a/headers/os/interface/LayoutBuilder.h b/headers/os/interface/LayoutBuilder.h index 3b50c7d494..61bb7be213 100644 --- a/headers/os/interface/LayoutBuilder.h +++ b/headers/os/interface/LayoutBuilder.h @@ -1328,7 +1328,7 @@ MenuItem::MenuItem(ParentBuilder* parentBuilder, BMenu* menu, Menu(menu), fMenuItem(item) { - SetParent(parentBuilder); + this->SetParent(parentBuilder); } diff --git a/headers/os/interface/Region.h b/headers/os/interface/Region.h index 55d8252efd..b7747f73ac 100644 --- a/headers/os/interface/Region.h +++ b/headers/os/interface/Region.h @@ -85,7 +85,7 @@ private: BRegion(const clipping_rect& rect); void _AdoptRegionData(BRegion& region); - bool _SetSize(long newSize); + bool _SetSize(int32 newSize); clipping_rect _Convert(const BRect& rect) const; clipping_rect _ConvertToInternal(const BRect& rect) const; @@ -93,8 +93,8 @@ private: const clipping_rect& rect) const; private: - long fCount; - long fDataSize; + int32 fCount; + int32 fDataSize; clipping_rect fBounds; clipping_rect* fData; }; diff --git a/headers/os/interface/TextView.h b/headers/os/interface/TextView.h index 81517e43cd..cf23a1a51b 100644 --- a/headers/os/interface/TextView.h +++ b/headers/os/interface/TextView.h @@ -413,7 +413,7 @@ private: void _ShowContextMenu(BPoint where); void _FilterDisallowedChars(char* text, - int32& length, text_run_array* runArray); + ssize_t& length, text_run_array* runArray); private: BPrivate::TextGapBuffer* fText; diff --git a/headers/os/kernel/OS.h b/headers/os/kernel/OS.h index 1f921f98ed..d5441da4d2 100644 --- a/headers/os/kernel/OS.h +++ b/headers/os/kernel/OS.h @@ -96,7 +96,7 @@ extern status_t set_area_protection(area_id id, uint32 newProtection); /* system private, use macros instead */ extern status_t _get_area_info(area_id id, area_info *areaInfo, size_t size); -extern status_t _get_next_area_info(team_id team, int32 *cookie, +extern status_t _get_next_area_info(team_id team, ssize_t *cookie, area_info *areaInfo, size_t size); #define get_area_info(id, areaInfo) \ @@ -645,7 +645,7 @@ typedef enum cpu_types { #define B_CPU_x86_VENDOR_MASK 0xff00 -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) typedef union { struct { uint32 max_eax; @@ -713,7 +713,8 @@ typedef enum platform_types { B_MK_61_PLATFORM, B_NINTENDO_64_PLATFORM, B_AMIGA_PLATFORM, - B_ATARI_PLATFORM + B_ATARI_PLATFORM, + B_64_BIT_PC_PLATFORM } platform_type; typedef struct { diff --git a/headers/os/kernel/debugger.h b/headers/os/kernel/debugger.h index 5b86c706d0..c443b3977a 100644 --- a/headers/os/kernel/debugger.h +++ b/headers/os/kernel/debugger.h @@ -13,13 +13,16 @@ // include architecture specific definitions #include +#include #include #include #include #include -#ifdef __INTEL__ +#ifdef __x86_64__ + typedef struct x86_64_debug_cpu_state debug_cpu_state; +#elif __INTEL__ typedef struct x86_debug_cpu_state debug_cpu_state; #elif __POWERPC__ typedef struct ppc_debug_cpu_state debug_cpu_state; diff --git a/headers/os/opengl/GL/glut.h b/headers/os/opengl/GL/glut.h index 137b8efa13..e131205e70 100644 --- a/headers/os/opengl/GL/glut.h +++ b/headers/os/opengl/GL/glut.h @@ -1,15 +1,18 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ #ifndef __glut_h__ #define __glut_h__ -/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ - -/* This program is freely distributable without licensing fees and is - provided without guarantee or warrantee expressed or implied. This - program is -not- in the public domain. */ #include #include + #if defined(__MINGW32__) #include #endif @@ -752,4 +755,5 @@ GLUTAPI int GLUTAPIENTRY glutGameModeGet(GLenum mode); } #endif + #endif /* __glut_h__ */ diff --git a/headers/os/support/SupportDefs.h b/headers/os/support/SupportDefs.h index 0529525366..e4f0c24e53 100644 --- a/headers/os/support/SupportDefs.h +++ b/headers/os/support/SupportDefs.h @@ -148,6 +148,14 @@ typedef generic_addr_t generic_size_t; #define B_PRIiTIME B_PRIi32 +/* Printed width of a pointer with the %p format (minus 0x prefix). */ +#ifdef B_HAIKU_64_BIT +# define B_PRINTF_POINTER_WIDTH 16 +#else +# define B_PRINTF_POINTER_WIDTH 8 +#endif + + /* Empty string ("") */ #ifdef __cplusplus extern const char *B_EMPTY_STRING; diff --git a/headers/posix/arch/x86_64/arch_setjmp.h b/headers/posix/arch/x86_64/arch_setjmp.h index 8371471f01..1e646f2679 100644 --- a/headers/posix/arch/x86_64/arch_setjmp.h +++ b/headers/posix/arch/x86_64/arch_setjmp.h @@ -6,7 +6,6 @@ #define _ARCH_SETJMP_H_ -/* TODO: A jmp_buf size of 12 might not be large enough. Increase to a large size if needed. */ -typedef int __jmp_buf[12]; +typedef unsigned long __jmp_buf[8]; #endif /* _ARCH_SETJMP_H_ */ diff --git a/headers/posix/arch/x86_64/fenv.h b/headers/posix/arch/x86_64/fenv.h index a9992f9fad..9a3df8eb9d 100644 --- a/headers/posix/arch/x86_64/fenv.h +++ b/headers/posix/arch/x86_64/fenv.h @@ -111,7 +111,8 @@ feclearexcept(int __excepts) static __inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { - int __mxcsr, __status; + uint32_t __mxcsr; + uint16_t __status; __stmxcsr(&__mxcsr); __fnstsw(&__status); @@ -125,7 +126,8 @@ int feraiseexcept(int __excepts); static __inline int fetestexcept(int __excepts) { - int __mxcsr, __status; + uint32_t __mxcsr; + uint16_t __status; __stmxcsr(&__mxcsr); __fnstsw(&__status); @@ -135,7 +137,7 @@ fetestexcept(int __excepts) static __inline int fegetround(void) { - int __control; + uint16_t __control; /* * We assume that the x87 and the SSE unit agree on the @@ -150,7 +152,8 @@ fegetround(void) static __inline int fesetround(int __round) { - int __mxcsr, __control; + uint32_t __mxcsr; + uint16_t __control; if (__round & ~_ROUND_MASK) return (-1); @@ -198,7 +201,7 @@ int fedisableexcept(int __mask); static __inline int fegetexcept(void) { - int __control; + uint16_t __control; /* * We assume that the masks for the x87 and the SSE unit are diff --git a/headers/posix/arch/x86_64/fpu.h b/headers/posix/arch/x86_64/fpu.h new file mode 100644 index 0000000000..a22d8ca1f8 --- /dev/null +++ b/headers/posix/arch/x86_64/fpu.h @@ -0,0 +1,218 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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: @(#)npx.h 5.3 (Berkeley) 1/18/91 + * $FreeBSD$ + */ + +/* + * Floating Point Data Structures and Constants + * W. Jolitz 1/90 + */ + +#ifndef _X86_FPU_H_ +#define _X86_FPU_H_ + +#define __aligned(x) __attribute__((__aligned__(x))) + +/* Environment information of floating point unit. */ +struct env87 { + int32_t en_cw; /* control word (16bits) */ + int32_t en_sw; /* status word (16bits) */ + int32_t en_tw; /* tag word (16bits) */ + int32_t en_fip; /* fp instruction pointer */ + uint16_t en_fcs; /* fp code segment selector */ + uint16_t en_opcode; /* opcode last executed (11 bits) */ + int32_t en_foo; /* fp operand offset */ + int32_t en_fos; /* fp operand segment selector */ +}; + +/* Contents of each x87 floating point accumulator. */ +struct fpacc87 { + uint8_t fp_bytes[10]; +}; + +/* Floating point context. (i386 fnsave/frstor) */ +struct save87 { + struct env87 sv_env; /* floating point control/status */ + struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */ + uint8_t sv_pad0[4]; /* saved status word (now unused) */ + /* + * Bogus padding for emulators. Emulators should use their own + * struct and arrange to store into this struct (ending here) + * before it is inspected for ptracing or for core dumps. Some + * emulators overwrite the whole struct. We have no good way of + * knowing how much padding to leave. Leave just enough for the + * GPL emulator's i387_union (176 bytes total). + */ + uint8_t sv_pad[64]; /* padding; used by emulators */ +}; + +/* Contents of each SSE extended accumulator. */ +struct xmmacc { + uint8_t xmm_bytes[16]; +}; + +/* Contents of the upper 16 bytes of each AVX extended accumulator. */ +struct ymmacc { + uint8_t ymm_bytes[16]; +}; + +/* Rename structs below depending on machine architecture. */ +#ifdef __i386__ +#define __envxmm32 envxmm +#else +#define __envxmm32 envxmm32 +#define __envxmm64 envxmm +#endif + +struct __envxmm32 { + uint16_t en_cw; /* control word (16bits) */ + uint16_t en_sw; /* status word (16bits) */ + uint16_t en_tw; /* tag word (16bits) */ + uint16_t en_opcode; /* opcode last executed (11 bits) */ + uint32_t en_fip; /* fp instruction pointer */ + uint16_t en_fcs; /* fp code segment selector */ + uint16_t en_pad0; /* padding */ + uint32_t en_foo; /* fp operand offset */ + uint16_t en_fos; /* fp operand segment selector */ + uint16_t en_pad1; /* padding */ + uint32_t en_mxcsr; /* SSE control/status register */ + uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ +}; + +struct __envxmm64 { + uint16_t en_cw; /* control word (16bits) */ + uint16_t en_sw; /* status word (16bits) */ + uint8_t en_tw; /* tag word (8bits) */ + uint8_t en_zero; + uint16_t en_opcode; /* opcode last executed (11 bits ) */ + uint64_t en_rip; /* fp instruction pointer */ + uint64_t en_rdp; /* fp operand pointer */ + uint32_t en_mxcsr; /* SSE control/status register */ + uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ +}; + +/* Floating point context. (i386 fxsave/fxrstor) */ +struct savexmm { + struct __envxmm32 sv_env; + struct { + struct fpacc87 fp_acc; + uint8_t fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[8]; + uint8_t sv_pad[224]; +} __aligned(16); + +#ifdef __i386__ +union savefpu { + struct save87 sv_87; + struct savexmm sv_xmm; +}; +#else +/* Floating point context. (amd64 fxsave/fxrstor) */ +struct savefpu { + struct __envxmm64 sv_env; + struct { + struct fpacc87 fp_acc; + uint8_t fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[16]; + uint8_t sv_pad[96]; +} __aligned(16); +#endif + +struct xstate_hdr { + uint64_t xstate_bv; + uint8_t xstate_rsrv0[16]; + uint8_t xstate_rsrv[40]; +}; + +struct savexmm_xstate { + struct xstate_hdr sx_hd; + struct ymmacc sx_ymm[16]; +}; + +struct savexmm_ymm { + struct __envxmm32 sv_env; + struct { + struct fpacc87 fp_acc; + int8_t fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[16]; + uint8_t sv_pad[96]; + struct savexmm_xstate sv_xstate; +} __aligned(64); + +struct savefpu_xstate { + struct xstate_hdr sx_hd; + struct ymmacc sx_ymm[16]; +}; + +struct savefpu_ymm { + struct __envxmm64 sv_env; + struct { + struct fpacc87 fp_acc; + int8_t fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[16]; + uint8_t sv_pad[96]; + struct savefpu_xstate sv_xstate; +} __aligned(64); + +#undef __envxmm32 +#undef __envxmm64 + +/* + * The hardware default control word for i387's and later coprocessors is + * 0x37F, giving: + * + * round to nearest + * 64-bit precision + * all exceptions masked. + * + * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc + * because of the difference between memory and fpu register stack arguments. + * If its using an intermediate fpu register, it has 80/64 bits to work + * with. If it uses memory, it has 64/53 bits to work with. However, + * gcc is aware of this and goes to a fair bit of trouble to make the + * best use of it. + * + * This is mostly academic for AMD64, because the ABI prefers the use + * SSE2 based math. For FreeBSD/amd64, we go with the default settings. + */ +#define __INITIAL_FPUCW__ 0x037F +#define __INITIAL_FPUCW_I386__ 0x127F +#define __INITIAL_NPXCW__ __INITIAL_FPUCW_I386__ +#define __INITIAL_MXCSR__ 0x1F80 +#define __INITIAL_MXCSR_MASK__ 0xFFBF + +#endif /* !_X86_FPU_H_ */ diff --git a/headers/posix/arch/x86_64/signal.h b/headers/posix/arch/x86_64/signal.h index f48a72f5fa..871d1f59b6 100644 --- a/headers/posix/arch/x86_64/signal.h +++ b/headers/posix/arch/x86_64/signal.h @@ -12,35 +12,108 @@ #if __x86_64__ -struct vregs { - unsigned long rax; /* gp regs */ - unsigned long rdx; - unsigned long rcx; - unsigned long rbx; - unsigned long rsi; - unsigned long rdi; - unsigned long rbp; - unsigned long rsp; - - unsigned long r8; /* egp regs */ - unsigned long r9; - unsigned long r10; - unsigned long r11; - unsigned long r12; - unsigned long r13; - unsigned long r14; - unsigned long r15; - - unsigned long rip; - -/*TODO: add -* Floatpoint -* MMX -* SSE -*/ +struct fp_stack { + unsigned char st0[10]; + unsigned char _reserved_42_47[6]; + unsigned char st1[10]; + unsigned char _reserved_58_63[6]; + unsigned char st2[10]; + unsigned char _reserved_74_79[6]; + unsigned char st3[10]; + unsigned char _reserved_90_95[6]; + unsigned char st4[10]; + unsigned char _reserved_106_111[6]; + unsigned char st5[10]; + unsigned char _reserved_122_127[6]; + unsigned char st6[10]; + unsigned char _reserved_138_143[6]; + unsigned char st7[10]; + unsigned char _reserved_154_159[6]; }; +struct mmx_regs { + unsigned char mm0[10]; + unsigned char _reserved_42_47[6]; + unsigned char mm1[10]; + unsigned char _reserved_58_63[6]; + unsigned char mm2[10]; + unsigned char _reserved_74_79[6]; + unsigned char mm3[10]; + unsigned char _reserved_90_95[6]; + unsigned char mm4[10]; + unsigned char _reserved_106_111[6]; + unsigned char mm5[10]; + unsigned char _reserved_122_127[6]; + unsigned char mm6[10]; + unsigned char _reserved_138_143[6]; + unsigned char mm7[10]; + unsigned char _reserved_154_159[6]; +}; + +struct xmm_regs { + unsigned char xmm0[16]; + unsigned char xmm1[16]; + unsigned char xmm2[16]; + unsigned char xmm3[16]; + unsigned char xmm4[16]; + unsigned char xmm5[16]; + unsigned char xmm6[16]; + unsigned char xmm7[16]; + unsigned char xmm8[16]; + unsigned char xmm9[16]; + unsigned char xmm10[16]; + unsigned char xmm11[16]; + unsigned char xmm12[16]; + unsigned char xmm13[16]; + unsigned char xmm14[16]; + unsigned char xmm15[16]; +}; + +struct fpu_state { + unsigned short control; + unsigned short status; + unsigned short tag; + unsigned short opcode; + unsigned long rip; + unsigned long rdp; + unsigned int mxcsr; + unsigned int mscsr_mask; + + union { + struct fp_stack fp; + struct mmx_regs mmx; + }; + + struct xmm_regs xmm; + unsigned char _reserved_416_511[96]; +}; + +struct vregs { + unsigned long rax; + unsigned long rbx; + unsigned long rcx; + unsigned long rdx; + unsigned long rdi; + unsigned long rsi; + unsigned long rbp; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; + + unsigned long rsp; + unsigned long rip; + unsigned long rflags; + + struct fpu_state fpu; +}; + + #endif /* __x86_64__ */ #endif /* _ARCH_SIGNAL_H_ */ diff --git a/headers/posix/fenv.h b/headers/posix/fenv.h index 0fb1e203c9..31fdd0b851 100644 --- a/headers/posix/fenv.h +++ b/headers/posix/fenv.h @@ -3,7 +3,7 @@ #if defined(__INTEL__) # include -#elif defined(_x86_64_) +#elif defined(__x86_64__) # include #elif defined(__ARM__) # include diff --git a/headers/posix/netinet/in.h b/headers/posix/netinet/in.h index 36310d1161..ab891cb8dd 100644 --- a/headers/posix/netinet/in.h +++ b/headers/posix/netinet/in.h @@ -26,7 +26,11 @@ typedef uint32_t in_addr_t; * and we are not allowed to import all the BeOS types here. */ #ifndef htonl - extern unsigned long __swap_int32(unsigned long); /* private */ +# ifdef __HAIKU_BEOS_COMPATIBLE_TYPES + extern unsigned long __swap_int32(unsigned long); /* private */ +# else + extern unsigned int __swap_int32(unsigned int); /* private */ +# endif extern uint16_t __swap_int16(uint16_t); /* private */ # if BYTE_ORDER == LITTLE_ENDIAN # define htonl(x) ((uint32_t)__swap_int32(x)) diff --git a/headers/posix/wchar.h b/headers/posix/wchar.h index eebc4e5bba..8b4f79e3eb 100644 --- a/headers/posix/wchar.h +++ b/headers/posix/wchar.h @@ -30,7 +30,7 @@ typedef struct { void* converter; char charset[64]; unsigned int count; - char data[1024 + 8]; // 1024 bytes for data, 8 for alignment space + char data[1024 + 8]; /* 1024 bytes for data, 8 for alignment space */ } mbstate_t; diff --git a/headers/private/kernel/arch/arm/arch_kernel.h b/headers/private/kernel/arch/arm/arch_kernel.h index af0a9e26f7..44a05e74a6 100644 --- a/headers/private/kernel/arch/arm/arch_kernel.h +++ b/headers/private/kernel/arch/arm/arch_kernel.h @@ -23,10 +23,10 @@ #define USER_BASE 0x100000 #define USER_BASE_ANY USER_BASE #define USER_SIZE (0x80000000 - (0x10000 + 0x100000)) -#define USER_TOP (USER_BASE + USER_SIZE) +#define USER_TOP (USER_BASE + (USER_SIZE - 1)) #define KERNEL_USER_DATA_BASE 0x6fff0000 #define USER_STACK_REGION 0x70000000 -#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION) +#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) #endif /* _KERNEL_ARCH_ARM_KERNEL_H */ diff --git a/headers/private/kernel/arch/elf.h b/headers/private/kernel/arch/elf.h index bc8d44f776..d2dc5d8588 100644 --- a/headers/private/kernel/arch/elf.h +++ b/headers/private/kernel/arch/elf.h @@ -5,23 +5,28 @@ #ifndef _KERNEL_ARCH_ELF_H #define _KERNEL_ARCH_ELF_H -struct Elf32_Rel; -struct Elf32_Rela; + +#include + + struct elf_image_info; + #ifdef __cplusplus extern "C" { #endif extern int arch_elf_relocate_rel(struct elf_image_info *image, - struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len); + struct elf_image_info *resolve_image, elf_rel *rel, int rel_len); extern int arch_elf_relocate_rela(struct elf_image_info *image, - struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len); + struct elf_image_info *resolve_image, elf_rela *rel, int rel_len); #ifdef __cplusplus } #endif + #include + #endif /* _KERNEL_ARCH_ELF_H */ diff --git a/headers/private/kernel/arch/m68k/arch_kernel.h b/headers/private/kernel/arch/m68k/arch_kernel.h index 85e9168d33..7f9806999a 100644 --- a/headers/private/kernel/arch/m68k/arch_kernel.h +++ b/headers/private/kernel/arch/m68k/arch_kernel.h @@ -23,10 +23,10 @@ #define USER_BASE 0x100000 #define USER_BASE_ANY USER_BASE #define USER_SIZE (0x80000000 - (0x10000 + 0x100000)) -#define USER_TOP (USER_BASE + USER_SIZE) +#define USER_TOP (USER_BASE + (USER_SIZE - 1)) #define KERNEL_USER_DATA_BASE 0x6fff0000 #define USER_STACK_REGION 0x70000000 -#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION) +#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) #endif /* _KERNEL_ARCH_M68K_KERNEL_H */ diff --git a/headers/private/kernel/arch/mipsel/arch_kernel.h b/headers/private/kernel/arch/mipsel/arch_kernel.h index 6eea165c55..42f3c8fbaf 100644 --- a/headers/private/kernel/arch/mipsel/arch_kernel.h +++ b/headers/private/kernel/arch/mipsel/arch_kernel.h @@ -26,11 +26,11 @@ #define USER_BASE 0x100000 #define USER_BASE_ANY USER_BASE #define USER_SIZE (0x80000000 - (0x10000 + 0x100000)) -#define USER_TOP (USER_BASE + USER_SIZE) +#define USER_TOP (USER_BASE + (USER_SIZE - 1)) #define KERNEL_USER_DATA_BASE 0x6fff0000 #define USER_STACK_REGION 0x70000000 -#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION) +#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) #endif /* _KERNEL_ARCH_MIPSEL_KERNEL_H */ diff --git a/headers/private/kernel/arch/ppc/arch_kernel.h b/headers/private/kernel/arch/ppc/arch_kernel.h index 3886034f11..c7d448084b 100644 --- a/headers/private/kernel/arch/ppc/arch_kernel.h +++ b/headers/private/kernel/arch/ppc/arch_kernel.h @@ -23,10 +23,10 @@ #define USER_BASE 0x100000 #define USER_BASE_ANY USER_BASE #define USER_SIZE (0x80000000 - (0x10000 + 0x100000)) -#define USER_TOP (USER_BASE + USER_SIZE) +#define USER_TOP (USER_BASE + (USER_SIZE - 1)) #define KERNEL_USER_DATA_BASE 0x6fff0000 #define USER_STACK_REGION 0x70000000 -#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION) +#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) #endif /* _KERNEL_ARCH_PPC_KERNEL_H */ diff --git a/headers/private/kernel/arch/x86/32/descriptors.h b/headers/private/kernel/arch/x86/32/descriptors.h new file mode 100644 index 0000000000..e09b849e3a --- /dev/null +++ b/headers/private/kernel/arch/x86/32/descriptors.h @@ -0,0 +1,146 @@ +/* + * Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ +#ifndef _KERNEL_ARCH_X86_32_DESCRIPTORS_H +#define _KERNEL_ARCH_X86_32_DESCRIPTORS_H + + +#define KERNEL_CODE_SEG 0x8 +#define KERNEL_DATA_SEG 0x10 + +#define USER_CODE_SEG 0x1b +#define USER_DATA_SEG 0x23 + +#define APM_CODE32_SEGMENT 0x28 +#define APM_CODE16_SEGMENT 0x30 +#define APM_DATA_SEGMENT 0x38 + +#define BIOS_DATA_SEGMENT 0x40 + + +#ifndef _ASSEMBLER + // this file can also be included from assembler as well + // (and is in arch_interrupts.S) + +#define DOUBLE_FAULT_TSS_BASE_SEGMENT 9 +#define TSS_BASE_SEGMENT (DOUBLE_FAULT_TSS_BASE_SEGMENT + smp_get_num_cpus()) +#define TLS_BASE_SEGMENT (TSS_BASE_SEGMENT + smp_get_num_cpus()) +#define APM_BASE_SEGMENT (TLS_BASE_SEGMENT + smp_get_num_cpus()) + +#define TSS_SEGMENT(cpu) (TSS_BASE_SEGMENT + cpu) + +// defines entries in the GDT/LDT + +struct segment_descriptor { + uint16 limit_00_15; // bit 0 - 15 + uint16 base_00_15; // 16 - 31 + uint32 base_23_16 : 8; // 0 - 7 + uint32 type : 4; // 8 - 11 + uint32 desc_type : 1; // 12 (0 = system, 1 = code/data) + uint32 privilege_level : 2; // 13 - 14 + uint32 present : 1; // 15 + uint32 limit_19_16 : 4; // 16 - 19 + uint32 available : 1; // 20 + uint32 zero : 1; // 21 + uint32 d_b : 1; // 22 + uint32 granularity : 1; // 23 + uint32 base_31_24 : 8; // 24 - 31 +}; + +struct interrupt_descriptor { + uint32 a; + uint32 b; +}; + +struct tss { + uint16 prev_task; + uint16 unused0; + uint32 sp0; + uint32 ss0; + uint32 sp1; + uint32 ss1; + uint32 sp2; + uint32 ss2; + uint32 cr3; + uint32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi; + uint32 es, cs, ss, ds, fs, gs; + uint32 ldt_seg_selector; + uint16 unused1; + uint16 io_map_base; +}; + + +static inline void +clear_segment_descriptor(segment_descriptor* desc) +{ + *(long long*)desc = 0; +} + + +static inline void +set_segment_descriptor_base(segment_descriptor* desc, addr_t base) +{ + desc->base_00_15 = (addr_t)base & 0xffff; // base is 32 bits long + desc->base_23_16 = ((addr_t)base >> 16) & 0xff; + desc->base_31_24 = ((addr_t)base >> 24) & 0xff; +} + + +static inline void +set_segment_descriptor(segment_descriptor* desc, addr_t base, uint32 limit, + uint8 type, uint8 privilegeLevel) +{ + set_segment_descriptor_base(desc, base); + + // limit is 20 bits long + if (limit & 0xfff00000) { + desc->limit_00_15 = ((addr_t)limit >> 12) & 0x0ffff; + desc->limit_19_16 = ((addr_t)limit >> 28) & 0xf; + desc->granularity = 1; // 4 KB granularity + } else { + desc->limit_00_15 = (addr_t)limit & 0x0ffff; + desc->limit_19_16 = ((addr_t)limit >> 16) & 0xf; + desc->granularity = 0; // 1 byte granularity + } + + desc->type = type; + desc->desc_type = DT_CODE_DATA_SEGMENT; + desc->privilege_level = privilegeLevel; + + desc->present = 1; + desc->available = 0; // system available bit is currently not used + desc->d_b = 1; // 32-bit code + + desc->zero = 0; +} + + +static inline void +set_tss_descriptor(segment_descriptor* desc, addr_t base, uint32 limit) +{ + // the TSS descriptor has a special layout different from the standard descriptor + set_segment_descriptor_base(desc, base); + + desc->limit_00_15 = (addr_t)limit & 0x0ffff; + desc->limit_19_16 = 0; + + desc->type = DT_TSS; + desc->desc_type = DT_SYSTEM_SEGMENT; + desc->privilege_level = DPL_KERNEL; + + desc->present = 1; + desc->granularity = 0; // 1 Byte granularity + desc->available = 0; // system available bit is currently not used + desc->d_b = 0; + + desc->zero = 0; +} + + +#endif /* _ASSEMBLER */ + +#endif /* _KERNEL_ARCH_X86_32_DESCRIPTORS_H */ diff --git a/headers/private/kernel/arch/x86/32/iframe.h b/headers/private/kernel/arch/x86/32/iframe.h new file mode 100644 index 0000000000..47c423826f --- /dev/null +++ b/headers/private/kernel/arch/x86/32/iframe.h @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ +#ifndef _KERNEL_ARCH_X86_32_IFRAME_H +#define _KERNEL_ARCH_X86_32_IFRAME_H + + +struct iframe { + uint32 type; // iframe type + uint32 gs; + uint32 fs; + uint32 es; + uint32 ds; + uint32 di; + uint32 si; + uint32 bp; + uint32 sp; + uint32 bx; + uint32 dx; + uint32 cx; + uint32 ax; + uint32 orig_eax; + uint32 orig_edx; + uint32 vector; + uint32 error_code; + uint32 ip; + uint32 cs; + uint32 flags; + + // user_sp and user_ss are only present when the iframe is a userland + // iframe (IFRAME_IS_USER()). A kernel iframe is shorter. + uint32 user_sp; + uint32 user_ss; +}; + +#define IFRAME_IS_USER(f) ((f)->cs == USER_CODE_SEG \ + || ((f)->flags & 0x20000) != 0) + + +#endif /* _KERNEL_ARCH_X86_32_IFRAME_H */ diff --git a/headers/private/kernel/arch/x86/64/descriptors.h b/headers/private/kernel/arch/x86/64/descriptors.h new file mode 100644 index 0000000000..3f05196586 --- /dev/null +++ b/headers/private/kernel/arch/x86/64/descriptors.h @@ -0,0 +1,169 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_X86_64_DESCRIPTORS_H +#define _KERNEL_ARCH_X86_64_DESCRIPTORS_H + + +// Segment definitions. +// Note that the ordering of these is important to SYSCALL/SYSRET. +#define KERNEL_CODE_SEG 0x08 +#define KERNEL_DATA_SEG 0x10 +#define USER_DATA_SEG 0x1b +#define USER_CODE_SEG 0x23 + + +#ifndef _ASSEMBLER + + +#define TSS_BASE_SEGMENT 5 +#define TSS_SEGMENT(cpu) (TSS_BASE_SEGMENT + cpu * 2) + + +// Structure of a segment descriptor. +struct segment_descriptor { + uint32 limit0 : 16; + uint32 base0 : 24; + uint32 type : 4; + uint32 desc_type : 1; + uint32 dpl : 2; + uint32 present : 1; + uint32 limit1 : 4; + uint32 available : 1; + uint32 long_mode : 1; + uint32 d_b : 1; + uint32 granularity : 1; + uint32 base1 : 8; +} _PACKED; + +// Structure of a TSS segment descriptor. +struct tss_descriptor { + uint32 limit0 : 16; + uint32 base0 : 24; + uint32 type : 4; + uint32 desc_type : 1; + uint32 dpl : 2; + uint32 present : 1; + uint32 limit1 : 4; + uint32 available : 1; + uint32 unused1 : 2; + uint32 granularity : 1; + uint32 base1 : 8; + uint32 base2 : 32; + uint32 unused2 : 32; +} _PACKED; + +// Structure of an interrupt descriptor. +struct interrupt_descriptor { + uint32 base0 : 16; + uint32 sel : 16; + uint32 ist : 3; + uint32 unused1 : 5; + uint32 type : 4; + uint32 unused2 : 1; + uint32 dpl : 2; + uint32 present : 1; + uint32 base1 : 16; + uint32 base2 : 32; + uint32 reserved : 32; +} _PACKED; + +struct gdt_idt_descr { + uint16 limit; + addr_t base; +} _PACKED; + +struct tss { + uint32 _reserved1; + uint64 sp0; + uint64 sp1; + uint64 sp2; + uint64 _reserved2; + uint64 ist1; + uint64 ist2; + uint64 ist3; + uint64 ist4; + uint64 ist5; + uint64 ist6; + uint64 ist7; + uint64 _reserved3; + uint16 _reserved4; + uint16 io_map_base; +} _PACKED; + + +static inline void +clear_segment_descriptor(segment_descriptor* desc) +{ + *(uint64*)desc = 0; +} + + +static inline void +set_segment_descriptor(segment_descriptor* desc, uint8 type, uint8 dpl) +{ + clear_segment_descriptor(desc); + + // In 64-bit mode the CPU ignores the base/limit of code/data segments, + // it always treats base as 0 and does no limit checks. + desc->base0 = 0; + desc->base1 = 0; + desc->limit0 = 0xffff; + desc->limit1 = 0xf; + desc->granularity = 1; + + desc->type = type; + desc->desc_type = DT_CODE_DATA_SEGMENT; + desc->dpl = dpl; + desc->present = 1; + + desc->long_mode = (type & DT_CODE_EXECUTE_ONLY) ? 1 : 0; + // Must be set to 1 for code segments only. +} + + +static inline void +set_tss_descriptor(segment_descriptor* _desc, uint64 base, uint32 limit) +{ + clear_segment_descriptor(_desc); + clear_segment_descriptor(&_desc[1]); + + // The TSS descriptor is a special format in 64-bit mode, it is 16 bytes + // instead of 8. + tss_descriptor* desc = (tss_descriptor*)_desc; + + desc->base0 = base & 0xffffff; + desc->base1 = (base >> 24) & 0xff; + desc->base2 = (base >> 32); + desc->limit0 = limit & 0xffff; + desc->limit1 = (limit >> 16) & 0xf; + + desc->present = 1; + desc->type = DT_TSS; + desc->desc_type = DT_SYSTEM_SEGMENT; + desc->dpl = DPL_KERNEL; +} + + +static inline void +set_interrupt_descriptor(interrupt_descriptor* desc, uint64 addr, uint32 type, + uint16 seg, uint32 dpl, uint32 ist) +{ + desc->base0 = addr & 0xffff; + desc->base1 = (addr >> 16) & 0xffff; + desc->base2 = (addr >> 32) & 0xffffffff; + desc->sel = seg; + desc->ist = ist; + desc->type = type; + desc->dpl = dpl; + desc->present = 1; + desc->unused1 = 0; + desc->unused2 = 0; + desc->reserved = 0; +} + + +#endif /* _ASSEMBLER */ + +#endif /* _KERNEL_ARCH_X86_64_DESCRIPTORS_H */ diff --git a/headers/private/kernel/arch/x86/64/iframe.h b/headers/private/kernel/arch/x86/64/iframe.h new file mode 100644 index 0000000000..2320949c5b --- /dev/null +++ b/headers/private/kernel/arch/x86/64/iframe.h @@ -0,0 +1,48 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_X86_64_IFRAME_H +#define _KERNEL_ARCH_X86_64_IFRAME_H + + +struct iframe { + uint64 type; + uint64 r15; + uint64 r14; + uint64 r13; + uint64 r12; + uint64 r11; + uint64 r10; + uint64 r9; + uint64 r8; + uint64 bp; + uint64 si; + uint64 di; + uint64 dx; + uint64 cx; + uint64 bx; + uint64 ax; + uint64 orig_rax; + uint64 vector; + uint64 error_code; + uint64 ip; + uint64 cs; + uint64 flags; + + // SP and SS are unconditionally present on x86_64, make both names + // available. + union { + uint64 sp; + uint64 user_sp; + }; + union { + uint64 ss; + uint64 user_ss; + }; +} _PACKED; + +#define IFRAME_IS_USER(f) (((f)->cs & DPL_USER) == DPL_USER) + + +#endif /* _KERNEL_ARCH_X86_64_IFRAME_H */ diff --git a/headers/private/kernel/arch/x86/apm.h b/headers/private/kernel/arch/x86/apm.h index 905ac0d249..cc557efeb2 100644 --- a/headers/private/kernel/arch/x86/apm.h +++ b/headers/private/kernel/arch/x86/apm.h @@ -7,7 +7,7 @@ #include -#include +#include struct kernel_args; @@ -50,6 +50,7 @@ typedef struct apm_info { #ifndef _BOOT_MODE +#ifndef __x86_64__ #ifdef __cplusplus extern "C" { #endif @@ -60,6 +61,7 @@ status_t apm_init(struct kernel_args *args); #ifdef __cplusplus } #endif +#endif // !__x86_64__ #endif // !_BOOT_MODE #endif /* KERNEL_APM_H */ diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index 2ce6bd0b4d..58694f3423 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -1,5 +1,6 @@ /* * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -14,13 +15,15 @@ #include #include +#ifdef __x86_64__ +# include +#else +# include +#endif + #endif // !_ASSEMBLER -#undef PAUSE -#define PAUSE() asm volatile ("pause;") - - // MSR registers (possibly Intel specific) #define IA32_MSR_TSC 0x10 #define IA32_MSR_APIC_BASE 0x1b @@ -34,6 +37,16 @@ #define IA32_MSR_MTRR_PHYSICAL_BASE_0 0x200 #define IA32_MSR_MTRR_PHYSICAL_MASK_0 0x201 +#define IA32_MSR_EFER 0xc0000080 + +// x86_64 MSRs. +#define IA32_MSR_STAR 0xc0000081 +#define IA32_MSR_LSTAR 0xc0000082 +#define IA32_MSR_FMASK 0xc0000084 +#define IA32_MSR_FS_BASE 0xc0000100 +#define IA32_MSR_GS_BASE 0xc0000101 +#define IA32_MSR_KERNEL_GS_BASE 0xc0000102 + // K8 MSR registers #define K8_MSR_IPM 0xc0010055 @@ -143,7 +156,6 @@ #define IA32_MTR_WRITE_PROTECTED 5 #define IA32_MTR_WRITE_BACK 6 - // EFLAGS register #define X86_EFLAGS_CARRY 0x00000001 #define X86_EFLAGS_RESERVED1 0x00000002 @@ -178,6 +190,7 @@ #ifndef _ASSEMBLER + struct X86PagingStructures; @@ -209,87 +222,6 @@ typedef struct x86_cpu_module_info { void (*get_optimized_functions)(x86_optimized_functions* functions); } x86_cpu_module_info; - -struct tss { - uint16 prev_task; - uint16 unused0; - uint32 sp0; - uint32 ss0; - uint32 sp1; - uint32 ss1; - uint32 sp2; - uint32 ss2; - uint32 cr3; - uint32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi; - uint32 es, cs, ss, ds, fs, gs; - uint32 ldt_seg_selector; - uint16 unused1; - uint16 io_map_base; -}; - -struct iframe { - uint32 type; // iframe type - uint32 gs; - uint32 fs; - uint32 es; - uint32 ds; - uint32 edi; - uint32 esi; - uint32 ebp; - uint32 esp; - uint32 ebx; - uint32 edx; - uint32 ecx; - uint32 eax; - uint32 orig_eax; - uint32 orig_edx; - uint32 vector; - uint32 error_code; - uint32 eip; - uint32 cs; - uint32 flags; - - // user_esp and user_ss are only present when the iframe is a userland - // iframe (IFRAME_IS_USER()). A kernel iframe is shorter. - uint32 user_esp; - uint32 user_ss; -}; - -struct vm86_iframe { - uint32 type; // iframe type - uint32 __null_gs; - uint32 __null_fs; - uint32 __null_es; - uint32 __null_ds; - uint32 edi; - uint32 esi; - uint32 ebp; - uint32 __kern_esp; - uint32 ebx; - uint32 edx; - uint32 ecx; - uint32 eax; - uint32 orig_eax; - uint32 orig_edx; - uint32 vector; - uint32 error_code; - uint32 eip; - uint16 cs, __csh; - uint32 flags; - uint32 esp; - uint16 ss, __ssh; - - /* vm86 mode specific part */ - uint16 es, __esh; - uint16 ds, __dsh; - uint16 fs, __fsh; - uint16 gs, __gsh; -}; - -#define IFRAME_IS_USER(f) ((f)->cs == USER_CODE_SEG \ - || ((f)->flags & 0x20000) != 0) -#define IFRAME_IS_VM86(f) (((f)->flags & 0x20000) != 0) - // features enum x86_feature_type { FEATURE_COMMON = 0, // cpuid eax=1, ecx register @@ -316,6 +248,7 @@ enum x86_vendors { VENDOR_UNKNOWN, }; + typedef struct arch_cpu_info { // saved cpu info enum x86_vendors vendor; @@ -331,71 +264,63 @@ typedef struct arch_cpu_info { struct X86PagingStructures* active_paging_structures; - uint32 dr6; // temporary storage for debug registers (cf. - uint32 dr7; // x86_exit_user_debug_at_kernel_entry()) + size_t dr6; // temporary storage for debug registers (cf. + size_t dr7; // x86_exit_user_debug_at_kernel_entry()) // local TSS for this cpu struct tss tss; +#ifndef __x86_64__ struct tss double_fault_tss; +#endif } arch_cpu_info; -#ifdef __cplusplus -extern "C" { -#endif + +#undef PAUSE +#define PAUSE() asm volatile ("pause;") #define nop() __asm__ ("nop"::) -struct arch_thread; +#define x86_read_cr0() ({ \ + size_t _v; \ + __asm__("mov %%cr0,%0" : "=r" (_v)); \ + _v; \ +}) -void __x86_setup_system_time(uint32 conversionFactor, - uint32 conversionFactorNsecs, bool conversionFactorNsecsShift); -void x86_context_switch(struct arch_thread* oldState, - struct arch_thread* newState); -void x86_userspace_thread_exit(void); -void x86_end_userspace_thread_exit(void); -void x86_swap_pgdir(uint32 newPageDir); -void i386_set_tss_and_kstack(addr_t kstack); -void i386_fnsave(void* fpuState); -void i386_fxsave(void* fpuState); -void i386_frstor(const void* fpuState); -void i386_fxrstor(const void* fpuState); -void i386_noop_swap(void* oldFpuState, const void* newFpuState); -void i386_fnsave_swap(void* oldFpuState, const void* newFpuState); -void i386_fxsave_swap(void* oldFpuState, const void* newFpuState); -uint32 x86_read_ebp(); -uint32 x86_read_cr0(); -void x86_write_cr0(uint32 value); -uint32 x86_read_cr4(); -void x86_write_cr4(uint32 value); -uint64 x86_read_msr(uint32 registerNumber); -void x86_write_msr(uint32 registerNumber, uint64 value); -void x86_set_task_gate(int32 cpu, int32 n, int32 segment); -void* x86_get_idt(int32 cpu); -uint32 x86_count_mtrrs(void); -void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type); -status_t x86_get_mtrr(uint32 index, uint64* _base, uint64* _length, - uint8* _type); -void x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos, - uint32 count); -void x86_init_fpu(); -bool x86_check_feature(uint32 feature, enum x86_feature_type type); -void* x86_get_double_fault_stack(int32 cpu, size_t* _size); -int32 x86_double_fault_get_cpu(void); -void x86_double_fault_exception(struct iframe* frame); -void x86_page_fault_exception_double_fault(struct iframe* frame); +#define x86_write_cr0(value) \ + __asm__("mov %0,%%cr0" : : "r" (value)) +#define x86_read_cr2() ({ \ + size_t _v; \ + __asm__("mov %%cr2,%0" : "=r" (_v)); \ + _v; \ +}) -#define read_cr3(value) \ - __asm__("movl %%cr3,%0" : "=r" (value)) +#define x86_read_cr3() ({ \ + size_t _v; \ + __asm__("mov %%cr3,%0" : "=r" (_v)); \ + _v; \ +}) -#define write_cr3(value) \ - __asm__("movl %0,%%cr3" : : "r" (value)) +#define x86_write_cr3(value) \ + __asm__("mov %0,%%cr3" : : "r" (value)) -#define read_dr3(value) \ - __asm__("movl %%dr3,%0" : "=r" (value)) +#define x86_read_cr4() ({ \ + size_t _v; \ + __asm__("mov %%cr4,%0" : "=r" (_v)); \ + _v; \ +}) -#define write_dr3(value) \ - __asm__("movl %0,%%dr3" : : "r" (value)) +#define x86_write_cr4(value) \ + __asm__("mov %0,%%cr4" : : "r" (value)) + +#define x86_read_dr3() ({ \ + size_t _v; \ + __asm__("mov %%dr3,%0" : "=r" (_v)); \ + _v; \ +}) + +#define x86_write_dr3(value) \ + __asm__("mov %0,%%dr3" : : "r" (value)) #define invalidate_TLB(va) \ __asm__("invlpg (%0)" : : "r" (va)) @@ -445,7 +370,57 @@ void x86_page_fault_exception_double_fault(struct iframe* frame); _v; \ }) -extern segment_descriptor* gGDT; + +#ifdef __cplusplus +extern "C" { +#endif + +struct arch_thread; + +#ifdef __x86_64__ +void __x86_setup_system_time(uint64 conversionFactor, + uint64 conversionFactorNsecs); +#else +void __x86_setup_system_time(uint32 conversionFactor, + uint32 conversionFactorNsecs, bool conversionFactorNsecsShift); +#endif + +void x86_context_switch(struct arch_thread* oldState, + struct arch_thread* newState); +void x86_userspace_thread_exit(void); +void x86_end_userspace_thread_exit(void); +void x86_swap_pgdir(addr_t newPageDir); +void x86_fxsave(void* fpuState); +void x86_fxrstor(const void* fpuState); +void x86_noop_swap(void* oldFpuState, const void* newFpuState); +void x86_fxsave_swap(void* oldFpuState, const void* newFpuState); +addr_t x86_get_stack_frame(); +uint64 x86_read_msr(uint32 registerNumber); +void x86_write_msr(uint32 registerNumber, uint64 value); +uint32 x86_count_mtrrs(void); +void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type); +status_t x86_get_mtrr(uint32 index, uint64* _base, uint64* _length, + uint8* _type); +void x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos, + uint32 count); +void x86_init_fpu(); +bool x86_check_feature(uint32 feature, enum x86_feature_type type); +void* x86_get_double_fault_stack(int32 cpu, size_t* _size); +int32 x86_double_fault_get_cpu(void); + +void x86_invalid_exception(iframe* frame); +void x86_fatal_exception(iframe* frame); +void x86_unexpected_exception(iframe* frame); +void x86_hardware_interrupt(iframe* frame); +void x86_page_fault_exception(iframe* iframe); + +#ifndef __x86_64__ + +void x86_fnsave(void* fpuState); +void x86_frstor(const void* fpuState); +void x86_fnsave_swap(void* oldFpuState, const void* newFpuState); + +#endif #ifdef __cplusplus diff --git a/headers/private/kernel/arch/x86/arch_debug.h b/headers/private/kernel/arch/x86/arch_debug.h index 789ecc7461..eb2028ffe5 100644 --- a/headers/private/kernel/arch/x86/arch_debug.h +++ b/headers/private/kernel/arch/x86/arch_debug.h @@ -10,7 +10,7 @@ struct arch_debug_registers { - uint32 ebp; + addr_t bp; }; diff --git a/headers/private/kernel/arch/x86/arch_int.h b/headers/private/kernel/arch/x86/arch_int.h index b8a5828d23..da4943726d 100644 --- a/headers/private/kernel/arch/x86/arch_int.h +++ b/headers/private/kernel/arch/x86/arch_int.h @@ -1,5 +1,6 @@ /* * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Distributed under the terms of the MIT License. */ #ifndef _KERNEL_ARCH_x86_INT_H @@ -20,30 +21,30 @@ arch_int_enable_interrupts_inline(void) static inline int arch_int_disable_interrupts_inline(void) { - int flags; + size_t flags; - asm volatile("pushfl;\n" - "popl %0;\n" + asm volatile("pushf;\n" + "pop %0;\n" "cli" : "=g" (flags)); - return flags ; + return (flags & 0x200) != 0; } static inline void arch_int_restore_interrupts_inline(int oldState) { - if (oldState & 0x200) - asm("sti"); + if (oldState) + asm("sti"); } static inline bool arch_int_are_interrupts_enabled_inline(void) { - int flags; + size_t flags; - asm volatile("pushfl;\n" - "popl %0;\n" : "=g" (flags)); + asm volatile("pushf;\n" + "pop %0;\n" : "=g" (flags)); return (flags & 0x200) != 0; } diff --git a/headers/private/kernel/arch/x86/arch_kernel.h b/headers/private/kernel/arch/x86/arch_kernel.h index 66bbfd0dbc..e6cf5db27b 100644 --- a/headers/private/kernel/arch/x86/arch_kernel.h +++ b/headers/private/kernel/arch/x86/arch_kernel.h @@ -1,6 +1,6 @@ /* * Copyright 2004-2008, Haiku Inc. All rights reserved. - * Distributes under the terms of the MIT license. + * Distributed under the terms of the MIT license. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the NewOS License. @@ -8,14 +8,58 @@ #ifndef _KERNEL_ARCH_x86_KERNEL_H #define _KERNEL_ARCH_x86_KERNEL_H + #ifndef _ASSEMBLER # include #endif + +#ifdef _BOOT_MODE + + +// 32-bit and 64-bit kernel load addresses. +#define KERNEL_LOAD_BASE 0x80000000 +#define KERNEL_LOAD_BASE_64_BIT 0xffffffff80000000ll + + +#elif defined(__x86_64__) + + +// Base of the kernel address space. +// KERNEL_BASE is the base of the kernel address space. This differs from the +// address where the kernel is loaded to: the kernel is loaded in the top 2GB +// of the virtual address space as required by GCC's kernel code model. The +// whole kernel address space is the top 512GB of the address space. +#define KERNEL_BASE 0xffffff8000000000 +#define KERNEL_SIZE 0x8000000000 +#define KERNEL_TOP (KERNEL_BASE + (KERNEL_SIZE - 1)) +#define KERNEL_LOAD_BASE 0xffffffff80000000 + +// Kernel physical memory map area. +#define KERNEL_PMAP_BASE 0xffffff0000000000 +#define KERNEL_PMAP_SIZE 0x8000000000 + +// Userspace address space layout. +// There is a 2MB hole just before the end of the bottom half of the address +// space. This means that if userland passes in a buffer that crosses into the +// uncanonical address region, it will be caught through a page fault. +#define USER_BASE 0x0 +#define USER_BASE_ANY 0x100000 +#define USER_SIZE (0x800000000000 - 0x200000) +#define USER_TOP (USER_BASE + (USER_SIZE - 1)) + +#define KERNEL_USER_DATA_BASE 0x7fffefff0000 +#define USER_STACK_REGION 0x7ffff0000000 +#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) + + +#else // __x86_64__ + + // memory layout -#define KERNEL_BASE 0x80000000 -#define KERNEL_SIZE 0x80000000 -#define KERNEL_TOP (KERNEL_BASE + (KERNEL_SIZE - 1)) +#define KERNEL_BASE 0x80000000 +#define KERNEL_SIZE 0x80000000 +#define KERNEL_TOP (KERNEL_BASE + (KERNEL_SIZE - 1)) /* User space layout is a little special: * The user space does not completely cover the space not covered by the @@ -27,13 +71,16 @@ * TODO: introduce the 1Mb lower barrier again - it's only used for vm86 mode, * and this should be moved into the kernel (and address space) completely. */ -#define USER_BASE 0x00 -#define USER_BASE_ANY 0x100000 -#define USER_SIZE (KERNEL_BASE - 0x10000) -#define USER_TOP (USER_BASE + USER_SIZE) +#define USER_BASE 0x0 +#define USER_BASE_ANY 0x100000 +#define USER_SIZE (KERNEL_BASE - 0x10000) +#define USER_TOP (USER_BASE + (USER_SIZE - 1)) #define KERNEL_USER_DATA_BASE 0x6fff0000 #define USER_STACK_REGION 0x70000000 -#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION) +#define USER_STACK_REGION_SIZE ((USER_TOP - USER_STACK_REGION) + 1) -#endif /* _KERNEL_ARCH_x86_KERNEL_H */ + +#endif // __x86_64__ + +#endif // _KERNEL_ARCH_x86_KERNEL_H diff --git a/headers/private/kernel/arch/x86/arch_kernel_args.h b/headers/private/kernel/arch/x86/arch_kernel_args.h index 0949d48726..7e6c967582 100644 --- a/headers/private/kernel/arch/x86/arch_kernel_args.h +++ b/headers/private/kernel/arch/x86/arch_kernel_args.h @@ -9,6 +9,10 @@ # error This file is included from only #endif + +#include + + #define MAX_BOOT_PTABLES 4 #define _PACKED __attribute__((packed)) @@ -22,26 +26,25 @@ typedef struct { uint32 system_time_cv_factor; uint64 cpu_clock_speed; uint32 phys_pgdir; - uint32 vir_pgdir; + uint64 vir_pgdir; uint32 num_pgtables; uint32 pgtables[MAX_BOOT_PTABLES]; - uint32 virtual_end; + uint64 virtual_end; uint32 phys_idt; - uint32 vir_idt; + uint64 vir_idt; uint32 phys_gdt; - uint32 vir_gdt; - uint32 page_hole; + uint64 vir_gdt; + uint64 page_hole; // smp stuff uint32 apic_time_cv_factor; // apic ticks per second uint32 apic_phys; - uint32 *apic; + FixedWidthPointer apic; uint32 ioapic_phys; - uint32 *ioapic; uint32 cpu_apic_id[MAX_BOOT_CPUS]; uint32 cpu_apic_version[MAX_BOOT_CPUS]; // hpet stuff uint32 hpet_phys; - uint32 *hpet; -} arch_kernel_args; + FixedWidthPointer hpet; +} _PACKED arch_kernel_args; #endif /* KERNEL_ARCH_x86_KERNEL_ARGS_H */ diff --git a/headers/private/kernel/arch/x86/arch_system_info.h b/headers/private/kernel/arch/x86/arch_system_info.h index e243607364..b8a7383de9 100644 --- a/headers/private/kernel/arch/x86/arch_system_info.h +++ b/headers/private/kernel/arch/x86/arch_system_info.h @@ -12,11 +12,11 @@ extern "C" { #endif -status_t get_current_cpuid(cpuid_info *info, uint32 eax); +status_t get_current_cpuid(cpuid_info* info, uint32 eax); uint32 get_eflags(void); void set_eflags(uint32 value); -status_t _user_get_cpuid(cpuid_info *info, uint32 eax, uint32 cpu); +status_t _user_get_cpuid(cpuid_info* info, uint32 eax, uint32 cpu); #ifdef __cplusplus } diff --git a/headers/private/kernel/arch/x86/arch_thread.h b/headers/private/kernel/arch/x86/arch_thread.h index f0513717c9..0769195543 100644 --- a/headers/private/kernel/arch/x86/arch_thread.h +++ b/headers/private/kernel/arch/x86/arch_thread.h @@ -16,39 +16,69 @@ extern "C" { #endif -struct iframe *i386_get_user_iframe(void); -struct iframe *i386_get_current_iframe(void); -struct iframe *i386_get_thread_user_iframe(Thread *thread); +struct sigaction; -uint32 x86_next_page_directory(Thread *from, Thread *to); -void x86_restart_syscall(struct iframe *frame); +struct iframe* x86_get_user_iframe(void); +struct iframe* x86_get_current_iframe(void); +struct iframe* x86_get_thread_user_iframe(Thread* thread); + +phys_addr_t x86_next_page_directory(Thread* from, Thread* to); +void x86_initial_return_to_userland(Thread* thread, struct iframe* iframe); + +void x86_restart_syscall(struct iframe* frame); +void x86_set_tls_context(Thread* thread); + + +#ifdef __x86_64__ + + +static inline Thread* +arch_thread_get_current_thread(void) +{ + addr_t addr; + __asm__("mov %%gs:0, %0" : "=r"(addr)); + return (Thread*)addr; +} + + +static inline void +arch_thread_set_current_thread(Thread* t) +{ + // Point GS segment base at thread architecture data. + t->arch_info.thread = t; + x86_write_msr(IA32_MSR_GS_BASE, (addr_t)&t->arch_info); +} + + +#else // __x86_64__ -void x86_set_tls_context(Thread *thread); // override empty macro #undef arch_syscall_64_bit_return_value void arch_syscall_64_bit_return_value(void); -static -inline Thread * +static inline Thread* arch_thread_get_current_thread(void) { - Thread *t; - read_dr3(t); + Thread* t = (Thread*)x86_read_dr3(); return t; } + static inline void -arch_thread_set_current_thread(Thread *t) +arch_thread_set_current_thread(Thread* t) { - write_dr3(t); + x86_write_dr3(t); } + +#endif // __x86_64__ + + #ifdef __cplusplus } #endif #endif /* _KERNEL_ARCH_x86_THREAD_H */ - diff --git a/headers/private/kernel/arch/x86/arch_thread_types.h b/headers/private/kernel/arch/x86/arch_thread_types.h index 0df49071c0..85dfc6bb08 100644 --- a/headers/private/kernel/arch/x86/arch_thread_types.h +++ b/headers/private/kernel/arch/x86/arch_thread_types.h @@ -11,32 +11,81 @@ #include + +namespace BKernel { + struct Thread; +} + + #define _ALIGNED(bytes) __attribute__((aligned(bytes))) // move this to somewhere else, maybe BeBuild.h? + +#ifndef __x86_64__ struct farcall { - uint32 *esp; - uint32 *ss; + uint32* esp; + uint32* ss; }; +#endif + // architecture specific thread info struct arch_thread { - struct farcall current_stack; - struct farcall interrupt_stack; +#ifdef __x86_64__ + // Back pointer to the containing Thread structure. The GS segment base is + // pointed here, used to get the current thread. + BKernel::Thread* thread; + + // RSP for kernel entry used by SYSCALL, and temporary scratch space. + uint64* syscall_rsp; + uint64* user_rsp; + + uint64* current_stack; +#else + struct farcall current_stack; + struct farcall interrupt_stack; +#endif // 512 byte floating point save point - this must be 16 byte aligned - uint8 fpu_state[512]; + uint8 fpu_state[512] _ALIGNED(16); + + addr_t GetFramePointer() const; } _ALIGNED(16); + struct arch_team { // gcc treats empty structures as zero-length in C, but as if they contain // a char in C++. So we have to put a dummy in to be able to use the struct // from both in a consistent way. - char dummy; + char dummy; }; + struct arch_fork_arg { struct iframe iframe; }; -#endif /* _KERNEL_ARCH_x86_THREAD_TYPES_H */ + +#ifdef __x86_64__ + + +inline addr_t +arch_thread::GetFramePointer() const +{ + return current_stack[1]; +} + + +#else + + +inline addr_t +arch_thread::GetFramePointer() const +{ + return current_stack.esp[2]; +} + + +#endif // __x86_64__ + +#endif // _KERNEL_ARCH_x86_THREAD_TYPES_H diff --git a/headers/private/kernel/arch/x86/arch_user_debugger.h b/headers/private/kernel/arch/x86/arch_user_debugger.h index 1b72d9b2f6..01a98e7639 100644 --- a/headers/private/kernel/arch/x86/arch_user_debugger.h +++ b/headers/private/kernel/arch/x86/arch_user_debugger.h @@ -9,8 +9,12 @@ #define ARCH_INIT_USER_DEBUG x86_init_user_debug // number of breakpoints the CPU supports -// Actually it supports 4, but DR3 is used to hold the Thread*. -#define X86_BREAKPOINT_COUNT 3 +// On 32-bit, DR3 is used to hold the Thread*. +#ifdef __x86_64__ +# define X86_BREAKPOINT_COUNT 4 +#else +# define X86_BREAKPOINT_COUNT 3 +#endif // debug status register DR6 enum { @@ -95,14 +99,14 @@ enum { struct arch_breakpoint { void *address; // NULL, if deactivated - uint32 type; // one of the architecture types above - uint32 length; // one of the length values above + size_t type; // one of the architecture types above + size_t length; // one of the length values above }; struct arch_team_debug_info { struct arch_breakpoint breakpoints[X86_BREAKPOINT_COUNT]; - uint32 dr7; // debug control register DR7 + size_t dr7; // debug control register DR7 }; struct arch_thread_debug_info { diff --git a/headers/private/kernel/arch/x86/bios.h b/headers/private/kernel/arch/x86/bios.h index c88fe772dd..145f08fbf9 100644 --- a/headers/private/kernel/arch/x86/bios.h +++ b/headers/private/kernel/arch/x86/bios.h @@ -9,6 +9,8 @@ #include +#ifndef __x86_64__ + #define BIOS32_PCI_SERVICE 'ICP$' struct bios32_service { @@ -29,4 +31,6 @@ status_t bios_init(void); } #endif +#endif /* __x86_64__ */ + #endif /* ARCH_x86_BIOS_H */ diff --git a/headers/private/kernel/arch/x86/descriptors.h b/headers/private/kernel/arch/x86/descriptors.h index 19d7e93a71..30dc9f657f 100644 --- a/headers/private/kernel/arch/x86/descriptors.h +++ b/headers/private/kernel/arch/x86/descriptors.h @@ -9,45 +9,14 @@ #define _KERNEL_ARCH_x86_DESCRIPTORS_H -#define KERNEL_CODE_SEG 0x8 -#define KERNEL_DATA_SEG 0x10 - -#define USER_CODE_SEG 0x1b -#define USER_DATA_SEG 0x23 - -#define APM_CODE32_SEGMENT 0x28 -#define APM_CODE16_SEGMENT 0x30 -#define APM_DATA_SEGMENT 0x38 - -#define BIOS_DATA_SEGMENT 0x40 - #ifndef _ASSEMBLER - // this file can also be included from assembler as well - // (and is in arch_interrupts.S) - -#define DOUBLE_FAULT_TSS_BASE_SEGMENT 9 -#define TSS_BASE_SEGMENT (DOUBLE_FAULT_TSS_BASE_SEGMENT + smp_get_num_cpus()) -#define TLS_BASE_SEGMENT (TSS_BASE_SEGMENT + smp_get_num_cpus()) -#define APM_BASE_SEGMENT (TLS_BASE_SEGMENT + smp_get_num_cpus()) -// defines entries in the GDT/LDT +#include + + +struct kernel_args; -typedef struct segment_descriptor { - uint16 limit_00_15; // bit 0 - 15 - uint16 base_00_15; // 16 - 31 - uint32 base_23_16 : 8; // 0 - 7 - uint32 type : 4; // 8 - 11 - uint32 desc_type : 1; // 12 (0 = system, 1 = code/data) - uint32 privilege_level : 2; // 13 - 14 - uint32 present : 1; // 15 - uint32 limit_19_16 : 4; // 16 - 19 - uint32 available : 1; // 20 - uint32 zero : 1; // 21 - uint32 d_b : 1; // 22 - uint32 granularity : 1; // 23 - uint32 base_31_24 : 8; // 24 - 31 -} segment_descriptor; enum descriptor_privilege_levels { DPL_KERNEL = 0, @@ -73,74 +42,25 @@ enum descriptor_types { DT_CODE_DATA_SEGMENT = 1, }; -static inline void -clear_segment_descriptor(struct segment_descriptor *desc) -{ - *(long long *)desc = 0; -} +enum gate_types { + GATE_INTERRUPT = 14, + GATE_TRAP = 15, +}; -static inline void -set_segment_descriptor_base(struct segment_descriptor *desc, addr_t base) -{ - desc->base_00_15 = (addr_t)base & 0xffff; // base is 32 bits long - desc->base_23_16 = ((addr_t)base >> 16) & 0xff; - desc->base_31_24 = ((addr_t)base >> 24) & 0xff; -} +void x86_descriptors_init(kernel_args* args); +void x86_descriptors_init_percpu(kernel_args* args, int cpu); +status_t x86_descriptors_init_post_vm(kernel_args* args); -static inline void -set_segment_descriptor(struct segment_descriptor *desc, addr_t base, uint32 limit, - uint8 type, uint8 privilegeLevel) -{ - set_segment_descriptor_base(desc, base); - - // limit is 20 bits long - if (limit & 0xfff00000) { - desc->limit_00_15 = ((addr_t)limit >> 12) & 0x0ffff; - desc->limit_19_16 = ((addr_t)limit >> 28) & 0xf; - desc->granularity = 1; // 4 KB granularity - } else { - desc->limit_00_15 = (addr_t)limit & 0x0ffff; - desc->limit_19_16 = ((addr_t)limit >> 16) & 0xf; - desc->granularity = 0; // 1 byte granularity - } - limit >>= 12; +#endif // !_ASSEMBLER - desc->type = type; - desc->desc_type = DT_CODE_DATA_SEGMENT; - desc->privilege_level = privilegeLevel; +#ifdef __x86_64__ +# include +#else +# include +#endif - desc->present = 1; - desc->available = 0; // system available bit is currently not used - desc->d_b = 1; // 32-bit code - - desc->zero = 0; -} - - -static inline void -set_tss_descriptor(struct segment_descriptor *desc, addr_t base, uint32 limit) -{ - // the TSS descriptor has a special layout different from the standard descriptor - set_segment_descriptor_base(desc, base); - - desc->limit_00_15 = (addr_t)limit & 0x0ffff; - desc->limit_19_16 = 0; - - desc->type = DT_TSS; - desc->desc_type = DT_SYSTEM_SEGMENT; - desc->privilege_level = DPL_KERNEL; - - desc->present = 1; - desc->granularity = 0; // 1 Byte granularity - desc->available = 0; // system available bit is currently not used - desc->d_b = 0; - - desc->zero = 0; -} - -#endif /* _ASSEMBLER */ #endif /* _KERNEL_ARCH_x86_DESCRIPTORS_H */ diff --git a/headers/private/kernel/arch/x86/selector.h b/headers/private/kernel/arch/x86/selector.h deleted file mode 100644 index 8dee724517..0000000000 --- a/headers/private/kernel/arch/x86/selector.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -** Copyright 2002, Michael Noisternig. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ -#ifndef _KERNEL_ARCH_x86_SELECTOR_H -#define _KERNEL_ARCH_x86_SELECTOR_H - -typedef uint32 selector_id; -typedef uint64 selector_type; - -// DATA segments are read-only -// CODE segments are execute-only -// both can be modified by using the suffixed enum versions -// legend: w = writable -// d = expand down -// r = readable -// c = conforming -enum segment_type { - DATA = 0x8, DATA_w, DATA_d, DATA_wd, CODE, CODE_r, CODE_c, CODE_rc -}; - -#define SELECTOR(base,limit,type,mode32) \ - (((uint64)(((((uint32)base)>>16)&0xff) | (((uint32)base)&0xff000000) | ((type)<<9) | ((mode32)<<22) | (1<<15))<<32) \ - | ( (limit) >= (1<<20) ? (((limit)>>12)&0xffff) | ((uint64)(((limit)>>12)&0xf0000)<<32) | ((uint64)1<<(23+32)) : ((limit)&0xffff) | ((uint64)((limit)&0xf0000)<<32) ) \ - | ((((uint32)base)&0xffff)<<16)) - -void i386_selector_init( void *gdt ); -selector_id i386_selector_add( selector_type selector ); -void i386_selector_remove( selector_id id ); -selector_type i386_selector_get( selector_id id ); - -#endif diff --git a/headers/private/kernel/arch/x86/smp_priv.h b/headers/private/kernel/arch/x86/smp_priv.h index f5e6f4564e..17b035123c 100644 --- a/headers/private/kernel/arch/x86/smp_priv.h +++ b/headers/private/kernel/arch/x86/smp_priv.h @@ -7,7 +7,6 @@ #include -int i386_smp_interrupt(int vector); void arch_smp_ack_interrupt(void); status_t arch_smp_set_apic_timer(bigtime_t relativeTimeout); status_t arch_smp_clear_apic_timer(void); diff --git a/headers/private/kernel/arch/x86/types.h b/headers/private/kernel/arch/x86/types.h deleted file mode 100644 index c70a4ecf3c..0000000000 --- a/headers/private/kernel/arch/x86/types.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ -#ifndef _ARCH_x86_TYPES_H -#define _ARCH_x86_TYPES_H - -#ifndef WIN32 - typedef unsigned long long uint64; - typedef long long int64; -#else /* WIN32 */ - typedef unsigned __int64 uint64; - typedef __int64 int64; -#endif - -typedef unsigned long uint32; -typedef long int32; -typedef unsigned short uint16; -typedef short int16; -typedef unsigned char uint8; -typedef char int8; -typedef unsigned long addr; - -#define _OBOS_TIME_T_ int /* basic time_t type */ - -/* define this as not all platforms have it set, but we'll make sure as - * some conditional checks need it - */ -#define __INTEL__ 1 - -#endif /* _ARCH_x86_TYPES_H */ diff --git a/headers/private/kernel/arch/x86/vm86.h b/headers/private/kernel/arch/x86/vm86.h deleted file mode 100644 index a7d939b422..0000000000 --- a/headers/private/kernel/arch/x86/vm86.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2008 Jan Klötzke - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _VM86_H -#define _VM86_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define VM86_MIN_RAM_SIZE 0x1000 -#define RETURN_TO_32_INT 255 - -struct vm86_state { - struct vm86_iframe regs; - area_id bios_area; - area_id ram_area; - unsigned int if_flag : 1; -}; - -status_t x86_vm86_enter(struct vm86_iframe *frame); -void x86_vm86_return(struct vm86_iframe *frame, status_t retval); - -status_t vm86_prepare(struct vm86_state *state, unsigned int ram_size); -void vm86_cleanup(struct vm86_state *state); -status_t vm86_do_int(struct vm86_state *state, uint8 vec); - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/headers/private/kernel/boot/addr_range.h b/headers/private/kernel/boot/addr_range.h index 1aa80e7d5a..80d0c7823f 100644 --- a/headers/private/kernel/boot/addr_range.h +++ b/headers/private/kernel/boot/addr_range.h @@ -11,15 +11,9 @@ typedef struct addr_range { - addr_t start; - size_t size; -} addr_range; - - -typedef struct phys_addr_range { - phys_addr_t start; - phys_size_t size; -} phys_addr_range; + uint64 start; + uint64 size; +} _PACKED addr_range; #ifdef __cplusplus @@ -27,28 +21,18 @@ extern "C" { #endif status_t insert_address_range(addr_range* ranges, uint32* _numRanges, - uint32 maxRanges, addr_t start, size_t size); + uint32 maxRanges, uint64 start, uint64 size); status_t remove_address_range(addr_range* ranges, uint32* _numRanges, - uint32 maxRanges, addr_t start, size_t size); -bool get_free_address_range(addr_range* ranges, uint32 numRanges, addr_t base, - size_t size, addr_t* _rangeBase); -bool is_address_range_covered(addr_range* ranges, uint32 numRanges, addr_t base, - size_t size); + uint32 maxRanges, uint64 start, uint64 size); +bool get_free_address_range(addr_range* ranges, uint32 numRanges, uint64 base, + uint64 size, uint64* _rangeBase); +bool is_address_range_covered(addr_range* ranges, uint32 numRanges, uint64 base, + uint64 size); void sort_address_ranges(addr_range* ranges, uint32 numRanges); -status_t insert_physical_address_range(phys_addr_range* ranges, - uint32* _numRanges, uint32 maxRanges, phys_addr_t start, phys_size_t size); -status_t remove_physical_address_range(phys_addr_range* ranges, - uint32* _numRanges, uint32 maxRanges, phys_addr_t start, phys_size_t size); -bool get_free_physical_address_range(phys_addr_range* ranges, uint32 numRanges, - phys_addr_t base, phys_size_t size, phys_addr_t* _rangeBase); -bool is_physical_address_range_covered(phys_addr_range* ranges, - uint32 numRanges, phys_addr_t base, phys_size_t size); -void sort_physical_address_ranges(phys_addr_range* ranges, uint32 numRanges); - -status_t insert_physical_memory_range(phys_addr_t start, phys_size_t size); -status_t insert_physical_allocated_range(phys_addr_t start, phys_size_t size); -status_t insert_virtual_allocated_range(addr_t start, size_t size); +status_t insert_physical_memory_range(uint64 start, uint64 size); +status_t insert_physical_allocated_range(uint64 start, uint64 size); +status_t insert_virtual_allocated_range(uint64 start, uint64 size); void ignore_physical_memory_ranges_beyond_4gb(); #ifdef __cplusplus diff --git a/headers/private/kernel/boot/arch.h b/headers/private/kernel/boot/arch.h index 0eabf2c7e4..2f4be42982 100644 --- a/headers/private/kernel/boot/arch.h +++ b/headers/private/kernel/boot/arch.h @@ -5,24 +5,21 @@ #ifndef KERNEL_BOOT_ARCH_H #define KERNEL_BOOT_ARCH_H + #include #include -#ifdef __cplusplus -extern "C" { -#endif - /* ELF support */ -extern status_t boot_arch_elf_relocate_rel(struct preloaded_image *image, - struct Elf32_Rel *rel, int rel_len); -extern status_t boot_arch_elf_relocate_rela(struct preloaded_image *image, - struct Elf32_Rela *rel, int rel_len); +extern status_t boot_arch_elf_relocate_rel(preloaded_elf32_image* image, + struct Elf32_Rel* rel, int rel_len); +extern status_t boot_arch_elf_relocate_rel(preloaded_elf64_image* image, + struct Elf64_Rel* rel, int rel_len); +extern status_t boot_arch_elf_relocate_rela(preloaded_elf32_image* image, + struct Elf32_Rela* rel, int rel_len); +extern status_t boot_arch_elf_relocate_rela(preloaded_elf64_image* image, + struct Elf64_Rela* rel, int rel_len); -#ifdef __cplusplus -} -#endif - #endif /* KERNEL_BOOT_ARCH_H */ diff --git a/headers/private/kernel/boot/disk_identifier.h b/headers/private/kernel/boot/disk_identifier.h index 52f2cebf37..b1c64e93fe 100644 --- a/headers/private/kernel/boot/disk_identifier.h +++ b/headers/private/kernel/boot/disk_identifier.h @@ -34,41 +34,41 @@ typedef struct disk_identifier { union { struct { uint16 base_address; - } legacy; + } _PACKED legacy; struct { uint8 bus; uint8 slot; uint8 function; - } pci; + } _PACKED pci; } bus; union { struct { bool master; - } ata; + } _PACKED ata; struct { bool master; uint8 logical_unit; - } atapi; + } _PACKED atapi; struct { uint8 logical_unit; - } scsi; + } _PACKED scsi; struct { uint8 tbd; - } usb; + } _PACKED usb; struct { uint64 guid; - } firewire; + } _PACKED firewire; struct { uint64 wwd; - } fibre; + } _PACKED fibre; struct { off_t size; struct { off_t offset; uint32 sum; - } check_sums[NUM_DISK_CHECK_SUMS]; - } unknown; + } _PACKED check_sums[NUM_DISK_CHECK_SUMS]; + } _PACKED unknown; } device; -} disk_identifier; +} _PACKED disk_identifier; #endif /* KERNEL_BOOT_DISK_IDENTIFIER_H */ diff --git a/headers/private/kernel/boot/driver_settings.h b/headers/private/kernel/boot/driver_settings.h index 6a30b34277..03d0d03b79 100644 --- a/headers/private/kernel/boot/driver_settings.h +++ b/headers/private/kernel/boot/driver_settings.h @@ -6,14 +6,15 @@ #define KERNEL_BOOT_DRIVER_SETTINGS_H +#include #include struct driver_settings_file { - struct driver_settings_file *next; + FixedWidthPointer next; char name[B_OS_NAME_LENGTH]; - char *buffer; - size_t size; -}; + FixedWidthPointer buffer; + uint32 size; +} _PACKED; #endif /* KERNEL_BOOT_DRIVER_SETTINGS_H */ diff --git a/headers/private/kernel/boot/elf.h b/headers/private/kernel/boot/elf.h index d825d440a7..2f38836472 100644 --- a/headers/private/kernel/boot/elf.h +++ b/headers/private/kernel/boot/elf.h @@ -1,7 +1,8 @@ /* -** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ + * Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ #ifndef KERNEL_BOOT_ELF_H #define KERNEL_BOOT_ELF_H @@ -9,45 +10,88 @@ #include #include #include +#include +typedef struct elf32_region { + area_id id; + uint32 start; + uint32 size; + int32 delta; +} _PACKED elf32_region; + +typedef struct elf64_region { + area_id id; + uint64 start; + uint64 size; + int64 delta; +} _PACKED elf64_region; struct preloaded_image { - struct preloaded_image *next; - char *name; - elf_region text_region; - elf_region data_region; + FixedWidthPointer next; + FixedWidthPointer name; + uint8 elf_class; addr_range dynamic_section; - struct Elf32_Ehdr elf_header; - struct Elf32_Sym *syms; - struct Elf32_Rel *rel; - int rel_len; - struct Elf32_Rela *rela; - int rela_len; - struct Elf32_Rel *pltrel; - int pltrel_len; - int pltrel_type; - - struct Elf32_Sym *debug_symbols; - const char *debug_string_table; - uint32 num_debug_symbols, debug_string_table_size; + FixedWidthPointer debug_string_table; + uint32 num_debug_symbols; + uint32 debug_string_table_size; ino_t inode; image_id id; // the ID field will be filled out in the kernel bool is_module; // set by the module initialization code -}; +} _PACKED; -#ifdef __cplusplus -extern "C" { +struct preloaded_elf32_image : public preloaded_image { + Elf32_Ehdr elf_header; + elf32_region text_region; + elf32_region data_region; + + FixedWidthPointer syms; + FixedWidthPointer rel; + int32 rel_len; + FixedWidthPointer rela; + int32 rela_len; + FixedWidthPointer pltrel; + int32 pltrel_len; + int32 pltrel_type; + + FixedWidthPointer debug_symbols; +} _PACKED; + +struct preloaded_elf64_image : public preloaded_image { + Elf64_Ehdr elf_header; + elf64_region text_region; + elf64_region data_region; + + FixedWidthPointer syms; + FixedWidthPointer rel; + int64 rel_len; + FixedWidthPointer rela; + int64 rela_len; + FixedWidthPointer pltrel; + int64 pltrel_len; + int64 pltrel_type; + + FixedWidthPointer debug_symbols; +} _PACKED; + + +#if B_HAIKU_64_BIT +typedef preloaded_elf64_image preloaded_elf_image; +#else +typedef preloaded_elf32_image preloaded_elf_image; #endif -extern status_t boot_elf_resolve_symbol(struct preloaded_image *image, - struct Elf32_Sym *symbol, addr_t *symbolAddress); -#ifdef __cplusplus -} +#ifdef _BOOT_MODE +extern status_t boot_elf_resolve_symbol(preloaded_elf32_image* image, + struct Elf32_Sym* symbol, Elf32_Addr* symbolAddress); +extern status_t boot_elf_resolve_symbol(preloaded_elf64_image* image, + struct Elf64_Sym* symbol, Elf64_Addr* symbolAddress); +extern void boot_elf64_set_relocation(Elf64_Addr resolveAddress, + Elf64_Addr finalAddress); #endif #endif /* KERNEL_BOOT_ELF_H */ diff --git a/headers/private/kernel/boot/kernel_args.h b/headers/private/kernel/boot/kernel_args.h index 5d226e5aa1..de7fb735e6 100644 --- a/headers/private/kernel/boot/kernel_args.h +++ b/headers/private/kernel/boot/kernel_args.h @@ -18,7 +18,8 @@ #include #include -#include +#include + #define CURRENT_KERNEL_ARGS_VERSION 1 #define MAX_KERNEL_ARGS_RANGE 20 @@ -43,28 +44,30 @@ typedef struct kernel_args { uint32 kernel_args_size; uint32 version; - struct preloaded_image kernel_image; - struct preloaded_image *preloaded_images; + FixedWidthPointer kernel_image; + FixedWidthPointer preloaded_images; - uint32 num_physical_memory_ranges; - phys_addr_range physical_memory_range[MAX_PHYSICAL_MEMORY_RANGE]; - uint32 num_physical_allocated_ranges; - phys_addr_range physical_allocated_range[MAX_PHYSICAL_ALLOCATED_RANGE]; - uint32 num_virtual_allocated_ranges; - addr_range virtual_allocated_range[MAX_VIRTUAL_ALLOCATED_RANGE]; - uint32 num_kernel_args_ranges; - addr_range kernel_args_range[MAX_KERNEL_ARGS_RANGE]; - uint64 ignored_physical_memory; + uint32 num_physical_memory_ranges; + addr_range physical_memory_range[MAX_PHYSICAL_MEMORY_RANGE]; + uint32 num_physical_allocated_ranges; + addr_range physical_allocated_range[MAX_PHYSICAL_ALLOCATED_RANGE]; + uint32 num_virtual_allocated_ranges; + addr_range virtual_allocated_range[MAX_VIRTUAL_ALLOCATED_RANGE]; + uint32 num_kernel_args_ranges; + addr_range kernel_args_range[MAX_KERNEL_ARGS_RANGE]; + uint64 ignored_physical_memory; uint32 num_cpus; addr_range cpu_kstack[MAX_BOOT_CPUS]; - KMessage boot_volume; + // boot volume KMessage data + FixedWidthPointer boot_volume; + int32 boot_volume_size; - struct driver_settings_file *driver_settings; + FixedWidthPointer driver_settings; struct { - phys_addr_range physical_buffer; + addr_range physical_buffer; uint32 bytes_per_row; uint16 width; uint16 height; @@ -72,12 +75,12 @@ typedef struct kernel_args { bool enabled; } frame_buffer; - void *vesa_modes; + FixedWidthPointer vesa_modes; uint16 vesa_modes_size; uint8 vesa_capabilities; - void *edid_info; + FixedWidthPointer edid_info; - void *debug_output; + FixedWidthPointer debug_output; uint32 debug_size; bool keep_debug_output_buffer; @@ -85,8 +88,8 @@ typedef struct kernel_args { arch_kernel_args arch_args; // bootsplash data - uint8 *boot_splash; + FixedWidthPointer boot_splash; -} kernel_args; +} _PACKED kernel_args; #endif /* KERNEL_BOOT_KERNEL_ARGS_H */ diff --git a/headers/private/kernel/boot/platform/bios_ia32/platform_kernel_args.h b/headers/private/kernel/boot/platform/bios_ia32/platform_kernel_args.h index e66bebe92c..a191a0db14 100644 --- a/headers/private/kernel/boot/platform/bios_ia32/platform_kernel_args.h +++ b/headers/private/kernel/boot/platform/bios_ia32/platform_kernel_args.h @@ -10,8 +10,9 @@ #endif -#include +#include #include +#include // must match SMP_MAX_CPUS in arch_smp.h @@ -25,9 +26,10 @@ typedef struct { uint16 serial_base_ports[MAX_SERIAL_PORTS]; - bios_drive *drives; // this does not contain the boot drive + FixedWidthPointer drives; + // this does not contain the boot drive apm_info apm; -} platform_kernel_args; +} _PACKED platform_kernel_args; #endif /* KERNEL_BOOT_PLATFORM_BIOS_IA32_KERNEL_ARGS_H */ diff --git a/headers/private/kernel/boot/stage2.h b/headers/private/kernel/boot/stage2.h index ce31fcbf89..7e18a9263a 100644 --- a/headers/private/kernel/boot/stage2.h +++ b/headers/private/kernel/boot/stage2.h @@ -8,10 +8,12 @@ #include +#include struct stage2_args; extern struct kernel_args gKernelArgs; +extern KMessage gBootVolume; #ifdef __cplusplus extern "C" { diff --git a/headers/private/kernel/elf.h b/headers/private/kernel/elf.h index 292cb9f818..3851504db4 100644 --- a/headers/private/kernel/elf.h +++ b/headers/private/kernel/elf.h @@ -9,6 +9,7 @@ #define _KERNEL_ELF_H +#include #include #include @@ -49,9 +50,9 @@ status_t elf_add_memory_image_symbol(image_id id, const char* name, addr_t address, size_t size, int32 type); status_t elf_init(struct kernel_args *args); -status_t _user_read_kernel_image_symbols(image_id id, - struct Elf32_Sym* symbolTable, int32* _symbolCount, - char* stringTable, size_t* _stringTableSize, addr_t* _imageDelta); +status_t _user_read_kernel_image_symbols(image_id id, elf_sym* symbolTable, + int32* _symbolCount, char* stringTable, size_t* _stringTableSize, + addr_t* _imageDelta); #ifdef __cplusplus } diff --git a/headers/private/kernel/elf_priv.h b/headers/private/kernel/elf_priv.h index 1594d1c639..0b6341fbaf 100644 --- a/headers/private/kernel/elf_priv.h +++ b/headers/private/kernel/elf_priv.h @@ -10,6 +10,7 @@ #include +#include #include @@ -24,60 +25,67 @@ typedef struct elf_region { } elf_region; struct elf_image_info { - struct elf_image_info *next; // next image in the hash - char *name; - image_id id; - int32 ref_count; - struct vnode *vnode; - elf_region text_region; - elf_region data_region; - addr_t dynamic_section; // pointer to the dynamic section - struct elf_linked_image *linked_images; + struct elf_image_info* next; // next image in the hash + char* name; + image_id id; + int32 ref_count; + struct vnode* vnode; + elf_region text_region; + elf_region data_region; + addr_t dynamic_section; // pointer to the dynamic section + struct elf_linked_image* linked_images; - bool symbolic; + bool symbolic; - struct Elf32_Ehdr *elf_header; + elf_ehdr* elf_header; // pointer to symbol participation data structures - char *needed; - uint32 *symhash; - struct Elf32_Sym *syms; - char *strtab; - struct Elf32_Rel *rel; - int rel_len; - struct Elf32_Rela *rela; - int rela_len; - struct Elf32_Rel *pltrel; - int pltrel_len; - int pltrel_type; + char* needed; + uint32* symhash; + elf_sym* syms; + char* strtab; + elf_rel* rel; + int rel_len; + elf_rela* rela; + int rela_len; + elf_rel* pltrel; + int pltrel_len; + int pltrel_type; - struct Elf32_Sym *debug_symbols; - uint32 num_debug_symbols; - const char *debug_string_table; + elf_sym* debug_symbols; + uint32 num_debug_symbols; + const char* debug_string_table; // versioning related structures - uint32 num_version_definitions; - struct Elf32_Verdef *version_definitions; - uint32 num_needed_versions; - struct Elf32_Verneed *needed_versions; - Elf32_Versym *symbol_versions; - struct elf_version_info *versions; - uint32 num_versions; + uint32 num_version_definitions; + elf_verdef* version_definitions; + uint32 num_needed_versions; + elf_verneed* needed_versions; + elf_versym* symbol_versions; + struct elf_version_info* versions; + uint32 num_versions; }; -#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)])) +#define STRING(image, offset) ((char*)(&(image)->strtab[(offset)])) #define SYMNAME(image, sym) STRING(image, (sym)->st_name) -#define SYMBOL(image, num) ((struct Elf32_Sym *)&(image)->syms[num]) +#define SYMBOL(image, num) (&(image)->syms[num]) #define HASHTABSIZE(image) ((image)->symhash[0]) -#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2]) -#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)]) +#define HASHBUCKETS(image) ((unsigned int*)&(image)->symhash[2]) +#define HASHCHAINS(image) ((unsigned int*)&(image)->symhash[2+HASHTABSIZE(image)]) + -extern #ifdef __cplusplus -"C" +extern "C" { #endif -status_t elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *sym, - struct elf_image_info *shared_image, addr_t *sym_addr); + +extern status_t elf_resolve_symbol(struct elf_image_info* image, + elf_sym* symbol, struct elf_image_info* sharedImage, + addr_t* _symbolAddress); + +#ifdef __cplusplus +} +#endif + #endif /* _KERNEL_ELF_PRIV_H */ diff --git a/headers/private/kernel/kernel.h b/headers/private/kernel/kernel.h index 28041cba1c..a5c01e37ea 100644 --- a/headers/private/kernel/kernel.h +++ b/headers/private/kernel/kernel.h @@ -15,6 +15,10 @@ #include +#ifndef KERNEL_LOAD_BASE +# define KERNEL_LOAD_BASE KERNEL_BASE +#endif + // macro to check whether an address is in the kernel address space (avoid // always-true checks) #if KERNEL_BASE == 0 @@ -27,7 +31,14 @@ #endif // Buffers passed in from user-space shouldn't point into the kernel. -#define IS_USER_ADDRESS(x) (!IS_KERNEL_ADDRESS(x)) +#if USER_BASE == 0 +# define IS_USER_ADDRESS(x) ((addr_t)(x) <= USER_TOP) +#elif USER_TOP == __HAIKU_ADDR_MAX +# define IS_USER_ADDRESS(x) ((addr_t)(x) >= USER_BASE) +#else +# define IS_USER_ADDRESS(x) \ + ((addr_t)(x) >= USER_BASE && (addr_t)(x) <= USER_TOP) +#endif #define DEBUG_KERNEL_STACKS // Note, debugging kernel stacks doesn't really work yet. Since the diff --git a/headers/private/kernel/smp.h b/headers/private/kernel/smp.h index 9483adfada..aa19ad35d9 100644 --- a/headers/private/kernel/smp.h +++ b/headers/private/kernel/smp.h @@ -34,7 +34,7 @@ enum { typedef uint32 cpu_mask_t; -typedef void (*smp_call_func)(uint32 data1, int32 currentCPU, uint32 data2, uint32 data3); +typedef void (*smp_call_func)(addr_t data1, int32 currentCPU, addr_t data2, addr_t data3); #ifdef __cplusplus @@ -49,14 +49,14 @@ status_t smp_init_post_generic_syscalls(void); bool smp_trap_non_boot_cpus(int32 cpu, uint32* rendezVous); void smp_wake_up_non_boot_cpus(void); void smp_cpu_rendezvous(volatile uint32 *var, int current_cpu); -void smp_send_ici(int32 targetCPU, int32 message, uint32 data, uint32 data2, uint32 data3, +void smp_send_ici(int32 targetCPU, int32 message, addr_t data, addr_t data2, addr_t data3, void *data_ptr, uint32 flags); -void smp_send_multicast_ici(cpu_mask_t cpuMask, int32 message, uint32 data, - uint32 data2, uint32 data3, void *data_ptr, uint32 flags); -void smp_send_broadcast_ici(int32 message, uint32 data, uint32 data2, uint32 data3, +void smp_send_multicast_ici(cpu_mask_t cpuMask, int32 message, addr_t data, + addr_t data2, addr_t data3, void *data_ptr, uint32 flags); +void smp_send_broadcast_ici(int32 message, addr_t data, addr_t data2, addr_t data3, void *data_ptr, uint32 flags); void smp_send_broadcast_ici_interrupts_disabled(int32 currentCPU, int32 message, - uint32 data, uint32 data2, uint32 data3, void *data_ptr, uint32 flags); + addr_t data, addr_t data2, addr_t data3, void *data_ptr, uint32 flags); int32 smp_get_num_cpus(void); void smp_set_num_cpus(int32 numCPUs); diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 017da64352..78e893da3b 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -187,9 +187,6 @@ private: typedef int32 (*thread_entry_func)(thread_func, void *); -typedef bool (*page_fault_callback)(addr_t address, addr_t faultAddress, - bool isWrite); - namespace BKernel { @@ -477,13 +474,7 @@ struct Thread : TeamThreadIteratorEntry, KernelReferenceable { } msg; // write_sem/read_sem are protected by fLock when accessed by // others, the other fields are protected by write_sem/read_sem - union { - addr_t fault_handler; - page_fault_callback fault_callback; - // TODO: this is a temporary field used for the vm86 implementation - // and should be removed again when that one is moved into the - // kernel entirely. - }; + addr_t fault_handler; int32 page_faults_allowed; /* this field may only stay in debug builds in the future */ diff --git a/headers/private/kernel/util/FixedWidthPointer.h b/headers/private/kernel/util/FixedWidthPointer.h new file mode 100644 index 0000000000..03295323c1 --- /dev/null +++ b/headers/private/kernel/util/FixedWidthPointer.h @@ -0,0 +1,156 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_UTIL_FIXED_WIDTH_POINTER_H +#define KERNEL_UTIL_FIXED_WIDTH_POINTER_H + + +#include + + +/*! + \class FixedWidthPointer + \brief Pointer class with fixed size (64-bit) storage. + + This class is a pointer-like class that uses a fixed size 64-bit storage. + This is used to make kernel_args compatible (i.e. the same size) for both + 32-bit and 64-bit kernels. +*/ +template +class FixedWidthPointer { +public: + Type * Pointer() const + { + return (Type*)(addr_t)fValue; + } + + operator Type*() const + { + return Pointer(); + } + + Type& operator*() const + { + return *Pointer(); + } + + Type* operator->() const + { + return Pointer(); + } + + Type& operator[](size_t i) const + { + return Pointer()[i]; + } + + FixedWidthPointer& operator=(const FixedWidthPointer& p) + { + fValue = p.fValue; + return *this; + } + + FixedWidthPointer& operator=(Type* p) + { + fValue = (addr_t)p; + return *this; + } + + /*! + Get the 64-bit pointer value. + \return Pointer address. + */ + uint64 Get() const + { + return fValue; + } + + /*! + Set the 64-bit pointer value. + \param addr New address for the pointer. + */ + void SetTo(uint64 addr) + { + fValue = addr; + } + +private: + uint64 fValue; +} _PACKED; + + +// Specialization for void pointers, can be converted to another pointer type. +template<> +class FixedWidthPointer { +public: + void * Pointer() const + { + return (void*)(addr_t)fValue; + } + + operator void*() const + { + return Pointer(); + } + + FixedWidthPointer& operator=(const FixedWidthPointer& p) + { + fValue = p.fValue; + return *this; + } + + FixedWidthPointer& operator=(void* p) + { + fValue = (addr_t)p; + return *this; + } + + uint64 Get() const + { + return fValue; + } + + void SetTo(uint64 addr) + { + fValue = addr; + } + +private: + uint64 fValue; +} _PACKED; + + +template +inline bool +operator==(const FixedWidthPointer& a, const Type* b) +{ + return a.Get() == (addr_t)b; +} + + +template +inline bool +operator!=(const FixedWidthPointer& a, const Type* b) +{ + return a.Get() != (addr_t)b; +} + + +template +inline bool +operator==(const FixedWidthPointer& a, Type* b) +{ + return a.Get() == (addr_t)b; +} + + +template +inline bool +operator!=(const FixedWidthPointer& a, Type* b) +{ + return a.Get() != (addr_t)b; +} + + +#endif /* KERNEL_UTIL_FIXED_WIDTH_POINTER_H */ diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index cdde48d47c..89d98b5801 100644 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -176,7 +176,7 @@ int _user_open_dir_entry_ref(dev_t device, ino_t inode, const char *name); int _user_open_dir(int fd, const char *path); int _user_open_parent_dir(int fd, char *name, size_t nameLength); -status_t _user_fcntl(int fd, int op, uint32 argument); +status_t _user_fcntl(int fd, int op, size_t argument); status_t _user_fsync(int fd); status_t _user_flock(int fd, int op); status_t _user_read_stat(int fd, const char *path, bool traverseLink, diff --git a/headers/private/kernel/vm/vm.h b/headers/private/kernel/vm/vm.h index 9163e3bca1..ef1b829915 100644 --- a/headers/private/kernel/vm/vm.h +++ b/headers/private/kernel/vm/vm.h @@ -176,7 +176,7 @@ status_t _user_get_memory_properties(team_id teamID, const void *address, area_id _user_area_for(void *address); area_id _user_find_area(const char *name); status_t _user_get_area_info(area_id area, area_info *info); -status_t _user_get_next_area_info(team_id team, int32 *cookie, area_info *info); +status_t _user_get_next_area_info(team_id team, ssize_t *cookie, area_info *info); status_t _user_resize_area(area_id area, size_t newSize); area_id _user_transfer_area(area_id area, void **_address, uint32 addressSpec, team_id target); diff --git a/headers/private/net/net_buffer.h b/headers/private/net/net_buffer.h index 6afc4d0037..809fa9395c 100644 --- a/headers/private/net/net_buffer.h +++ b/headers/private/net/net_buffer.h @@ -85,9 +85,9 @@ struct net_buffer_module_info { status_t (*direct_access)(net_buffer* buffer, uint32 offset, size_t bytes, void** _data); - status_t (*read)(net_buffer* buffer, uint32 offset, void* data, + status_t (*read)(net_buffer* buffer, size_t offset, void* data, size_t bytes); - status_t (*write)(net_buffer* buffer, uint32 offset, + status_t (*write)(net_buffer* buffer, size_t offset, const void* data, size_t bytes); int32 (*checksum)(net_buffer* buffer, uint32 offset, size_t bytes, diff --git a/headers/private/runtime_loader/runtime_loader.h b/headers/private/runtime_loader/runtime_loader.h index 132a674f5d..cc9b96cd98 100644 --- a/headers/private/runtime_loader/runtime_loader.h +++ b/headers/private/runtime_loader/runtime_loader.h @@ -15,6 +15,7 @@ #include #include +#include // #pragma mark - runtime loader libroot interface @@ -100,13 +101,13 @@ typedef struct image_t { // pointer to symbol participation data structures uint32 *symhash; - struct Elf32_Sym *syms; + elf_sym *syms; char *strtab; - struct Elf32_Rel *rel; + elf_rel *rel; int rel_len; - struct Elf32_Rela *rela; + elf_rela *rela; int rela_len; - struct Elf32_Rel *pltrel; + elf_rel *pltrel; int pltrel_len; uint32 num_needed; @@ -114,20 +115,20 @@ typedef struct image_t { // versioning related structures uint32 num_version_definitions; - struct Elf32_Verdef *version_definitions; + elf_verdef *version_definitions; uint32 num_needed_versions; - struct Elf32_Verneed *needed_versions; - Elf32_Versym *symbol_versions; + elf_verneed *needed_versions; + elf_versym *symbol_versions; elf_version_info *versions; uint32 num_versions; #ifdef __cplusplus - struct Elf32_Sym* (*find_undefined_symbol)(struct image_t* rootImage, + elf_sym* (*find_undefined_symbol)(struct image_t* rootImage, struct image_t* image, const SymbolLookupInfo& lookupInfo, struct image_t** foundInImage); #else - struct Elf32_Sym* (*find_undefined_symbol)(struct image_t* rootImage, + elf_sym* (*find_undefined_symbol)(struct image_t* rootImage, struct image_t* image, const struct SymbolLookupInfo* lookupInfo, struct image_t** foundInImage); @@ -152,12 +153,12 @@ typedef struct image_queue_t { #define IMAGE_FLAG_RTLD_MASK 0x03 // RTLD_{LAZY,NOW} | RTLD_{LOCAL,GLOBAL} -#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)])) +#define STRING(image, offset) ((char*)(&(image)->strtab[(offset)])) #define SYMNAME(image, sym) STRING(image, (sym)->st_name) -#define SYMBOL(image, num) ((struct Elf32_Sym *)&(image)->syms[num]) +#define SYMBOL(image, num) (&(image)->syms[num]) #define HASHTABSIZE(image) ((image)->symhash[0]) -#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2]) -#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)]) +#define HASHBUCKETS(image) ((unsigned int*)&(image)->symhash[2]) +#define HASHCHAINS(image) ((unsigned int*)&(image)->symhash[2+HASHTABSIZE(image)]) // The name of the area the runtime loader creates for debugging purposes. diff --git a/headers/private/shared/cpu_type.h b/headers/private/shared/cpu_type.h index c9454230d7..2c97ae15d8 100644 --- a/headers/private/shared/cpu_type.h +++ b/headers/private/shared/cpu_type.h @@ -28,7 +28,7 @@ int32 get_rounded_cpu_speed(void); #endif -#if __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) /*! Tries to parse an Intel CPU ID string to match our usual naming scheme. Note, this function is not thread safe, and must only be called once at a time. @@ -87,7 +87,7 @@ get_cpu_vendor_string(enum cpu_types type) /* We're not that nice here. */ return "IBM/Motorola"; #endif -#if __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) /* Determine x86 vendor name */ switch (type & B_CPU_x86_VENDOR_MASK) { case B_CPU_INTEL_x86: @@ -113,7 +113,7 @@ get_cpu_vendor_string(enum cpu_types type) } -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) /*! Parameter 'name' needs to point to an allocated array of 49 characters. */ void get_cpuid_model_string(char *name) @@ -168,16 +168,16 @@ get_cpuid_model_string(char *name) } } } -#endif /* __INTEL__ */ +#endif /* __INTEL__ || __x86_64__ */ const char * get_cpu_model_string(system_info *info) { -#if __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) char cpuidName[49]; /* for use with get_cpuid_model_string() */ -#endif /* __INTEL__ */ +#endif /* __INTEL__ || __x86_64__ */ /* Determine CPU type */ switch (info->cpu_type) { @@ -195,7 +195,7 @@ get_cpu_model_string(system_info *info) default: return NULL; #endif /* __POWERPC__ */ -#if __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) case B_CPU_x86: return "Unknown x86"; @@ -405,7 +405,7 @@ get_cpu_model_string(system_info *info) return parse_intel(cpuidName); } return NULL; -#endif /* __INTEL__ */ +#endif /* __INTEL__ || __x86_64__ */ } } diff --git a/headers/private/system/arch/x86/arch_elf.h b/headers/private/system/arch/x86/arch_elf.h index 4ec86759cb..922ab095a7 100644 --- a/headers/private/system/arch/x86/arch_elf.h +++ b/headers/private/system/arch/x86/arch_elf.h @@ -19,4 +19,8 @@ #define R_386_GOTOFF 9 /* add GOT relative symbol address */ #define R_386_GOTPC 10 /* add PC relative GOT table address */ +#ifdef _BOOT_MODE +# include "../x86_64/arch_elf.h" +#endif + #endif /* _KERNEL_ARCH_x86_ELF_H */ diff --git a/headers/private/system/arch/x86_64/arch_commpage_defs.h b/headers/private/system/arch/x86_64/arch_commpage_defs.h new file mode 100644 index 0000000000..bf7809e38a --- /dev/null +++ b/headers/private/system/arch/x86_64/arch_commpage_defs.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H +#define _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H + +#ifndef _SYSTEM_COMMPAGE_DEFS_H +# error Must not be included directly. Include instead! +#endif + +#define COMMPAGE_ENTRY_X86_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) +#define COMMPAGE_ENTRY_X86_MEMSET (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) +#define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER \ + (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 2) + +#define ARCH_USER_COMMPAGE_ADDR (0xffffffffffff0000) + +#endif /* _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H */ diff --git a/headers/private/system/arch/x86_64/arch_config.h b/headers/private/system/arch/x86_64/arch_config.h new file mode 100644 index 0000000000..2c4e64320c --- /dev/null +++ b/headers/private/system/arch/x86_64/arch_config.h @@ -0,0 +1,15 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_x86_64_CONFIG_H +#define _KERNEL_ARCH_x86_64_CONFIG_H + +#define FUNCTION_CALL_PARAMETER_ALIGNMENT_TYPE unsigned long + +#define STACK_GROWS_DOWNWARDS + +//#define ATOMIC_FUNCS_ARE_SYSCALLS +//#define ATOMIC64_FUNCS_ARE_SYSCALLS + +#endif /* _KERNEL_ARCH_x86_64_CONFIG_H */ diff --git a/headers/private/system/arch/x86_64/arch_cpu_defs.h b/headers/private/system/arch/x86_64/arch_cpu_defs.h new file mode 100644 index 0000000000..e10ef985d4 --- /dev/null +++ b/headers/private/system/arch/x86_64/arch_cpu_defs.h @@ -0,0 +1,12 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _SYSTEM_ARCH_X86_DEFS_H +#define _SYSTEM_ARCH_X86_DEFS_H + + +#define SPINLOCK_PAUSE() asm volatile("pause;") + + +#endif /* _SYSTEM_ARCH_X86_DEFS_H */ diff --git a/headers/private/system/arch/x86_64/arch_elf.h b/headers/private/system/arch/x86_64/arch_elf.h new file mode 100644 index 0000000000..6bbba4e5b3 --- /dev/null +++ b/headers/private/system/arch/x86_64/arch_elf.h @@ -0,0 +1,55 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_x86_64_ELF_H +#define _KERNEL_ARCH_x86_64_ELF_H + + +/* Relocation types. */ +#define R_X86_64_NONE 0 /* No relocation. */ +#define R_X86_64_64 1 /* Direct 64-bit. */ +#define R_X86_64_PC32 2 /* PC relative 32-bit signed. */ +#define R_X86_64_GOT32 3 /* 32-bit GOT entry. */ +#define R_X86_64_PLT32 4 /* 32-bit PLT address. */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime. */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry. */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry. */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base. */ +#define R_X86_64_GOTPCREL 9 /* 32-bit signed PC relative offset to GOT. */ +#define R_X86_64_32 10 /* Direct 32-bit zero-extended. */ +#define R_X86_64_32S 11 /* Direct 32-bit sign-extended. */ +#define R_X86_64_16 12 /* Direct 16-bit zero-extended. */ +#define R_X86_64_PC16 13 /* 16-bit sign-extended PC relative. */ +#define R_X86_64_8 14 /* Direct 8-bit sign-extended. */ +#define R_X86_64_PC8 15 /* 8-bit sign-extended PC relative. */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol. */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block. */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block. */ +#define R_X86_64_TLSGD 19 /* 32-bit signed PC relative offset to two GOT entries (GD). */ +#define R_X86_64_TLSLD 20 /* 32-bit signed PC relative offset to two GOT entries (LD). */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block. */ +#define R_X86_64_GOTTPOFF 22 /* 32-bit signed PC relative offset to GOT entry (IE). */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block. */ +#define R_X86_64_PC64 24 /* PC relative 64-bit. */ +#define R_X86_64_GOTOFF64 25 /* 64-bit offset to GOT. */ +#define R_X86_64_GOTPC32 26 /* 32 bit signed PC relative offset to GOT. */ +#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset. */ +#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset to GOT entry. */ +#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT. */ +#define R_X86_64_GOTPLT64 30 /* Like GOT64, says PLT entry needed. */ +#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset to PLT entry. */ +#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend. */ +#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend. */ +#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ +#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS descriptor. */ +#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ +#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base. */ + + +#ifdef _BOOT_MODE +# include "../x86/arch_elf.h" +#endif + + +#endif /* _KERNEL_ARCH_x86_64_ELF_H */ diff --git a/headers/private/system/arch/x86_64/arch_real_time_data.h b/headers/private/system/arch/x86_64/arch_real_time_data.h new file mode 100644 index 0000000000..d6350c39f2 --- /dev/null +++ b/headers/private/system/arch/x86_64/arch_real_time_data.h @@ -0,0 +1,17 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_ARCH_REAL_TIME_DATA_H +#define _KERNEL_ARCH_REAL_TIME_DATA_H + +#include +#include + + +struct arch_real_time_data { + bigtime_t system_time_offset; + uint32 system_time_conversion_factor; +}; + +#endif /* _KERNEL_ARCH_REAL_TIME_DATA_H */ diff --git a/headers/private/system/arch/x86_64/asm_defs.h b/headers/private/system/arch/x86_64/asm_defs.h new file mode 100644 index 0000000000..26d13c5691 --- /dev/null +++ b/headers/private/system/arch/x86_64/asm_defs.h @@ -0,0 +1,17 @@ +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef SYSTEM_ARCH_X86_64_ASM_DEFS_H +#define SYSTEM_ARCH_X86_64_ASM_DEFS_H + + +#define SYMBOL(name) .global name; name +#define SYMBOL_END(name) 1: .size name, 1b - name +#define STATIC_FUNCTION(name) .type name, @function; name +#define FUNCTION(name) .global name; .type name, @function; name +#define FUNCTION_END(name) 1: .size name, 1b - name + + +#endif /* SYSTEM_ARCH_X86_64_ASM_DEFS_H */ + diff --git a/headers/private/system/elf32.h b/headers/private/system/elf32.h index 4feee0692b..c1bf7e245d 100644 --- a/headers/private/system/elf32.h +++ b/headers/private/system/elf32.h @@ -9,10 +9,7 @@ #define _ELF32_H -#include -#include - -#include +#include typedef uint32 Elf32_Addr; @@ -25,8 +22,6 @@ typedef Elf32_Half Elf32_Versym; /*** ELF header ***/ -#define EI_NIDENT 16 - struct Elf32_Ehdr { uint8 e_ident[EI_NIDENT]; Elf32_Half e_type; @@ -48,73 +43,6 @@ struct Elf32_Ehdr { #endif }; -#define ELF_MAGIC "\x7f""ELF" - -// e_ident[] indices -#define EI_MAG0 0 -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_PAD 7 - -// e_machine (Architecture) -#define EM_NONE 0 // No machine -#define EM_M32 1 // AT&T WE 32100 -#define EM_SPARC 2 // Sparc -#define EM_386 3 // Intel 80386 -#define EM_68K 4 // Motorola m68k family -#define EM_88K 5 // Motorola m88k family -#define EM_486 6 // Intel 80486, Reserved for future use -#define EM_860 7 // Intel 80860 -#define EM_MIPS 8 // MIPS R3000 (officially, big-endian only) -#define EM_S370 9 // IBM System/370 -#define EM_MIPS_RS3_LE 10 // MIPS R3000 little-endian, Deprecated -#define EM_PARISC 15 // HPPA -#define EM_VPP550 17 // Fujitsu VPP500 -#define EM_SPARC32PLUS 18 // Sun "v8plus" -#define EM_960 19 // Intel 80960 -#define EM_PPC 20 // PowerPC -#define EM_PPC64 21 // 64-bit PowerPC -#define EM_S390 22 // IBM S/390 -#define EM_V800 36 // NEC V800 series -#define EM_FR20 37 // Fujitsu FR20 -#define EM_RH32 38 // TRW RH32 -#define EM_MCORE 39 // Motorola M*Core -#define EM_RCE 39 // Old name for MCore -#define EM_ARM 40 // ARM -#define EM_OLD_ALPHA 41 // Digital Alpha -#define EM_SH 42 // Renesas / SuperH SH -#define EM_SPARCV9 43 // SPARC v9 64-bit -#define EM_TRICORE 44 // Siemens Tricore embedded processor -#define EM_ARC 45 // ARC Cores -#define EM_H8_300 46 // Renesas H8/300 -#define EM_H8_300H 47 // Renesas H8/300H -#define EM_H8S 48 // Renesas H8S -#define EM_H8_500 49 // Renesas H8/500 -#define EM_IA_64 50 // Intel IA-64 Processor -#define EM_MIPS_X 51 // Stanford MIPS-X -#define EM_COLDFIRE 52 // Motorola Coldfire -#define EM_68HC12 53 // Motorola M68HC12 -#define EM_MMA 54 // Fujitsu Multimedia Accelerator -#define EM_PCP 55 // Siemens PCP -#define EM_NCPU 56 // Sony nCPU embedded RISC processor -#define EM_NDR1 57 // Denso NDR1 microprocesspr -#define EM_STARCORE 58 // Motorola Star*Core processor -#define EM_ME16 59 // Toyota ME16 processor -#define EM_ST100 60 // STMicroelectronics ST100 processor -#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor -#define EM_X86_64 62 // Advanced Micro Devices X86-64 processor - -// architecture class (EI_CLASS) -#define ELFCLASS32 1 -#define ELFCLASS64 2 -// endian (EI_DATA) -#define ELFDATA2LSB 1 /* little endian */ -#define ELFDATA2MSB 2 /* big endian */ - /*** section header ***/ @@ -131,45 +59,6 @@ struct Elf32_Shdr { Elf32_Word sh_entsize; }; -// special section indices -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - -// section header type -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 - -#define SHT_GNU_verdef 0x6ffffffd /* version definition section */ -#define SHT_GNU_verneed 0x6ffffffe /* version needs section */ -#define SHT_GNU_versym 0x6fffffff /* version symbol table */ - -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff - -// section header flags -#define SHF_WRITE 1 -#define SHF_ALLOC 2 -#define SHF_EXECINSTR 4 - -#define SHF_MASKPROC 0xf0000000 - /*** program header ***/ @@ -189,27 +78,6 @@ struct Elf32_Phdr { #endif }; -// program header segment types -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_STACK 0x6474e551 - -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7fffffff - -// program header segment flags -#define PF_EXECUTE 0x1 -#define PF_WRITE 0x2 -#define PF_READ 0x4 -#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ) - -#define PF_MASKPROC 0xf0000000 - struct Elf32_Sym { Elf32_Word st_name; Elf32_Addr st_value; @@ -221,6 +89,7 @@ struct Elf32_Sym { #ifdef __cplusplus uint8 Bind() const; uint8 Type() const; + void SetInfo(uint8 bind, uint8 type); #endif }; @@ -228,22 +97,6 @@ struct Elf32_Sym { #define ELF32_ST_TYPE(i) ((i) & 0xf) #define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf)) -#define STT_NOTYPE 0 -#define STT_OBJECT 1 -#define STT_FUNC 2 -#define STT_SECTION 3 -#define STT_FILE 4 -#define STT_LOPROC 13 -#define STT_HIPROC 15 - -#define STB_LOCAL 0 -#define STB_GLOBAL 1 -#define STB_WEAK 2 -#define STB_LOPROC 13 -#define STB_HIPROC 15 - -#define STN_UNDEF 0 - struct Elf32_Rel { Elf32_Addr r_offset; Elf32_Word r_info; @@ -276,58 +129,6 @@ struct Elf32_Dyn { } d_un; }; -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_BIND_NOW 24 /* no lazy binding */ -#define DT_INIT_ARRAY 25 /* init function array */ -#define DT_FINI_ARRAY 26 /* termination function array */ -#define DT_INIT_ARRAYSZ 27 /* init function array size */ -#define DT_FINI_ARRAYSZ 28 /* termination function array size */ -#define DT_RUNPATH 29 /* library search path (supersedes DT_RPATH) */ -#define DT_FLAGS 30 /* flags (see below) */ -#define DT_ENCODING 32 -#define DT_PREINIT_ARRAY 32 /* preinitialization array */ -#define DT_PREINIT_ARRAYSZ 33 /* preinitialization array size */ - -#define DT_VERSYM 0x6ffffff0 /* symbol version table */ -#define DT_VERDEF 0x6ffffffc /* version definition table */ -#define DT_VERDEFNUM 0x6ffffffd /* number of version definitions */ -#define DT_VERNEED 0x6ffffffe /* table with needed versions */ -#define DT_VERNEEDNUM 0x6fffffff /* number of needed versions */ - -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff - - -/* DT_FLAGS values */ -#define DF_ORIGIN 0x01 -#define DF_SYMBOLIC 0x02 -#define DF_TEXTREL 0x04 -#define DF_BIND_NOW 0x08 -#define DF_STATIC_TLS 0x10 - /* version definition section */ @@ -342,30 +143,6 @@ struct Elf32_Verdef { Elf32_Word vd_next; /* byte offset to next verdef entry */ }; -/* values for vd_version (version revision) */ -#define VER_DEF_NONE 0 /* no version */ -#define VER_DEF_CURRENT 1 /* current version */ -#define VER_DEF_NUM 2 /* given version number */ - -/* values for vd_flags (version information flags) */ -#define VER_FLG_BASE 0x1 /* version definition of file itself */ -#define VER_FLG_WEAK 0x2 /* weak version identifier */ - -/* values for versym symbol index */ -#define VER_NDX_LOCAL 0 /* symbol is local */ -#define VER_NDX_GLOBAL 1 /* symbol is global/unversioned */ -#define VER_NDX_INITIAL 2 /* initial version -- that's the one given - to symbols when a library becomes - versioned; handled by the linker (and - runtime loader) similar to - VER_NDX_GLOBAL */ -#define VER_NDX_LORESERVE 0xff00 /* beginning of reserved entries */ -#define VER_NDX_ELIMINATE 0xff01 /* symbol is to be eliminated */ - -#define VER_NDX_FLAG_HIDDEN 0x8000 /* flag: version is hidden */ -#define VER_NDX_MASK 0x7fff /* mask to get the actual version index */ -#define VER_NDX(x) ((x) & VER_NDX_MASK) - /* auxiliary version information */ @@ -387,11 +164,6 @@ struct Elf32_Verneed { Elf32_Word vn_next; /* byte offset to next verneed entry */ }; -/* values for vn_version (version revision) */ -#define VER_NEED_NONE 0 /* no version */ -#define VER_NEED_CURRENT 1 /* current version */ -#define VER_NEED_NUM 2 /* given version number */ - /* auxiliary needed version information */ @@ -404,9 +176,6 @@ struct Elf32_Vernaux { Elf32_Word vna_next; /* byte offset to next vernaux entry */ }; -/* values for vna_flags */ -#define VER_FLG_WEAK 0x2 /* weak version identifier */ - /*** inline functions ***/ @@ -450,6 +219,11 @@ Elf32_Sym::Type() const return ELF32_ST_TYPE(st_info); } +inline void +Elf32_Sym::SetInfo(uint8 bind, uint8 type) +{ + st_info = ELF32_ST_INFO(bind, type); +} inline uint8 Elf32_Rel::SymbolIndex() const diff --git a/headers/private/system/elf64.h b/headers/private/system/elf64.h new file mode 100644 index 0000000000..3efd48b32a --- /dev/null +++ b/headers/private/system/elf64.h @@ -0,0 +1,247 @@ +/* + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + * + * Copyright 2002-2011, Haiku Inc. All Rights Reserved. + * Distributed under the terms of the MIT license. + */ +#ifndef _ELF64_H +#define _ELF64_H + + +#include + + +typedef uint64 Elf64_Addr; +typedef uint64 Elf64_Off; +typedef uint16 Elf64_Half; +typedef uint32 Elf64_Word; +typedef int32 Elf64_Sword; +typedef uint64 Elf64_Xword; +typedef int64 Elf64_Sxword; + +typedef Elf64_Half Elf64_Versym; + +/*** ELF header ***/ + +struct Elf64_Ehdr { + uint8 e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; + +#ifdef __cplusplus + bool IsHostEndian() const; +#endif +}; + + +/*** section header ***/ + +struct Elf64_Shdr { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +}; + + +/*** program header ***/ + +struct Elf64_Phdr { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; /* offset from the beginning of the file of the segment */ + Elf64_Addr p_vaddr; /* virtual address for the segment in memory */ + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; /* the size of the segment in the file */ + Elf64_Xword p_memsz; /* the size of the segment in memory */ + Elf64_Xword p_align; + +#ifdef __cplusplus + bool IsReadWrite() const; + bool IsExecutable() const; +#endif +}; + +struct Elf64_Sym { + Elf64_Word st_name; + uint8 st_info; + uint8 st_other; + Elf64_Half st_shndx; + Elf64_Addr st_value; + Elf64_Xword st_size; + +#ifdef __cplusplus + uint8 Bind() const; + uint8 Type() const; + void SetInfo(uint8 bind, uint8 type); +#endif +}; + +#define ELF64_ST_BIND(i) ((i) >> 4) +#define ELF64_ST_TYPE(i) ((i) & 0xf) +#define ELF64_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf)) + +struct Elf64_Rel { + Elf64_Addr r_offset; + Elf64_Xword r_info; + +#ifdef __cplusplus + uint8 SymbolIndex() const; + uint8 Type() const; +#endif +}; + +#ifdef __cplusplus +struct Elf64_Rela : public Elf64_Rel { +#else +struct Elf64_Rela { + Elf64_Addr r_offset; + Elf64_Xword r_info; +#endif + Elf64_Sxword r_addend; +}; + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffffL) +#define ELF64_R_INFO(s, t) ((((Elf64_Xword)(s)) << 32) + ((t) & 0xffffffffL)) + +struct Elf64_Dyn { + Elf64_Sxword d_tag; + union { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +}; + + +/* version definition section */ + +struct Elf64_Verdef { + Elf64_Half vd_version; /* version revision */ + Elf64_Half vd_flags; /* version information flags */ + Elf64_Half vd_ndx; /* version index as specified in the + symbol version table */ + Elf64_Half vd_cnt; /* number of associated verdaux entries */ + Elf64_Word vd_hash; /* version name hash value */ + Elf64_Word vd_aux; /* byte offset to verdaux array */ + Elf64_Word vd_next; /* byte offset to next verdef entry */ +}; + + +/* auxiliary version information */ + +struct Elf64_Verdaux { + Elf64_Word vda_name; /* string table offset to version or dependency + name */ + Elf64_Word vda_next; /* byte offset to next verdaux entry */ +}; + + +/* version dependency section */ + +struct Elf64_Verneed { + Elf64_Half vn_version; /* version of structure */ + Elf64_Half vn_cnt; /* number of associated vernaux entries */ + Elf64_Word vn_file; /* byte offset to file name for this + dependency */ + Elf64_Word vn_aux; /* byte offset to vernaux array */ + Elf64_Word vn_next; /* byte offset to next verneed entry */ +}; + + +/* auxiliary needed version information */ + +struct Elf64_Vernaux { + Elf64_Word vna_hash; /* dependency name hash value */ + Elf64_Half vna_flags; /* dependency specific information flags */ + Elf64_Half vna_other; /* version index as specified in the symbol + version table */ + Elf64_Word vna_name; /* string table offset to dependency name */ + Elf64_Word vna_next; /* byte offset to next vernaux entry */ +}; + + +/*** inline functions ***/ + +#ifdef __cplusplus + +inline bool +Elf64_Ehdr::IsHostEndian() const +{ +#if B_HOST_IS_LENDIAN + return e_ident[EI_DATA] == ELFDATA2LSB; +#elif B_HOST_IS_BENDIAN + return e_ident[EI_DATA] == ELFDATA2MSB; +#endif +} + + +inline bool +Elf64_Phdr::IsReadWrite() const +{ + return !(~p_flags & (PF_READ | PF_WRITE)); +} + + +inline bool +Elf64_Phdr::IsExecutable() const +{ + return (p_flags & PF_EXECUTE) != 0; +} + + +inline uint8 +Elf64_Sym::Bind() const +{ + return ELF64_ST_BIND(st_info); +} + + +inline uint8 +Elf64_Sym::Type() const +{ + return ELF64_ST_TYPE(st_info); +} + + +inline void +Elf64_Sym::SetInfo(uint8 bind, uint8 type) +{ + st_info = ELF64_ST_INFO(bind, type); +} + + +inline uint8 +Elf64_Rel::SymbolIndex() const +{ + return ELF64_R_SYM(r_info); +} + + +inline uint8 +Elf64_Rel::Type() const +{ + return ELF64_R_TYPE(r_info); +} + +#endif /* __cplusplus */ + +#endif /* _ELF64_H_ */ diff --git a/headers/private/system/elf_common.h b/headers/private/system/elf_common.h new file mode 100644 index 0000000000..31eb0c0ecd --- /dev/null +++ b/headers/private/system/elf_common.h @@ -0,0 +1,301 @@ +/* + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + * + * Copyright 2002-2011, Haiku Inc. All Rights Reserved. + * Distributed under the terms of the MIT license. + */ +#ifndef _ELF_COMMON_H +#define _ELF_COMMON_H + + +#include +#include + +#include + + +/*** ELF header ***/ + +#define EI_NIDENT 16 + +#define ELF_MAGIC "\x7f""ELF" + +// e_ident[] indices +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_PAD 7 + +// e_machine (Architecture) +#define EM_NONE 0 // No machine +#define EM_M32 1 // AT&T WE 32100 +#define EM_SPARC 2 // Sparc +#define EM_386 3 // Intel 80386 +#define EM_68K 4 // Motorola m68k family +#define EM_88K 5 // Motorola m88k family +#define EM_486 6 // Intel 80486, Reserved for future use +#define EM_860 7 // Intel 80860 +#define EM_MIPS 8 // MIPS R3000 (officially, big-endian only) +#define EM_S370 9 // IBM System/370 +#define EM_MIPS_RS3_LE 10 // MIPS R3000 little-endian, Deprecated +#define EM_PARISC 15 // HPPA +#define EM_VPP550 17 // Fujitsu VPP500 +#define EM_SPARC32PLUS 18 // Sun "v8plus" +#define EM_960 19 // Intel 80960 +#define EM_PPC 20 // PowerPC +#define EM_PPC64 21 // 64-bit PowerPC +#define EM_S390 22 // IBM S/390 +#define EM_V800 36 // NEC V800 series +#define EM_FR20 37 // Fujitsu FR20 +#define EM_RH32 38 // TRW RH32 +#define EM_MCORE 39 // Motorola M*Core +#define EM_RCE 39 // Old name for MCore +#define EM_ARM 40 // ARM +#define EM_OLD_ALPHA 41 // Digital Alpha +#define EM_SH 42 // Renesas / SuperH SH +#define EM_SPARCV9 43 // SPARC v9 64-bit +#define EM_TRICORE 44 // Siemens Tricore embedded processor +#define EM_ARC 45 // ARC Cores +#define EM_H8_300 46 // Renesas H8/300 +#define EM_H8_300H 47 // Renesas H8/300H +#define EM_H8S 48 // Renesas H8S +#define EM_H8_500 49 // Renesas H8/500 +#define EM_IA_64 50 // Intel IA-64 Processor +#define EM_MIPS_X 51 // Stanford MIPS-X +#define EM_COLDFIRE 52 // Motorola Coldfire +#define EM_68HC12 53 // Motorola M68HC12 +#define EM_MMA 54 // Fujitsu Multimedia Accelerator +#define EM_PCP 55 // Siemens PCP +#define EM_NCPU 56 // Sony nCPU embedded RISC processor +#define EM_NDR1 57 // Denso NDR1 microprocesspr +#define EM_STARCORE 58 // Motorola Star*Core processor +#define EM_ME16 59 // Toyota ME16 processor +#define EM_ST100 60 // STMicroelectronics ST100 processor +#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor +#define EM_X86_64 62 // Advanced Micro Devices X86-64 processor + +// architecture class (EI_CLASS) +#define ELFCLASS32 1 +#define ELFCLASS64 2 +// endian (EI_DATA) +#define ELFDATA2LSB 1 /* little endian */ +#define ELFDATA2MSB 2 /* big endian */ + + +/*** section header ***/ + +// special section indices +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +// section header type +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 + +#define SHT_GNU_verdef 0x6ffffffd /* version definition section */ +#define SHT_GNU_verneed 0x6ffffffe /* version needs section */ +#define SHT_GNU_versym 0x6fffffff /* version symbol table */ + +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +// section header flags +#define SHF_WRITE 1 +#define SHF_ALLOC 2 +#define SHF_EXECINSTR 4 + +#define SHF_MASKPROC 0xf0000000 + + +/*** program header ***/ + +// program header segment types +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_STACK 0x6474e551 + +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +// program header segment flags +#define PF_EXECUTE 0x1 +#define PF_WRITE 0x2 +#define PF_READ 0x4 +#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ) + +#define PF_MASKPROC 0xf0000000 + +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +#define STN_UNDEF 0 + + +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_BIND_NOW 24 /* no lazy binding */ +#define DT_INIT_ARRAY 25 /* init function array */ +#define DT_FINI_ARRAY 26 /* termination function array */ +#define DT_INIT_ARRAYSZ 27 /* init function array size */ +#define DT_FINI_ARRAYSZ 28 /* termination function array size */ +#define DT_RUNPATH 29 /* library search path (supersedes DT_RPATH) */ +#define DT_FLAGS 30 /* flags (see below) */ +#define DT_ENCODING 32 +#define DT_PREINIT_ARRAY 32 /* preinitialization array */ +#define DT_PREINIT_ARRAYSZ 33 /* preinitialization array size */ + +#define DT_VERSYM 0x6ffffff0 /* symbol version table */ +#define DT_VERDEF 0x6ffffffc /* version definition table */ +#define DT_VERDEFNUM 0x6ffffffd /* number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* table with needed versions */ +#define DT_VERNEEDNUM 0x6fffffff /* number of needed versions */ + +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff + + +/* DT_FLAGS values */ +#define DF_ORIGIN 0x01 +#define DF_SYMBOLIC 0x02 +#define DF_TEXTREL 0x04 +#define DF_BIND_NOW 0x08 +#define DF_STATIC_TLS 0x10 + + +/* version definition section */ + +/* values for vd_version (version revision) */ +#define VER_DEF_NONE 0 /* no version */ +#define VER_DEF_CURRENT 1 /* current version */ +#define VER_DEF_NUM 2 /* given version number */ + +/* values for vd_flags (version information flags) */ +#define VER_FLG_BASE 0x1 /* version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* weak version identifier */ + +/* values for versym symbol index */ +#define VER_NDX_LOCAL 0 /* symbol is local */ +#define VER_NDX_GLOBAL 1 /* symbol is global/unversioned */ +#define VER_NDX_INITIAL 2 /* initial version -- that's the one given + to symbols when a library becomes + versioned; handled by the linker (and + runtime loader) similar to + VER_NDX_GLOBAL */ +#define VER_NDX_LORESERVE 0xff00 /* beginning of reserved entries */ +#define VER_NDX_ELIMINATE 0xff01 /* symbol is to be eliminated */ + +#define VER_NDX_FLAG_HIDDEN 0x8000 /* flag: version is hidden */ +#define VER_NDX_MASK 0x7fff /* mask to get the actual version index */ +#define VER_NDX(x) ((x) & VER_NDX_MASK) + + +/* version dependency section */ + +/* values for vn_version (version revision) */ +#define VER_NEED_NONE 0 /* no version */ +#define VER_NEED_CURRENT 1 /* current version */ +#define VER_NEED_NUM 2 /* given version number */ + + +/* auxiliary needed version information */ + +/* values for vna_flags */ +#define VER_FLG_WEAK 0x2 /* weak version identifier */ + + +// Determine the correct ELF types to use for the architecture + +#if B_HAIKU_64_BIT +# define _ELF_TYPE(type) Elf64_##type +#else +# define _ELF_TYPE(type) Elf32_##type +#endif +#define DEFINE_ELF_TYPE(type, name) \ + struct _ELF_TYPE(type); \ + typedef struct _ELF_TYPE(type) name + +DEFINE_ELF_TYPE(Ehdr, elf_ehdr); +DEFINE_ELF_TYPE(Phdr, elf_phdr); +DEFINE_ELF_TYPE(Shdr, elf_shdr); +DEFINE_ELF_TYPE(Sym, elf_sym); +DEFINE_ELF_TYPE(Dyn, elf_dyn); +DEFINE_ELF_TYPE(Rel, elf_rel); +DEFINE_ELF_TYPE(Rela, elf_rela); +DEFINE_ELF_TYPE(Verdef, elf_verdef); +DEFINE_ELF_TYPE(Verdaux, elf_verdaux); +DEFINE_ELF_TYPE(Verneed, elf_verneed); +DEFINE_ELF_TYPE(Vernaux, elf_vernaux); + +#undef DEFINE_ELF_TYPE +#undef _ELF_TYPE + +typedef uint16 elf_versym; + +#if B_HAIKU_64_BIT +# define ELF_CLASS ELFCLASS64 +#else +# define ELF_CLASS ELFCLASS32 +#endif + + +#endif /* _ELF_COMMON_H_ */ diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 81cd20c10e..438a3ea310 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -21,7 +22,6 @@ extern "C" { struct attr_info; struct dirent; -struct Elf32_Sym; struct fd_info; struct fd_set; struct fs_info; @@ -226,7 +226,7 @@ extern status_t _kern_get_image_info(image_id id, image_info *info, extern status_t _kern_get_next_image_info(team_id team, int32 *cookie, image_info *info, size_t size); extern status_t _kern_read_kernel_image_symbols(image_id id, - struct Elf32_Sym* symbolTable, int32* _symbolCount, + elf_sym* symbolTable, int32* _symbolCount, char* stringTable, size_t* _stringTableSize, addr_t* _imageDelta); @@ -253,7 +253,7 @@ extern int _kern_open_dir_entry_ref(dev_t device, ino_t inode, extern int _kern_open_dir(int fd, const char *path); extern int _kern_open_parent_dir(int fd, char *name, size_t nameLength); -extern status_t _kern_fcntl(int fd, int op, uint32 argument); +extern status_t _kern_fcntl(int fd, int op, size_t argument); extern status_t _kern_fsync(int fd); extern status_t _kern_flock(int fd, int op); extern off_t _kern_seek(int fd, off_t pos, int seekType); @@ -411,7 +411,7 @@ extern status_t _kern_delete_area(area_id area); extern area_id _kern_area_for(void *address); extern area_id _kern_find_area(const char *name); extern status_t _kern_get_area_info(area_id area, area_info *info); -extern status_t _kern_get_next_area_info(team_id team, int32 *cookie, +extern status_t _kern_get_next_area_info(team_id team, ssize_t *cookie, area_info *info); extern status_t _kern_resize_area(area_id area, size_t newSize); extern area_id _kern_transfer_area(area_id area, void **_address, @@ -534,7 +534,7 @@ extern void _kern_clear_caches(void *address, size_t length, extern bool _kern_cpu_enabled(int32 cpu); extern status_t _kern_set_cpu_enabled(int32 cpu, bool enabled); -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) // our only x86 only syscall extern status_t _kern_get_cpuid(cpuid_info *info, uint32 eax, uint32 cpu); #endif diff --git a/src/add-ons/disk_systems/bfs/BFSAddOn.cpp b/src/add-ons/disk_systems/bfs/BFSAddOn.cpp index b33c828a77..8fd7d64b3b 100644 --- a/src/add-ons/disk_systems/bfs/BFSAddOn.cpp +++ b/src/add-ons/disk_systems/bfs/BFSAddOn.cpp @@ -255,11 +255,11 @@ BFSPartitionHandle::Repair(bool checkOnly) while (ioctl(fd, BFS_IOCTL_CHECK_NEXT_NODE, &result, sizeof(result)) == 0) { if (++counter % 50 == 0) - printf("%9Ld nodes processed\x1b[1A\n", counter); + printf("%9" B_PRId64 " nodes processed\x1b[1A\n", counter); if (result.pass == BFS_CHECK_PASS_BITMAP) { if (result.errors) { - printf("%s (inode = %lld)", result.name, result.inode); + printf("%s (inode = %" B_PRIdINO ")", result.name, result.inode); if ((result.errors & BFS_MISSING_BLOCKS) != 0) printf(", some blocks weren't allocated"); if ((result.errors & BFS_BLOCKS_ALREADY_SET) != 0) diff --git a/src/add-ons/input_server/devices/wacom/MasterServerDevice.cpp b/src/add-ons/input_server/devices/wacom/MasterServerDevice.cpp index 4c3675d63f..69ea6fd8e0 100644 --- a/src/add-ons/input_server/devices/wacom/MasterServerDevice.cpp +++ b/src/add-ons/input_server/devices/wacom/MasterServerDevice.cpp @@ -60,7 +60,7 @@ MasterServerDevice::~MasterServerDevice() // cleanup _StopAll(); if (_LockDevices()) { - while (PointingDevice* device = (PointingDevice*)fDevices.RemoveItem(0L)) + while (PointingDevice* device = (PointingDevice*)fDevices.RemoveItem((int32)0)) delete device; _UnlockDevices(); } diff --git a/src/add-ons/kernel/bluetooth/btCoreData/Jamfile b/src/add-ons/kernel/bluetooth/btCoreData/Jamfile index c5ea92268b..a0f577eb33 100644 --- a/src/add-ons/kernel/bluetooth/btCoreData/Jamfile +++ b/src/add-ons/kernel/bluetooth/btCoreData/Jamfile @@ -1,7 +1,7 @@ SubDir HAIKU_TOP src add-ons kernel bluetooth btCoreData ; UsePrivateHeaders kernel net bluetooth ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] ; UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; # disable debug output, if debugging is disabled diff --git a/src/add-ons/kernel/bluetooth/hci/Jamfile b/src/add-ons/kernel/bluetooth/hci/Jamfile index 5cf637f091..4a3020cb20 100644 --- a/src/add-ons/kernel/bluetooth/hci/Jamfile +++ b/src/add-ons/kernel/bluetooth/hci/Jamfile @@ -2,7 +2,7 @@ SubDir HAIKU_TOP src add-ons kernel bluetooth hci ; UsePrivateKernelHeaders ; UsePrivateHeaders net bluetooth ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] ; UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; # disable debug output, if debugging is disabled diff --git a/src/add-ons/kernel/bus_managers/acpi/BusManager.cpp b/src/add-ons/kernel/bus_managers/acpi/BusManager.cpp index 692898bb44..ea63dba1be 100644 --- a/src/add-ons/kernel/bus_managers/acpi/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/acpi/BusManager.cpp @@ -715,6 +715,20 @@ get_table(const char* signature, uint32 instance, void** tableHeader) } +status_t +read_bit_register(uint32 regid, uint32 *val) +{ + return AcpiReadBitRegister(regid, (UINT32 *)val); +} + + +status_t +write_bit_register(uint32 regid, uint32 val) +{ + return AcpiWriteBitRegister(regid, val); +} + + struct acpi_module_info gACPIModule = { { B_ACPI_MODULE_NAME, @@ -759,5 +773,7 @@ struct acpi_module_info gACPIModule = { prepare_sleep_state, enter_sleep_state, reboot, - get_table + get_table, + read_bit_register, + write_bit_register }; diff --git a/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp b/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp index 969ed2b328..1aefcbc4eb 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp +++ b/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp @@ -29,7 +29,7 @@ ATAChannel::ATAChannel(device_node *node) gDeviceManager->get_attr_uint32(node, ATA_CHANNEL_ID_ITEM, &fChannelID, true); - snprintf(fDebugContext, sizeof(fDebugContext), " %lu", fChannelID); + snprintf(fDebugContext, sizeof(fDebugContext), " %" B_PRIu32, fChannelID); if (fUseDMA) { void *settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); @@ -879,7 +879,7 @@ ATAChannel::_FlushAndWait(bigtime_t waitTime) status_t ATAChannel::_ReadPIOBlock(ATARequest *request, size_t length) { - uint32 transferred = 0; + size_t transferred = 0; status_t result = _TransferPIOBlock(request, length, &transferred); request->CCB()->data_resid -= transferred; diff --git a/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp b/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp index f055eb1d75..323b30fd8b 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp +++ b/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp @@ -574,7 +574,7 @@ ATADevice::Configure() status_t ATADevice::Identify() { - snprintf(fDebugContext, sizeof(fDebugContext), "%s %lu-%u", + snprintf(fDebugContext, sizeof(fDebugContext), "%s %" B_PRIu32 "-%u", IsATAPI() ? "pi" : "", fChannel->ChannelID(), fIndex); ATARequest request(false); diff --git a/src/add-ons/kernel/bus_managers/config_manager/Jamfile b/src/add-ons/kernel/bus_managers/config_manager/Jamfile index b0333cae66..e88370ef0b 100644 --- a/src/add-ons/kernel/bus_managers/config_manager/Jamfile +++ b/src/add-ons/kernel/bus_managers/config_manager/Jamfile @@ -7,4 +7,5 @@ KernelAddon config_manager : : config_manager_arch.a ; -SubInclude HAIKU_TOP src add-ons kernel bus_managers config_manager arch $(TARGET_ARCH) ; +SubInclude HAIKU_TOP src add-ons kernel bus_managers config_manager arch + $(TARGET_KERNEL_ARCH) ; diff --git a/src/add-ons/kernel/bus_managers/config_manager/config_manager.c b/src/add-ons/kernel/bus_managers/config_manager/config_manager.c index 4f6ede94aa..ccb7a66261 100644 --- a/src/add-ons/kernel/bus_managers/config_manager/config_manager.c +++ b/src/add-ons/kernel/bus_managers/config_manager/config_manager.c @@ -29,7 +29,7 @@ static pci_module_info *gPCI = NULL; static status_t driver_get_next_device_info(bus_type bus, uint64 *cookie, struct device_info *info, uint32 size) { - FUNCTION("(bus = %d, cookie = %lld)\n", bus, *cookie); + FUNCTION("(bus = %d, cookie = %" B_PRId64 ")\n", bus, *cookie); return B_ENTRY_NOT_FOUND; } @@ -37,7 +37,7 @@ driver_get_next_device_info(bus_type bus, uint64 *cookie, struct device_info *in static status_t driver_get_device_info_for(uint64 id, struct device_info *info, uint32 size) { - FUNCTION("(id = %Ld)\n", id); + FUNCTION("(id = %" B_PRId64 ")\n", id); return B_ENTRY_NOT_FOUND; } @@ -45,7 +45,7 @@ driver_get_device_info_for(uint64 id, struct device_info *info, uint32 size) static status_t driver_get_size_of_current_configuration_for(uint64 id) { - FUNCTION("(id = %Ld)\n", id); + FUNCTION("(id = %" B_PRId64 ")\n", id); return B_ENTRY_NOT_FOUND; } @@ -53,7 +53,8 @@ driver_get_size_of_current_configuration_for(uint64 id) static status_t driver_get_current_configuration_for(uint64 id, struct device_configuration *current, uint32 size) { - FUNCTION("(id = %Ld, current = %p, size = %lu)\n", id, current, size); + FUNCTION("(id = %" B_PRId64 ", current = %p, size = %" B_PRIu32 ")\n", id, + current, size); return B_ENTRY_NOT_FOUND; } @@ -61,7 +62,7 @@ driver_get_current_configuration_for(uint64 id, struct device_configuration *cur static status_t driver_get_size_of_possible_configurations_for(uint64 id) { - FUNCTION("(id = %Ld)\n", id); + FUNCTION("(id = %" B_PRId64 ")\n", id); return B_ENTRY_NOT_FOUND; } @@ -69,7 +70,8 @@ driver_get_size_of_possible_configurations_for(uint64 id) static status_t driver_get_possible_configurations_for(uint64 id, struct possible_device_configurations *possible, uint32 size) { - FUNCTION("(id = %Ld, possible = %p, size = %lu)\n", id, possible, size); + FUNCTION("(id = %" B_PRId64 ", possible = %p, size = %" B_PRIu32 ")\n", id, + possible, size); return B_ENTRY_NOT_FOUND; } @@ -86,7 +88,7 @@ static status_t driver_get_nth_resource_descriptor_of_type(const struct device_configuration *config, uint32 num, resource_type type, resource_descriptor *descr, uint32 size) { - FUNCTION("(config = %p, num = %ld)\n", config, num); + FUNCTION("(config = %p, num = %" B_PRId32 ")\n", config, num); return B_ENTRY_NOT_FOUND; } diff --git a/src/add-ons/kernel/bus_managers/isa/Jamfile b/src/add-ons/kernel/bus_managers/isa/Jamfile index d31c44db12..77719db55a 100644 --- a/src/add-ons/kernel/bus_managers/isa/Jamfile +++ b/src/add-ons/kernel/bus_managers/isa/Jamfile @@ -3,8 +3,9 @@ SubDir HAIKU_TOP src add-ons kernel bus_managers isa ; UsePrivateKernelHeaders ; KernelAddon isa : - isa.c + isa.cpp : isa_arch_bus_manager.a ; -SubInclude HAIKU_TOP src add-ons kernel bus_managers isa arch $(TARGET_ARCH) ; +SubInclude HAIKU_TOP src add-ons kernel bus_managers isa arch + $(TARGET_KERNEL_ARCH) ; diff --git a/src/add-ons/kernel/bus_managers/isa/arch/x86/Jamfile b/src/add-ons/kernel/bus_managers/isa/arch/x86/Jamfile index 8c49de72a8..2618a2e39b 100644 --- a/src/add-ons/kernel/bus_managers/isa/arch/x86/Jamfile +++ b/src/add-ons/kernel/bus_managers/isa/arch/x86/Jamfile @@ -6,7 +6,7 @@ UsePrivateHeaders kernel [ FDirName kernel arch x86 ] ; UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; KernelStaticLibrary isa_arch_bus_manager : - isa_dma.c - isa_controller.c + isa_dma.cpp + isa_controller.cpp ; diff --git a/src/add-ons/kernel/bus_managers/isa/arch/x86/isa_controller.c b/src/add-ons/kernel/bus_managers/isa/arch/x86/isa_controller.cpp similarity index 100% rename from src/add-ons/kernel/bus_managers/isa/arch/x86/isa_controller.c rename to src/add-ons/kernel/bus_managers/isa/arch/x86/isa_controller.cpp diff --git a/src/add-ons/kernel/bus_managers/isa/arch/x86/isa_dma.c b/src/add-ons/kernel/bus_managers/isa/arch/x86/isa_dma.cpp similarity index 100% rename from src/add-ons/kernel/bus_managers/isa/arch/x86/isa_dma.c rename to src/add-ons/kernel/bus_managers/isa/arch/x86/isa_dma.cpp diff --git a/src/add-ons/kernel/bus_managers/isa/isa.c b/src/add-ons/kernel/bus_managers/isa/isa.cpp similarity index 100% rename from src/add-ons/kernel/bus_managers/isa/isa.c rename to src/add-ons/kernel/bus_managers/isa/isa.cpp diff --git a/src/add-ons/kernel/bus_managers/pci/Jamfile b/src/add-ons/kernel/bus_managers/pci/Jamfile index 79d1b0e00a..c4ea478e92 100644 --- a/src/add-ons/kernel/bus_managers/pci/Jamfile +++ b/src/add-ons/kernel/bus_managers/pci/Jamfile @@ -3,7 +3,7 @@ SubDir HAIKU_TOP src add-ons kernel bus_managers pci ; UsePrivateKernelHeaders ; UsePrivateHeaders shared ; UsePrivateHeaders [ FDirName kernel util ] ; -UseHeaders [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ; +UseHeaders [ FDirName $(SUBDIR) arch $(TARGET_KERNEL_ARCH) ] ; KernelAddon pci : pci.cpp @@ -20,4 +20,5 @@ ObjectHdrs [ FGristFiles pci_info$(SUFOBJ) ] : [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR) apps devices ] ; Includes [ FGristFiles pci_info.cpp ] : pcihdr.h ; -SubInclude HAIKU_TOP src add-ons kernel bus_managers pci arch $(TARGET_ARCH) ; +SubInclude HAIKU_TOP src add-ons kernel bus_managers pci arch + $(TARGET_KERNEL_ARCH) ; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile index 9328c66541..f03f6c7048 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/Jamfile @@ -7,9 +7,9 @@ UsePrivateHeaders kernel [ FDirName kernel arch x86 ] [ FDirName kernel util ] ; KernelStaticLibrary pci_arch_bus_manager : pci_arch_info.cpp pci_arch_module.cpp - pci_bios.c - pci_controller.c - pci_io.c - pci_irq.c + pci_bios.cpp + pci_controller.cpp + pci_io.cpp + pci_irq.cpp pci_msi.cpp ; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.c b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp similarity index 100% rename from src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.c rename to src/add-ons/kernel/bus_managers/pci/arch/x86/pci_bios.cpp diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.c b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp similarity index 89% rename from src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.c rename to src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp index 79431d88c9..4a0fd7fc5a 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.c +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_controller.cpp @@ -181,29 +181,29 @@ pci_ram_address(const void *physical_address_in_system_memory) pci_controller pci_controller_x86_mech1 = { - .read_pci_config = pci_mech1_read_config, - .write_pci_config = pci_mech1_write_config, - .get_max_bus_devices = pci_mech1_get_max_bus_devices, - .read_pci_irq = pci_x86_irq_read, - .write_pci_irq = pci_x86_irq_write, + pci_mech1_read_config, + pci_mech1_write_config, + pci_mech1_get_max_bus_devices, + pci_x86_irq_read, + pci_x86_irq_write, }; pci_controller pci_controller_x86_mech2 = { - .read_pci_config = pci_mech2_read_config, - .write_pci_config = pci_mech2_write_config, - .get_max_bus_devices = pci_mech2_get_max_bus_devices, - .read_pci_irq = pci_x86_irq_read, - .write_pci_irq = pci_x86_irq_write, + pci_mech2_read_config, + pci_mech2_write_config, + pci_mech2_get_max_bus_devices, + pci_x86_irq_read, + pci_x86_irq_write, }; pci_controller pci_controller_x86_bios = { - .read_pci_config = pci_bios_read_config, - .write_pci_config = pci_bios_write_config, - .get_max_bus_devices = pci_bios_get_max_bus_devices, - .read_pci_irq = pci_x86_irq_read, - .write_pci_irq = pci_x86_irq_write, + pci_bios_read_config, + pci_bios_write_config, + pci_bios_get_max_bus_devices, + pci_x86_irq_read, + pci_x86_irq_write, }; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_io.c b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_io.cpp similarity index 100% rename from src/add-ons/kernel/bus_managers/pci/arch/x86/pci_io.c rename to src/add-ons/kernel/bus_managers/pci/arch/x86/pci_io.cpp diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.c b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.cpp similarity index 100% rename from src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.c rename to src/add-ons/kernel/bus_managers/pci/arch/x86/pci_irq.cpp diff --git a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp index 880c0c804c..719c490760 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/x86/pci_msi.cpp @@ -163,7 +163,7 @@ pci_enable_msi(uint8 virtualBus, uint8 _device, uint8 function) gPCI->WriteConfig(device, info->capability_offset + PCI_msi_control, 2, info->control_value); - dprintf("msi enabled: 0x%04lx\n", + dprintf("msi enabled: 0x%04" B_PRIx32 "\n", gPCI->ReadConfig(device, info->capability_offset + PCI_msi_control, 2)); return B_OK; } diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index 93bb755a06..c91ce3d149 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -350,7 +350,7 @@ display_io(int argc, char **argv) if (i != 0) kprintf("\n"); - kprintf("[0x%lx] ", address + i * itemSize); + kprintf("[0x%" B_PRIx32 "] ", address + i * itemSize); if (num > displayWidth) { // make sure the spacing in the last line is correct @@ -362,13 +362,13 @@ display_io(int argc, char **argv) switch (itemSize) { case 1: - kprintf(" %02x", pci_read_io_8(address + i * itemSize)); + kprintf(" %02" B_PRIx8, pci_read_io_8(address + i * itemSize)); break; case 2: - kprintf(" %04x", pci_read_io_16(address + i * itemSize)); + kprintf(" %04" B_PRIx16, pci_read_io_16(address + i * itemSize)); break; case 4: - kprintf(" %08lx", pci_read_io_32(address + i * itemSize)); + kprintf(" %08" B_PRIx32, pci_read_io_32(address + i * itemSize)); break; } } @@ -569,7 +569,7 @@ PCI::~PCI() status_t PCI::_CreateVirtualBus(int domain, uint8 bus, uint8 *virtualBus) { -#if defined(__INTEL__) +#if defined(__INTEL__) || defined(__x86_64__) // IA32 doesn't use domains if (domain) @@ -607,7 +607,7 @@ PCI::_CreateVirtualBus(int domain, uint8 bus, uint8 *virtualBus) status_t PCI::ResolveVirtualBus(uint8 virtualBus, int *domain, uint8 *bus) { -#if defined(__INTEL__) +#if defined(__INTEL__) || defined(__x86_64__) // IA32 doesn't use domains *bus = virtualBus; @@ -739,8 +739,11 @@ PCI::_EnumerateBus(int domain, uint8 bus, uint8 *subordinateBus) if (baseClass != PCI_bridge || subClass != PCI_pci) continue; - TRACE(("PCI: found PCI-PCI bridge: domain %u, bus %u, dev %u, func %u\n", domain, bus, dev, function)); - TRACE(("PCI: original settings: pcicmd %04lx, primary-bus %lu, secondary-bus %lu, subordinate-bus %lu\n", + TRACE(("PCI: found PCI-PCI bridge: domain %u, bus %u, dev %u, func %u\n", + domain, bus, dev, function)); + TRACE(("PCI: original settings: pcicmd %04" B_PRIx32 ", primary-bus " + "%" B_PRIu32 ", secondary-bus %" B_PRIu32 ", subordinate-bus " + "%" B_PRIu32 "\n", ReadConfig(domain, bus, dev, function, PCI_command, 2), ReadConfig(domain, bus, dev, function, PCI_primary_bus, 1), ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1), @@ -758,7 +761,9 @@ PCI::_EnumerateBus(int domain, uint8 bus, uint8 *subordinateBus) WriteConfig(domain, bus, dev, function, PCI_secondary_bus, 1, 0); WriteConfig(domain, bus, dev, function, PCI_subordinate_bus, 1, 0); - TRACE(("PCI: disabled settings: pcicmd %04lx, primary-bus %lu, secondary-bus %lu, subordinate-bus %lu\n", + TRACE(("PCI: disabled settings: pcicmd %04" B_PRIx32 ", primary-bus " + "%" B_PRIu32 ", secondary-bus %" B_PRIu32 ", subordinate-bus " + "%" B_PRIu32 "\n", ReadConfig(domain, bus, dev, function, PCI_command, 2), ReadConfig(domain, bus, dev, function, PCI_primary_bus, 1), ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1), @@ -803,7 +808,9 @@ PCI::_EnumerateBus(int domain, uint8 bus, uint8 *subordinateBus) pcicmd |= PCI_command_io | PCI_command_memory | PCI_command_master; WriteConfig(domain, bus, dev, function, PCI_command, 2, pcicmd); - TRACE(("PCI: probing settings: pcicmd %04lx, primary-bus %lu, secondary-bus %lu, subordinate-bus %lu\n", + TRACE(("PCI: probing settings: pcicmd %04" B_PRIx32 ", primary-bus " + "%" B_PRIu32 ", secondary-bus %" B_PRIu32 ", subordinate-bus " + "%" B_PRIu32 "\n", ReadConfig(domain, bus, dev, function, PCI_command, 2), ReadConfig(domain, bus, dev, function, PCI_primary_bus, 1), ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1), @@ -815,7 +822,9 @@ PCI::_EnumerateBus(int domain, uint8 bus, uint8 *subordinateBus) // close Scheunentor WriteConfig(domain, bus, dev, function, PCI_subordinate_bus, 1, lastUsedBusNumber); - TRACE(("PCI: configured settings: pcicmd %04lx, primary-bus %lu, secondary-bus %lu, subordinate-bus %lu\n", + TRACE(("PCI: configured settings: pcicmd %04" B_PRIx32 ", primary-bus " + "%" B_PRIu32 ", secondary-bus %" B_PRIu32 ", subordinate-bus " + "%" B_PRIu32 "\n", ReadConfig(domain, bus, dev, function, PCI_command, 2), ReadConfig(domain, bus, dev, function, PCI_primary_bus, 1), ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1), @@ -1236,11 +1245,11 @@ PCI::_ReadHeaderInfo(PCIDev *dev) WriteConfig(dev->domain, dev->bus, dev->device, dev->function, PCI_command, 2, pcicmd); - dev->info.u.h0.rom_base = (ulong)pci_ram_address( - (void *)dev->info.u.h0.rom_base_pci); + dev->info.u.h0.rom_base = (addr_t)pci_ram_address( + (void *)(addr_t)dev->info.u.h0.rom_base_pci); for (int i = 0; i < 6; i++) { - dev->info.u.h0.base_registers[i] = (ulong)pci_ram_address( - (void *)dev->info.u.h0.base_registers_pci[i]); + dev->info.u.h0.base_registers[i] = (addr_t)pci_ram_address( + (void *)(addr_t)dev->info.u.h0.base_registers_pci[i]); } dev->info.u.h0.cardbus_cis = ReadConfig(dev->domain, dev->bus, @@ -1282,11 +1291,11 @@ PCI::_ReadHeaderInfo(PCIDev *dev) WriteConfig(dev->domain, dev->bus, dev->device, dev->function, PCI_command, 2, pcicmd); - dev->info.u.h1.rom_base = (ulong)pci_ram_address( - (void *)dev->info.u.h1.rom_base_pci); + dev->info.u.h1.rom_base = (addr_t)pci_ram_address( + (void *)(addr_t)dev->info.u.h1.rom_base_pci); for (int i = 0; i < 2; i++) { - dev->info.u.h1.base_registers[i] = (ulong)pci_ram_address( - (void *)dev->info.u.h1.base_registers_pci[i]); + dev->info.u.h1.base_registers[i] = (addr_t)pci_ram_address( + (void *)(addr_t)dev->info.u.h1.base_registers_pci[i]); } dev->info.u.h1.primary_bus = ReadConfig(dev->domain, dev->bus, @@ -1397,7 +1406,7 @@ PCI::_RefreshDeviceInfo(PCIBus *bus) for (PCIDev *dev = bus->child; dev; dev = dev->next) { _ReadBasicInfo(dev); _ReadHeaderInfo(dev); -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) pci_read_arch_info(dev); #endif if (dev->child) diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index 626ed79030..a75fcfed8e 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -15,7 +15,7 @@ #include "pci_controller.h" -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) #include "pci_arch_info.h" #endif @@ -47,7 +47,7 @@ struct PCIDev { uint8 device; uint8 function; pci_info info; -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) pci_arch_info arch_info; #endif }; diff --git a/src/add-ons/kernel/bus_managers/pci/pci_fixup.cpp b/src/add-ons/kernel/bus_managers/pci/pci_fixup.cpp index ac1365a6be..7ab20f61be 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_fixup.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_fixup.cpp @@ -44,7 +44,7 @@ jmicron_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, // Read controller control register (0x40). uint32 val = pci->ReadConfig(domain, bus, device, function, 0x40, 4); - dprintf("jmicron_fixup_ahci: Register 0x40 : 0x%08lx\n", val); + dprintf("jmicron_fixup_ahci: Register 0x40 : 0x%08" B_PRIx32 "\n", val); // Clear bits. val &= ~(1 << 1); @@ -67,7 +67,7 @@ jmicron_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, val |= (1 << 14); val |= (1 << 23); - dprintf("jmicron_fixup_ahci: Register 0x40 : 0x%08lx\n", val); + dprintf("jmicron_fixup_ahci: Register 0x40 : 0x%08" B_PRIx32 "\n", val); pci->WriteConfig(domain, bus, device, function, 0x40, 4, val); // Read IRQ from controller at function 0 and assign this IRQ to the @@ -108,9 +108,9 @@ intel_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function, dprintf("intel_fixup_ahci: domain %u, bus %u, device %u, function %u, " "deviceId 0x%04x\n", domain, bus, device, function, deviceId); - dprintf("intel_fixup_ahci: 0x24: 0x%08lx\n", + dprintf("intel_fixup_ahci: 0x24: 0x%08" B_PRIx32 "\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); - dprintf("intel_fixup_ahci: 0x90: 0x%02lx\n", + dprintf("intel_fixup_ahci: 0x90: 0x%02" B_PRIx32 "\n", pci->ReadConfig(domain, bus, device, function, 0x90, 1)); uint8 map = pci->ReadConfig(domain, bus, device, function, 0x90, 1); @@ -125,10 +125,10 @@ intel_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function, pcicmd & ~(PCI_command_io | PCI_command_memory)); pci->WriteConfig(domain, bus, device, function, 0x24, 4, 0xffffffff); - dprintf("intel_fixup_ahci: ide-bar5 bits-1: 0x%08lx\n", + dprintf("intel_fixup_ahci: ide-bar5 bits-1: 0x%08" B_PRIx32 "\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); pci->WriteConfig(domain, bus, device, function, 0x24, 4, 0); - dprintf("intel_fixup_ahci: ide-bar5 bits-0: 0x%08lx\n", + dprintf("intel_fixup_ahci: ide-bar5 bits-0: 0x%08" B_PRIx32 "\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); map &= ~0x03; @@ -136,10 +136,10 @@ intel_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function, pci->WriteConfig(domain, bus, device, function, 0x90, 1, map); pci->WriteConfig(domain, bus, device, function, 0x24, 4, 0xffffffff); - dprintf("intel_fixup_ahci: ahci-bar5 bits-1: 0x%08lx\n", + dprintf("intel_fixup_ahci: ahci-bar5 bits-1: 0x%08" B_PRIx32 "\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); pci->WriteConfig(domain, bus, device, function, 0x24, 4, 0); - dprintf("intel_fixup_ahci: ahci-bar5 bits-0: 0x%08lx\n", + dprintf("intel_fixup_ahci: ahci-bar5 bits-0: 0x%08" B_PRIx32 "\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); if (deviceId == 0x27c0 || deviceId == 0x27c4) // restore on ICH7 @@ -148,9 +148,9 @@ intel_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function, pci->WriteConfig(domain, bus, device, function, PCI_command, 2, pcicmd); } - dprintf("intel_fixup_ahci: 0x24: 0x%08lx\n", + dprintf("intel_fixup_ahci: 0x24: 0x%08" B_PRIx32 "\n", pci->ReadConfig(domain, bus, device, function, 0x24, 4)); - dprintf("intel_fixup_ahci: 0x90: 0x%02lx\n", + dprintf("intel_fixup_ahci: 0x90: 0x%02" B_PRIx32 "\n", pci->ReadConfig(domain, bus, device, function, 0x90, 1)); } @@ -158,7 +158,7 @@ intel_fixup_ahci(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function, static void ati_fixup_ixp(PCI *pci, int domain, uint8 bus, uint8 device, uint8 function, uint16 deviceId) { -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) /* ATI Technologies Inc, IXP chipset: * This chipset seems broken, at least on my laptop I must force * the timer IRQ trigger mode, else no interrupt comes in. diff --git a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp index c869d92629..ba748a0fa8 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp @@ -13,7 +13,7 @@ #include "pci.h" #define PCI_VERBOSE 1 -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) // enabling it makes the pci bus_manager binary about 1MB // some other platforms have issues with floppy image size... // TODO: Move this define to BuildSetup? @@ -42,11 +42,13 @@ print_pci2pci_bridge_info(const pci_info *info, bool verbose) uint32 io_limit = (((uint32)info->u.h1.io_limit & 0xf0) << 8) + 0xfff; if (info->u.h1.io_limit & 1) io_limit += info->u.h1.io_limit_upper16 << 16; - TRACE(("PCI: I/O window %04lx-%04lx\n", io_base, io_limit)); + TRACE(("PCI: I/O window %04" B_PRIx32 "-%04" B_PRIx32 "\n", io_base, + io_limit)); uint32 memory_base = ((uint32)info->u.h1.memory_base & 0xfff0) << 16; uint32 memory_limit = (((uint32)info->u.h1.memory_limit & 0xfff0) << 16) + 0xfffff; - TRACE(("PCI: memory window %04lx-%04lx\n", memory_base, memory_limit)); + TRACE(("PCI: memory window %04" B_PRIx32 "-%04" B_PRIx32 "\n", + memory_base, memory_limit)); uint64 prefetchable_memory_base = ((uint32)info->u.h1.prefetchable_memory_base & 0xfff0) << 16; if (info->u.h1.prefetchable_memory_base & 1) { @@ -60,18 +62,19 @@ print_pci2pci_bridge_info(const pci_info *info, bool verbose) prefetchable_memory_limit += (uint64)info->u.h1.prefetchable_memory_limit_upper32 << 32; } - TRACE(("PCI: prefetchable memory window %016llx-%016llx\n", + TRACE(("PCI: prefetchable memory window %016" B_PRIx64 "-%016" B_PRIx64 "\n", prefetchable_memory_base, prefetchable_memory_limit)); TRACE(("PCI: bridge_control %04x, secondary_status %04x\n", info->u.h1.bridge_control, info->u.h1.secondary_status)); TRACE(("PCI: interrupt_line %02x, interrupt_pin %02x\n", info->u.h1.interrupt_line, info->u.h1.interrupt_pin)); - TRACE(("PCI: ROM base host %08lx, pci %08lx, size ??\n", + TRACE(("PCI: ROM base host %08" B_PRIx32 ", pci %08" B_PRIx32 ", size ??\n", info->u.h1.rom_base, info->u.h1.rom_base_pci)); for (int i = 0; i < 2; i++) - TRACE(("PCI: base reg %d: host %08lx, pci %08lx, size %08lx, flags %02x\n", - i, info->u.h1.base_registers[i], info->u.h1.base_registers_pci[i], - info->u.h1.base_register_sizes[i], info->u.h1.base_register_flags[i])); + TRACE(("PCI: base reg %d: host %08" B_PRIx32 ", pci %08" B_PRIx32 ", " + "size %08" B_PRIx32 ", flags %02x\n", i, info->u.h1.base_registers[i], + info->u.h1.base_registers_pci[i], info->u.h1.base_register_sizes[i], + info->u.h1.base_register_flags[i])); } @@ -79,18 +82,20 @@ static void print_pci2cardbus_bridge_info(const pci_info *info, bool verbose) { TRACE(("PCI: subsystem_id %04x, subsystem_vendor_id %04x\n", - info->u.h2.subsystem_id, info->u.h2.subsystem_vendor_id)); - TRACE(("PCI: primary_bus %02x, secondary_bus %02x, subordinate_bus %02x, secondary_latency %02x\n", - info->u.h2.primary_bus, info->u.h2.secondary_bus, info->u.h2.subordinate_bus, info->u.h2.secondary_latency)); + info->u.h2.subsystem_id, info->u.h2.subsystem_vendor_id)); + TRACE(("PCI: primary_bus %02x, secondary_bus %02x, subordinate_bus %02x, " + "secondary_latency %02x\n", info->u.h2.primary_bus, + info->u.h2.secondary_bus, info->u.h2.subordinate_bus, + info->u.h2.secondary_latency)); TRACE(("PCI: bridge_control %04x, secondary_status %04x\n", - info->u.h2.bridge_control, info->u.h2.secondary_status)); - TRACE(("PCI: memory_base_upper32 %08lx, memory_base %08lx\n", - info->u.h2.memory_base_upper32, info->u.h2.memory_base)); - TRACE(("PCI: memory_limit_upper32 %08lx, memory_limit %08lx\n", - info->u.h2.memory_limit_upper32, info->u.h2.memory_limit)); - TRACE(("PCI: io_base_upper32 %08lx, io_base %08lx\n", + info->u.h2.bridge_control, info->u.h2.secondary_status)); + TRACE(("PCI: memory_base_upper32 %08" B_PRIx32 ", memory_base %08" + B_PRIx32 "\n", info->u.h2.memory_base_upper32, info->u.h2.memory_base)); + TRACE(("PCI: memory_limit_upper32 %08" B_PRIx32 ", memory_limit %08" + B_PRIx32 "\n", info->u.h2.memory_limit_upper32, info->u.h2.memory_limit)); + TRACE(("PCI: io_base_upper32 %08" B_PRIx32 ", io_base %08" B_PRIx32 "\n", info->u.h2.io_base_upper32, info->u.h2.io_base)); - TRACE(("PCI: io_limit_upper32 %08lx, io_limit %08lx\n", + TRACE(("PCI: io_limit_upper32 %08" B_PRIx32 ", io_limit %08" B_PRIx32 "\n", info->u.h2.io_limit_upper32, info->u.h2.io_limit)); } @@ -98,16 +103,20 @@ print_pci2cardbus_bridge_info(const pci_info *info, bool verbose) static void print_generic_info(const pci_info *info, bool verbose) { - TRACE(("PCI: ROM base host %08lx, pci %08lx, size %08lx\n", - info->u.h0.rom_base, info->u.h0.rom_base_pci, info->u.h0.rom_size)); - TRACE(("PCI: cardbus_CIS %08lx, subsystem_id %04x, subsystem_vendor_id %04x\n", - info->u.h0.cardbus_cis, info->u.h0.subsystem_id, info->u.h0.subsystem_vendor_id)); - TRACE(("PCI: interrupt_line %02x, interrupt_pin %02x, min_grant %02x, max_latency %02x\n", - info->u.h0.interrupt_line, info->u.h0.interrupt_pin, info->u.h0.min_grant, info->u.h0.max_latency)); + TRACE(("PCI: ROM base host %08" B_PRIx32 ", pci %08" B_PRIx32 ", size " + "%08" B_PRIx32 "\n", info->u.h0.rom_base, info->u.h0.rom_base_pci, + info->u.h0.rom_size)); + TRACE(("PCI: cardbus_CIS %08" B_PRIx32 ", subsystem_id %04x, " + "subsystem_vendor_id %04x\n", info->u.h0.cardbus_cis, + info->u.h0.subsystem_id, info->u.h0.subsystem_vendor_id)); + TRACE(("PCI: interrupt_line %02x, interrupt_pin %02x, min_grant %02x, " + "max_latency %02x\n", info->u.h0.interrupt_line, info->u.h0.interrupt_pin, + info->u.h0.min_grant, info->u.h0.max_latency)); for (int i = 0; i < 6; i++) - TRACE(("PCI: base reg %d: host %08lx, pci %08lx, size %08lx, flags %02x\n", - i, info->u.h0.base_registers[i], info->u.h0.base_registers_pci[i], - info->u.h0.base_register_sizes[i], info->u.h0.base_register_flags[i])); + TRACE(("PCI: base reg %d: host %08" B_PRIx32 ", pci %08" B_PRIx32 ", " + "size %08" B_PRIx32 ", flags %02x\n", i, info->u.h0.base_registers[i], + info->u.h0.base_registers_pci[i], info->u.h0.base_register_sizes[i], + info->u.h0.base_register_flags[i])); } diff --git a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp index 8685fdbb38..fc71f6c2f8 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_module.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_module.cpp @@ -89,7 +89,7 @@ module_info *modules[] = { (module_info *)&gPCIRootModule, (module_info *)&gPCIDeviceModule, (module_info *)&gPCILegacyDriverModule, -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) // add platforms when they provide an arch specific module (module_info *)&gPCIArchModule, #endif diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_common.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_common.cpp index 889c657247..37f902e74d 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.cpp @@ -117,7 +117,8 @@ ps2_selftest() uint8 in; res = ps2_command(PS2_CTRL_SELF_TEST, NULL, 0, &in, 1); if (res != B_OK || in != 0x55) { - INFO("ps2: controller self test failed, status 0x%08lx, data 0x%02x\n", res, in); + INFO("ps2: controller self test failed, status 0x%08" B_PRIx32 ", data " + "0x%02x\n", res, in); return B_ERROR; } return B_OK; @@ -131,7 +132,8 @@ ps2_setup_command_byte(bool interruptsEnabled) uint8 cmdbyte; res = ps2_command(PS2_CTRL_READ_CMD, NULL, 0, &cmdbyte, 1); - TRACE("ps2: get command byte: res 0x%08lx, cmdbyte 0x%02x\n", res, cmdbyte); + TRACE("ps2: get command byte: res 0x%08" B_PRIx32 ", cmdbyte 0x%02x\n", + res, cmdbyte); if (res != B_OK) cmdbyte = 0x47; @@ -144,7 +146,8 @@ ps2_setup_command_byte(bool interruptsEnabled) cmdbyte &= ~(PS2_BITS_KEYBOARD_INTERRUPT | PS2_BITS_AUX_INTERRUPT); res = ps2_command(PS2_CTRL_WRITE_CMD, &cmdbyte, 1, NULL, 0); - TRACE("ps2: set command byte: res 0x%08lx, cmdbyte 0x%02x\n", res, cmdbyte); + TRACE("ps2: set command byte: res 0x%08" B_PRIx32 ", cmdbyte 0x%02x\n", + res, cmdbyte); return res; } @@ -205,7 +208,8 @@ done: // This fixes bug report #1175 res = ps2_command(0xae, NULL, 0, NULL, 0); if (res != B_OK) { - INFO("ps2: active multiplexing d3 workaround failed, status 0x%08lx\n", res); + INFO("ps2: active multiplexing d3 workaround failed, status 0x%08" + B_PRIx32 "\n", res); } return B_OK; @@ -256,7 +260,7 @@ ps2_command(uint8 cmd, const uint8 *out, int outCount, uint8 *in, int inCount) #ifdef TRACE_PS2 for (i = 0; i < inCount; i++) TRACE("ps2: ps2_command in 0x%02x\n", in[i]); - TRACE("ps2: ps2_command result 0x%08lx\n", res); + TRACE("ps2: ps2_command result 0x%08" B_PRIx32 "\n", res); #endif atomic_add(&sIgnoreInterrupts, -1); diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.cpp index e1363010d2..0cb799a5a4 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.cpp @@ -203,8 +203,8 @@ ps2_dev_publish(ps2_dev *dev) } snooze(timeout / 20); } - TRACE("ps2: publishing %s: parent %s is %s; wait time %Ld\n", - dev->name, dev->parent_dev->name, + TRACE("ps2: publishing %s: parent %s is %s; wait time %" B_PRId64 + "\n", dev->name, dev->parent_dev->name, status == B_OK ? "enabled" : "busy", system_time() - start); } @@ -219,7 +219,8 @@ ps2_dev_publish(ps2_dev *dev) dev->active = true; - INFO("ps2: devfs_publish_device %s, status = 0x%08lx\n", dev->name, status); + INFO("ps2: devfs_publish_device %s, status = 0x%08" B_PRIx32 "\n", + dev->name, status); } @@ -239,8 +240,8 @@ ps2_dev_unpublish(ps2_dev *dev) if ((dev->flags & PS2_FLAG_ENABLED) && dev->disconnect) dev->disconnect(dev); - INFO("ps2: devfs_unpublish_device %s, status = 0x%08lx\n", dev->name, - status); + INFO("ps2: devfs_unpublish_device %s, status = 0x%08" B_PRIx32 "\n", + dev->name, status); } @@ -370,7 +371,8 @@ standard_command_timeout(ps2_dev *dev, uint8 cmd, const uint8 *out, res = get_sem_count(dev->result_sem, &sem_count); if (res == B_OK && sem_count != 0) { - TRACE("ps2: ps2_dev_command: sem_count %ld, fixing!\n", sem_count); + TRACE("ps2: ps2_dev_command: sem_count %" B_PRId32 ", fixing!\n", + sem_count); if (sem_count > 0) acquire_sem_etc(dev->result_sem, sem_count, 0, 0); else @@ -423,8 +425,8 @@ standard_command_timeout(ps2_dev *dev, uint8 cmd, const uint8 *out, if (res != B_OK) atomic_and(&dev->flags, ~PS2_FLAG_CMD); - TRACE("ps2: ps2_dev_command wait for ack res 0x%08lx, wait-time %Ld\n", - res, system_time() - start); + TRACE("ps2: ps2_dev_command wait for ack res 0x%08" B_PRIx32 ", " + "wait-time %" B_PRId64 "\n", res, system_time() - start); if (atomic_get(&dev->flags) & PS2_FLAG_ACK) { TRACE("ps2: ps2_dev_command got ACK\n"); @@ -458,15 +460,15 @@ standard_command_timeout(ps2_dev *dev, uint8 cmd, const uint8 *out, res = B_IO_ERROR; } - TRACE("ps2: ps2_dev_command wait for input res 0x%08lx, " - "wait-time %Ld\n", res, system_time() - start); + TRACE("ps2: ps2_dev_command wait for input res 0x%08" B_PRIx32 ", " + "wait-time %" B_PRId64 "\n", res, system_time() - start); for (i = 0; i < in_count; i++) TRACE("ps2: ps2_dev_command rx: 0x%02x\n", in[i]); } } - TRACE("ps2: ps2_dev_command result 0x%08lx\n", res); + TRACE("ps2: ps2_dev_command result 0x%08" B_PRIx32 "\n", res); return res; } diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.cpp index ec6fa42e92..06a6049c08 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.cpp @@ -88,7 +88,8 @@ set_typematic(int32 rate, bigtime_t delay) { uint8 value; - TRACE("ps2: set_typematic rate %ld, delay %Ld\n", rate, delay); + TRACE("ps2: set_typematic rate %" B_PRId32 ", delay %" B_PRId64 "\n", + rate, delay); // input server and keyboard preferences *seem* to use a range of 20-300 if (rate < 20) @@ -271,8 +272,8 @@ probe_keyboard(void) status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_RESET, NULL, 0, &data, 1); if (status != B_OK || data != 0xaa) { - INFO("ps2: keyboard reset failed, status 0x%08lx, data 0x%02x\n", - status, data); + INFO("ps2: keyboard reset failed, status 0x%08" B_PRIx32 ", data 0x%02x" + "\n", status, data); return B_ERROR; } @@ -297,14 +298,15 @@ probe_keyboard(void) status = ps2_command(PS2_CTRL_READ_CMD, NULL, 0, &cmdbyte, 1); if (status != B_OK) { - INFO("ps2: cannot read CMD byte on kbd probe:0x%#08lx\n", status); + INFO("ps2: cannot read CMD byte on kbd probe:%#08" B_PRIx32 "\n", + status); } else if ((cmdbyte & PS2_BITS_KEYBOARD_DISABLED) == PS2_BITS_KEYBOARD_DISABLED) { cmdbyte &= ~PS2_BITS_KEYBOARD_DISABLED; status = ps2_command(PS2_CTRL_WRITE_CMD, &cmdbyte, 1, NULL, 0); if (status != B_OK) { - INFO("ps2: cannot write 0x%02x to CMD byte on kbd probe:0x%08lx\n", - cmdbyte, status); + INFO("ps2: cannot write 0x%02x to CMD byte on kbd probe:%#08" + B_PRIx32 "\n", cmdbyte, status); } } @@ -312,7 +314,7 @@ probe_keyboard(void) PS2_CMD_GET_DEVICE_ID, NULL, 0, sKeyboardIds, sizeof(sKeyboardIds)); if (status != B_OK) { - INFO("ps2: cannot read keyboard device id:0x%#08lx\n", status); + INFO("ps2: cannot read keyboard device id:%#08" B_PRIx32 "\n", status); } return B_OK; @@ -529,7 +531,8 @@ keyboard_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) case KB_SET_CONTROL_ALT_DEL_TIMEOUT: case KB_CANCEL_CONTROL_ALT_DEL: case KB_DELAY_CONTROL_ALT_DEL: - INFO("ps2: ioctl 0x%lx not implemented yet, returning B_OK\n", op); + INFO("ps2: ioctl 0x%" B_PRIx32 " not implemented yet, returning " + "B_OK\n", op); return B_OK; case KB_SET_DEBUG_READER: @@ -541,7 +544,7 @@ keyboard_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) return B_OK; default: - INFO("ps2: invalid ioctl 0x%lx\n", op); + INFO("ps2: invalid ioctl 0x%" B_PRIx32 "\n", op); return B_DEV_INVALID_IOCTL; } } diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_service.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_service.cpp index 10bee95468..162c121f26 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_service.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_service.cpp @@ -128,7 +128,8 @@ ps2_service_thread(void *arg) break; } } else { - INFO("ps2: ps2_service_thread: Error, status 0x%08lx, terminating\n", status); + INFO("ps2: ps2_service_thread: Error, status 0x%08" B_PRIx32 ", " + "terminating\n", status); break; } } diff --git a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp index 9da56a54f1..338a45f647 100644 --- a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp @@ -51,7 +51,7 @@ is_sg_list_dma_safe(scsi_ccb *request) } // if there are no further restrictions - be happy - if (dma_boundary == ~0UL && alignment == 0 && max_sg_block_size == 0) + if (dma_boundary == ~(uint32)0 && alignment == 0 && max_sg_block_size == 0) return true; // argh - controller is a bit picky, so make sure he likes us diff --git a/src/add-ons/kernel/bus_managers/scsi/queuing.cpp b/src/add-ons/kernel/bus_managers/scsi/queuing.cpp index 3282b74f80..58d151622c 100644 --- a/src/add-ons/kernel/bus_managers/scsi/queuing.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/queuing.cpp @@ -55,7 +55,8 @@ static void scsi_insert_new_request( scsi_device_info *device, { scsi_ccb *first, *last, *before, *next; - SHOW_FLOW( 3, "inserting new_request=%p, pos=%Ld", new_request, new_request->sort ); + SHOW_FLOW( 3, "inserting new_request=%p, pos=%" B_PRId64, new_request, + new_request->sort ); first = device->queued_reqs; @@ -65,7 +66,7 @@ static void scsi_insert_new_request( scsi_device_info *device, return; } - SHOW_FLOW( 3, "first=%p, pos=%Ld, last_pos=%Ld", + SHOW_FLOW( 3, "first=%p, pos=%" B_PRId64 ", last_pos=%" B_PRId64, first, first->sort, device->last_sort ); // don't let syncs bypass others @@ -153,7 +154,7 @@ static void scsi_insert_new_request( scsi_device_info *device, return; } - SHOW_FLOW( 1, "inserting after %p (pos=%Ld) and before %p (pos=%Ld)", + SHOW_FLOW( 1, "inserting after %p (pos=%" B_PRId64 ") and before %p (pos=%" B_PRId64 ")", before, before->sort, next, next->sort ); // if we haven't found a proper position, we automatically insert diff --git a/src/add-ons/kernel/bus_managers/scsi/scatter_gather.cpp b/src/add-ons/kernel/bus_managers/scsi/scatter_gather.cpp index f4b2da0020..2d4977f430 100644 --- a/src/add-ons/kernel/bus_managers/scsi/scatter_gather.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/scatter_gather.cpp @@ -51,7 +51,7 @@ fill_temp_sg(scsi_ccb *ccb) if (mapped_len != ccb->data_length) goto too_complex; - if (dma_boundary != ~0UL || ccb->data_length > max_sg_block_size) { + if (dma_boundary != ~(uint32)0 || ccb->data_length > max_sg_block_size) { // S/G list may not be controller-compatible: // we have to split offending entries SHOW_FLOW(3, "Checking violation of dma boundary 0x%x and entry size 0x%x", @@ -64,7 +64,7 @@ fill_temp_sg(scsi_ccb *ccb) max_len = (dma_boundary + 1) - (temp_sg[cur_idx].address & dma_boundary); // restrict size per sg item - max_len = std::min(max_len, max_sg_block_size); + max_len = std::min(max_len, (addr_t)max_sg_block_size); SHOW_FLOW(4, "addr=%#" B_PRIxPHYSADDR ", size=%x, max_len=%x, " "idx=%d, num=%d", temp_sg[cur_idx].address, @@ -107,7 +107,8 @@ create_temp_sg(scsi_ccb *ccb) physical_entry *temp_sg; status_t res; - SHOW_FLOW(3, "ccb=%p, data=%p, data_length=%lu", ccb, ccb->data, ccb->data_length); + SHOW_FLOW(3, "ccb=%p, data=%p, data_length=%" B_PRIu32, ccb, ccb->data, + ccb->data_length); ccb->sg_list = temp_sg = (physical_entry*)locked_pool->alloc(temp_sg_pool); if (temp_sg == NULL) { diff --git a/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h b/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h index 5a1105ad32..1c4fd70635 100644 --- a/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h +++ b/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h @@ -121,21 +121,21 @@ typedef struct scsi_bus_info { typedef struct dma_buffer { area_id area; // area of DMA buffer uchar *address; // address of DMA buffer - uint32 size; // size of DMA buffer + size_t size; // size of DMA buffer area_id sg_list_area; // area of S/G list physical_entry *sg_list; // address of S/G list - uint32 sg_count; // number of entries in S/G list + size_t sg_count; // number of entries in S/G list bool inuse; // true, if in use bigtime_t last_use; // timestamp of last usage area_id sg_orig; // area of S/G list to original data physical_entry *sg_list_orig; // S/G list to original data - uint32 sg_count_max_orig; // maximum size (in entries) - uint32 sg_count_orig; // current size (in entries) + size_t sg_count_max_orig; // maximum size (in entries) + size_t sg_count_orig; // current size (in entries) uchar *orig_data; // pointer to original data const physical_entry *orig_sg_list; // original S/G list - uint32 orig_sg_count; // size of original S/G list + size_t orig_sg_count; // size of original S/G list } dma_buffer; diff --git a/src/add-ons/kernel/bus_managers/scsi/scsi_io.cpp b/src/add-ons/kernel/bus_managers/scsi/scsi_io.cpp index d07405a08d..23663d9cfc 100644 --- a/src/add-ons/kernel/bus_managers/scsi/scsi_io.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/scsi_io.cpp @@ -367,7 +367,7 @@ scsi_check_enqueue_request(scsi_ccb *request) if (request->sort >= 0) { device->last_sort = request->sort; - SHOW_FLOW(1, "%Ld", device->last_sort); + SHOW_FLOW(1, "%" B_PRId64, device->last_sort); } execute = true; @@ -618,7 +618,7 @@ scsi_check_exec_service(scsi_bus_info *bus) if (request->sort >= 0) { device->last_sort = request->sort; - SHOW_FLOW(1, "%Ld", device->last_sort); + SHOW_FLOW(1, "%" B_PRId64, device->last_sort); } RELEASE_BEN(&bus->mutex); diff --git a/src/add-ons/kernel/bus_managers/scsi/virtual_memory.cpp b/src/add-ons/kernel/bus_managers/scsi/virtual_memory.cpp index 94baaa832b..3dd7b8d129 100644 --- a/src/add-ons/kernel/bus_managers/scsi/virtual_memory.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/virtual_memory.cpp @@ -56,8 +56,8 @@ get_iovec_memory_map(iovec *vec, size_t vec_count, size_t vec_offset, size_t len range_start = (char *)vec->iov_base + vec_offset; range_len = std::min(vec->iov_len - vec_offset, left_len); - SHOW_FLOW( 3, "range_start=%x, range_len=%x", - (int)range_start, (int)range_len ); + SHOW_FLOW( 3, "range_start=%" B_PRIxADDR ", range_len=%" B_PRIxSIZE, + (addr_t)range_start, range_len ); vec_offset = 0; diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index e16995231b..1d6ce1b7e3 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -81,11 +81,11 @@ Device::Device(Object *parent, int8 hubAddress, uint8 hubPort, &actualLength); if (status < B_OK || actualLength != sizeof(usb_configuration_descriptor)) { - TRACE_ERROR("error fetching configuration %ld\n", i); + TRACE_ERROR("error fetching configuration %" B_PRId32 "\n", i); return; } - TRACE("configuration %ld\n", i); + TRACE("configuration %" B_PRId32 "\n", i); TRACE("\tlength:..............%d\n", configDescriptor.length); TRACE("\tdescriptor_type:.....0x%02x\n", configDescriptor.descriptor_type); TRACE("\ttotal_length:........%d\n", configDescriptor.total_length); @@ -106,8 +106,8 @@ Device::Device(Object *parent, int8 hubAddress, uint8 hubPort, if (status < B_OK || actualLength != configDescriptor.total_length) { TRACE_ERROR("error fetching full configuration" - " descriptor %ld got %lu expected %u\n", i, - actualLength, configDescriptor.total_length); + " descriptor %" B_PRId32 " got %" B_PRIuSIZE " expected %" + B_PRIu16 "\n", i, actualLength, configDescriptor.total_length); free(configData); return; } diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index df51aeac4d..271efaffe4 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -87,7 +87,7 @@ Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort, USB_REQUEST_SET_FEATURE, PORT_POWER, i + 1, 0, NULL, 0, NULL); if (status < B_OK) - TRACE_ERROR("power up failed on port %ld\n", i); + TRACE_ERROR("power up failed on port %" B_PRId32 "\n", i); } // Wait for power to stabilize @@ -201,10 +201,11 @@ Hub::Explore(change_item **changeList) #ifdef TRACE_USB if (fPortStatus[i].change) { - TRACE("port %ld: status: 0x%04x; change: 0x%04x\n", i, + TRACE("port %" B_PRId32 ": status: 0x%04x; change: 0x%04x\n", i, fPortStatus[i].status, fPortStatus[i].change); - TRACE("device at port %ld: %p (%ld)\n", i, fChildren[i], - fChildren[i] != NULL ? fChildren[i]->USBID() : 0); + TRACE("device at port %" B_PRId32 ": %p (%" B_PRId32 ")\n", i, + fChildren[i], fChildren[i] != NULL + ? fChildren[i]->USBID() : 0); } #endif @@ -216,7 +217,7 @@ Hub::Explore(change_item **changeList) if (fPortStatus[i].status & PORT_STATUS_CONNECTION) { // new device attached! - TRACE_ALWAYS("port %ld: new device connected\n", i); + TRACE_ALWAYS("port %" B_PRId32 ": new device connected\n", i); int32 retry = 2; while (retry--) { @@ -226,7 +227,8 @@ Hub::Explore(change_item **changeList) // reset the port, this will also enable it result = ResetPort(i); if (result < B_OK) { - TRACE_ERROR("resetting port %ld failed\n", i); + TRACE_ERROR("resetting port %" B_PRId32 " failed\n", + i); break; } @@ -282,7 +284,7 @@ Hub::Explore(change_item **changeList) } } else { // Device removed... - TRACE_ALWAYS("port %ld: device removed\n", i); + TRACE_ALWAYS("port %" B_PRId32 ": device removed\n", i); if (fChildren[i] != NULL) { TRACE("removing device %p\n", fChildren[i]); fChildren[i]->Changed(changeList, false); @@ -293,28 +295,31 @@ Hub::Explore(change_item **changeList) // other port changes we do not really handle, report and clear them if (fPortStatus[i].change & PORT_STATUS_ENABLE) { - TRACE_ALWAYS("port %ld %sabled\n", i, (fPortStatus[i].status & PORT_STATUS_ENABLE) ? "en" : "dis"); + TRACE_ALWAYS("port %" B_PRId32 " %sabled\n", i, + (fPortStatus[i].status & PORT_STATUS_ENABLE) ? "en" : "dis"); DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_ENABLE, i + 1, 0, NULL, 0, NULL); } if (fPortStatus[i].change & PORT_STATUS_SUSPEND) { - TRACE_ALWAYS("port %ld is %ssuspended\n", i, (fPortStatus[i].status & PORT_STATUS_SUSPEND) ? "" : "not "); + TRACE_ALWAYS("port %" B_PRId32 " is %ssuspended\n", i, + (fPortStatus[i].status & PORT_STATUS_SUSPEND) ? "" : "not "); DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_SUSPEND, i + 1, 0, NULL, 0, NULL); } if (fPortStatus[i].change & PORT_STATUS_OVER_CURRENT) { - TRACE_ALWAYS("port %ld is %sin an over current state\n", i, (fPortStatus[i].status & PORT_STATUS_OVER_CURRENT) ? "" : "not "); + TRACE_ALWAYS("port %" B_PRId32 " is %sin an over current state\n", + i, (fPortStatus[i].status & PORT_STATUS_OVER_CURRENT) ? "" : "not "); DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_OVER_CURRENT, i + 1, 0, NULL, 0, NULL); } if (fPortStatus[i].change & PORT_STATUS_RESET) { - TRACE_ALWAYS("port %ld was reset\n", i); + TRACE_ALWAYS("port %" B_PRId32 "was reset\n", i); DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, i + 1, 0, NULL, 0, NULL); @@ -400,7 +405,7 @@ Hub::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, if (*index < bufferSize) { int32 managerIndex = GetStack()->IndexOfBusManager(GetBusManager()); size_t totalBytes = snprintf(string + *index, bufferSize - *index, - "%ld", managerIndex); + "%" B_PRId32, managerIndex); *index += std::min(totalBytes, bufferSize - *index - 1); } } @@ -418,7 +423,7 @@ Hub::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, if (fChildren[i] == device) { if (*index < bufferSize) { size_t totalBytes = snprintf(string + *index, - bufferSize - *index, "/%ld", i); + bufferSize - *index, "/%" B_PRId32, i); *index += std::min(totalBytes, bufferSize - *index - 1); } break; diff --git a/src/add-ons/kernel/bus_managers/usb/Jamfile b/src/add-ons/kernel/bus_managers/usb/Jamfile index 737c74ebf8..5c8afe8560 100644 --- a/src/add-ons/kernel/bus_managers/usb/Jamfile +++ b/src/add-ons/kernel/bus_managers/usb/Jamfile @@ -28,8 +28,7 @@ KernelStaticLibrary libusb.a : Object.cpp PhysicalMemoryAllocator.cpp $(compatSources) - : -fno-pic -; +; KernelAddon usb : usb.cpp diff --git a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp index 29450ea9a9..c86dbd01f1 100644 --- a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp +++ b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp @@ -77,8 +77,6 @@ PhysicalMemoryAllocator::PhysicalMemoryAllocator(const char *name, fArea = create_area(fName, &fLogicalBase, B_ANY_KERNEL_ADDRESS, roundedSize, B_32_BIT_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); - // TODO: Use B_CONTIGUOUS when the TODOs regarding 64 bit physical - // addresses are fixed (if possible). if (fArea < B_OK) { TRACE_ERROR(("PMA: failed to create memory area\n")); return; @@ -131,9 +129,8 @@ PhysicalMemoryAllocator::_Unlock() status_t PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress, - void **physicalAddress) + phys_addr_t *physicalAddress) { -// TODO: physicalAddress should be a phys_addr_t*! #ifdef HAIKU_TARGET_PLATFORM_HAIKU if (debug_debugger_running()) { for (int32 i = 0; i < 64; i++) { @@ -142,7 +139,7 @@ PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress, fDebugUseMap |= mask; *logicalAddress = (void *)((uint8 *)fLogicalBase + fDebugBase + i * fDebugChunkSize); - *physicalAddress = (void *)(fPhysicalBase + fDebugBase + *physicalAddress = (phys_addr_t)(fPhysicalBase + fDebugBase + i * fDebugChunkSize); return B_OK; } @@ -204,7 +201,7 @@ PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress, _Unlock(); size_t offset = fBlockSize[arrayToUse] * i; *logicalAddress = (void *)((uint8 *)fLogicalBase + offset); - *physicalAddress = (void *)(fPhysicalBase + offset); + *physicalAddress = (phys_addr_t)(fPhysicalBase + offset); return B_OK; } } @@ -234,9 +231,8 @@ PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress, status_t PhysicalMemoryAllocator::Deallocate(size_t size, void *logicalAddress, - void *physicalAddress) + phys_addr_t physicalAddress) { -// TODO: physicalAddress should be a phys_addr_t! #ifdef HAIKU_TARGET_PLATFORM_HAIKU if (debug_debugger_running()) { uint32 index = ((uint8 *)logicalAddress - (uint8 *)fLogicalBase @@ -259,9 +255,9 @@ PhysicalMemoryAllocator::Deallocate(size_t size, void *logicalAddress, } } - uint32 offset; + phys_addr_t offset; if (logicalAddress) - offset = (uint32)logicalAddress - (uint32)fLogicalBase; + offset = (addr_t)logicalAddress - (addr_t)fLogicalBase; else if (physicalAddress) offset = (addr_t)physicalAddress - fPhysicalBase; else { @@ -318,7 +314,7 @@ PhysicalMemoryAllocator::PrintToStream() dprintf("\tMin block size:\t\t\t%ld bytes\n", fBlockSize[0]); dprintf("\tMax block size:\t\t\t%ld bytes\n", fBlockSize[fArrayCount - 1]); dprintf("\tMin count per block:\t%ld\n\n", fArrayLength[fArrayCount - 1]); - dprintf("\tArray count:\t\t\t%ld\n", fArrayCount); + dprintf("\tArray count:\t\t\t%" B_PRId32 "\n", fArrayCount); dprintf("\tArray slots:\t\t\t% 8ld", fArrayLength[0]); for (int32 i = 1; i < fArrayCount; i++) @@ -344,7 +340,7 @@ PhysicalMemoryAllocator::DumpArrays() { uint32 padding = 2; for (int32 i = 0; i < fArrayCount; i++) { - dprintf("\tArray(%ld):\t", i); + dprintf("\tArray(%" B_PRId32 "):\t", i); for (size_t j = 0; j < fArrayLength[i]; j++) { if (padding > 2) { for (uint32 k = 0; k < (padding - 2) / 4; k++) @@ -393,9 +389,9 @@ PhysicalMemoryAllocator::DumpFreeSlots() } if (i > 0) - dprintf(", % 8ld", freeSlots); + dprintf(", %8" B_PRIu32, freeSlots); else - dprintf("% 8ld", freeSlots); + dprintf("%8" B_PRIu32, freeSlots); } dprintf("\n"); } diff --git a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.h b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.h index 90207cea12..ce12f24e72 100644 --- a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.h +++ b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.h @@ -26,12 +26,12 @@ public: status_t Allocate(size_t size, void **logicalAddress, - void **physicalAddress); + phys_addr_t *physicalAddress); // one of both addresses needs to be provided, the other may be NULL status_t Deallocate(size_t size, void *logicalAddress, - void *physicalAddress); + phys_addr_t physicalAddress); void PrintToStream(); void DumpArrays(); diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index 049d6f0c3e..6c815161a2 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -278,24 +278,25 @@ Stack::BusManagerAt(int32 index) const status_t -Stack::AllocateChunk(void **logicalAddress, void **physicalAddress, size_t size) +Stack::AllocateChunk(void **logicalAddress, phys_addr_t *physicalAddress, + size_t size) { return fAllocator->Allocate(size, logicalAddress, physicalAddress); } status_t -Stack::FreeChunk(void *logicalAddress, void *physicalAddress, size_t size) +Stack::FreeChunk(void *logicalAddress, phys_addr_t physicalAddress, + size_t size) { return fAllocator->Deallocate(size, logicalAddress, physicalAddress); } area_id -Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size, +Stack::AllocateArea(void **logicalAddress, phys_addr_t *physicalAddress, size_t size, const char *name) { -// TODO: physicalAddress should be a phys_addr_t*! TRACE("allocating %ld bytes for %s\n", size, name); void *logAddress; @@ -323,10 +324,10 @@ Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size, *logicalAddress = logAddress; if (physicalAddress) - *physicalAddress = (void*)(addr_t)physicalEntry.address; + *physicalAddress = (phys_addr_t)physicalEntry.address; - TRACE("area = %ld, size = %ld, log = %p, phy = %#" B_PRIxPHYSADDR "\n", - area, size, logAddress, physicalEntry.address); + TRACE("area = %" B_PRId32 ", size = %" B_PRIuSIZE ", log = %p, phy = %#" + B_PRIxPHYSADDR "\n", area, size, logAddress, physicalEntry.address); return area; } diff --git a/src/add-ons/kernel/bus_managers/usb/usb.cpp b/src/add-ons/kernel/bus_managers/usb/usb.cpp index 7887f2ba4c..83cf8a926b 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb.cpp +++ b/src/add-ons/kernel/bus_managers/usb/usb.cpp @@ -145,7 +145,7 @@ uninstall_notify(const char *driverName) const usb_device_descriptor * get_device_descriptor(usb_device device) { - TRACE_MODULE("get_device_descriptor(%ld)\n", device); + TRACE_MODULE("get_device_descriptor(%" B_PRId32 ")\n", device); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return NULL; @@ -157,7 +157,8 @@ get_device_descriptor(usb_device device) const usb_configuration_info * get_nth_configuration(usb_device device, uint32 index) { - TRACE_MODULE("get_nth_configuration(%ld, %lu)\n", device, index); + TRACE_MODULE("get_nth_configuration(%" B_PRId32 ", %" B_PRIu32 ")\n", + device, index); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return NULL; @@ -169,7 +170,7 @@ get_nth_configuration(usb_device device, uint32 index) const usb_configuration_info * get_configuration(usb_device device) { - TRACE_MODULE("get_configuration(%ld)\n", device); + TRACE_MODULE("get_configuration(%" B_PRId32 ")\n", device); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return NULL; @@ -182,7 +183,8 @@ status_t set_configuration(usb_device device, const usb_configuration_info *configuration) { - TRACE_MODULE("set_configuration(%ld, %p)\n", device, configuration); + TRACE_MODULE("set_configuration(%" B_PRId32 ", %p)\n", device, + configuration); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; @@ -194,7 +196,7 @@ set_configuration(usb_device device, status_t set_alt_interface(usb_device device, const usb_interface_info *interface) { - TRACE_MODULE("set_alt_interface(%ld, %p)\n", device, interface); + TRACE_MODULE("set_alt_interface(%" B_PRId32 ", %p)\n", device, interface); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; @@ -206,7 +208,7 @@ set_alt_interface(usb_device device, const usb_interface_info *interface) status_t set_feature(usb_id handle, uint16 selector) { - TRACE_MODULE("set_feature(%ld, %d)\n", handle, selector); + TRACE_MODULE("set_feature(%" B_PRId32 ", %d)\n", handle, selector); Object *object = gUSBStack->GetObject(handle); if (!object) return B_DEV_INVALID_PIPE; @@ -218,7 +220,7 @@ set_feature(usb_id handle, uint16 selector) status_t clear_feature(usb_id handle, uint16 selector) { - TRACE_MODULE("clear_feature(%ld, %d)\n", handle, selector); + TRACE_MODULE("clear_feature(%" B_PRId32 ", %d)\n", handle, selector); Object *object = gUSBStack->GetObject(handle); if (!object) return B_DEV_INVALID_PIPE; @@ -230,7 +232,7 @@ clear_feature(usb_id handle, uint16 selector) status_t get_status(usb_id handle, uint16 *status) { - TRACE_MODULE("get_status(%ld, %p)\n", handle, status); + TRACE_MODULE("get_status(%" B_PRId32 ", %p)\n", handle, status); if (!status) return B_BAD_VALUE; @@ -246,7 +248,8 @@ status_t get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID, void *data, size_t dataLength, size_t *actualLength) { - TRACE_MODULE("get_descriptor(%ld, 0x%02x, 0x%02x, 0x%04x, %p, %ld, %p)\n", + TRACE_MODULE("get_descriptor(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, %p, " + "%" B_PRIuSIZE ", %p)\n", device, type, index, languageID, data, dataLength, actualLength); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) @@ -261,8 +264,9 @@ status_t send_request(usb_device device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) { - TRACE_MODULE("send_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, %p, %p)\n", - device, requestType, request, value, index, length, data, actualLength); + TRACE_MODULE("send_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x, " + "%d, %p, %p)\n", device, requestType, request, value, index, length, + data, actualLength); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; @@ -277,9 +281,9 @@ queue_request(usb_device device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, usb_callback_func callback, void *callbackCookie) { - TRACE_MODULE("queue_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %u, %p, %p, %p)\n", - device, requestType, request, value, index, length, data, callback, - callbackCookie); + TRACE_MODULE("queue_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x," + " %u, %p, %p, %p)\n", device, requestType, request, value, index, + length, data, callback, callbackCookie); Object *object = gUSBStack->GetObject(device); if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_DEV_INVALID_PIPE; @@ -293,7 +297,7 @@ status_t queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) { - TRACE_MODULE("queue_interrupt(%ld, %p, %ld, %p, %p)\n", + TRACE_MODULE("queue_interrupt(%" B_PRId32 ", %p, %ld, %p, %p)\n", pipe, data, dataLength, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) @@ -308,7 +312,7 @@ status_t queue_bulk(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) { - TRACE_MODULE("queue_bulk(%ld, %p, %ld, %p, %p)\n", + TRACE_MODULE("queue_bulk(%"B_PRId32 ", %p, %" B_PRIuSIZE ", %p, %p)\n", pipe, data, dataLength, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) @@ -323,7 +327,7 @@ status_t queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, usb_callback_func callback, void *callbackCookie) { - TRACE_MODULE("queue_bulk_v(%ld, %p, %ld, %p, %p)\n", + TRACE_MODULE("queue_bulk_v(%" B_PRId32 ", %p, %" B_PRIuSIZE " %p, %p)\n", pipe, vector, vectorCount, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) @@ -338,8 +342,8 @@ status_t queue_bulk_v_physical(usb_pipe pipe, iovec *vector, size_t vectorCount, usb_callback_func callback, void *callbackCookie) { - TRACE_MODULE("queue_bulk_v_physical(%ld, %p, %ld, %p, %p)\n", - pipe, vector, vectorCount, callback, callbackCookie); + TRACE_MODULE("queue_bulk_v_physical(%" B_PRId32 ", %p, %" B_PRIuSIZE + ", %p, %p)\n", pipe, vector, vectorCount, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) return B_DEV_INVALID_PIPE; @@ -355,7 +359,8 @@ queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, void *callbackCookie) { - TRACE_MODULE("queue_isochronous(%ld, %p, %ld, %p, %ld, %p, 0x%08lx, %p, %p)\n", + TRACE_MODULE("queue_isochronous(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, " + "%" B_PRId32 ", %p, 0x%08" B_PRIx32 ", %p, %p)\n", pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, flags, callback, callbackCookie); Object *object = gUSBStack->GetObject(pipe); @@ -372,8 +377,8 @@ status_t set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, uint16 maxBufferDurationMS, uint16 sampleSize) { - TRACE_MODULE("set_pipe_policy(%ld, %d, %d, %d)\n", pipe, maxQueuedPackets, - maxBufferDurationMS, sampleSize); + TRACE_MODULE("set_pipe_policy(%" B_PRId32 ", %d, %d, %d)\n", pipe, + maxQueuedPackets, maxBufferDurationMS, sampleSize); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) return B_DEV_INVALID_PIPE; @@ -386,7 +391,7 @@ set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, status_t cancel_queued_transfers(usb_pipe pipe) { - TRACE_MODULE("cancel_queued_transfers(%ld)\n", pipe); + TRACE_MODULE("cancel_queued_transfers(%" B_PRId32 ")\n", pipe); Object *object = gUSBStack->GetObject(pipe); if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) return B_DEV_INVALID_PIPE; @@ -398,7 +403,8 @@ cancel_queued_transfers(usb_pipe pipe) status_t usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) { - TRACE_MODULE("usb_ioctl(%lu, %p, %ld)\n", opcode, buffer, bufferSize); + TRACE_MODULE("usb_ioctl(%" B_PRIu32 ", %p, %" B_PRIuSIZE ")\n", opcode, + buffer, bufferSize); switch (opcode) { case 'DNAM': { @@ -564,21 +570,21 @@ struct usb_module_info gModuleInfoV3 = { const usb_device_descriptor * get_device_descriptor_v2(const void *device) { - return get_device_descriptor((usb_id)device); + return get_device_descriptor((usb_id)(ssize_t)device); } const usb_configuration_info * get_nth_configuration_v2(const void *device, uint index) { - return get_nth_configuration((usb_id)device, index); + return get_nth_configuration((usb_id)(ssize_t)device, index); } const usb_configuration_info * get_configuration_v2(const void *device) { - return get_configuration((usb_id)device); + return get_configuration((usb_id)(ssize_t)device); } @@ -586,35 +592,35 @@ status_t set_configuration_v2(const void *device, const usb_configuration_info *configuration) { - return set_configuration((usb_id)device, configuration); + return set_configuration((usb_id)(ssize_t)device, configuration); } status_t set_alt_interface_v2(const void *device, const usb_interface_info *interface) { - return set_alt_interface((usb_id)device, interface); + return set_alt_interface((usb_id)(ssize_t)device, interface); } status_t set_feature_v2(const void *object, uint16 selector) { - return set_feature((usb_id)object, selector); + return set_feature((usb_id)(ssize_t)object, selector); } status_t clear_feature_v2(const void *object, uint16 selector) { - return clear_feature((usb_id)object, selector); + return clear_feature((usb_id)(ssize_t)object, selector); } status_t get_status_v2(const void *object, uint16 *status) { - return get_status((usb_id)object, status); + return get_status((usb_id)(ssize_t)object, status); } @@ -622,7 +628,7 @@ status_t get_descriptor_v2(const void *device, uint8 type, uint8 index, uint16 languageID, void *data, size_t dataLength, size_t *actualLength) { - return get_descriptor((usb_id)device, type, index, languageID, data, + return get_descriptor((usb_id)(ssize_t)device, type, index, languageID, data, dataLength, actualLength); } @@ -632,7 +638,7 @@ send_request_v2(const void *device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t /*dataLength*/, size_t *actualLength) { - return send_request((usb_id)device, requestType, request, value, index, + return send_request((usb_id)(ssize_t)device, requestType, request, value, index, length, data, actualLength); } @@ -642,7 +648,7 @@ queue_request_v2(const void *device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie) { - return queue_request((usb_id)device, requestType, request, value, index, + return queue_request((usb_id)(ssize_t)device, requestType, request, value, index, length, data, callback, callbackCookie); } @@ -651,7 +657,7 @@ status_t queue_interrupt_v2(const void *pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) { - return queue_interrupt((usb_id)pipe, data, dataLength, callback, + return queue_interrupt((usb_id)(ssize_t)pipe, data, dataLength, callback, callbackCookie); } @@ -660,7 +666,7 @@ status_t queue_bulk_v2(const void *pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) { - return queue_bulk((usb_id)pipe, data, dataLength, callback, + return queue_bulk((usb_id)(ssize_t)pipe, data, dataLength, callback, callbackCookie); } @@ -673,7 +679,7 @@ queue_isochronous_v2(const void *pipe, void *data, size_t dataLength, // ToDo: convert rlea to usb_iso_packet_descriptor // ToDo: use a flag to indicate that the callback shall produce a rlea usb_iso_packet_descriptor *packetDesc = NULL; - return queue_isochronous((usb_id)pipe, data, dataLength, packetDesc, 0, + return queue_isochronous((usb_id)(ssize_t)pipe, data, dataLength, packetDesc, 0, NULL, 0, callback, callbackCookie); } @@ -682,7 +688,7 @@ status_t set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets, uint16 maxBufferDurationMS, uint16 sampleSize) { - return set_pipe_policy((usb_id)pipe, maxQueuedPackets, maxBufferDurationMS, + return set_pipe_policy((usb_id)(ssize_t)pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize); } @@ -690,7 +696,7 @@ set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets, status_t cancel_queued_transfers_v2(const void *pipe) { - return cancel_queued_transfers((usb_id)pipe); + return cancel_queued_transfers((usb_id)(ssize_t)pipe); } diff --git a/src/add-ons/kernel/bus_managers/usb/usb_private.h b/src/add-ons/kernel/bus_managers/usb/usb_private.h index dbc3f04b79..be8b3215ea 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_private.h @@ -17,7 +17,7 @@ #define TRACE_OUTPUT(x, y, z...) \ { \ - dprintf("usb %s%s %ld: ", y, (x)->TypeName(), (x)->USBID()); \ + dprintf("usb %s%s %" B_PRId32 ": ", y, (x)->TypeName(), (x)->USBID()); \ dprintf(z); \ } @@ -136,13 +136,14 @@ public: BusManager * BusManagerAt(int32 index) const; status_t AllocateChunk(void **logicalAddress, - void **physicalAddress, + phys_addr_t *physicalAddress, size_t size); status_t FreeChunk(void *logicalAddress, - void *physicalAddress, size_t size); + phys_addr_t physicalAddress, + size_t size); area_id AllocateArea(void **logicalAddress, - void **physicalAddress, + phys_addr_t *physicalAddress, size_t size, const char *name); void NotifyDeviceChange(Device *device, diff --git a/src/add-ons/kernel/bus_managers/usb/usbspec_private.h b/src/add-ons/kernel/bus_managers/usb/usbspec_private.h index 5e70ad2b96..2103994f74 100644 --- a/src/add-ons/kernel/bus_managers/usb/usbspec_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usbspec_private.h @@ -39,8 +39,8 @@ struct memory_chunk { - addr_t next_item; - addr_t physical; + uint32 next_item; + uint32 physical; }; diff --git a/src/add-ons/kernel/busses/agp_gart/Jamfile b/src/add-ons/kernel/busses/agp_gart/Jamfile index e7078ce150..c0177357ef 100644 --- a/src/add-ons/kernel/busses/agp_gart/Jamfile +++ b/src/add-ons/kernel/busses/agp_gart/Jamfile @@ -3,7 +3,7 @@ SubDir HAIKU_TOP src add-ons kernel busses agp_gart ; SetSubDirSupportedPlatformsBeOSCompatible ; SubDirC++Flags -fno-rtti ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] ; UsePrivateHeaders [ FDirName graphics intel_extreme ] ; UsePrivateHeaders [ FDirName graphics common ] ; UsePrivateHeaders drivers graphics kernel ; diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index 86ca3265fd..1a93c63a45 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -65,7 +65,9 @@ void print_descriptor_chain(ehci_qtd *descriptor) { while (descriptor) { - dprintf(" %08lx n%08lx a%08lx t%08lx %08lx %08lx %08lx %08lx %08lx s%ld\n", + dprintf(" %08" B_PRIx32 " n%08" B_PRIx32 " a%08" B_PRIx32 " t%08" B_PRIx32 + " %08" B_PRIx32 " %08" B_PRIx32 " %08" B_PRIx32 " %08" B_PRIx32 + " %08" B_PRIx32 " s%"B_PRIuSIZE "\n", descriptor->this_phy, descriptor->next_phy, descriptor->alt_next_phy, descriptor->token, descriptor->buffer_phy[0], descriptor->buffer_phy[1], @@ -82,14 +84,17 @@ print_descriptor_chain(ehci_qtd *descriptor) void print_queue(ehci_qh *queueHead) { - dprintf("queue: t%08lx n%08lx ch%08lx ca%08lx cu%08lx\n", + dprintf("queue: t%08" B_PRIx32 " n%08" B_PRIx32 " ch%08" B_PRIx32 + " ca%08" B_PRIx32 " cu%08" B_PRIx32 "\n", queueHead->this_phy, queueHead->next_phy, queueHead->endpoint_chars, queueHead->endpoint_caps, queueHead->current_qtd_phy); - dprintf("overlay: n%08lx a%08lx t%08lx %08lx %08lx %08lx %08lx %08lx\n", - queueHead->overlay.next_phy, queueHead->overlay.alt_next_phy, - queueHead->overlay.token, queueHead->overlay.buffer_phy[0], - queueHead->overlay.buffer_phy[1], queueHead->overlay.buffer_phy[2], - queueHead->overlay.buffer_phy[3], queueHead->overlay.buffer_phy[4]); + dprintf("overlay: n%08" B_PRIx32 " a%08" B_PRIx32 " t%08" B_PRIx32 + " %08" B_PRIx32 " %08" B_PRIx32 " %08" B_PRIx32 " %08" B_PRIx32 + " %08" B_PRIx32 "\n", queueHead->overlay.next_phy, + queueHead->overlay.alt_next_phy, queueHead->overlay.token, + queueHead->overlay.buffer_phy[0], queueHead->overlay.buffer_phy[1], + queueHead->overlay.buffer_phy[2], queueHead->overlay.buffer_phy[3], + queueHead->overlay.buffer_phy[4]); print_descriptor_chain(queueHead->element_log); } @@ -201,11 +206,12 @@ EHCI::EHCI(pci_info *info, Stack *stack) // map the registers uint32 offset = fPCIInfo->u.h0.base_registers[0] & (B_PAGE_SIZE - 1); - addr_t physicalAddress = fPCIInfo->u.h0.base_registers[0] - offset; + phys_addr_t physicalAddress = fPCIInfo->u.h0.base_registers[0] - offset; size_t mapSize = (fPCIInfo->u.h0.base_register_sizes[0] + offset + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); - TRACE("map physical memory 0x%08lx (base: 0x%08lx; offset: %lx); size: %ld\n", + TRACE("map physical memory 0x%08" B_PRIx32 " (base: 0x%08" B_PRIxPHYSADDR + "; offset: %" B_PRIx32 "); size: %" B_PRIu32 "\n", fPCIInfo->u.h0.base_registers[0], physicalAddress, offset, fPCIInfo->u.h0.base_register_sizes[0]); @@ -220,11 +226,11 @@ EHCI::EHCI(pci_info *info, Stack *stack) fCapabilityRegisters += offset; fOperationalRegisters = fCapabilityRegisters + ReadCapReg8(EHCI_CAPLENGTH); - TRACE("mapped capability registers: 0x%08lx\n", (uint32)fCapabilityRegisters); - TRACE("mapped operational registers: 0x%08lx\n", (uint32)fOperationalRegisters); + TRACE("mapped capability registers: 0x%p\n", fCapabilityRegisters); + TRACE("mapped operational registers: 0x%p\n", fOperationalRegisters); - TRACE("structural parameters: 0x%08lx\n", ReadCapReg32(EHCI_HCSPARAMS)); - TRACE("capability parameters: 0x%08lx\n", ReadCapReg32(EHCI_HCCPARAMS)); + TRACE("structural parameters: 0x%08" B_PRIx32 "\n", ReadCapReg32(EHCI_HCSPARAMS)); + TRACE("capability parameters: 0x%08" B_PRIx32 "\n", ReadCapReg32(EHCI_HCCPARAMS)); if (EHCI_HCCPARAMS_FRAME_CACHE(ReadCapReg32(EHCI_HCCPARAMS))) fThreshold = 2 + 8; @@ -237,7 +243,7 @@ EHCI::EHCI(pci_info *info, Stack *stack) uint32 extendedCapPointer = ReadCapReg32(EHCI_HCCPARAMS) >> EHCI_ECP_SHIFT; extendedCapPointer &= EHCI_ECP_MASK; if (extendedCapPointer > 0) { - TRACE("extended capabilities register at %ld\n", extendedCapPointer); + TRACE("extended capabilities register at %" B_PRIu32 "\n", extendedCapPointer); uint32 legacySupport = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, extendedCapPointer, 4); @@ -376,20 +382,23 @@ EHCI::EHCI(pci_info *info, Stack *stack) // allocate the periodic frame list fPeriodicFrameListArea = fStack->AllocateArea((void **)&fPeriodicFrameList, - (void **)&physicalAddress, frameListSize, "USB EHCI Periodic Framelist"); + &physicalAddress, frameListSize, "USB EHCI Periodic Framelist"); if (fPeriodicFrameListArea < B_OK) { TRACE_ERROR("unable to allocate periodic framelist\n"); return; } - if ((physicalAddress & 0xfff) != 0) - panic("EHCI_PERIODICLISTBASE not aligned on 4k: 0x%lx\n", physicalAddress); + if ((physicalAddress & 0xfff) != 0) { + panic("EHCI_PERIODICLISTBASE not aligned on 4k: 0x%" B_PRIxPHYSADDR + "\n", physicalAddress); + } + // set the periodic frame list base on the controller WriteOpReg(EHCI_PERIODICLISTBASE, (uint32)physicalAddress); // create the interrupt entries to support different polling intervals TRACE("creating interrupt entries\n"); - addr_t physicalBase = physicalAddress + B_PAGE_SIZE; + uint32_t physicalBase = physicalAddress + B_PAGE_SIZE; uint8 *logicalBase = (uint8 *)fPeriodicFrameList + B_PAGE_SIZE; memset(logicalBase, 0, B_PAGE_SIZE); @@ -410,16 +419,21 @@ EHCI::EHCI(pci_info *info, Stack *stack) | (0xff << EHCI_QH_CAPS_ISM_SHIFT); physicalBase += sizeof(interrupt_entry); + if ((physicalBase & 0x10) != 0) { + panic("physical base for interrupt entry %" B_PRId32 + " not aligned on 32, interrupt entry structure size %lu\n", + i, sizeof(interrupt_entry)); + } } // create the itd and sitd entries TRACE("build up iso entries\n"); - addr_t itdPhysicalBase = physicalAddress + B_PAGE_SIZE + B_PAGE_SIZE; + uint32_t itdPhysicalBase = physicalAddress + B_PAGE_SIZE + B_PAGE_SIZE; itd_entry* itds = (itd_entry *)((uint8 *)fPeriodicFrameList + B_PAGE_SIZE + B_PAGE_SIZE); memset(itds, 0, itdListSize); - addr_t sitdPhysicalBase = itdPhysicalBase + itdListSize; + uint32_t sitdPhysicalBase = itdPhysicalBase + itdListSize; sitd_entry* sitds = (sitd_entry *)((uint8 *)fPeriodicFrameList + B_PAGE_SIZE + B_PAGE_SIZE + itdListSize); memset(sitds, 0, sitdListSize); @@ -427,23 +441,25 @@ EHCI::EHCI(pci_info *info, Stack *stack) fItdEntries = new(std::nothrow) ehci_itd *[EHCI_VFRAMELIST_ENTRIES_COUNT]; fSitdEntries = new(std::nothrow) ehci_sitd *[EHCI_VFRAMELIST_ENTRIES_COUNT]; + dprintf("sitd entry size %lu, itd entry size %lu\n", sizeof(sitd_entry), sizeof(itd_entry)); for (int32 i = 0; i < EHCI_VFRAMELIST_ENTRIES_COUNT; i++) { ehci_sitd *sitd = &sitds[i].sitd; sitd->this_phy = sitdPhysicalBase | EHCI_ITEM_TYPE_SITD; sitd->back_phy = EHCI_ITEM_TERMINATE; fSitdEntries[i] = sitd; - TRACE("sitd entry %ld %p 0x%lx\n", i, sitd, sitd->this_phy); + TRACE("sitd entry %" B_PRId32 " %p 0x%" B_PRIx32 "\n", i, sitd, sitd->this_phy); ehci_itd *itd = &itds[i].itd; itd->this_phy = itdPhysicalBase | EHCI_ITEM_TYPE_ITD; itd->next_phy = sitd->this_phy; fItdEntries[i] = itd; - TRACE("itd entry %ld %p 0x%lx\n", i, itd, itd->this_phy); + TRACE("itd entry %" B_PRId32 " %p 0x%" B_PRIx32 "\n", i, itd, itd->this_phy); sitdPhysicalBase += sizeof(sitd_entry); itdPhysicalBase += sizeof(itd_entry); if ((sitdPhysicalBase & 0x10) != 0 || (itdPhysicalBase & 0x10) != 0) - panic("physical base for entry %ld not aligned on 32\n", i); + panic("physical base for entry %" B_PRId32 " not aligned on 32\n", + i); } // build flat interrupt tree @@ -479,7 +495,7 @@ EHCI::EHCI(pci_info *info, Stack *stack) for (int32 i = 0; i < EHCI_FRAMELIST_ENTRIES_COUNT; i++) { fPeriodicFrameList[i] = fItdEntries[i & (EHCI_VFRAMELIST_ENTRIES_COUNT - 1)]->this_phy; - TRACE("periodic entry %ld linked to 0x%lx\n", i, fPeriodicFrameList[i]); + TRACE("periodic entry %" B_PRId32 " linked to 0x%" B_PRIx32 "\n", i, fPeriodicFrameList[i]); } // Create the array that will keep bandwidth information @@ -504,7 +520,7 @@ EHCI::EHCI(pci_info *info, Stack *stack) fAsyncQueueHead->overlay.next_phy = EHCI_ITEM_TERMINATE; WriteOpReg(EHCI_ASYNCLISTADDR, (uint32)fAsyncQueueHead->this_phy); - TRACE("set the async list addr to 0x%08lx\n", ReadOpReg(EHCI_ASYNCLISTADDR)); + TRACE("set the async list addr to 0x%08" B_PRIx32 "\n", ReadOpReg(EHCI_ASYNCLISTADDR)); fInitOK = true; TRACE("EHCI host controller driver constructed\n"); @@ -554,7 +570,7 @@ status_t EHCI::Start() { TRACE("starting EHCI host controller\n"); - TRACE("usbcmd: 0x%08lx; usbsts: 0x%08lx\n", ReadOpReg(EHCI_USBCMD), + TRACE("usbcmd: 0x%08" B_PRIx32 "; usbsts: 0x%08" B_PRIx32 "\n", ReadOpReg(EHCI_USBCMD), ReadOpReg(EHCI_USBSTS)); bool hasPerPortChangeEvent = (ReadCapReg32(EHCI_HCCPARAMS) @@ -589,7 +605,7 @@ EHCI::Start() bool running = false; for (int32 i = 0; i < 10; i++) { uint32 status = ReadOpReg(EHCI_USBSTS); - TRACE("try %ld: status 0x%08lx\n", i, status); + TRACE("try %" B_PRId32 ": status 0x%08" B_PRIx32 "\n", i, status); if (status & EHCI_USBSTS_HCHALTED) { snooze(10000); @@ -729,9 +745,10 @@ EHCI::SubmitIsochronous(Transfer *transfer) return B_NO_MEMORY; } - TRACE("isochronous submitted size=%ld bytes, TDs=%ld, " - "maxPacketSize=%ld, packetSize=%ld, restSize=%ld\n", transfer->DataLength(), - isochronousData->packet_count, pipe->MaxPacketSize(), packetSize, restSize); + TRACE("isochronous submitted size=%" B_PRIuSIZE " bytes, TDs=%" B_PRIu32 ", " + "maxPacketSize=%" B_PRIuSIZE ", packetSize=%" B_PRIuSIZE ", restSize=%" + B_PRIuSIZE "\n", transfer->DataLength(), isochronousData->packet_count, + pipe->MaxPacketSize(), packetSize, restSize); // Find the entry where to start inserting the first Isochronous descriptor if (isochronousData->flags & USB_ISO_ASAP || @@ -741,7 +758,7 @@ EHCI::SubmitIsochronous(Transfer *transfer) currentFrame = fNextStartingFrame; else { uint32 threshold = fThreshold; - TRACE("threshold: %ld\n", threshold); + TRACE("threshold: %" B_PRIu32 "\n", threshold); // find the first available frame with enough bandwidth. // This should always be the case, as defining the starting frame @@ -768,8 +785,8 @@ EHCI::SubmitIsochronous(Transfer *transfer) uint16 itdIndex = 0; size_t dataLength = transfer->DataLength(); void* bufferLog; - addr_t bufferPhy; - if (fStack->AllocateChunk(&bufferLog, (void**)&bufferPhy, dataLength) < B_OK) { + phys_addr_t bufferPhy; + if (fStack->AllocateChunk(&bufferLog, &bufferPhy, dataLength) < B_OK) { TRACE_ERROR("unable to allocate itd buffer\n"); delete[] isoRequest; return B_NO_MEMORY; @@ -777,7 +794,7 @@ EHCI::SubmitIsochronous(Transfer *transfer) memset(bufferLog, 0, dataLength); - addr_t currentPhy = bufferPhy; + phys_addr_t currentPhy = bufferPhy; uint32 frameCount = 0; while (dataLength > 0) { ehci_itd* itd = CreateItdDescriptor(); @@ -792,7 +809,7 @@ EHCI::SubmitIsochronous(Transfer *transfer) | (length << EHCI_ITD_TLENGTH_SHIFT) | (pg << EHCI_ITD_PG_SHIFT) | (offset << EHCI_ITD_TOFFSET_SHIFT); itd->last_token = i; - TRACE("isochronous filled slot %ld 0x%lx\n", i, itd->token[i]); + TRACE("isochronous filled slot %" B_PRId32 " 0x%" B_PRIx32 "\n", i, itd->token[i]); dataLength -= length; offset += length; if (dataLength > 0 && offset > 0xfff) { @@ -815,7 +832,8 @@ EHCI::SubmitIsochronous(Transfer *transfer) ((((pipe->MaxPacketSize() >> EHCI_ITD_MAXPACKETSIZE_LENGTH) + 1) & EHCI_ITD_MUL_MASK) << EHCI_ITD_MUL_SHIFT); - TRACE("isochronous filled itd buffer_phy[0,1,2] 0x%lx, 0x%lx 0x%lx\n", + TRACE("isochronous filled itd buffer_phy[0,1,2] 0x%" B_PRIx32 ", 0x%" + B_PRIx32 " 0x%" B_PRIx32 "\n", itd->buffer_phy[0], itd->buffer_phy[1], itd->buffer_phy[2]); if (!LockIsochronous()) @@ -905,7 +923,8 @@ EHCI::AddTo(Stack *stack) if (!sPCIModule) { status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); if (status < B_OK) { - TRACE_MODULE_ERROR("getting pci module failed! 0x%08lx\n", status); + TRACE_MODULE_ERROR("getting pci module failed! 0x%08" B_PRIx32 + "\n", status); return status; } } @@ -1178,7 +1197,7 @@ EHCI::Interrupt() uint32 status = ReadOpReg(EHCI_USBSTS) & EHCI_USBSTS_INTMASK; if ((status & fEnabledInterrupts) == 0) { if (status != 0) { - TRACE("discarding not enabled interrupts 0x%08lx\n", status); + TRACE("discarding not enabled interrupts 0x%08" B_PRIx32 "\n", status); WriteOpReg(EHCI_USBSTS, status); } @@ -1480,13 +1499,14 @@ EHCI::FinishTransfers() uint32 status = descriptor->token; if (status & EHCI_QTD_STATUS_ACTIVE) { // still in progress - TRACE("qtd (0x%08lx) still active\n", descriptor->this_phy); + TRACE("qtd (0x%08" B_PRIx32 ") still active\n", descriptor->this_phy); break; } if (status & EHCI_QTD_STATUS_ERRMASK) { // a transfer error occured - TRACE_ERROR("qtd (0x%08lx) error: 0x%08lx\n", descriptor->this_phy, status); + TRACE_ERROR("qtd (0x%" B_PRIx32 ") error: 0x%08" B_PRIx32 + "\n", descriptor->this_phy, status); uint8 errorCount = status >> EHCI_QTD_ERRCOUNT_SHIFT; errorCount &= EHCI_QTD_ERRCOUNT_MASK; @@ -1535,7 +1555,7 @@ EHCI::FinishTransfers() if (descriptor->next_phy & EHCI_ITEM_TERMINATE) { // we arrived at the last (stray) descriptor, we're done - TRACE("qtd (0x%08lx) done\n", descriptor->this_phy); + TRACE("qtd (0x%08" B_PRIx32 ") done\n", descriptor->this_phy); callbackStatus = B_OK; transferDone = true; break; @@ -1718,9 +1738,10 @@ EHCI::FinishIsochronousTransfers() ehci_itd *itd = fItdEntries[currentFrame]; - TRACE("FinishIsochronousTransfers itd %p phy 0x%lx prev (%p/0x%lx)" - " at frame %ld\n", itd, itd->this_phy, itd->prev, - itd->prev != NULL ? itd->prev->this_phy : 0, currentFrame); + TRACE("FinishIsochronousTransfers itd %p phy 0x%" B_PRIx32 + " prev (%p/0x%" B_PRIx32 ") at frame %" B_PRId32 "\n", itd, + itd->this_phy, itd->prev, itd->prev != NULL + ? itd->prev->this_phy : 0, currentFrame); if (!LockIsochronous()) continue; @@ -1728,9 +1749,10 @@ EHCI::FinishIsochronousTransfers() // Process the frame till it has isochronous descriptors in it. while (!(itd->next_phy & EHCI_ITEM_TERMINATE) && itd->prev != NULL) { TRACE("FinishIsochronousTransfers checking itd %p last_token" - " %ld\n", itd, itd->last_token); - TRACE("FinishIsochronousTransfers tokens 0x%lx 0x%lx 0x%lx " - "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", + " %" B_PRId32 "\n", itd, itd->last_token); + TRACE("FinishIsochronousTransfers tokens 0x%" B_PRIx32 " 0x%" + B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx32 + " 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx32 "\n", itd->token[0], itd->token[1], itd->token[2], itd->token[3], itd->token[4], itd->token[5], itd->token[6], itd->token[7]); if (((itd->token[itd->last_token] >> EHCI_ITD_STATUS_SHIFT) @@ -1784,7 +1806,7 @@ EHCI::FinishIsochronousTransfers() delete [] transfer->descriptors; delete transfer->transfer; fStack->FreeChunk(transfer->buffer_log, - (void *)transfer->buffer_phy, transfer->buffer_size); + (phys_addr_t)transfer->buffer_phy, transfer->buffer_size); delete transfer; transferDone = true; } else { @@ -1809,7 +1831,7 @@ ehci_qh * EHCI::CreateQueueHead() { ehci_qh *result; - void *physicalAddress; + phys_addr_t physicalAddress; if (fStack->AllocateChunk((void **)&result, &physicalAddress, sizeof(ehci_qh)) < B_OK) { TRACE_ERROR("failed to allocate queue head\n"); @@ -1889,7 +1911,7 @@ EHCI::FreeQueueHead(ehci_qh *queueHead) FreeDescriptorChain(queueHead->element_log); FreeDescriptor(queueHead->stray_log); - fStack->FreeChunk(queueHead, (void *)queueHead->this_phy, sizeof(ehci_qh)); + fStack->FreeChunk(queueHead, (phys_addr_t)queueHead->this_phy, sizeof(ehci_qh)); } @@ -2088,7 +2110,7 @@ ehci_qtd * EHCI::CreateDescriptor(size_t bufferSize, uint8 pid) { ehci_qtd *result; - void *physicalAddress; + phys_addr_t physicalAddress; if (fStack->AllocateChunk((void **)&result, &physicalAddress, sizeof(ehci_qtd)) < B_OK) { TRACE_ERROR("failed to allocate a qtd\n"); @@ -2118,7 +2140,7 @@ EHCI::CreateDescriptor(size_t bufferSize, uint8 pid) if (fStack->AllocateChunk(&result->buffer_log, &physicalAddress, bufferSize) < B_OK) { TRACE_ERROR("unable to allocate qtd buffer\n"); - fStack->FreeChunk(result, (void *)result->this_phy, sizeof(ehci_qtd)); + fStack->FreeChunk(result, (phys_addr_t)result->this_phy, sizeof(ehci_qtd)); return NULL; } @@ -2181,10 +2203,10 @@ EHCI::FreeDescriptor(ehci_qtd *descriptor) if (descriptor->buffer_log) { fStack->FreeChunk(descriptor->buffer_log, - (void *)descriptor->buffer_phy[0], descriptor->buffer_size); + (phys_addr_t)descriptor->buffer_phy[0], descriptor->buffer_size); } - fStack->FreeChunk(descriptor, (void *)descriptor->this_phy, + fStack->FreeChunk(descriptor, (phys_addr_t)descriptor->this_phy, sizeof(ehci_qtd)); } @@ -2207,7 +2229,7 @@ ehci_itd * EHCI::CreateItdDescriptor() { ehci_itd *result; - void *physicalAddress; + phys_addr_t physicalAddress; if (fStack->AllocateChunk((void **)&result, &physicalAddress, sizeof(ehci_itd)) < B_OK) { TRACE_ERROR("failed to allocate a itd\n"); @@ -2226,7 +2248,7 @@ ehci_sitd * EHCI::CreateSitdDescriptor() { ehci_sitd *result; - void *physicalAddress; + phys_addr_t physicalAddress; if (fStack->AllocateChunk((void **)&result, &physicalAddress, sizeof(ehci_sitd)) < B_OK) { TRACE_ERROR("failed to allocate a sitd\n"); @@ -2247,7 +2269,7 @@ EHCI::FreeDescriptor(ehci_itd *descriptor) if (!descriptor) return; - fStack->FreeChunk(descriptor, (void *)descriptor->this_phy, + fStack->FreeChunk(descriptor, (phys_addr_t)descriptor->this_phy, sizeof(ehci_itd)); } @@ -2258,7 +2280,7 @@ EHCI::FreeDescriptor(ehci_sitd *descriptor) if (!descriptor) return; - fStack->FreeChunk(descriptor, (void *)descriptor->this_phy, + fStack->FreeChunk(descriptor, (phys_addr_t)descriptor->this_phy, sizeof(ehci_sitd)); } @@ -2558,7 +2580,8 @@ EHCI::ReadIsochronousDescriptorChain(isochronous_transfer_data *transfer) } } - TRACE("ReadIsochronousDescriptorChain packet count %ld\n", packet); + TRACE("ReadIsochronousDescriptorChain packet count %" B_PRId32 "\n", + packet); return totalLength; } diff --git a/src/add-ons/kernel/busses/usb/ehci.h b/src/add-ons/kernel/busses/usb/ehci.h index 8692939b74..4680e2bc3d 100644 --- a/src/add-ons/kernel/busses/usb/ehci.h +++ b/src/add-ons/kernel/busses/usb/ehci.h @@ -199,7 +199,7 @@ static pci_module_info * sPCIModule; // Periodic transfer framelist and interrupt entries area_id fPeriodicFrameListArea; - addr_t * fPeriodicFrameList; + uint32 * fPeriodicFrameList; interrupt_entry * fInterruptEntries; ehci_itd ** fItdEntries; ehci_sitd ** fSitdEntries; diff --git a/src/add-ons/kernel/busses/usb/ehci_hardware.h b/src/add-ons/kernel/busses/usb/ehci_hardware.h index 876414d184..90579f67c2 100644 --- a/src/add-ons/kernel/busses/usb/ehci_hardware.h +++ b/src/add-ons/kernel/busses/usb/ehci_hardware.h @@ -130,13 +130,13 @@ // Isochronous (High-Speed) Transfer Descriptors (iTD, EHCI Spec 3.2) typedef struct ehci_itd { // Hardware Part - addr_t next_phy; + uint32 next_phy; uint32 token[8]; - addr_t buffer_phy[7]; - addr_t ext_buffer_phy[7]; + uint32 buffer_phy[7]; + uint32 ext_buffer_phy[7]; // Software Part - addr_t this_phy; + uint32 this_phy; struct ehci_itd *next; struct ehci_itd *prev; uint32 last_token; @@ -172,7 +172,7 @@ typedef struct ehci_itd { // Split Transaction Isochronous Transfer Descriptors (siTD, EHCI Spec 3.3) typedef struct ehci_sitd { // Hardware Part - addr_t next_phy; + uint32 next_phy; uint8 port_number; uint8 hub_address; uint8 endpoint; @@ -183,34 +183,34 @@ typedef struct ehci_sitd { uint16 transfer_length; uint8 cprogmask; uint8 status; - addr_t buffer_phy[2]; - addr_t back_phy; - addr_t ext_buffer_phy[2]; + uint32 buffer_phy[2]; + uint32 back_phy; + uint32 ext_buffer_phy[2]; // Software Part - addr_t this_phy; + uint32 this_phy; struct ehci_sitd *next; struct ehci_sitd *prev; size_t buffer_size; void *buffer_log; -} ehci_sitd; +} _PACKED ehci_sitd; // Queue Element Transfer Descriptors (qTD, EHCI Spec 3.5) typedef struct ehci_qtd { // Hardware Part - addr_t next_phy; - addr_t alt_next_phy; + uint32 next_phy; + uint32 alt_next_phy; uint32 token; - addr_t buffer_phy[5]; - addr_t ext_buffer_phy[5]; + uint32 buffer_phy[5]; + uint32 ext_buffer_phy[5]; // Software Part - addr_t this_phy; + uint32 this_phy; struct ehci_qtd *next_log; void *alt_next_log; size_t buffer_size; void *buffer_log; -} ehci_qtd; +} _PACKED ehci_qtd; #define EHCI_QTD_DATA_TOGGLE (1 << 31) @@ -244,21 +244,21 @@ typedef struct ehci_qtd { // Queue Head (QH, EHCI Spec 3.6) typedef struct ehci_qh { // Hardware Part - addr_t next_phy; + uint32 next_phy; uint32 endpoint_chars; uint32 endpoint_caps; - addr_t current_qtd_phy; + uint32 current_qtd_phy; struct { - addr_t next_phy; - addr_t alt_next_phy; + uint32 next_phy; + uint32 alt_next_phy; uint32 token; - addr_t buffer_phy[5]; - addr_t ext_buffer_phy[5]; + uint32 buffer_phy[5]; + uint32 ext_buffer_phy[5]; } overlay; // Software Part - addr_t this_phy; + uint32 this_phy; struct ehci_qh *next_log; struct ehci_qh *prev_log; ehci_qtd *stray_log; @@ -268,17 +268,30 @@ typedef struct ehci_qh { typedef struct { ehci_qh queue_head; +#ifdef B_HAIKU_64_BIT + uint32 padding[6]; +#else uint32 padding[2]; +#endif } interrupt_entry; typedef struct { ehci_itd itd; +#ifdef B_HAIKU_64_BIT + uint32 padding[1]; // align on 128 +#else uint32 padding[5]; // align on 128 +#endif } itd_entry; typedef struct { ehci_sitd sitd; - uint32 padding[2]; // align on 64 + +#ifdef B_HAIKU_64_BIT + uint32 padding[14]; // align on 64 +#else + uint32 padding[2]; // align on 64 +#endif } sitd_entry; #define EHCI_INTERRUPT_ENTRIES_COUNT (7 + 1) // (log 128 / log 2) + 1 diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index 73bc7692a1..670192ee8c 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -101,7 +101,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) uint32 offset = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_base_registers, 4); offset &= PCI_address_memory_32_mask; - TRACE_ALWAYS("iospace offset: 0x%lx\n", offset); + TRACE_ALWAYS("iospace offset: 0x%" B_PRIx32 "\n", offset); fRegisterArea = map_physical_memory("OHCI memory mapped registers", offset, B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, @@ -123,7 +123,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) return; } - void *hccaPhysicalAddress; + phys_addr_t hccaPhysicalAddress; fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress, sizeof(ohci_hcca), "USB OHCI Host Controller Communication Area"); @@ -167,7 +167,8 @@ OHCI::OHCI(pci_info *info, Stack *stack) for (int32 i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { fInterruptEndpoints[i] = _AllocateEndpoint(); if (!fInterruptEndpoints[i]) { - TRACE_ERROR("failed to allocate interrupt endpoint %ld", i); + TRACE_ERROR("failed to allocate interrupt endpoint %" B_PRId32 "\n", + i); while (--i >= 0) _FreeEndpoint(fInterruptEndpoints[i]); _FreeEndpoint(fDummyBulk); @@ -388,7 +389,7 @@ OHCI::Start() uint32 control = _ReadReg(OHCI_CONTROL); if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK) != OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) { - TRACE_ERROR("controller not started (0x%08lx)!\n", control); + TRACE_ERROR("controller not started (0x%08" B_PRIx32 ")!\n", control); return B_ERROR; } else TRACE("controller is operational!\n"); @@ -435,7 +436,8 @@ OHCI::SubmitTransfer(Transfer *transfer) return _SubmitIsochronousTransfer(transfer); } - TRACE_ERROR("tried to submit transfer for unknown pipe type %lu\n", type); + TRACE_ERROR("tried to submit transfer for unknown pipe type %" B_PRIu32 "\n", + type); return B_ERROR; } @@ -511,7 +513,7 @@ OHCI::CancelQueuedTransfers(Pipe *pipe, bool force) status_t OHCI::NotifyPipeChange(Pipe *pipe, usb_change change) { - TRACE("pipe change %d for pipe 0x%08lx\n", change, (uint32)pipe); + TRACE("pipe change %d for pipe %p\n", change, pipe); if (pipe->DeviceAddress() == fRootHubAddress) { // no need to insert/remove endpoint descriptors for the root hub return B_OK; @@ -550,7 +552,8 @@ OHCI::AddTo(Stack *stack) if (!sPCIModule) { status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); if (status < B_OK) { - TRACE_MODULE_ERROR("getting pci module failed! 0x%08lx\n", status); + TRACE_MODULE_ERROR("getting pci module failed! 0x%08" B_PRIx32 "\n", + status); return status; } } @@ -972,7 +975,7 @@ OHCI::_FinishTransfers() // was halted because of this td, but we do not need // to know, as when it was halted by another td this // still ensures that this td was handled before). - TRACE_ERROR("td error: 0x%08lx\n", status); + TRACE_ERROR("td error: 0x%08" B_PRIx32 "\n", status); switch (status) { case OHCI_TD_CONDITION_CRC_ERROR: @@ -1082,7 +1085,7 @@ OHCI::_FinishTransfers() // break the descriptor chain on the last descriptor transfer->last_descriptor->next_logical_descriptor = NULL; - TRACE("transfer %p done with status 0x%08lx\n", + TRACE("transfer %p done with status 0x%08" B_PRIx32 "\n", transfer, callbackStatus); // if canceled the callback has already been called @@ -1372,7 +1375,7 @@ ohci_endpoint_descriptor * OHCI::_AllocateEndpoint() { ohci_endpoint_descriptor *endpoint; - void *physicalAddress; + phys_addr_t physicalAddress; mutex *lock = (mutex *)malloc(sizeof(mutex)); if (lock == NULL) { @@ -1391,7 +1394,7 @@ OHCI::_AllocateEndpoint() mutex_init(lock, "ohci endpoint lock"); endpoint->flags = OHCI_ENDPOINT_SKIP; - endpoint->physical_address = (addr_t)physicalAddress; + endpoint->physical_address = (uint32)physicalAddress; endpoint->head_physical_descriptor = 0; endpoint->tail_logical_descriptor = NULL; endpoint->tail_physical_descriptor = 0; @@ -1411,7 +1414,7 @@ OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) mutex_destroy(endpoint->lock); free(endpoint->lock); - fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address, + fStack->FreeChunk((void *)endpoint, endpoint->physical_address, sizeof(ohci_endpoint_descriptor)); } @@ -1568,7 +1571,7 @@ ohci_general_td * OHCI::_CreateGeneralDescriptor(size_t bufferSize) { ohci_general_td *descriptor; - void *physicalAddress; + phys_addr_t physicalAddress; if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, sizeof(ohci_general_td)) != B_OK) { @@ -1576,7 +1579,7 @@ OHCI::_CreateGeneralDescriptor(size_t bufferSize) return NULL; } - descriptor->physical_address = (addr_t)physicalAddress; + descriptor->physical_address = (uint32)physicalAddress; descriptor->next_physical_descriptor = 0; descriptor->next_logical_descriptor = NULL; descriptor->buffer_size = bufferSize; @@ -1588,12 +1591,13 @@ OHCI::_CreateGeneralDescriptor(size_t bufferSize) } if (fStack->AllocateChunk(&descriptor->buffer_logical, - (void **)&descriptor->buffer_physical, bufferSize) != B_OK) { + &physicalAddress, bufferSize) != B_OK) { TRACE_ERROR("failed to allocate space for buffer\n"); - fStack->FreeChunk(descriptor, (void *)descriptor->physical_address, + fStack->FreeChunk(descriptor, descriptor->physical_address, sizeof(ohci_general_td)); return NULL; } + descriptor->buffer_physical = physicalAddress; descriptor->last_physical_byte_address = descriptor->buffer_physical + bufferSize - 1; @@ -1609,10 +1613,10 @@ OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor) if (descriptor->buffer_logical) { fStack->FreeChunk(descriptor->buffer_logical, - (void *)descriptor->buffer_physical, descriptor->buffer_size); + descriptor->buffer_physical, descriptor->buffer_size); } - fStack->FreeChunk((void *)descriptor, (void *)descriptor->physical_address, + fStack->FreeChunk((void *)descriptor, descriptor->physical_address, sizeof(ohci_general_td)); } @@ -1865,11 +1869,11 @@ void OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint) { TRACE_ALWAYS("endpoint %p\n", endpoint); - dprintf("\tflags........... 0x%08lx\n", endpoint->flags); - dprintf("\ttail_physical... 0x%08lx\n", endpoint->tail_physical_descriptor); - dprintf("\thead_physical... 0x%08lx\n", endpoint->head_physical_descriptor); - dprintf("\tnext_physical... 0x%08lx\n", endpoint->next_physical_endpoint); - dprintf("\tphysical........ 0x%08lx\n", endpoint->physical_address); + dprintf("\tflags........... 0x%08" B_PRIx32 "\n", endpoint->flags); + dprintf("\ttail_physical... 0x%08" B_PRIx32 "\n", endpoint->tail_physical_descriptor); + dprintf("\thead_physical... 0x%08" B_PRIx32 "\n", endpoint->head_physical_descriptor); + dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", endpoint->next_physical_endpoint); + dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", endpoint->physical_address); dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor); dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint); } @@ -1880,11 +1884,11 @@ OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor) { while (topDescriptor) { TRACE_ALWAYS("descriptor %p\n", topDescriptor); - dprintf("\tflags........... 0x%08lx\n", topDescriptor->flags); - dprintf("\tbuffer_physical. 0x%08lx\n", topDescriptor->buffer_physical); - dprintf("\tnext_physical... 0x%08lx\n", topDescriptor->next_physical_descriptor); - dprintf("\tlast_byte....... 0x%08lx\n", topDescriptor->last_physical_byte_address); - dprintf("\tphysical........ 0x%08lx\n", topDescriptor->physical_address); + dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags); + dprintf("\tbuffer_physical. 0x%08" B_PRIx32 "\n", topDescriptor->buffer_physical); + dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor); + dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_physical_byte_address); + dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address); dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size); dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical); dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor); diff --git a/src/add-ons/kernel/busses/usb/ohci_hardware.h b/src/add-ons/kernel/busses/usb/ohci_hardware.h index e98575f873..308a27b182 100644 --- a/src/add-ons/kernel/busses/usb/ohci_hardware.h +++ b/src/add-ons/kernel/busses/usb/ohci_hardware.h @@ -301,7 +301,7 @@ typedef struct { uint32 head_physical_descriptor; // Queue head physical pointer uint32 next_physical_endpoint; // Physical pointer to the next endpoint // Software part - addr_t physical_address; // Physical pointer to this address + uint32 physical_address; // Physical pointer to this address void *tail_logical_descriptor; // Queue tail logical pointer void *next_logical_endpoint; // Logical pointer to the next endpoint mutex *lock; // Protects tail changes and checks @@ -340,7 +340,7 @@ typedef struct { uint32 next_physical_descriptor; // Physical pointer next descriptor uint32 last_physical_byte_address; // Physical pointer to buffer end // Software part - addr_t physical_address; // Physical address of this descriptor + uint32 physical_address; // Physical address of this descriptor size_t buffer_size; // Size of the buffer void *buffer_logical; // Logical pointer to the buffer void *next_logical_descriptor; // Logical pointer next descriptor @@ -395,7 +395,7 @@ typedef struct { uint32 last_byte_address; // Physical buffer end uint16 offset[OHCI_ITD_NOFFSET]; // Buffer offsets // Software part - addr_t physical_address; // Physical address of this descriptor + uint32 physical_address; // Physical address of this descriptor void *next_logical_descriptor; // Logical pointer next descriptor void *next_done_descriptor; // Used for collision in the hash table } ohci_isochronous_td; diff --git a/src/add-ons/kernel/busses/usb/uhci.cpp b/src/add-ons/kernel/busses/usb/uhci.cpp index db3de2c9df..7463fb5d5b 100644 --- a/src/add-ons/kernel/busses/usb/uhci.cpp +++ b/src/add-ons/kernel/busses/usb/uhci.cpp @@ -146,7 +146,8 @@ void print_descriptor_chain(uhci_td *descriptor) { while (descriptor) { - dprintf("ph: 0x%08lx; lp: 0x%08lx; vf: %s; q: %s; t: %s; st: 0x%08lx; to: 0x%08lx\n", + dprintf("ph: 0x%08" B_PRIx32 "; lp: 0x%08" B_PRIx32 "; vf: %s; q: %s; " + "t: %s; st: 0x%08" B_PRIx32 "; to: 0x%08" B_PRIx32 "\n", descriptor->this_phy & 0xffffffff, descriptor->link_phy & 0xfffffff0, descriptor->link_phy & 0x4 ? "y" : "n", descriptor->link_phy & 0x2 ? "qh" : "td", @@ -174,13 +175,13 @@ Queue::Queue(Stack *stack) mutex_init(&fLock, "uhci queue lock"); - void *physicalAddress; + phys_addr_t physicalAddress; fStatus = fStack->AllocateChunk((void **)&fQueueHead, &physicalAddress, sizeof(uhci_qh)); if (fStatus < B_OK) return; - fQueueHead->this_phy = (addr_t)physicalAddress; + fQueueHead->this_phy = (uint32)physicalAddress; fQueueHead->element_phy = QH_TERMINATE; fStrayDescriptor = NULL; @@ -193,10 +194,10 @@ Queue::~Queue() Lock(); mutex_destroy(&fLock); - fStack->FreeChunk(fQueueHead, (void *)fQueueHead->this_phy, sizeof(uhci_qh)); + fStack->FreeChunk(fQueueHead, fQueueHead->this_phy, sizeof(uhci_qh)); if (fStrayDescriptor) - fStack->FreeChunk(fStrayDescriptor, (void *)fStrayDescriptor->this_phy, + fStack->FreeChunk(fStrayDescriptor, fStrayDescriptor->this_phy, sizeof(uhci_td)); } @@ -244,7 +245,7 @@ Queue::TerminateByStrayDescriptor() { // According to the *BSD USB sources, there needs to be a stray transfer // descriptor in order to get some chipset to work nicely (like the PIIX). - void *physicalAddress; + phys_addr_t physicalAddress; status_t result = fStack->AllocateChunk((void **)&fStrayDescriptor, &physicalAddress, sizeof(uhci_td)); if (result < B_OK) { @@ -253,7 +254,7 @@ Queue::TerminateByStrayDescriptor() } fStrayDescriptor->status = 0; - fStrayDescriptor->this_phy = (addr_t)physicalAddress; + fStrayDescriptor->this_phy = (uint32)physicalAddress; fStrayDescriptor->link_phy = TD_TERMINATE; fStrayDescriptor->link_log = NULL; fStrayDescriptor->buffer_phy = 0; @@ -263,7 +264,7 @@ Queue::TerminateByStrayDescriptor() | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | TD_TOKEN_IN; if (!Lock()) { - fStack->FreeChunk(fStrayDescriptor, (void *)fStrayDescriptor->this_phy, + fStack->FreeChunk(fStrayDescriptor, fStrayDescriptor->this_phy, sizeof(uhci_td)); return B_ERROR; } @@ -346,7 +347,7 @@ Queue::RemoveTransfer(uhci_qh *transfer, bool lock) } -addr_t +uint32 Queue::PhysicalAddress() { return fQueueHead->this_phy; @@ -358,8 +359,14 @@ Queue::PrintToStream() { #ifdef TRACE_USB TRACE("queue:\n"); - dprintf("link phy: 0x%08lx; link type: %s; terminate: %s\n", fQueueHead->link_phy & 0xfff0, fQueueHead->link_phy & 0x0002 ? "QH" : "TD", fQueueHead->link_phy & 0x0001 ? "yes" : "no"); - dprintf("elem phy: 0x%08lx; elem type: %s; terminate: %s\n", fQueueHead->element_phy & 0xfff0, fQueueHead->element_phy & 0x0002 ? "QH" : "TD", fQueueHead->element_phy & 0x0001 ? "yes" : "no"); + dprintf("link phy: 0x%08" B_PRIx32 "; link type: %s; terminate: %s\n", + fQueueHead->link_phy & 0xfff0, + fQueueHead->link_phy & 0x0002 ? "QH" : "TD", + fQueueHead->link_phy & 0x0001 ? "yes" : "no"); + dprintf("elem phy: 0x%08" B_PRIx32 "; elem type: %s; terminate: %s\n", + fQueueHead->element_phy & 0xfff0, + fQueueHead->element_phy & 0x0002 ? "QH" : "TD", + fQueueHead->element_phy & 0x0001 ? "yes" : "no"); #endif } @@ -413,11 +420,11 @@ UHCI::UHCI(pci_info *info, Stack *stack) fRegisterBase = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_memory_base, 4); fRegisterBase &= PCI_address_io_mask; - TRACE("iospace offset: 0x%08lx\n", fRegisterBase); + TRACE("iospace offset: 0x%08" B_PRIx32 "\n", fRegisterBase); if (fRegisterBase == 0) { fRegisterBase = fPCIInfo->u.h0.base_registers[0]; - TRACE_ALWAYS("register base: 0x%08lx\n", fRegisterBase); + TRACE_ALWAYS("register base: 0x%08" B_PRIx32 "\n", fRegisterBase); } // enable pci address access @@ -444,9 +451,9 @@ UHCI::UHCI(pci_info *info, Stack *stack) } // Setup the frame list - void *physicalAddress; - fFrameArea = fStack->AllocateArea((void **)&fFrameList, - (void **)&physicalAddress, 4096, "USB UHCI framelist"); + phys_addr_t physicalAddress; + fFrameArea = fStack->AllocateArea((void **)&fFrameList, &physicalAddress, + 4096, "USB UHCI framelist"); if (fFrameArea < B_OK) { TRACE_ERROR("unable to create an area for the frame pointer list\n"); @@ -641,7 +648,7 @@ UHCI::Start() bool running = false; for (int32 i = 0; i < 10; i++) { uint16 status = ReadReg16(UHCI_USBSTS); - TRACE("current loop %ld, status 0x%04x\n", i, status); + TRACE("current loop %" B_PRId32 ", status 0x%04x\n", i, status); if (status & UHCI_USBSTS_HCHALT) snooze(10000); @@ -1149,7 +1156,7 @@ UHCI::SubmitIsochronous(Transfer *transfer) } } - TRACE("isochronous submitted size=%ld bytes, TDs=%ld, " + TRACE("isochronous submitted size=%ld bytes, TDs=%" B_PRId32 ", " "packetSize=%ld, restSize=%ld\n", transfer->DataLength(), isochronousData->packet_count, packetSize, restSize); @@ -1328,8 +1335,8 @@ UHCI::FinishTransfers() continue; TRACE("finishing transfers (first transfer: 0x%08lx; last" - " transfer: 0x%08lx)\n", (uint32)fFirstTransfer, - (uint32)fLastTransfer); + " transfer: 0x%08lx)\n", (addr_t)fFirstTransfer, + (addr_t)fLastTransfer); transfer_data *lastTransfer = NULL; transfer_data *transfer = fFirstTransfer; Unlock(); @@ -1343,15 +1350,16 @@ UHCI::FinishTransfers() uint32 status = descriptor->status; if (status & TD_STATUS_ACTIVE) { // still in progress - TRACE("td (0x%08lx) still active\n", descriptor->this_phy); + TRACE("td (0x%08" B_PRIx32 ") still active\n", + descriptor->this_phy); break; } if (status & TD_ERROR_MASK) { // an error occured - TRACE_ERROR("td (0x%08lx) error: status: 0x%08lx;" - " token: 0x%08lx;\n", descriptor->this_phy, status, - descriptor->token); + TRACE_ERROR("td (0x%08" B_PRIx32 ") error: status: 0x%08" + B_PRIx32 "; token: 0x%08" B_PRIx32 ";\n", + descriptor->this_phy, status, descriptor->token); uint8 errorCount = status >> TD_ERROR_COUNT_SHIFT; errorCount &= TD_ERROR_COUNT_MASK; @@ -1396,7 +1404,7 @@ UHCI::FinishTransfers() && uhci_td_actual_length(descriptor) < uhci_td_maximum_length(descriptor))) { // all descriptors are done, or we have a short packet - TRACE("td (0x%08lx) ok\n", descriptor->this_phy); + TRACE("td (0x%08" B_PRIx32 ") ok\n", descriptor->this_phy); callbackStatus = B_OK; transferDone = true; break; @@ -1919,8 +1927,8 @@ UHCI::AddTo(Stack *stack) if (!sPCIModule) { status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); if (status < B_OK) { - TRACE_MODULE_ERROR("AddTo(): getting pci module failed! 0x%08lx\n", - status); + TRACE_MODULE_ERROR("AddTo(): getting pci module failed! 0x%08" + B_PRIx32 "\n", status); return status; } } @@ -1956,8 +1964,8 @@ UHCI::AddTo(Stack *stack) } if (bus->InitCheck() < B_OK) { - TRACE_MODULE_ERROR("AddTo(): InitCheck() failed 0x%08lx\n", - bus->InitCheck()); + TRACE_MODULE_ERROR("AddTo(): InitCheck() failed 0x%08" B_PRIx32 + "\n", bus->InitCheck()); delete bus; continue; } @@ -2027,12 +2035,12 @@ uhci_qh * UHCI::CreateTransferQueue(uhci_td *descriptor) { uhci_qh *queueHead; - void *physicalAddress; - if (fStack->AllocateChunk((void **)&queueHead, - &physicalAddress, sizeof(uhci_qh)) < B_OK) + phys_addr_t physicalAddress; + if (fStack->AllocateChunk((void **)&queueHead, &physicalAddress, + sizeof(uhci_qh)) < B_OK) return NULL; - queueHead->this_phy = (addr_t)physicalAddress; + queueHead->this_phy = (uint32)physicalAddress; queueHead->element_phy = descriptor->this_phy; return queueHead; } @@ -2044,7 +2052,7 @@ UHCI::FreeTransferQueue(uhci_qh *queueHead) if (!queueHead) return; - fStack->FreeChunk(queueHead, (void *)queueHead->this_phy, sizeof(uhci_qh)); + fStack->FreeChunk(queueHead, queueHead->this_phy, sizeof(uhci_qh)); } @@ -2052,7 +2060,7 @@ uhci_td * UHCI::CreateDescriptor(Pipe *pipe, uint8 direction, size_t bufferSize) { uhci_td *result; - void *physicalAddress; + phys_addr_t physicalAddress; if (fStack->AllocateChunk((void **)&result, &physicalAddress, sizeof(uhci_td)) < B_OK) { @@ -2060,7 +2068,7 @@ UHCI::CreateDescriptor(Pipe *pipe, uint8 direction, size_t bufferSize) return NULL; } - result->this_phy = (addr_t)physicalAddress; + result->this_phy = (uint32)physicalAddress; result->status = TD_STATUS_ACTIVE; if (pipe->Type() & USB_OBJECT_ISO_PIPE) result->status |= TD_CONTROL_ISOCHRONOUS; @@ -2090,12 +2098,13 @@ UHCI::CreateDescriptor(Pipe *pipe, uint8 direction, size_t bufferSize) return result; } - if (fStack->AllocateChunk(&result->buffer_log, (void **)&result->buffer_phy, + if (fStack->AllocateChunk(&result->buffer_log, &physicalAddress, bufferSize) < B_OK) { TRACE_ERROR("unable to allocate space for the buffer\n"); - fStack->FreeChunk(result, (void *)result->this_phy, sizeof(uhci_td)); + fStack->FreeChunk(result, result->this_phy, sizeof(uhci_td)); return NULL; } + result->buffer_phy = physicalAddress; return result; } @@ -2150,10 +2159,10 @@ UHCI::FreeDescriptor(uhci_td *descriptor) if (descriptor->buffer_log) { fStack->FreeChunk(descriptor->buffer_log, - (void *)descriptor->buffer_phy, descriptor->buffer_size); + descriptor->buffer_phy, descriptor->buffer_size); } - fStack->FreeChunk(descriptor, (void *)descriptor->this_phy, sizeof(uhci_td)); + fStack->FreeChunk(descriptor, descriptor->this_phy, sizeof(uhci_td)); } diff --git a/src/add-ons/kernel/busses/usb/uhci.h b/src/add-ons/kernel/busses/usb/uhci.h index ec2588e60e..a0c2b892de 100644 --- a/src/add-ons/kernel/busses/usb/uhci.h +++ b/src/add-ons/kernel/busses/usb/uhci.h @@ -45,7 +45,7 @@ public: status_t RemoveTransfer(uhci_qh *transfer, bool lock = true); - addr_t PhysicalAddress(); + uint32 PhysicalAddress(); void PrintToStream(); diff --git a/src/add-ons/kernel/busses/usb/uhci_hardware.h b/src/add-ons/kernel/busses/usb/uhci_hardware.h index 6ff3def43d..5398425326 100644 --- a/src/add-ons/kernel/busses/usb/uhci_hardware.h +++ b/src/add-ons/kernel/busses/usb/uhci_hardware.h @@ -92,7 +92,7 @@ typedef struct uint32 token; // Contains the packet header (where it needs to be sent) uint32 buffer_phy; // A pointer to the buffer with the actual packet // Software part - addr_t this_phy; // A physical pointer to this address + uint32 this_phy; // A physical pointer to this address void *link_log; // Pointer to the next logical TD/QT void *buffer_log; // Pointer to the logical buffer size_t buffer_size; // Size of the buffer @@ -167,7 +167,7 @@ typedef struct uint32 link_phy; // Link to the next TD/QH uint32 element_phy; // Pointer to the first element in the queue // Software part - addr_t this_phy; // The physical pointer to this address + uint32 this_phy; // The physical pointer to this address void *link_log; // Pointer to the next logical TD/QH } uhci_qh; diff --git a/src/add-ons/kernel/console/vga_text/Jamfile b/src/add-ons/kernel/console/vga_text/Jamfile index 4e697e891a..8deb5694a4 100644 --- a/src/add-ons/kernel/console/vga_text/Jamfile +++ b/src/add-ons/kernel/console/vga_text/Jamfile @@ -1,6 +1,6 @@ SubDir HAIKU_TOP src add-ons kernel console vga_text ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] +UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; KernelAddon vga_text : diff --git a/src/add-ons/kernel/cpu/Jamfile b/src/add-ons/kernel/cpu/Jamfile index 8c8a5616e9..89decfdb70 100644 --- a/src/add-ons/kernel/cpu/Jamfile +++ b/src/add-ons/kernel/cpu/Jamfile @@ -1,3 +1,3 @@ SubDir HAIKU_TOP src add-ons kernel cpu ; -SubInclude HAIKU_TOP src add-ons kernel cpu $(TARGET_ARCH) ; +SubInclude HAIKU_TOP src add-ons kernel cpu $(TARGET_KERNEL_ARCH) ; diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp index f2a65fb66e..f5873ff361 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp @@ -185,8 +185,8 @@ test_capacity(cd_driver_info *info) } if (info->capacity != info->original_capacity) { - dprintf("scsi_cd: adjusted capacity from %llu to %llu blocks.\n", - info->original_capacity, info->capacity); + dprintf("scsi_cd: adjusted capacity from %" B_PRIu64 " to %" B_PRIu64 + " blocks.\n", info->original_capacity, info->capacity); } return B_OK; @@ -980,7 +980,8 @@ cd_set_capacity(cd_driver_info* info, uint64 capacity, uint32 blockSize) } if (info->block_size != 0) { - dprintf("old %ld, new %ld\n", info->block_size, blockSize); + dprintf("old %" B_PRId32 ", new %" B_PRId32 "\n", info->block_size, + blockSize); panic("updating DMAResource not yet implemented..."); } diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp index 655ffc3728..18ebc55906 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp @@ -411,7 +411,8 @@ das_set_capacity(das_driver_info* info, uint64 capacity, uint32 blockSize) if (info->block_size != blockSize) { if (info->block_size != 0) { - dprintf("old %ld, new %ld\n", info->block_size, blockSize); + dprintf("old %" B_PRId32 ", new %" B_PRId32 "\n", info->block_size, + blockSize); panic("updating DMAResource not yet implemented..."); } diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index c5c82b1bce..b01e828cca 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -23,7 +23,7 @@ #define DRIVER_NAME "usb_disk" #define DEVICE_NAME_BASE "disk/usb/" -#define DEVICE_NAME DEVICE_NAME_BASE"%ld/%d/raw" +#define DEVICE_NAME DEVICE_NAME_BASE"%" B_PRIu32 "/%d/raw" //#define TRACE_USB_DISK @@ -135,7 +135,7 @@ status_t usb_disk_receive_csw(disk_device *device, command_status_wrapper *status); status_t usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, uint32 logicalBlockAddress, - uint16 transferLength, void *data, uint32 *dataLength, + uint16 transferLength, void *data, size_t *dataLength, bool directionIn); status_t usb_disk_request_sense(device_lun *lun); @@ -264,7 +264,7 @@ usb_disk_receive_csw(disk_device *device, command_status_wrapper *status) status_t usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, uint32 logicalBlockAddress, uint16 transferLength, void *data, - uint32 *dataLength, bool directionIn) + size_t *dataLength, bool directionIn) { TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %lu; tlen: %u; data: " "%p; dlen: %p (%lu); in: %c\n", @@ -432,7 +432,7 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, status_t usb_disk_request_sense(device_lun *lun) { - uint32 dataLength = sizeof(scsi_request_sense_6_parameter); + size_t dataLength = sizeof(scsi_request_sense_6_parameter); scsi_request_sense_6_parameter parameter; status_t result = usb_disk_operation(lun, SCSI_REQUEST_SENSE_6, 6, 0, dataLength, ¶meter, &dataLength, true); @@ -497,7 +497,7 @@ usb_disk_request_sense(device_lun *lun) status_t usb_disk_mode_sense(device_lun *lun) { - uint32 dataLength = sizeof(scsi_mode_sense_6_parameter); + size_t dataLength = sizeof(scsi_mode_sense_6_parameter); scsi_mode_sense_6_parameter parameter; status_t result = usb_disk_operation(lun, SCSI_MODE_SENSE_6, 6, SCSI_MODE_PAGE_DEVICE_CONFIGURATION, dataLength, ¶meter, @@ -543,7 +543,7 @@ usb_disk_test_unit_ready(device_lun *lun) status_t usb_disk_inquiry(device_lun *lun) { - uint32 dataLength = sizeof(scsi_inquiry_6_parameter); + size_t dataLength = sizeof(scsi_inquiry_6_parameter); scsi_inquiry_6_parameter parameter; status_t result = B_ERROR; for (uint32 tries = 0; tries < 3; tries++) { @@ -591,7 +591,7 @@ usb_disk_reset_capacity(device_lun *lun) status_t usb_disk_update_capacity(device_lun *lun) { - uint32 dataLength = sizeof(scsi_read_capacity_10_parameter); + size_t dataLength = sizeof(scsi_read_capacity_10_parameter); scsi_read_capacity_10_parameter parameter; status_t result = B_ERROR; @@ -1131,7 +1131,7 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) #endif default: - TRACE_ALWAYS("unhandled ioctl %ld\n", op); + TRACE_ALWAYS("unhandled ioctl %" B_PRId32 "\n", op); break; } @@ -1182,7 +1182,7 @@ usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length) } *length = 0; - TRACE_ALWAYS("read fails with 0x%08lx\n", result); + TRACE_ALWAYS("read fails with 0x%08" B_PRIx32 "\n", result); return result; } @@ -1233,7 +1233,7 @@ usb_disk_write(void *cookie, off_t position, const void *buffer, } *length = 0; - TRACE_ALWAYS("write fails with 0x%08lx\n", result); + TRACE_ALWAYS("write fails with 0x%08" B_PRIx32 "\n", result); return result; } @@ -1275,7 +1275,7 @@ init_driver() status_t result = get_module(B_USB_MODULE_NAME, (module_info **)&gUSBModule); if (result < B_OK) { - TRACE_ALWAYS("getting module failed 0x%08lx\n", result); + TRACE_ALWAYS("getting module failed 0x%08" B_PRIx32 "\n", result); mutex_destroy(&gDeviceListLock); return result; } diff --git a/src/add-ons/kernel/drivers/graphics/3dfx/driver.cpp b/src/add-ons/kernel/drivers/graphics/3dfx/driver.cpp index 4bf33b7ffe..70ca7220bf 100644 --- a/src/add-ons/kernel/drivers/graphics/3dfx/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/3dfx/driver.cpp @@ -14,7 +14,6 @@ #include #ifdef __HAIKU__ #include -#include #endif // __HAIKU__ #include "DriverInterface.h" diff --git a/src/add-ons/kernel/drivers/graphics/ati/driver.cpp b/src/add-ons/kernel/drivers/graphics/ati/driver.cpp index b8eca53943..cc302c6b04 100644 --- a/src/add-ons/kernel/drivers/graphics/ati/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/ati/driver.cpp @@ -8,12 +8,12 @@ #include #include +#include #include #include #include #include #include -#include #include "DriverInterface.h" @@ -249,52 +249,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw) #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) - vm86_state vmState; - - status_t status = vm86_prepare(&vmState, 0x2000); + bios_module_info* biosModule; + status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); if (status != B_OK) { - TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n", + TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n", status); return status; } - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 0; // 0 = report DDC service - vmState.regs.ecx = 0; - vmState.regs.es = 0; - vmState.regs.edi = 0; + bios_state* state; + status = biosModule->prepare(&state); + if (status != B_OK) { + TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n", + status); + put_module(B_BIOS_MODULE_NAME); + return status; + } - status = vm86_do_int(&vmState, 0x10); + bios_regs regs = {}; + regs.eax = 0x4f15; + regs.ebx = 0; // 0 = report DDC service + regs.ecx = 0; + regs.es = 0; + regs.edi = 0; + + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { // AH contains the error code, and AL determines whether or not the // function is supported. - if (vmState.regs.eax != 0x4f) + if (regs.eax != 0x4f) status = B_NOT_SUPPORTED; // Test if DDC is supported by the monitor. - if ((vmState.regs.ebx & 3) == 0) + if ((regs.ebx & 3) == 0) status = B_NOT_SUPPORTED; } if (status == B_OK) { - // According to the author of the vm86 functions, the address of any - // object to receive data must be >= 0x1000 and within the ram size - // specified in the second argument of the vm86_prepare() call above. - // Thus, the address of the struct to receive the EDID info is set to - // 0x1000. + edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state, + sizeof(edid1_raw)); + if (edid == NULL) { + status = B_NO_MEMORY; + goto out; + } - edid1_raw* edid = (edid1_raw*)0x1000; + regs.eax = 0x4f15; + regs.ebx = 1; // 1 = read EDID + regs.ecx = 0; + regs.edx = 0; + regs.es = ADDRESS_SEGMENT(edid); + regs.edi = ADDRESS_OFFSET(edid); - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 1; // 1 = read EDID - vmState.regs.ecx = 0; - vmState.regs.edx = 0; - vmState.regs.es = ADDRESS_SEGMENT(edid); - vmState.regs.edi = ADDRESS_OFFSET(edid); - - status = vm86_do_int(&vmState, 0x10); + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { - if (vmState.regs.eax != 0x4f) { + if (regs.eax != 0x4f) { status = B_NOT_SUPPORTED; } else { // Copy the EDID info to the caller's location, and compute the @@ -322,8 +330,9 @@ GetEdidFromBIOS(edid1_raw& edidRaw) } } - vm86_cleanup(&vmState); - +out: + biosModule->finish(state); + put_module(B_BIOS_MODULE_NAME); return status; } @@ -336,31 +345,40 @@ SetVesaDisplayMode(uint16 mode) #define SET_MODE_MASK 0x01ff #define SET_MODE_LINEAR_BUFFER (1 << 14) - vm86_state vmState; - - status_t status = vm86_prepare(&vmState, 0x2000); + bios_module_info* biosModule; + status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); if (status != B_OK) { - TRACE("SetVesaDisplayMode(); vm86_prepare() failed, status: 0x%lx\n", - status); + TRACE("SetVesaDisplayMode(0x%x): failed to get BIOS module: 0x%" B_PRIx32 + "\n", mode, status); return status; } - vmState.regs.eax = 0x4f02; - vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; - - status = vm86_do_int(&vmState, 0x10); + bios_state* state; + status = biosModule->prepare(&state); if (status != B_OK) { - TRACE("SetVesaDisplayMode(0x%x): vm86_do_int failed\n", mode); + TRACE("SetVesaDisplayMode(0x%x): bios_prepare() failed: 0x%" B_PRIx32 + "\n", mode, status); + put_module(B_BIOS_MODULE_NAME); + return status; } - if (status == B_OK && (vmState.regs.eax & 0xffff) != 0x4f) { - TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04lx\n", mode, - vmState.regs.eax & 0xffff); + bios_regs regs = {}; + regs.eax = 0x4f02; + regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; + + status = biosModule->interrupt(state, 0x10, ®s); + if (status != B_OK) { + TRACE("SetVesaDisplayMode(0x%x): BIOS interrupt failed\n", mode); + } + + if (status == B_OK && (regs.eax & 0xffff) != 0x4f) { + TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04" B_PRIx32 "\n", + mode, regs.eax & 0xffff); status = B_ERROR; } - vm86_cleanup(&vmState); - + biosModule->finish(state); + put_module(B_BIOS_MODULE_NAME); return status; } diff --git a/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp index eddd81d017..edb7b9e46a 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp @@ -10,12 +10,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include "DriverInterface.h" @@ -148,52 +148,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw) #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) - vm86_state vmState; - - status_t status = vm86_prepare(&vmState, 0x2000); + bios_module_info* biosModule; + status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); if (status != B_OK) { - TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n", + TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n", status); return status; } - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 0; // 0 = report DDC service - vmState.regs.ecx = 0; - vmState.regs.es = 0; - vmState.regs.edi = 0; + bios_state* state; + status = biosModule->prepare(&state); + if (status != B_OK) { + TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n", + status); + put_module(B_BIOS_MODULE_NAME); + return status; + } - status = vm86_do_int(&vmState, 0x10); + bios_regs regs = {}; + regs.eax = 0x4f15; + regs.ebx = 0; // 0 = report DDC service + regs.ecx = 0; + regs.es = 0; + regs.edi = 0; + + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { - // AH contains the error code, and AL determines wether or not the + // AH contains the error code, and AL determines whether or not the // function is supported. - if (vmState.regs.eax != 0x4f) + if (regs.eax != 0x4f) status = B_NOT_SUPPORTED; // Test if DDC is supported by the monitor. - if ((vmState.regs.ebx & 3) == 0) + if ((regs.ebx & 3) == 0) status = B_NOT_SUPPORTED; } if (status == B_OK) { - // According to the author of the vm86 functions, the address of any - // object to receive data must be >= 0x1000 and within the ram size - // specified in the second argument of the vm86_prepare() call above. - // Thus, the address of the struct to receive the EDID info is set to - // 0x1000. + edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state, + sizeof(edid1_raw)); + if (edid == NULL) { + status = B_NO_MEMORY; + goto out; + } - edid1_raw* edid = (edid1_raw*)0x1000; + regs.eax = 0x4f15; + regs.ebx = 1; // 1 = read EDID + regs.ecx = 0; + regs.edx = 0; + regs.es = ADDRESS_SEGMENT(edid); + regs.edi = ADDRESS_OFFSET(edid); - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 1; // 1 = read EDID - vmState.regs.ecx = 0; - vmState.regs.edx = 0; - vmState.regs.es = ADDRESS_SEGMENT(edid); - vmState.regs.edi = ADDRESS_OFFSET(edid); - - status = vm86_do_int(&vmState, 0x10); + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { - if (vmState.regs.eax != 0x4f) { + if (regs.eax != 0x4f) { status = B_NOT_SUPPORTED; } else { // Copy the EDID info to the caller's location, and compute the @@ -221,9 +229,11 @@ GetEdidFromBIOS(edid1_raw& edidRaw) } } - vm86_cleanup(&vmState); +out: + biosModule->finish(state); + put_module(B_BIOS_MODULE_NAME); - TRACE("GetEdidFromBIOS() status: 0x%lx\n", status); + TRACE("GetEdidFromBIOS() status: 0x%" B_PRIx32 "\n", status); return status; } diff --git a/src/add-ons/kernel/drivers/graphics/s3/driver.cpp b/src/add-ons/kernel/drivers/graphics/s3/driver.cpp index d57d8947e7..d737fdef63 100644 --- a/src/add-ons/kernel/drivers/graphics/s3/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/s3/driver.cpp @@ -8,13 +8,13 @@ #include #include +#ifdef __HAIKU__ +#include +#endif // __HAIKU__ #include #include #include #include -#ifdef __HAIKU__ -#include -#endif // __HAIKU__ #include "DriverInterface.h" @@ -493,51 +493,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw) #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) - vm86_state vmState; - - status_t status = vm86_prepare(&vmState, 0x2000); + bios_module_info* biosModule; + status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); if (status != B_OK) { - TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: %lx\n", status); + TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n", + status); return status; } - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 0; // 0 = report DDC service - vmState.regs.ecx = 0; - vmState.regs.es = 0; - vmState.regs.edi = 0; + bios_state* state; + status = biosModule->prepare(&state); + if (status != B_OK) { + TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n", + status); + put_module(B_BIOS_MODULE_NAME); + return status; + } - status = vm86_do_int(&vmState, 0x10); + bios_regs regs = {}; + regs.eax = 0x4f15; + regs.ebx = 0; // 0 = report DDC service + regs.ecx = 0; + regs.es = 0; + regs.edi = 0; + + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { // AH contains the error code, and AL determines whether or not the // function is supported. - if (vmState.regs.eax != 0x4f) + if (regs.eax != 0x4f) status = B_NOT_SUPPORTED; // Test if DDC is supported by the monitor. - if ((vmState.regs.ebx & 3) == 0) + if ((regs.ebx & 3) == 0) status = B_NOT_SUPPORTED; } if (status == B_OK) { - // According to the author of the vm86 functions, the address of any - // object to receive data must be >= 0x1000 and within the ram size - // specified in the second argument of the vm86_prepare() call above. - // Thus, the address of the struct to receive the EDID info is set to - // 0x1000. + edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state, + sizeof(edid1_raw)); + if (edid == NULL) { + status = B_NO_MEMORY; + goto out; + } - edid1_raw* edid = (edid1_raw*)0x1000; + regs.eax = 0x4f15; + regs.ebx = 1; // 1 = read EDID + regs.ecx = 0; + regs.edx = 0; + regs.es = ADDRESS_SEGMENT(edid); + regs.edi = ADDRESS_OFFSET(edid); - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 1; // 1 = read EDID - vmState.regs.ecx = 0; - vmState.regs.edx = 0; - vmState.regs.es = ADDRESS_SEGMENT(edid); - vmState.regs.edi = ADDRESS_OFFSET(edid); - - status = vm86_do_int(&vmState, 0x10); + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { - if (vmState.regs.eax != 0x4f) { + if (regs.eax != 0x4f) { status = B_NOT_SUPPORTED; } else { // Copy the EDID info to the caller's location, and compute the @@ -565,9 +574,11 @@ GetEdidFromBIOS(edid1_raw& edidRaw) } } - vm86_cleanup(&vmState); +out: + biosModule->finish(state); + put_module(B_BIOS_MODULE_NAME); - TRACE("GetEdidFromBIOS() status: 0x%lx\n", status); + TRACE("GetEdidFromBIOS() status: 0x%" B_PRIx32 "\n", status); return status; } diff --git a/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp b/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp index 6e31f6d870..0a3dd14455 100644 --- a/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp +++ b/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp @@ -9,10 +9,11 @@ #include +#include + #include #include #include -#include #include #include "driver.h" @@ -20,6 +21,43 @@ #include "vesa_info.h" +static bios_module_info* sBIOSModule; + + +/*! Loads the BIOS module and sets up a state for it. The BIOS module is only + loaded when we need it, as it is quite a large module. +*/ +static status_t +vbe_call_prepare(bios_state** state) +{ + status_t status; + + status = get_module(B_BIOS_MODULE_NAME, (module_info**)&sBIOSModule); + if (status != B_OK) { + dprintf(DEVICE_NAME ": failed to get BIOS module: %s\n", + strerror(status)); + return status; + } + + status = sBIOSModule->prepare(state); + if (status != B_OK) { + dprintf(DEVICE_NAME ": failed to prepare BIOS state: %s\n", + strerror(status)); + put_module(B_BIOS_MODULE_NAME); + } + + return status; +} + + +static void +vbe_call_finish(bios_state* state) +{ + sBIOSModule->finish(state); + put_module(B_BIOS_MODULE_NAME); +} + + static status_t find_graphics_card(addr_t frameBuffer, addr_t& base, size_t& size) { @@ -80,26 +118,31 @@ get_color_space_for_depth(uint32 depth) static status_t -vbe_get_mode_info(struct vm86_state& vmState, uint16 mode, - struct vbe_mode_info* modeInfo) +vbe_get_mode_info(bios_state* state, uint16 mode, struct vbe_mode_info* modeInfo) { - struct vbe_mode_info* vbeModeInfo = (struct vbe_mode_info*)0x1000; - + void* vbeModeInfo = sBIOSModule->allocate_mem(state, + sizeof(struct vbe_mode_info)); + if (vbeModeInfo == NULL) + return B_NO_MEMORY; memset(vbeModeInfo, 0, sizeof(vbe_mode_info)); - vmState.regs.eax = 0x4f01; - vmState.regs.ecx = mode; - vmState.regs.es = 0x1000 >> 4; - vmState.regs.edi = 0x0000; - status_t status = vm86_do_int(&vmState, 0x10); + uint32 physicalAddress = sBIOSModule->physical_address(state, vbeModeInfo); + bios_regs regs = {}; + regs.eax = 0x4f01; + regs.ecx = mode; + regs.es = physicalAddress >> 4; + regs.edi = physicalAddress - (regs.es << 4); + + status_t status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): vm86 failed\n", mode); + dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): BIOS failed: %s\n", mode, + strerror(status)); return status; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { - dprintf(DEVICE_NAME ": vbe_get_mode_info(): BIOS returned 0x%04lx\n", - vmState.regs.eax & 0xffff); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): BIOS returned " + "0x%04" B_PRIx32 "\n", mode, regs.eax & 0xffff); return B_ENTRY_NOT_FOUND; } @@ -109,20 +152,22 @@ vbe_get_mode_info(struct vm86_state& vmState, uint16 mode, static status_t -vbe_set_mode(struct vm86_state& vmState, uint16 mode) +vbe_set_mode(bios_state* state, uint16 mode) { - vmState.regs.eax = 0x4f02; - vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; + bios_regs regs = {}; + regs.eax = 0x4f02; + regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; - status_t status = vm86_do_int(&vmState, 0x10); + status_t status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vbe_set_mode(%u): vm86 failed\n", mode); + dprintf(DEVICE_NAME ": vbe_set_mode(%u): BIOS failed: %s\n", mode, + strerror(status)); return status; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { - dprintf(DEVICE_NAME ": vbe_set_mode(): BIOS returned 0x%04lx\n", - vmState.regs.eax & 0xffff); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vbe_set_mode(%u): BIOS returned 0x%04" B_PRIx32 + "\n", mode, regs.eax & 0xffff); return B_ERROR; } @@ -152,64 +197,64 @@ vbe_get_dpms_capabilities(uint32& vbeMode, uint32& mode) vbeMode = 0; mode = B_DPMS_ON; - // Prepare vm86 mode environment - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vbe_get_dpms_capabilities(): vm86_prepare " - "failed: %s\n", strerror(status)); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } - vmState.regs.eax = 0x4f10; - vmState.regs.ebx = 0; - vmState.regs.esi = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f10; + regs.ebx = 0; + regs.esi = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): vm86 failed\n"); + dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS failed: %s\n", + strerror(status)); goto out; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { + if ((regs.eax & 0xffff) != 0x4f) { dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS returned " - "0x%04lx\n", vmState.regs.eax & 0xffff); + "0x%04" B_PRIx32 "\n", regs.eax & 0xffff); status = B_ERROR; goto out; } - vbeMode = vmState.regs.ebx >> 8; + vbeMode = regs.ebx >> 8; mode = vbe_to_system_dpms(vbeMode); out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } static status_t -vbe_set_bits_per_gun(vm86_state& vmState, vesa_info& info, uint8 bits) +vbe_set_bits_per_gun(bios_state* state, vesa_info& info, uint8 bits) { info.bits_per_gun = 6; - vmState.regs.eax = 0x4f08; - vmState.regs.ebx = (bits << 8) | 1; + bios_regs regs = {}; + regs.eax = 0x4f08; + regs.ebx = (bits << 8) | 1; - status_t status = vm86_do_int(&vmState, 0x10); + status_t status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): vm86 failed: %s\n", + dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS failed: %s\n", strerror(status)); return status; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { - dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS returned 0x%04lx\n", - vmState.regs.eax & 0xffff); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS returned " + "0x%04" B_PRIx32 "\n", regs.eax & 0xffff); return B_ERROR; } - info.bits_per_gun = vmState.regs.ebx >> 8; + info.bits_per_gun = regs.ebx >> 8; return B_OK; } @@ -219,17 +264,14 @@ vbe_set_bits_per_gun(vesa_info& info, uint8 bits) { info.bits_per_gun = 6; - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vbe_set_bits_per_gun(): vm86_prepare failed: " - "%s\n", strerror(status)); + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } - status = vbe_set_bits_per_gun(vmState, info, bits); + status = vbe_set_bits_per_gun(state, info, bits); - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } @@ -386,31 +428,29 @@ vesa_set_display_mode(vesa_info& info, uint32 mode) if (mode >= info.shared_info->vesa_mode_count) return B_ENTRY_NOT_FOUND; - // Prepare vm86 mode environment - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vesa_set_display_mode(): vm86_prepare failed\n"); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } // Get mode information struct vbe_mode_info modeInfo; - status = vbe_get_mode_info(vmState, info.modes[mode].mode, &modeInfo); + status = vbe_get_mode_info(state, info.modes[mode].mode, &modeInfo); if (status != B_OK) { dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n"); goto out; } // Set mode - status = vbe_set_mode(vmState, info.modes[mode].mode); + status = vbe_set_mode(state, info.modes[mode].mode); if (status != B_OK) { dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n"); goto out; } if (info.modes[mode].bits_per_pixel <= 8) - vbe_set_bits_per_gun(vmState, info, 8); + vbe_set_bits_per_gun(state, info, 8); // Map new frame buffer if necessary @@ -426,7 +466,7 @@ vesa_set_display_mode(vesa_info& info, uint32 mode) } out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } @@ -437,38 +477,36 @@ vesa_get_dpms_mode(vesa_info& info, uint32& mode) mode = B_DPMS_ON; // we always return a valid mode - // Prepare vm86 mode environment - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vesa_get_dpms_mode(): vm86_prepare failed: %s\n", - strerror(status)); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } - vmState.regs.eax = 0x4f10; - vmState.regs.ebx = 2; - vmState.regs.esi = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f10; + regs.ebx = 2; + regs.esi = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): vm86 failed: %s\n", + dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS failed: %s\n", strerror(status)); goto out; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { - dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS returned 0x%04lx\n", - vmState.regs.eax & 0xffff); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS returned " + "0x%" B_PRIx32 "\n", regs.eax & 0xffff); status = B_ERROR; goto out; } - mode = vbe_to_system_dpms(vmState.regs.ebx >> 8); + mode = vbe_to_system_dpms(regs.ebx >> 8); out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } @@ -489,36 +527,34 @@ vesa_set_dpms_mode(vesa_info& info, uint32 mode) vbeMode &= info.vbe_dpms_capabilities; - // Prepare vm86 mode environment - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vesa_set_dpms_mode(): vm86_prepare failed: %s\n", - strerror(status)); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } - vmState.regs.eax = 0x4f10; - vmState.regs.ebx = (vbeMode << 8) | 1; - vmState.regs.esi = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f10; + regs.ebx = (vbeMode << 8) | 1; + regs.esi = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): vm86 failed: %s\n", + dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS failed: %s\n", strerror(status)); goto out; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { - dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS returned 0x%04lx\n", - vmState.regs.eax & 0xffff); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS returned " + "0x%04" B_PRIx32 "\n", regs.eax & 0xffff); status = B_ERROR; goto out; } out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } @@ -527,26 +563,33 @@ status_t vesa_set_indexed_colors(vesa_info& info, uint8 first, uint8* colors, uint16 count) { + bios_regs regs = {}; + uint32 shift, physicalAddress; + if (first + count > 256) count = 256 - first; - // Prepare vm86 mode environment - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vesa_set_indexed_colors(): vm86_prepare failed: " - "%s\n", strerror(status)); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; + + uint8* palette = (uint8*)sBIOSModule->allocate_mem(state, 256 * 4); + if (palette == NULL) { + status = B_NO_MEMORY; + goto out; } - uint8* palette = (uint8*)0x1000; - uint32 shift = 8 - info.bits_per_gun; + shift = 8 - info.bits_per_gun; // convert colors to VESA palette for (int32 i = first; i < count; i++) { uint8 color[3]; - if (user_memcpy(color, &colors[i * 3], 3) < B_OK) - return B_BAD_ADDRESS; + if (user_memcpy(color, &colors[i * 3], 3) < B_OK) { + status = B_BAD_ADDRESS; + goto out; + } // order is BGR- palette[i * 4 + 0] = color[2] >> shift; @@ -556,27 +599,28 @@ vesa_set_indexed_colors(vesa_info& info, uint8 first, uint8* colors, } // set palette - vmState.regs.eax = 0x4f09; - vmState.regs.ebx = 0; - vmState.regs.ecx = count; - vmState.regs.edx = first; - vmState.regs.es = 0x1000 >> 4; - vmState.regs.edi = 0x0000; + physicalAddress = sBIOSModule->physical_address(state, palette); + regs.eax = 0x4f09; + regs.ebx = 0; + regs.ecx = count; + regs.edx = first; + regs.es = physicalAddress >> 4; + regs.edi = physicalAddress - (regs.es << 4); - status = vm86_do_int(&vmState, 0x10); + status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): vm86 failed: %s\n", + dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): BIOS failed: %s\n", strerror(status)); goto out; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { + if ((regs.eax & 0xffff) != 0x4f) { dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): BIOS returned " - "0x%04lx\n", vmState.regs.eax & 0xffff); + "0x%04" B_PRIx32 "\n", regs.eax & 0xffff); status = B_ERROR; } out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } diff --git a/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp b/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp index 657b7f5139..51ca81f02a 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp @@ -62,7 +62,7 @@ usb_hid_device_added(usb_device device, void **cookie) // ensure default configuration is set status_t result = gUSBModule->set_configuration(device, config); if (result != B_OK) { - TRACE_ALWAYS("set_configuration() failed 0x%08lx\n", result); + TRACE_ALWAYS("set_configuration() failed 0x%08" B_PRIx32 "\n", result); return result; } @@ -78,8 +78,8 @@ usb_hid_device_added(usb_device device, void **cookie) for (size_t i = 0; i < config->interface_count; i++) { const usb_interface_info *interface = config->interface[i].active; uint8 interfaceClass = interface->descr->interface_class; - TRACE("interface %lu: class: %u; subclass: %u; protocol: %u\n", - i, interfaceClass, interface->descr->interface_subclass, + TRACE("interface %" B_PRIuSIZE ": class: %u; subclass: %u; protocol: " + "%u\n", i, interfaceClass, interface->descr->interface_subclass, interface->descr->interface_protocol); // check for quirky devices first @@ -128,7 +128,7 @@ usb_hid_device_added(usb_device device, void **cookie) char pathBuffer[128]; const char *basePath = handler->BasePath(); while (true) { - sprintf(pathBuffer, "%s%ld", basePath, index++); + sprintf(pathBuffer, "%s%" B_PRId32, basePath, index++); if (gDeviceList->FindDevice(pathBuffer) == NULL) { // this name is still free, use it handler->SetPublishPath(strdup(pathBuffer)); @@ -149,7 +149,7 @@ usb_hid_device_added(usb_device device, void **cookie) if (!devicesFound) return B_ERROR; - *cookie = (void *)parentCookie; + *cookie = (void *)(addr_t)parentCookie; return B_OK; } @@ -158,8 +158,8 @@ status_t usb_hid_device_removed(void *cookie) { mutex_lock(&sDriverLock); - int32 parentCookie = (int32)cookie; - TRACE("device_removed(%ld)\n", parentCookie); + int32 parentCookie = (int32)(addr_t)cookie; + TRACE("device_removed(%" B_PRId32 ")\n", parentCookie); for (int32 i = 0; i < gDeviceList->CountDevices(); i++) { ProtocolHandler *handler = (ProtocolHandler *)gDeviceList->DeviceAt(i); diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDCollection.cpp b/src/add-ons/kernel/drivers/input/usb_hid/HIDCollection.cpp index 3935e244fd..bfa424de46 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDCollection.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDCollection.cpp @@ -214,18 +214,18 @@ HIDCollection::PrintToStream(uint32 indentLevel) TRACE_ALWAYS("%sHIDCollection %p\n", indent, this); TRACE_ALWAYS("%s\ttype: %u %s\n", indent, fType, typeName); - TRACE_ALWAYS("%s\tusage: 0x%08lx\n", indent, fUsage); + TRACE_ALWAYS("%s\tusage: 0x%08" B_PRIx32 "\n", indent, fUsage); TRACE_ALWAYS("%s\tstring id: %u\n", indent, fStringID); TRACE_ALWAYS("%s\tphysical id: %u\n", indent, fPhysicalID); - TRACE_ALWAYS("%s\titem count: %lu\n", indent, fItemCount); + TRACE_ALWAYS("%s\titem count: %" B_PRIu32 "\n", indent, fItemCount); for (uint32 i = 0; i < fItemCount; i++) { HIDReportItem *item = fItems[i]; if (item != NULL) item->PrintToStream(indentLevel + 1); } - TRACE_ALWAYS("%s\tchild count: %lu\n", indent, fChildCount); + TRACE_ALWAYS("%s\tchild count: %" B_PRIu32 "\n", indent, fChildCount); for (uint32 i = 0; i < fChildCount; i++) { HIDCollection *child = fChildren[i]; if (child != NULL) diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp index aeacd6e43f..c1e15e1e3b 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp @@ -273,7 +273,8 @@ HIDDevice::MaybeScheduleTransfer() status_t result = gUSBModule->queue_interrupt(fInterruptPipe, fTransferBuffer, fTransferBufferSize, _TransferCallback, this); if (result != B_OK) { - TRACE_ALWAYS("failed to schedule interrupt transfer 0x%08lx\n", result); + TRACE_ALWAYS("failed to schedule interrupt transfer 0x%08" B_PRIx32 "\n", + result); return result; } diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDReport.cpp b/src/add-ons/kernel/drivers/input/usb_hid/HIDReport.cpp index e38ebd8dd4..fe735b7d88 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDReport.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDReport.cpp @@ -157,7 +157,7 @@ HIDReport::SetReport(status_t status, uint8 *report, size_t length) fReportStatus = status; fCurrentReport = report; if (status == B_OK && length * 8 < fReportSize) { - TRACE_ALWAYS("report of %lu bits too small, expected %lu bits\n", + TRACE_ALWAYS("report of %lu bits too small, expected %" B_PRIu32 " bits\n", length * 8, fReportSize); fReportStatus = B_ERROR; } @@ -276,10 +276,10 @@ HIDReport::PrintToStream() TRACE_ALWAYS("\ttype: %u %s\n", fType, typeName); TRACE_ALWAYS("\treport id: %u\n", fReportID); - TRACE_ALWAYS("\treport size: %lu bits = %lu bytes\n", fReportSize, - (fReportSize + 7) / 8); + TRACE_ALWAYS("\treport size: %" B_PRIu32 " bits = %" B_PRIu32 " bytes\n", + fReportSize, (fReportSize + 7) / 8); - TRACE_ALWAYS("\titem count: %lu\n", fItemsUsed); + TRACE_ALWAYS("\titem count: %" B_PRIu32 "\n", fItemsUsed); for (uint32 i = 0; i < fItemsUsed; i++) { HIDReportItem *item = fItems[i]; if (item != NULL) diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDReportItem.cpp b/src/add-ons/kernel/drivers/input/usb_hid/HIDReportItem.cpp index d83d267bde..76faca711d 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDReportItem.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDReportItem.cpp @@ -180,14 +180,14 @@ HIDReportItem::PrintToStream(uint32 indentLevel) indent[indentLevel] = 0; TRACE_ALWAYS("%sHIDReportItem %p\n", indent, this); - TRACE_ALWAYS("%s\tbyte offset: %lu\n", indent, fByteOffset); + TRACE_ALWAYS("%s\tbyte offset: %" B_PRIu32 "\n", indent, fByteOffset); TRACE_ALWAYS("%s\tshift: %u\n", indent, fShift); - TRACE_ALWAYS("%s\tmask: 0x%08lx\n", indent, fMask); + TRACE_ALWAYS("%s\tmask: 0x%08" B_PRIx32 "\n", indent, fMask); TRACE_ALWAYS("%s\thas data: %s\n", indent, fHasData ? "yes" : "no"); TRACE_ALWAYS("%s\tarray: %s\n", indent, fArray ? "yes" : "no"); TRACE_ALWAYS("%s\trelative: %s\n", indent, fRelative ? "yes" : "no"); - TRACE_ALWAYS("%s\tminimum: %lu\n", indent, fMinimum); - TRACE_ALWAYS("%s\tmaximum: %lu\n", indent, fMaximum); - TRACE_ALWAYS("%s\tusage minimum: 0x%08lx\n", indent, fUsageMinimum); - TRACE_ALWAYS("%s\tusage maximum: 0x%08lx\n", indent, fUsageMaximum); + TRACE_ALWAYS("%s\tminimum: %" B_PRIu32 "\n", indent, fMinimum); + TRACE_ALWAYS("%s\tmaximum: %" B_PRIu32 "\n", indent, fMaximum); + TRACE_ALWAYS("%s\tusage minimum: 0x%08" B_PRIx32 "\n", indent, fUsageMinimum); + TRACE_ALWAYS("%s\tusage maximum: 0x%08" B_PRIx32 "\n", indent, fUsageMaximum); } diff --git a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardProtocolHandler.cpp b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardProtocolHandler.cpp index 824031ce3f..083c5fe431 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardProtocolHandler.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardProtocolHandler.cpp @@ -425,7 +425,7 @@ KeyboardProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer, return B_OK; } - TRACE_ALWAYS("keyboard device unhandled control 0x%08lx\n", op); + TRACE_ALWAYS("keyboard device unhandled control 0x%08" B_PRIx32 "\n", op); return B_ERROR; } diff --git a/src/add-ons/kernel/drivers/network/etherpci/etherpci.c b/src/add-ons/kernel/drivers/network/etherpci/etherpci.c index 7b20fdd689..98146ac786 100644 --- a/src/add-ons/kernel/drivers/network/etherpci/etherpci.c +++ b/src/add-ons/kernel/drivers/network/etherpci/etherpci.c @@ -370,10 +370,10 @@ output_count(etherpci_private_t *data) /* * How many waiting for input? */ -static long +static int32 input_count(etherpci_private_t *data) { - long count; + int32 count; get_sem_count(data->ilock, &count); return (count); @@ -1207,7 +1207,7 @@ enable_addressing(etherpci_private_t *data) data->reg_base = data->reg_base + offset; #endif - dprintf(kDevName ": reg_base=%lx\n", data->reg_base); + dprintf(kDevName ": reg_base=%" B_PRIx32 "\n", data->reg_base); /* enable pci address access */ cmd = (gPCIModInfo->read_pci_config)(data->pciInfo->bus, data->pciInfo->device, data->pciInfo->function, PCI_command, 2); @@ -1377,7 +1377,7 @@ init_driver(void) /* Create device name list*/ for (i=0; isem_lock = sem = create_sem(1, DRIVER_NAME "_lock"); if (sem < B_OK) { - DPRINTF_ERR("create_sem() failed 0x%lx\n", sem); + DPRINTF_ERR("create_sem() failed 0x%" B_PRIx32 "\n", sem); free(device); return NULL; } device->rx_sem = sem = create_sem(1, DRIVER_NAME"_receive"); if (sem < B_OK) { - DPRINTF_ERR("create_sem() failed 0x%lx\n", sem); + DPRINTF_ERR("create_sem() failed 0x%" B_PRIx32 "\n", sem); delete_sem(device->sem_lock); free(device); return NULL; @@ -202,7 +202,7 @@ create_device(const usb_device dev, const usb_interface_info *ii, uint16 ifno) device->rx_sem_cb = sem = create_sem(0, DRIVER_NAME"_receive_cb"); if (sem < B_OK) { - DPRINTF_ERR("create_sem() failed 0x%lx\n", sem); + DPRINTF_ERR("create_sem() failed 0x%" B_PRIx32 "\n", sem); delete_sem(device->rx_sem); delete_sem(device->sem_lock); free(device); @@ -499,7 +499,7 @@ pegasus_device_read(driver_cookie *cookie, off_t position, void *buffer, size_t // block until receive is available (if blocking is allowed) if ((status = acquire_sem_etc(dev->rx_sem, 1, B_CAN_INTERRUPT | blockFlag, 0)) != B_NO_ERROR) { - DPRINTF_ERR("cannot acquire read sem: %lx, %s\n", status, strerror(status)); + DPRINTF_ERR("cannot acquire read sem: %" B_PRIx32 ", %s\n", status, strerror(status)); #ifndef __HAIKU__ *_length = 0; #endif @@ -510,13 +510,13 @@ pegasus_device_read(driver_cookie *cookie, off_t position, void *buffer, size_t status = usb->queue_bulk(dev->pipe_in, dev->rx_buffer, MAX_FRAME_SIZE, &pegasus_rx_callback, dev); if (status != B_OK) { - DPRINTF_ERR("queue_bulk:failed:%08lx\n", status); + DPRINTF_ERR("queue_bulk:failed:%08" B_PRIx32 "\n", status); goto rx_done; } // block until data is available (if blocking is allowed) if ((status = acquire_sem_etc(dev->rx_sem_cb, 1, B_CAN_INTERRUPT | blockFlag, 0)) != B_NO_ERROR) { - DPRINTF_ERR("cannot acquire read sem: %lx, %s\n", status, strerror(status)); + DPRINTF_ERR("cannot acquire read sem: %" B_PRIx32 ", %s\n", status, strerror(status)); #ifndef __HAIKU__ *_length = 0; #endif @@ -567,7 +567,7 @@ pegasus_device_write(driver_cookie *cookie, off_t position, const void *buffer, // block until a free tx descriptor is available if ((status = acquire_sem_etc(dev->tx_sem, 1, B_TIMEOUT, ETHER_TRANSMIT_TIMEOUT)) < B_NO_ERROR) { - DPRINTF_ERR("write: acquiring sem failed: %lx, %s\n", status, strerror(status)); + DPRINTF_ERR("write: acquiring sem failed: %" B_PRIx32 ", %s\n", status, strerror(status)); return status; } @@ -594,13 +594,13 @@ pegasus_device_write(driver_cookie *cookie, off_t position, const void *buffer, &pegasus_tx_callback, dev); if (status != B_OK){ - DPRINTF_ERR("queue_bulk:failed:%08lx\n", status); + DPRINTF_ERR("queue_bulk:failed:%08" B_PRIx32 "\n", status); goto tx_done; } // block until data is sent (if blocking is allowed) if ((status = acquire_sem_etc(dev->tx_sem_cb, 1, B_CAN_INTERRUPT, 0)) != B_NO_ERROR) { - DPRINTF_ERR("cannot acquire write done sem: %lx, %s\n", status, strerror(status)); + DPRINTF_ERR("cannot acquire write done sem: %" B_PRIx32 ", %s\n", status, strerror(status)); #ifndef __HAIKU__ *_length = 0; #endif diff --git a/src/add-ons/kernel/drivers/network/sis19x/DataRing.cpp b/src/add-ons/kernel/drivers/network/sis19x/DataRing.cpp index 51150d8a38..e347899412 100644 --- a/src/add-ons/kernel/drivers/network/sis19x/DataRing.cpp +++ b/src/add-ons/kernel/drivers/network/sis19x/DataRing.cpp @@ -197,8 +197,8 @@ DataRing::Dump() { int32 count = 0; get_sem_count(fSemaphore, &count); - kprintf("Tx:[count:%ld] head:%lu tail:%lu dirty:%lu\n", - count, fHead, fTail, fHead - fTail); + kprintf("Tx:[count:%" B_PRId32 "] head:%" B_PRIu32 " tail:%" B_PRIu32 " " + "dirty:%" B_PRIu32 "\n", count, fHead, fTail, fHead - fTail); kprintf("\tPktSize\t\tCmdStat\t\tBufPtr\t\tEOD\n"); @@ -206,8 +206,9 @@ DataRing::Dump() volatile TxDescriptor& D = fDescriptors[i]; char marker = ((fTail % TxDescriptorsCount) == i) ? '=' : ' '; marker = ((fHead % TxDescriptorsCount) == i) ? '>' : marker; - kprintf("%02lx %c\t%08lx\t%08lx\t%08lx\t%08lx\n", i, marker, - D.fPacketSize, D.fCommandStatus, D.fBufferPointer, D.fEOD); + kprintf("%02lx %c\t%08" B_PRIx32 "\t%08" B_PRIx32 "\t%08" B_PRIx32 + "\t%08" B_PRIx32 "\n", i, marker, D.fPacketSize, + D.fCommandStatus, D.fBufferPointer, D.fEOD); } } @@ -335,8 +336,8 @@ DataRing::Dump() { int32 count = 0; get_sem_count(fSemaphore, &count); - kprintf("Rx:[count:%ld] head:%lu tail:%lu dirty:%lu\n", - count, fHead, fTail, fHead - fTail); + kprintf("Rx:[count:%" B_PRId32 "] head:%" B_PRIu32 " tail:%" B_PRIu32 " " + "dirty:%" B_PRIu32 "\n", count, fHead, fTail, fHead - fTail); for (size_t i = 0; i < 2; i++) { kprintf("\tStatSize\tPktInfo\t\tBufPtr\t\tEOD %c", @@ -344,7 +345,8 @@ DataRing::Dump() } for (size_t i = 0; i < RxDescriptorsCount / 2; i++) { - const char* mask = "%02lx %c\t%08lx\t%08lx\t%08lx\t%08lx %c"; + const char* mask = "%02" B_PRIx32 " %c\t%08" B_PRIx32 "\t%08" B_PRIx32 + "\t%08" B_PRIx32 "\t%08" B_PRIx32 " %c"; for (size_t ii = 0; ii < 2; ii++) { size_t index = ii == 0 ? i : (i + RxDescriptorsCount / 2); diff --git a/src/add-ons/kernel/drivers/network/sis19x/Device.cpp b/src/add-ons/kernel/drivers/network/sis19x/Device.cpp index 6fcd5d9737..feb94f512a 100644 --- a/src/add-ons/kernel/drivers/network/sis19x/Device.cpp +++ b/src/add-ons/kernel/drivers/network/sis19x/Device.cpp @@ -736,7 +736,8 @@ Device::DumpRegisters() for (size_t i = 0; i < _countof(RegisterEntries); i++) { uint32 registerContents = ReadPCI32(RegisterEntries[i].Base); - kprintf("%s:\t%08lx\n", RegisterEntries[i].Name, registerContents); + kprintf("%s:\t%08" B_PRIx32 "\n", RegisterEntries[i].Name, + registerContents); if (RegisterEntries[i].writeBack) { WritePCI32(RegisterEntries[i].Base, registerContents); } diff --git a/src/add-ons/kernel/drivers/network/sis19x/Driver.cpp b/src/add-ons/kernel/drivers/network/sis19x/Driver.cpp index bfce9dfb48..bb8bcf02d6 100644 --- a/src/add-ons/kernel/drivers/network/sis19x/Driver.cpp +++ b/src/add-ons/kernel/drivers/network/sis19x/Driver.cpp @@ -83,7 +83,7 @@ static int SiS19X_DebuggerCommand(int argc, char** argv) } if (cardId >= numCards) { - kprintf("%lld - invalid index.\n", cardId); + kprintf("%" B_PRId64 " - invalid index.\n", cardId); kprintf(usageInfo); return 0; } diff --git a/src/add-ons/kernel/drivers/network/sis19x/Settings.cpp b/src/add-ons/kernel/drivers/network/sis19x/Settings.cpp index 007d45f42b..f253af6ba9 100644 --- a/src/add-ons/kernel/drivers/network/sis19x/Settings.cpp +++ b/src/add-ons/kernel/drivers/network/sis19x/Settings.cpp @@ -101,7 +101,7 @@ void SiS19X_trace(bool force, const char* func, const char *fmt, ...) bigtime_t time = system_time(); uint32 msec = time / 1000; uint32 sec = msec / 1000; - sprintf(buf_ptr, "%02ld.%02ld.%03ld:", + sprintf(buf_ptr, "%02" B_PRId32 ".%02" B_PRId32 ".%03" B_PRId32 ":", sec / 60, sec % 60, msec % 1000); buf_ptr += strlen(buf_ptr); } diff --git a/src/add-ons/kernel/drivers/network/sis900/sis900.c b/src/add-ons/kernel/drivers/network/sis900/sis900.c index 839b6981cf..befb4d2874 100644 --- a/src/add-ons/kernel/drivers/network/sis900/sis900.c +++ b/src/add-ons/kernel/drivers/network/sis900/sis900.c @@ -149,12 +149,12 @@ sis900_txInterrupt(struct sis_info *info) /* Does the device generate extra interrupts? */ if (status & SiS900_DESCR_OWN) { - struct buffer_desc *descriptor = (void *)read32(info->registers + SiS900_MAC_Tx_DESCR); + uint32 descriptor = read32(info->registers + SiS900_MAC_Tx_DESCR); int16 that; for (that = 0; that < NUM_Tx_DESCR && physicalAddress(&info->txDescriptor[that], - sizeof(struct buffer_desc)) != (addr_t)descriptor; + sizeof(struct buffer_desc)) != descriptor; that++) { } if (that == NUM_Tx_DESCR) @@ -172,7 +172,7 @@ sis900_txInterrupt(struct sis_info *info) if (status & (SiS900_DESCR_Tx_ABORT | SiS900_DESCR_Tx_UNDERRUN | SiS900_DESCR_Tx_OOW_COLLISION)) { - dprintf("tx error: %lx\n", status); + dprintf("tx error: %" B_PRIx32 "\n", status); } else info->txDescriptor[info->txInterruptIndex].status = 0; @@ -740,7 +740,7 @@ sis900_createRings(struct sis_info *info) // initialize transmit buffer descriptors for (i = 1; i < NUM_Tx_DESCR; i++) - info->txBuffer[i] = (void *)(((uint32)info->txBuffer[0]) + (i * BUFFER_SIZE)); + info->txBuffer[i] = (void *)(((addr_t)info->txBuffer[0]) + (i * BUFFER_SIZE)); for (i = 0; i < NUM_Tx_DESCR; i++) { info->txDescriptor[i].status = 0; @@ -765,7 +765,7 @@ sis900_createRings(struct sis_info *info) // initialize receive buffer descriptors for (i = 1; i < NUM_Rx_DESCR; i++) - info->rxBuffer[i] = (void *)(((uint32)info->rxBuffer[0]) + (i * BUFFER_SIZE)); + info->rxBuffer[i] = (void *)(((addr_t)info->rxBuffer[0]) + (i * BUFFER_SIZE)); for (i = 0; i < NUM_Rx_DESCR; i++) { info->rxDescriptor[i].status = MAX_FRAME_SIZE; diff --git a/src/add-ons/kernel/drivers/network/wb840/wb840.c b/src/add-ons/kernel/drivers/network/wb840/wb840.c index d478006fd9..4335d35037 100644 --- a/src/add-ons/kernel/drivers/network/wb840/wb840.c +++ b/src/add-ons/kernel/drivers/network/wb840/wb840.c @@ -539,7 +539,7 @@ wb_create_rings(wb_device* device) return device->rxArea; for (i = 1; i < WB_RX_LIST_CNT; i++) { - device->rxBuffer[i] = (void*)(((uint32)device->rxBuffer[0]) + device->rxBuffer[i] = (void*)(((addr_t)device->rxBuffer[0]) + (i * WB_BUFBYTES)); } @@ -567,7 +567,7 @@ wb_create_rings(wb_device* device) } for (i = 1; i < WB_TX_LIST_CNT; i++) { - device->txBuffer[i] = (void*)(((uint32)device->txBuffer[0]) + device->txBuffer[i] = (void*)(((addr_t)device->txBuffer[0]) + (i * WB_BUFBYTES)); } diff --git a/src/add-ons/kernel/drivers/power/Jamfile b/src/add-ons/kernel/drivers/power/Jamfile index 56d91431ba..45feced8e9 100644 --- a/src/add-ons/kernel/drivers/power/Jamfile +++ b/src/add-ons/kernel/drivers/power/Jamfile @@ -5,3 +5,4 @@ SubInclude HAIKU_TOP src add-ons kernel drivers power acpi_button ; SubInclude HAIKU_TOP src add-ons kernel drivers power acpi_lid ; SubInclude HAIKU_TOP src add-ons kernel drivers power acpi_thermal ; SubInclude HAIKU_TOP src add-ons kernel drivers power enhanced_speedstep ; +SubInclude HAIKU_TOP src add-ons kernel drivers power x86_cpuidle ; diff --git a/src/add-ons/kernel/drivers/power/x86_cpuidle/Jamfile b/src/add-ons/kernel/drivers/power/x86_cpuidle/Jamfile new file mode 100644 index 0000000000..51612506a6 --- /dev/null +++ b/src/add-ons/kernel/drivers/power/x86_cpuidle/Jamfile @@ -0,0 +1,10 @@ +SubDir HAIKU_TOP src add-ons kernel drivers power x86_cpuidle ; + +UsePrivateKernelHeaders ; + +KernelAddon x86_cpuidle : + acpi_cpuidle.cpp + intel_cpuidle.cpp + ; + +Depends x86_cpuidle : acpi ; diff --git a/src/add-ons/kernel/drivers/power/x86_cpuidle/acpi_cpuidle.cpp b/src/add-ons/kernel/drivers/power/x86_cpuidle/acpi_cpuidle.cpp new file mode 100644 index 0000000000..dbce64caa5 --- /dev/null +++ b/src/add-ons/kernel/drivers/power/x86_cpuidle/acpi_cpuidle.cpp @@ -0,0 +1,583 @@ +/* + * Copyright 2012, Haiku, Inc. All Rights Reserved. + * + * Distributed under the terms of the MIT License. + * + * Authors: + * Yongcong Du + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "x86_cpuidle.h" + +#define ACPI_PDC_REVID 0x1 +#define ACPI_OSC_QUERY (1 << 0) + +#define ACPI_PDC_P_FFH (1 << 0) +#define ACPI_PDC_C_C1_HALT (1 << 1) +#define ACPI_PDC_T_FFH (1 << 2) +#define ACPI_PDC_SMP_C1PT (1 << 3) +#define ACPI_PDC_SMP_C2C3 (1 << 4) +#define ACPI_PDC_SMP_P_SW (1 << 5) +#define ACPI_PDC_SMP_C_SW (1 << 6) +#define ACPI_PDC_SMP_T_SW (1 << 7) +#define ACPI_PDC_C_C1_FFH (1 << 8) +#define ACPI_PDC_C_C2C3_FFH (1 << 9) +#define ACPI_PDC_P_HWCOORD (1 << 11) + +// Bus Master check required +#define ACPI_PDC_GAS_BM (1 << 1) + +#define ACPI_CSTATE_HALT 0x1 +#define ACPI_CSTATE_SYSIO 0x2 +#define ACPI_CSTATE_FFH 0x3 + +// Bus Master Check +#define ACPI_FLAG_C_BM (1 << 0) +// Bus master arbitration +#define ACPI_FLAG_C_ARB (1 << 1) + +// Copied from acpica's actypes.h, where's the best place to put? +#define ACPI_BITREG_BUS_MASTER_STATUS 0x01 +#define ACPI_BITREG_BUS_MASTER_RLD 0x0F +#define ACPI_BITREG_ARB_DISABLE 0x13 + +#define ACPI_STATE_C0 (uint8) 0 +#define ACPI_STATE_C1 (uint8) 1 +#define ACPI_STATE_C2 (uint8) 2 +#define ACPI_STATE_C3 (uint8) 3 +#define ACPI_C_STATES_MAX ACPI_STATE_C3 +#define ACPI_C_STATE_COUNT 4 + + +#define ACPI_CPUIDLE_MODULE_NAME "drivers/power/x86_cpuidle/acpi/driver_v1" + +struct acpicpu_reg { + uint8 reg_desc; + uint16 reg_reslen; + uint8 reg_spaceid; + uint8 reg_bitwidth; + uint8 reg_bitoffset; + uint8 reg_accesssize; + uint64 reg_addr; +} __attribute__((packed)); + +struct acpi_cpuidle_driver_info { + device_node *node; + acpi_device_module_info *acpi; + acpi_device acpi_cookie; + uint32 flags; +}; + +struct acpi_cstate_info { + uint32 address; + uint8 skip_bm_sts; + uint8 method; + uint8 type; +}; + +static acpi_cpuidle_driver_info *acpi_processor[B_MAX_CPU_COUNT]; +static CpuidleDevice sAcpiDevice; +static device_manager_info *sDeviceManager; +static acpi_module_info *sAcpi; +CpuidleModuleInfo *gIdle; + + +static status_t +acpi_eval_pdc(acpi_cpuidle_driver_info *device) +{ + acpi_objects arg; + acpi_object_type obj; + uint32 cap[3]; + + arg.count = 1; + arg.pointer = &obj; + cap[0] = 1; + cap[1] = 1; + cap[2] = ACPI_PDC_C_C1_HALT | ACPI_PDC_SMP_C1PT | ACPI_PDC_SMP_C2C3; + cap[2] |= ACPI_PDC_SMP_P_SW | ACPI_PDC_SMP_C_SW | ACPI_PDC_SMP_T_SW; + cap[2] |= ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH; + cap[2] |= ACPI_PDC_SMP_T_SW | ACPI_PDC_P_FFH | ACPI_PDC_P_HWCOORD | ACPI_PDC_T_FFH; + obj.object_type = ACPI_TYPE_BUFFER; + obj.data.buffer.length = sizeof(cap); + obj.data.buffer.buffer = cap; + status_t status = device->acpi->evaluate_method(device->acpi_cookie, "_PDC", &arg, NULL); + return status; +} + + +static status_t +acpi_eval_osc(acpi_cpuidle_driver_info *device) +{ + // guid for intel platform + dprintf("%s@%p\n", __func__, device->acpi_cookie); + static uint8 uuid[] = { + 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29, 0xBE, 0x47, + 0x9E, 0xBD, 0xD8, 0x70, 0x58, 0x71, 0x39, 0x53 + }; + uint32 cap[2]; + cap[0] = 0; + cap[1] = ACPI_PDC_C_C1_HALT | ACPI_PDC_SMP_C1PT | ACPI_PDC_SMP_C2C3; + cap[1] |= ACPI_PDC_SMP_P_SW | ACPI_PDC_SMP_C_SW | ACPI_PDC_SMP_T_SW; + cap[1] |= ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH; + cap[1] |= ACPI_PDC_SMP_T_SW | ACPI_PDC_P_FFH | ACPI_PDC_P_HWCOORD | ACPI_PDC_T_FFH; + + acpi_objects arg; + acpi_object_type obj[4]; + + arg.count = 4; + arg.pointer = obj; + + obj[0].object_type = ACPI_TYPE_BUFFER; + obj[0].data.buffer.length = sizeof(uuid); + obj[0].data.buffer.buffer = uuid; + obj[1].object_type = ACPI_TYPE_INTEGER; + obj[1].data.integer = ACPI_PDC_REVID; + obj[2].object_type = ACPI_TYPE_INTEGER; + obj[2].data.integer = sizeof(cap)/sizeof(cap[0]); + obj[3].object_type = ACPI_TYPE_BUFFER; + obj[3].data.buffer.length = sizeof(cap); + obj[3].data.buffer.buffer = (void *)cap; + + acpi_data buf; + buf.pointer = NULL; + buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status_t status = device->acpi->evaluate_method(device->acpi_cookie, "_OSC", &arg, &buf); + if (status != B_OK) + return status; + acpi_object_type *osc = (acpi_object_type *)buf.pointer; + if (osc->object_type != ACPI_TYPE_BUFFER) + return B_BAD_TYPE; + if (osc->data.buffer.length != sizeof(cap)) + return B_BUFFER_OVERFLOW; + return status; +} + + +static inline bool +acpi_cstate_bm_check(void) +{ + uint32 val; + sAcpi->read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &val); + if (!val) + return false; + sAcpi->write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); + + return true; +} + + +static inline void +acpi_cstate_ffh_enter(CpuidleCstate *cState) +{ + cpu_ent *cpu = get_cpu_struct(); + if (cpu->invoke_scheduler) + return; + + x86_monitor((void *)&cpu->invoke_scheduler, 0, 0); + if (!cpu->invoke_scheduler) + x86_mwait((unsigned long)cState->pData, 1); +} + + +static inline void +acpi_cstate_halt(void) +{ + cpu_ent *cpu = get_cpu_struct(); + if (cpu->invoke_scheduler) + return; + asm("hlt"); +} + + +static void +acpi_cstate_enter(CpuidleCstate *cState) +{ + acpi_cstate_info *ci = (acpi_cstate_info *)cState->pData; + if (ci->method == ACPI_CSTATE_FFH) + acpi_cstate_ffh_enter(cState); + else if (ci->method == ACPI_CSTATE_SYSIO) + in8(ci->address); + else + acpi_cstate_halt(); +} + + +static int32 +acpi_cstate_idle(int32 state, CpuidleDevice *device) +{ + CpuidleCstate *cState = &device->cStates[state]; + acpi_cstate_info *ci = (acpi_cstate_info *)cState->pData; + if (!ci->skip_bm_sts) { + // we fall back to C1 if there's bus master activity + if (acpi_cstate_bm_check()) + state = 1; + } + if (ci->type != ACPI_STATE_C3) + acpi_cstate_enter(cState); + + // set BM_RLD for Bus Master to activity to wake the system from C3 + // With Newer chipsets BM_RLD is a NOP Since DMA is automatically handled + // during C3 State + acpi_cpuidle_driver_info *pi = acpi_processor[smp_get_current_cpu()]; + if (pi->flags & ACPI_FLAG_C_BM) + sAcpi->write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1); + + // disable bus master arbitration during C3 + if (pi->flags & ACPI_FLAG_C_ARB) + sAcpi->write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); + + acpi_cstate_enter(cState); + + // clear BM_RLD and re-enable the arbiter + if (pi->flags & ACPI_FLAG_C_BM) + sAcpi->write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + + if (pi->flags & ACPI_FLAG_C_ARB) + sAcpi->write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); + + return state; +} + + +static status_t +acpi_cstate_add(acpi_object_type *object, CpuidleCstate *cState) +{ + acpi_cstate_info *ci = (acpi_cstate_info *)malloc(sizeof(acpi_cstate_info)); + if (!ci) + return B_NO_MEMORY; + + if (object->object_type != ACPI_TYPE_PACKAGE) { + dprintf("invalid _CST object\n"); + return B_ERROR; + } + + if (object->data.package.count != 4) { + dprintf("invalid _CST number\n"); + return B_ERROR; + } + + // type + acpi_object_type * pointer = &object->data.package.objects[1]; + if (pointer->object_type != ACPI_TYPE_INTEGER) { + dprintf("invalid _CST elem type\n"); + return B_ERROR; + } + uint32 n = pointer->data.integer; + if (n < 1 || n > 3) { + dprintf("invalid _CST elem value\n"); + return B_ERROR; + } + ci->type = n; + dprintf("C%" B_PRId32 "\n", n); + snprintf(cState->name, sizeof(cState->name), "C%"B_PRId32, n); + + // Latency + pointer = &object->data.package.objects[2]; + if (pointer->object_type != ACPI_TYPE_INTEGER) { + dprintf("invalid _CST elem type\n"); + return B_ERROR; + } + n = pointer->data.integer; + cState->latency = n; + dprintf("Latency: %" B_PRId32 "\n", n); + + // power + pointer = &object->data.package.objects[3]; + if (pointer->object_type != ACPI_TYPE_INTEGER) { + dprintf("invalid _CST elem type\n"); + return B_ERROR; + } + n = pointer->data.integer; + dprintf("power: %" B_PRId32 "\n", n); + + // register + pointer = &object->data.package.objects[0]; + if (pointer->object_type != ACPI_TYPE_BUFFER) { + dprintf("invalid _CST elem type\n"); + return B_ERROR; + } + if (pointer->data.buffer.length < 15) { + dprintf("invalid _CST elem length\n"); + return B_ERROR; + } + + struct acpicpu_reg *reg = (struct acpicpu_reg *)pointer->data.buffer.buffer; + switch (reg->reg_spaceid) { + case ACPI_ADR_SPACE_SYSTEM_IO: + dprintf("IO method\n"); + if (reg->reg_addr == 0) { + dprintf("illegal address\n"); + return B_ERROR; + } + if (reg->reg_bitwidth != 8) { + dprintf("invalid source length\n"); + return B_ERROR; + } + ci->address = reg->reg_addr; + ci->method = ACPI_CSTATE_SYSIO; + break; + case ACPI_ADR_SPACE_FIXED_HARDWARE: + { + dprintf("FFH method\n"); + ci->method = ACPI_CSTATE_FFH; + ci->address = reg->reg_addr; + + // skip checking BM_STS if ACPI_PDC_GAS_BM is cleared + cpu_ent *cpu = get_cpu_struct(); + if ((cpu->arch.vendor == VENDOR_INTEL) && + !(reg->reg_accesssize & ACPI_PDC_GAS_BM)) + ci->skip_bm_sts = 1; + break; + } + default: + dprintf("invalid spaceid %" B_PRId8 "\n", reg->reg_spaceid); + break; + } + cState->pData = ci; + cState->EnterIdle = acpi_cstate_idle; + + return B_OK; +} + + +static void +acpi_cstate_quirks(acpi_cpuidle_driver_info *device) +{ + cpu_ent *cpu = get_cpu_struct(); + // Calculated Model Value: M = (Extended Model << 4) + Model + uint32 model = (cpu->arch.extended_model << 4) + cpu->arch.model; + + // On all recent Intel platforms, ARB_DIS is not necessary + if (cpu->arch.vendor != VENDOR_INTEL) + return; + if (cpu->arch.family > 0xf || (cpu->arch.family == 6 && model >= 0xf)) + device->flags &= ~ACPI_FLAG_C_ARB; +} + + +static status_t +acpi_cpuidle_setup(acpi_cpuidle_driver_info *device) +{ + // _PDC is deprecated in the ACPI 3.0, we will try _OSC firstly + // and fall back to _PDC if _OSC fail + status_t status = acpi_eval_osc(device); + if (status != B_OK) + status = acpi_eval_pdc(device); + if (status != B_OK) { + dprintf("faile to eval _OSC and _PDC\n"); + return status; + } + + acpi_data buffer; + buffer.pointer = NULL; + buffer.length = ACPI_ALLOCATE_BUFFER; + + dprintf("evaluate _CST @%p\n", device->acpi_cookie); + status = device->acpi->evaluate_method(device->acpi_cookie, "_CST", NULL, + &buffer); + if (status != B_OK) { + dprintf("failed to get _CST\n"); + return B_IO_ERROR; + } + + acpi_object_type *object = (acpi_object_type *)buffer.pointer; + if (object->object_type != ACPI_TYPE_PACKAGE) + dprintf("invalid _CST type\n"); + if (object->data.package.count < 2) + dprintf("invalid _CST count\n"); + + acpi_object_type *pointer = object->data.package.objects; + if (pointer[0].object_type != ACPI_TYPE_INTEGER) + dprintf("invalid _CST type 2\n"); + uint32 n = pointer[0].data.integer; + if (n != object->data.package.count - 1) + dprintf("invalid _CST count 2\n"); + if (n > 8) + dprintf("_CST has too many states\n"); + dprintf("cpuidle found %" B_PRId32 " cstates\n", n); + uint32 count = 1; + for (uint32 i = 1; i <= n; i++) { + pointer = &object->data.package.objects[i]; + if (acpi_cstate_add(pointer, &sAcpiDevice.cStates[count]) == B_OK) + ++count; + } + sAcpiDevice.cStateCount = count; + free(buffer.pointer); + + // TODO we assume BM is a must and ARB_DIS is always available + device->flags |= ACPI_FLAG_C_ARB | ACPI_FLAG_C_BM; + + acpi_cstate_quirks(device); + + return B_OK; +} + + +static status_t +acpi_cpuidle_init(void) +{ + dprintf("acpi_cpuidle_init\n"); + + for (int32 i = 0; i < smp_get_num_cpus(); i++) + if (acpi_cpuidle_setup(acpi_processor[i]) != B_OK) + return B_ERROR; + + status_t status = gIdle->AddDevice(&sAcpiDevice); + if (status == B_OK) + dprintf("using acpi idle\n"); + return status; +} + + +static status_t +acpi_processor_init(acpi_cpuidle_driver_info *device) +{ + status_t status = B_ERROR; + + acpi_data buffer; + buffer.pointer = NULL; + buffer.length = ACPI_ALLOCATE_BUFFER; + dprintf("get acpi processor @%p\n", device->acpi_cookie); + status = device->acpi->evaluate_method(device->acpi_cookie, NULL, NULL, + &buffer); + if (status != B_OK) { + dprintf("failed to get processor obj\n"); + return B_IO_ERROR; + } + acpi_object_type *object = (acpi_object_type *)buffer.pointer; + dprintf("acpi cpu%"B_PRId32": P_BLK at %#x/%lu\n", + object->data.processor.cpu_id, + object->data.processor.pblk_address, + object->data.processor.pblk_length); + int32 cpuid = object->data.processor.cpu_id; + free(buffer.pointer); + if (cpuid > smp_get_num_cpus()) + return B_ERROR; + + if (smp_get_num_cpus() == 1) + cpuid = 1; + + acpi_processor[cpuid-1] = device; + + if (cpuid == 1) { + if (intel_cpuidle_init() != B_OK) + return acpi_cpuidle_init(); + } + + return B_OK; +} + + +static float +acpi_cpuidle_support(device_node *parent) +{ + const char *bus; + uint32 device_type; + + dprintf("acpi_cpuidle_support\n"); + // make sure parent is really the ACPI bus manager + if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) + return -1; + + if (strcmp(bus, "acpi")) + return 0.0; + + // check whether it's really a cpu Device + if (sDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM, &device_type, false) != B_OK + || device_type != ACPI_TYPE_PROCESSOR) { + return 0.0; + } + + return 0.6; +} + + +static status_t +acpi_cpuidle_register_device(device_node *node) +{ + device_attr attrs[] = { + { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "ACPI CPU IDLE" }}, + { NULL } + }; + + dprintf("acpi_cpuidle_register_device\n"); + return sDeviceManager->register_node(node, ACPI_CPUIDLE_MODULE_NAME, attrs, + NULL, NULL); +} + + +static status_t +acpi_cpuidle_init_driver(device_node *node, void **driverCookie) +{ + dprintf("acpi_cpuidle_init_driver\n"); + acpi_cpuidle_driver_info *device; + device = (acpi_cpuidle_driver_info *)calloc(1, sizeof(*device)); + if (device == NULL) + return B_NO_MEMORY; + + *driverCookie = device; + + device->node = node; + + device_node *parent; + parent = sDeviceManager->get_parent_node(node); + sDeviceManager->get_driver(parent, (driver_module_info **)&device->acpi, + (void **)&device->acpi_cookie); + sDeviceManager->put_node(parent); + + return acpi_processor_init(device); +} + + +static void +acpi_cpuidle_uninit_driver(void *driverCookie) +{ + dprintf("acpi_cpuidle_uninit_driver"); + acpi_cpuidle_driver_info *device = (acpi_cpuidle_driver_info *)driverCookie; + free(device); +} + + +module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager }, + { B_ACPI_MODULE_NAME, (module_info **)&sAcpi}, + { B_CPUIDLE_MODULE_NAME, (module_info **)&gIdle }, + {} +}; + + +static driver_module_info sAcpiidleModule = { + { + ACPI_CPUIDLE_MODULE_NAME, + 0, + NULL + }, + + acpi_cpuidle_support, + acpi_cpuidle_register_device, + acpi_cpuidle_init_driver, + acpi_cpuidle_uninit_driver, + NULL, + NULL, // rescan + NULL, // removed +}; + + +module_info *modules[] = { + (module_info *)&sAcpiidleModule, + NULL +}; diff --git a/src/add-ons/kernel/drivers/power/x86_cpuidle/intel_cpuidle.cpp b/src/add-ons/kernel/drivers/power/x86_cpuidle/intel_cpuidle.cpp new file mode 100644 index 0000000000..7f6fbd6c4b --- /dev/null +++ b/src/add-ons/kernel/drivers/power/x86_cpuidle/intel_cpuidle.cpp @@ -0,0 +1,121 @@ +/* + * Copyright 2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Yongcong Du + */ + +#include +#include +#include + +#include + +#include + +#include "x86_cpuidle.h" + +static CpuidleDevice sIntelDevice; + +static void *kMwaitEax[] = { + // C0, we never use it + (void *)0x00, + // MWAIT C1 + (void *)0x00, + // MWAIT C2 + (void *)0x10, + // MWAIT C3 + (void *)0x20, + // MWAIT C4 + (void *)0x30, + // MWAIT C5 + (void *)0x40, + // MWAIT C6, 0x2 is used to fully shrink L2 cache + (void *)0x52 +}; + + +static int32 +IntelCstateIdleEnter(int32 state, CpuidleDevice *device) +{ + cpu_ent *cpu = get_cpu_struct(); + if (cpu->invoke_scheduler) + return 0; + + CpuidleCstate *cState = &device->cStates[state]; + x86_monitor((void *)&cpu->invoke_scheduler, 0, 0); + if (!cpu->invoke_scheduler) + x86_mwait((unsigned long)cState->pData, 1); + + return state; +} + + +static CpuidleCstate sSnbcStates[CPUIDLE_CSTATE_MAX] = { + {}, + { + "C1-SNB", + 1, + IntelCstateIdleEnter, + }, + { + "C3-SNB", + 80, + IntelCstateIdleEnter, + }, + { + "C6-SNB", + 104, + IntelCstateIdleEnter, + }, + { + "C7-SNB", + 109, + IntelCstateIdleEnter, + }, +}; + + +status_t +intel_cpuidle_init(void) +{ + dprintf("intel idle init\n"); + cpu_ent *cpu = get_cpu_struct(); + if (cpu->arch.vendor != VENDOR_INTEL || cpu->arch.family != 6) + return B_ERROR; + + // Calculated Model Value: M = (Extended Model << 4) + Model + uint32 model = (cpu->arch.extended_model << 4) + cpu->arch.model; + if (model != 0x2a && model != 0x2d) + return B_ERROR; + + cpuid_info cpuid; + get_current_cpuid(&cpuid, 5); + /* ecx[0] monitor/mwait extension supported + * ecx[1] support for treating interrupts as break-events for mwait + * edx number of sub-states + */ + if ((cpuid.regs.ecx & 0x1) == 0 || + (cpuid.regs.ecx & 0x2) == 0 || + cpuid.regs.edx == 0) { + return B_ERROR; + } + + sIntelDevice.cStateCount = 1; + for (int32 i = 1; i < CPUIDLE_CSTATE_MAX; i++) { + int32 subStates = (cpuid.regs.edx >> ((i) * 4)) & 0xf; + // no sub-states means the state is not available + if (!subStates) + continue; + sIntelDevice.cStates[sIntelDevice.cStateCount] = + sSnbcStates[i]; + sIntelDevice.cStates[sIntelDevice.cStateCount].pData = + kMwaitEax[i]; + sIntelDevice.cStateCount++; + } + status_t status = gIdle->AddDevice(&sIntelDevice); + if (status == B_OK) + dprintf("using intel idle\n"); + return status; +} diff --git a/src/add-ons/kernel/drivers/power/x86_cpuidle/x86_cpuidle.h b/src/add-ons/kernel/drivers/power/x86_cpuidle/x86_cpuidle.h new file mode 100644 index 0000000000..4b6285cb34 --- /dev/null +++ b/src/add-ons/kernel/drivers/power/x86_cpuidle/x86_cpuidle.h @@ -0,0 +1,30 @@ +/* + * Copyright 2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern CpuidleModuleInfo *gIdle; + +static inline void +x86_monitor(const void *addr, unsigned long ecx, unsigned long edx) +{ + asm volatile("monitor" + :: "a" (addr), "c" (ecx), "d"(edx)); +} + +static inline void +x86_mwait(unsigned long eax, unsigned long ecx) +{ + asm volatile("mwait" + :: "a" (eax), "c" (ecx)); +} + +status_t intel_cpuidle_init(void); + +#ifdef __cplusplus +} +#endif diff --git a/src/add-ons/kernel/drivers/tty/tty.cpp b/src/add-ons/kernel/drivers/tty/tty.cpp index d18d91c154..4cc10d1ee4 100644 --- a/src/add-ons/kernel/drivers/tty/tty.cpp +++ b/src/add-ons/kernel/drivers/tty/tty.cpp @@ -1480,14 +1480,14 @@ tty_write_to_tty_slave_unsafe(tty_cookie* sourceCookie, const char* data, static void dump_tty_settings(struct tty_settings& settings) { - kprintf(" pgrp_id: %ld\n", settings.pgrp_id); - kprintf(" session_id: %ld\n", settings.session_id); + kprintf(" pgrp_id: %" B_PRId32 "\n", settings.pgrp_id); + kprintf(" session_id: %" B_PRId32 "\n", settings.session_id); kprintf(" termios:\n"); - kprintf(" c_iflag: 0x%08lx\n", settings.termios.c_iflag); - kprintf(" c_oflag: 0x%08lx\n", settings.termios.c_oflag); - kprintf(" c_cflag: 0x%08lx\n", settings.termios.c_cflag); - kprintf(" c_lflag: 0x%08lx\n", settings.termios.c_lflag); + kprintf(" c_iflag: 0x%08" B_PRIx32 "\n", settings.termios.c_iflag); + kprintf(" c_oflag: 0x%08" B_PRIx32 "\n", settings.termios.c_oflag); + kprintf(" c_cflag: 0x%08" B_PRIx32 "\n", settings.termios.c_cflag); + kprintf(" c_lflag: 0x%08" B_PRIx32 "\n", settings.termios.c_lflag); kprintf(" c_line: %d\n", settings.termios.c_line); kprintf(" c_ispeed: %u\n", settings.termios.c_ispeed); kprintf(" c_ospeed: %u\n", settings.termios.c_ospeed); @@ -1504,15 +1504,15 @@ static void dump_tty_struct(struct tty& tty) { kprintf(" tty @: %p\n", &tty); - kprintf(" index: %ld\n", tty.index); + kprintf(" index: %" B_PRId32 "\n", tty.index); kprintf(" is_master: %s\n", tty.is_master ? "true" : "false"); - kprintf(" open_count: %ld\n", tty.open_count); + kprintf(" open_count: %" B_PRId32 "\n", tty.open_count); kprintf(" select_pool: %p\n", tty.select_pool); - kprintf(" pending_eof: %lu\n", tty.pending_eof); + kprintf(" pending_eof: %" B_PRIu32 "\n", tty.pending_eof); kprintf(" lock: %p\n", tty.lock); kprintf(" input_buffer:\n"); - kprintf(" first: %ld\n", tty.input_buffer.first); + kprintf(" first: %" B_PRId32 "\n", tty.input_buffer.first); kprintf(" in: %lu\n", tty.input_buffer.in); kprintf(" size: %lu\n", tty.input_buffer.size); kprintf(" buffer: %p\n", tty.input_buffer.buffer); @@ -1782,7 +1782,7 @@ tty_ioctl(tty_cookie* cookie, uint32 op, void* buffer, size_t length) // wait for event (timeout if !NULL) case TCVTIME: // BeOS (bigtime_t*) set highrez VTIME case 'ochr': // BeOS (int*) same as ichr for write - dprintf("tty: unsupported legacy opcode %lu\n", op); + dprintf("tty: unsupported legacy opcode %" B_PRIu32 "\n", op); // TODO ? break; @@ -1791,7 +1791,7 @@ tty_ioctl(tty_cookie* cookie, uint32 op, void* buffer, size_t length) break; case TCQUERYCONNECTED: // BeOS - dprintf("tty: unsupported legacy opcode %lu\n", op); + dprintf("tty: unsupported legacy opcode %" B_PRIu32 "\n", op); // BeOS didn't implement them anyway break; diff --git a/src/add-ons/kernel/file_cache/Jamfile b/src/add-ons/kernel/file_cache/Jamfile index 02ccf99341..6d83c5a6d0 100644 --- a/src/add-ons/kernel/file_cache/Jamfile +++ b/src/add-ons/kernel/file_cache/Jamfile @@ -1,7 +1,7 @@ SubDir HAIKU_TOP src add-ons kernel file_cache ; UsePrivateKernelHeaders ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] ; UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; KernelAddon log : diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp index 82b00469c5..df5d999206 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp @@ -767,7 +767,7 @@ BPlusTree::Validate(bool repair, bool& _errorsFound) fHeader.MaxNumberOfLevels()); } - if (check.VisitedCount() != fHeader.MaximumSize() / fNodeSize) { + if ((off_t)check.VisitedCount() != fHeader.MaximumSize() / fNodeSize) { dprintf("inode %" B_PRIdOFF ": visited %" B_PRIuSIZE " from %" B_PRIdOFF " nodes.\n", fStream->ID(), check.VisitedCount(), fHeader.MaximumSize() / fNodeSize); @@ -791,7 +791,7 @@ BPlusTree::MakeEmpty() header->max_number_of_levels = HOST_ENDIAN_TO_BFS_INT32(1); header->root_node_pointer = HOST_ENDIAN_TO_BFS_INT64(NodeSize()); - if (fStream->Size() > NodeSize() * 2) + if (fStream->Size() > (off_t)NodeSize() * 2) header->free_node_pointer = HOST_ENDIAN_TO_BFS_INT64(2 * NodeSize()); else { header->free_node_pointer @@ -812,10 +812,10 @@ BPlusTree::MakeEmpty() offset += NodeSize()) { bplustree_node* node = cached.SetToWritable(transaction, offset, false); if (node == NULL) { - dprintf("--> could not open %lld\n", offset); + dprintf("--> could not open %" B_PRIdOFF "\n", offset); return B_IO_ERROR; } - if (offset < fStream->Size() - NodeSize()) + if (offset < fStream->Size() - (off_t)NodeSize()) node->left_link = HOST_ENDIAN_TO_BFS_INT64(offset + NodeSize()); else node->left_link = HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL); @@ -2913,8 +2913,8 @@ bplustree_node::CheckIntegrity(uint32 nodeSize) const return B_BAD_DATA; } if (Values()[i] == -1) { - dprintf("invalid node %p, value %d: %lld: values corrupted\n", - this, (int)i, Values()[i]); + dprintf("invalid node %p, value %d: %" B_PRIdOFF ": values " + "corrupted\n", this, (int)i, Values()[i]); return B_BAD_DATA; } } diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index 2b0baacb43..feebed32c6 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -2132,8 +2132,8 @@ BlockAllocator::_AddInodeToIndex(Inode* inode) void BlockAllocator::Dump(int32 index) { - kprintf("allocation groups: %ld (base %p)\n", fNumGroups, fGroups); - kprintf("blocks per group: %ld\n", fBlocksPerGroup); + kprintf("allocation groups: %" B_PRId32 " (base %p)\n", fNumGroups, fGroups); + kprintf("blocks per group: %" B_PRId32 "\n", fBlocksPerGroup); for (int32 i = 0; i < fNumGroups; i++) { if (index != -1 && i != index) @@ -2141,15 +2141,15 @@ BlockAllocator::Dump(int32 index) AllocationGroup& group = fGroups[i]; - kprintf("[%3ld] num bits: %lu (%p)\n", i, group.NumBits(), - &group); - kprintf(" num blocks: %lu\n", group.NumBlocks()); - kprintf(" start: %ld\n", group.Start()); - kprintf(" first free: %ld\n", group.fFirstFree); - kprintf(" largest start: %ld%s\n", group.fLargestStart, + kprintf("[%3" B_PRId32 "] num bits: %" B_PRIu32 " (%p)\n", i, + group.NumBits(), &group); + kprintf(" num blocks: %" B_PRIu32 "\n", group.NumBlocks()); + kprintf(" start: %" B_PRId32 "\n", group.Start()); + kprintf(" first free: %" B_PRId32 "\n", group.fFirstFree); + kprintf(" largest start: %" B_PRId32 "%s\n", group.fLargestStart, group.fLargestValid ? "" : " (invalid)"); - kprintf(" largest length: %ld\n", group.fLargestLength); - kprintf(" free bits: %ld\n", group.fFreeBits); + kprintf(" largest length: %" B_PRId32 "\n", group.fLargestLength); + kprintf(" free bits: %" B_PRId32 "\n", group.fFreeBits); } } diff --git a/src/add-ons/kernel/file_systems/bfs/Debug.cpp b/src/add-ons/kernel/file_systems/bfs/Debug.cpp index f9c6cf71b8..02a8a58972 100644 --- a/src/add-ons/kernel/file_systems/bfs/Debug.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Debug.cpp @@ -299,8 +299,9 @@ dump_inode(int argc, char** argv) kprintf(" tree: %p\n", inode->Tree()); kprintf(" file cache: %p\n", inode->FileCache()); kprintf(" file map: %p\n", inode->Map()); - kprintf(" old size: %Ld\n", inode->OldSize()); - kprintf(" old last modified: %Ld\n", inode->OldLastModified()); + kprintf(" old size: %" B_PRIdOFF "\n", inode->OldSize()); + kprintf(" old last modified: %" B_PRIdOFF "\n", + inode->OldLastModified()); node = &inode->Node(); } @@ -334,8 +335,9 @@ dump_volume(int argc, char** argv) run.start = HOST_ENDIAN_TO_BFS_INT16(strtoul(arg + 1, NULL, 0)); run.length = 0; - kprintf("%ld.%u -> block %Ld, bitmap block %ld\n", - run.AllocationGroup(), run.Start(), volume->ToBlock(run), + kprintf("%" B_PRId32 ".%u -> block %" B_PRIdOFF ", bitmap block" + " %" B_PRId32 "\n", run.AllocationGroup(), run.Start(), + volume->ToBlock(run), volume->SuperBlock().BlocksPerAllocationGroup() * run.AllocationGroup() + 1); } else { @@ -343,16 +345,16 @@ dump_volume(int argc, char** argv) off_t offset = parse_expression(arg); block_run run = volume->ToBlockRun(offset); - kprintf("block %Ld -> %ld.%u, bitmap block %ld\n", offset, - run.AllocationGroup(), run.Start(), - volume->SuperBlock().BlocksPerAllocationGroup() + kprintf("block %" B_PRIdOFF " -> %" B_PRId32 ".%u, bitmap block" + " %" B_PRId32 "\n", offset, run.AllocationGroup(), + run.Start(), volume->SuperBlock().BlocksPerAllocationGroup() * run.AllocationGroup() + 1); } } return 0; } - kprintf("id: %ld\n", volume->ID()); + kprintf("id: %" B_PRId32 "\n", volume->ID()); kprintf("block cache: %p\n", volume->BlockCache()); kprintf("journal: %p\n", volume->GetJournal(0)); kprintf("allocator: %p\n", &volume->Allocator()); @@ -397,9 +399,9 @@ dump_block_run_array(int argc, char** argv) for (uint32 i = 0; i < count; i++) { if (blockSize != 0) - dprintf("[%3lu] %10" B_PRIdOFF " ", i, offset); + dprintf("[%3" B_PRIu32 "] %10" B_PRIdOFF " ", i, offset); else - dprintf("[%3lu] ", i); + dprintf("[%3" B_PRIu32 "] ", i); uint32 size = runs[i].Length() * blockSize; if (searchOffset != 0 && searchOffset >= offset diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.cpp b/src/add-ons/kernel/file_systems/bfs/Journal.cpp index 473ad284ca..a10f76ff84 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Journal.cpp @@ -1093,15 +1093,15 @@ void Journal::Dump() { kprintf("Journal %p\n", this); - kprintf(" log start: %ld\n", fVolume->LogStart()); - kprintf(" log end: %ld\n", fVolume->LogEnd()); + kprintf(" log start: %" B_PRId32 "\n", fVolume->LogStart()); + kprintf(" log end: %" B_PRId32 "\n", fVolume->LogEnd()); kprintf(" owner: %p\n", fOwner); - kprintf(" log size: %lu\n", fLogSize); - kprintf(" max transaction size: %lu\n", fMaxTransactionSize); - kprintf(" used: %lu\n", fUsed); - kprintf(" unwritten: %ld\n", fUnwrittenTransactions); - kprintf(" timestamp: %lld\n", fTimestamp); - kprintf(" transaction ID: %ld\n", fTransactionID); + kprintf(" log size: %" B_PRIu32 "\n", fLogSize); + kprintf(" max transaction size: %" B_PRIu32 "\n", fMaxTransactionSize); + kprintf(" used: %" B_PRIu32 "\n", fUsed); + kprintf(" unwritten: %" B_PRId32 "\n", fUnwrittenTransactions); + kprintf(" timestamp: %" B_PRId64 "\n", fTimestamp); + kprintf(" transaction ID: %" B_PRId32 "\n", fTransactionID); kprintf(" has subtransaction: %d\n", fHasSubtransaction); kprintf(" separate sub-trans.: %d\n", fSeparateSubTransactions); kprintf("entries:\n"); @@ -1112,8 +1112,8 @@ Journal::Dump() while (iterator.HasNext()) { LogEntry* entry = iterator.Next(); - kprintf(" %p %6ld %6lu %6lu\n", entry, entry->TransactionID(), - entry->Start(), entry->Length()); + kprintf(" %p %6" B_PRId32 " %6" B_PRIu32 " %6" B_PRIu32 "\n", entry, + entry->TransactionID(), entry->Start(), entry->Length()); } } diff --git a/src/add-ons/kernel/file_systems/bindfs/Jamfile b/src/add-ons/kernel/file_systems/bindfs/Jamfile index dd5d19091e..4e6892d178 100644 --- a/src/add-ons/kernel/file_systems/bindfs/Jamfile +++ b/src/add-ons/kernel/file_systems/bindfs/Jamfile @@ -16,7 +16,7 @@ HAIKU_BIND_FS_SOURCES = KernelAddon bindfs : $(HAIKU_BIND_FS_SOURCES) - : $(HAIKU_STATIC_LIBSUPC++) + : $(HAIKU_KERNEL_LIBSUPC++) ; diff --git a/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp b/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp index 5fd8d6c75c..cdd0916c0a 100644 --- a/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp +++ b/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp @@ -265,7 +265,7 @@ OverlayInode::OverlayInode(OverlayVolume *volume, fs_vnode *superVnode, fIsDataModified(false), fFileCache(NULL) { - TRACE("inode created %lld\n", fInodeNumber); + TRACE("inode created %" B_PRIdINO "\n", fInodeNumber); recursive_lock_init(&fLock, "write overlay inode lock"); if (superVnode != NULL) @@ -290,7 +290,7 @@ OverlayInode::OverlayInode(OverlayVolume *volume, fs_vnode *superVnode, OverlayInode::~OverlayInode() { - TRACE("inode destroyed %lld\n", fInodeNumber); + TRACE("inode destroyed %" B_PRIdINO "\n", fInodeNumber); if (fFileCache != NULL) file_cache_delete(fFileCache); diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index d0576a0423..d3df7997fb 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -89,7 +89,7 @@ KernelAddon packagefs $(HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES) $(libSharedSources) - : $(HAIKU_STATIC_LIBSUPC++) libz.a + : $(HAIKU_KERNEL_LIBSUPC++) libz.a ; diff --git a/src/add-ons/kernel/file_systems/ramfs/Jamfile b/src/add-ons/kernel/file_systems/ramfs/Jamfile index 9dc1ba8fa3..5e04563c3a 100644 --- a/src/add-ons/kernel/file_systems/ramfs/Jamfile +++ b/src/add-ons/kernel/file_systems/ramfs/Jamfile @@ -45,5 +45,5 @@ KernelAddon ramfs SymLink.cpp Volume.cpp - : $(HAIKU_LIBSUPC++) + : $(HAIKU_KERNEL_LIBSUPC++) ; diff --git a/src/add-ons/kernel/file_systems/reiserfs/Jamfile b/src/add-ons/kernel/file_systems/reiserfs/Jamfile index 571c2a1c9b..b28d32fc07 100644 --- a/src/add-ons/kernel/file_systems/reiserfs/Jamfile +++ b/src/add-ons/kernel/file_systems/reiserfs/Jamfile @@ -28,5 +28,5 @@ KernelAddon reiserfs VNode.cpp Volume.cpp - : $(HAIKU_STATIC_LIBSUPC++) + : $(HAIKU_KERNEL_LIBSUPC++) ; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Jamfile b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Jamfile index 153fd267c8..7c842e7f73 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Jamfile +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Jamfile @@ -41,5 +41,5 @@ KernelAddon userlandfs UserlandFS.cpp Volume.cpp - : $(HAIKU_STATIC_LIBSUPC++) + : $(HAIKU_KERNEL_LIBSUPC++) ; diff --git a/src/add-ons/kernel/generic/Jamfile b/src/add-ons/kernel/generic/Jamfile index a2a6bfc1fa..9a1677d11b 100644 --- a/src/add-ons/kernel/generic/Jamfile +++ b/src/add-ons/kernel/generic/Jamfile @@ -2,6 +2,8 @@ SubDir HAIKU_TOP src add-ons kernel generic ; SubInclude HAIKU_TOP src add-ons kernel generic ata_adapter ; SubInclude HAIKU_TOP src add-ons kernel generic atomizer ; +SubInclude HAIKU_TOP src add-ons kernel generic bios ; +SubInclude HAIKU_TOP src add-ons kernel generic cpuidle ; SubInclude HAIKU_TOP src add-ons kernel generic dpc ; SubInclude HAIKU_TOP src add-ons kernel generic ide_adapter ; SubInclude HAIKU_TOP src add-ons kernel generic locked_pool ; diff --git a/src/add-ons/kernel/generic/ata_adapter/ata_adapter.cpp b/src/add-ons/kernel/generic/ata_adapter/ata_adapter.cpp index 4289ed755b..e0a258a7b9 100644 --- a/src/add-ons/kernel/generic/ata_adapter/ata_adapter.cpp +++ b/src/add-ons/kernel/generic/ata_adapter/ata_adapter.cpp @@ -250,8 +250,8 @@ ata_adapter_prepare_dma(ata_adapter_channel_info *channel, writeToDevice ? "write" : "read", sgListCount); for (i = sgListCount - 1, prd = channel->prdt; i >= 0; --i, ++prd, ++sgList) { - prd->address = B_HOST_TO_LENDIAN_INT32((uint32)pci->ram_address(device, - (void*)(addr_t)sgList->address)); + prd->address = B_HOST_TO_LENDIAN_INT32((uint32)(addr_t)pci->ram_address( + device, (void*)(addr_t)sgList->address)); // 0 means 64K - this is done automatically be discarding upper 16 bits prd->count = B_HOST_TO_LENDIAN_INT16((uint16)sgList->size); prd->EOT = i == 0; @@ -266,8 +266,8 @@ ata_adapter_prepare_dma(ata_adapter_channel_info *channel, pci->write_io_32(device, channel->bus_master_base + ATA_BM_PRDT_ADDRESS, (pci->read_io_32(device, channel->bus_master_base + ATA_BM_PRDT_ADDRESS) & 3) - | (B_HOST_TO_LENDIAN_INT32((uint32)pci->ram_address(device, - (void *)channel->prdt_phys)) & ~3)); + | (B_HOST_TO_LENDIAN_INT32((uint32)(addr_t)pci->ram_address(device, + (void*)(addr_t)channel->prdt_phys)) & ~3)); // reset interrupt and error signal status = pci->read_io_8(device, channel->bus_master_base diff --git a/src/add-ons/kernel/generic/bios/Jamfile b/src/add-ons/kernel/generic/bios/Jamfile new file mode 100644 index 0000000000..cab1336c9c --- /dev/null +++ b/src/add-ons/kernel/generic/bios/Jamfile @@ -0,0 +1,23 @@ +SubDir HAIKU_TOP src add-ons kernel generic bios ; + +UseHeaders [ LibraryHeaders x86emu ] ; +UsePrivateKernelHeaders ; + +SEARCH_SOURCE += [ FDirName $(SUBDIR) x86emu ] ; + +local x86emuSources = + decode.c + fpu.c + ops.c + ops2.c + prim_ops.c + sys.c +; + +KernelAddon bios : + $(x86emuSources) + bios.cpp +; + +SEARCH on [ FGristFiles $(x86emuSources) ] + = [ FDirName $(HAIKU_TOP) src libs x86emu ] ; diff --git a/src/add-ons/kernel/generic/bios/bios.cpp b/src/add-ons/kernel/generic/bios/bios.cpp new file mode 100644 index 0000000000..a887896226 --- /dev/null +++ b/src/add-ons/kernel/generic/bios/bios.cpp @@ -0,0 +1,367 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include + +#include +#include +#include + +#include "x86emu.h" + + +struct BIOSState { + BIOSState() + : + mapped_address(0), + bios_area(-1), + ram_area(-1), + allocated_size(0) + { + } + + ~BIOSState() + { + if (bios_area >= 0) + delete_area(bios_area); + if (ram_area >= 0) + delete_area(ram_area); + } + + addr_t mapped_address; + area_id bios_area; + area_id ram_area; + size_t allocated_size; +}; + + +// BIOS memory layout definitions. +static const uint32 kBDABase = 0; +static const uint32 kBDASize = 0x1000; +static const uint32 kEBDABase = 0x90000; +static const uint32 kEBDASize = 0x70000; +static const uint32 kRAMBase = 0x1000; +static const uint32 kRAMSize = 0x8f000; +static const uint32 kStackSize = 0x1000; +static const uint32 kTotalSize = 0x100000; + + +static sem_id sBIOSLock; +static BIOSState* sCurrentBIOSState; + + +// #pragma mark - X86EMU hooks. + + +static x86emuu8 +x86emu_pio_inb(X86EMU_pioAddr port) +{ + return in8(port); +} + + +static x86emuu16 +x86emu_pio_inw(X86EMU_pioAddr port) +{ + return in16(port); +} + + +static x86emuu32 +x86emu_pio_inl(X86EMU_pioAddr port) +{ + return in32(port); +} + + +static void +x86emu_pio_outb(X86EMU_pioAddr port, x86emuu8 data) +{ + out8(data, port); +} + + +static void +x86emu_pio_outw(X86EMU_pioAddr port, x86emuu16 data) +{ + out16(data, port); +} + + +static void +x86emu_pio_outl(X86EMU_pioAddr port, x86emuu32 data) +{ + out32(data, port); +} + + +static X86EMU_pioFuncs x86emu_pio_funcs = { + x86emu_pio_inb, + x86emu_pio_inw, + x86emu_pio_inl, + x86emu_pio_outb, + x86emu_pio_outw, + x86emu_pio_outl, +}; + + +static x86emuu8 +x86emu_mem_rdb(x86emuu32 addr) +{ + return *(x86emuu8*)((addr_t)addr + sCurrentBIOSState->mapped_address); +} + + +static x86emuu16 +x86emu_mem_rdw(x86emuu32 addr) +{ + return *(x86emuu16*)((addr_t)addr + sCurrentBIOSState->mapped_address); +} + + +static x86emuu32 +x86emu_mem_rdl(x86emuu32 addr) +{ + return *(x86emuu32*)((addr_t)addr + sCurrentBIOSState->mapped_address); +} + + +static void +x86emu_mem_wrb(x86emuu32 addr, x86emuu8 val) +{ + *(x86emuu8*)((addr_t)addr + sCurrentBIOSState->mapped_address) = val; +} + + +static void +x86emu_mem_wrw(x86emuu32 addr, x86emuu16 val) +{ + *(x86emuu16*)((addr_t)addr + sCurrentBIOSState->mapped_address) = val; +} + + +static void +x86emu_mem_wrl(x86emuu32 addr, x86emuu32 val) +{ + *(x86emuu32*)((addr_t)addr + sCurrentBIOSState->mapped_address) = val; +} + + +static X86EMU_memFuncs x86emu_mem_funcs = { + x86emu_mem_rdb, + x86emu_mem_rdw, + x86emu_mem_rdl, + x86emu_mem_wrb, + x86emu_mem_wrw, + x86emu_mem_wrl, +}; + + +// #pragma mark - + + +static void* +bios_allocate_mem(bios_state* state, size_t size) +{ + // Simple allocator for memory to pass to the BIOS. No need for a complex + // allocator here, there is only a few allocations per BIOS usage. + + size = ROUNDUP(size, 4); + + if (state->allocated_size + size > kRAMSize) + return NULL; + + void* address + = (void*)(state->mapped_address + kRAMBase + state->allocated_size); + state->allocated_size += size; + + return address; +} + + +static uint32 +bios_physical_address(bios_state* state, void* virtualAddress) +{ + return (uint32)((addr_t)virtualAddress - state->mapped_address); +} + + +static void* +bios_virtual_address(bios_state* state, uint32 physicalAddress) +{ + return (void*)((addr_t)physicalAddress + state->mapped_address); +} + + +static status_t +bios_prepare(bios_state** _state) +{ + status_t status; + + BIOSState* state = new(std::nothrow) BIOSState; + if (state == NULL) + return B_NO_MEMORY; + ObjectDeleter stateDeleter(state); + + // Reserve a chunk of address space to map at. + status = vm_reserve_address_range(VMAddressSpace::KernelID(), + (void**)&state->mapped_address, B_ANY_KERNEL_ADDRESS, + kTotalSize, 0); + if (status != B_OK) + return status; + + // Map RAM for for the BIOS. + state->ram_area = create_area("bios ram", (void**)&state->mapped_address, + B_EXACT_ADDRESS, kBDASize + kRAMSize, B_NO_LOCK, B_KERNEL_READ_AREA + | B_KERNEL_WRITE_AREA); + if (state->ram_area < B_OK) { + vm_unreserve_address_range(VMAddressSpace::KernelID(), + (void*)state->mapped_address, kTotalSize); + return state->ram_area; + } + + // Copy the interrupt vectors and the BIOS data area. + status = vm_memcpy_from_physical((void*)state->mapped_address, kBDABase, + kBDASize, false); + if (status != B_OK) { + vm_unreserve_address_range(VMAddressSpace::KernelID(), + (void*)state->mapped_address, kTotalSize); + return status; + } + + // Map the extended BIOS data area and VGA memory. + void* address = (void*)(state->mapped_address + kEBDABase); + state->bios_area = map_physical_memory("bios", kEBDABase, kEBDASize, + B_EXACT_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, &address); + if (state->bios_area < B_OK) { + vm_unreserve_address_range(VMAddressSpace::KernelID(), + (void*)state->mapped_address, kTotalSize); + return state->bios_area; + } + + // Attempt to acquire exclusive access to the BIOS. + acquire_sem(sBIOSLock); + + stateDeleter.Detach(); + *_state = state; + return B_OK; +} + + +static status_t +bios_interrupt(bios_state* state, uint8 vector, bios_regs* regs) +{ + sCurrentBIOSState = state; + + // Allocate a stack. + void* stack = bios_allocate_mem(state, kStackSize); + if (stack == NULL) + return B_NO_MEMORY; + uint32 stackTop = bios_physical_address(state, stack) + kStackSize; + + // X86EMU finishes when it encounters a HLT instruction, allocate a + // byte to store one in and set the return address of the interrupt to + // point to it. + void* halt = bios_allocate_mem(state, 1); + if (halt == NULL) + return B_NO_MEMORY; + *(uint8*)halt = 0xF4; + + // Copy in the registers. + memset(&M, 0, sizeof(M)); + M.x86.R_EAX = regs->eax; + M.x86.R_EBX = regs->ebx; + M.x86.R_ECX = regs->ecx; + M.x86.R_EDX = regs->edx; + M.x86.R_EDI = regs->edi; + M.x86.R_ESI = regs->esi; + M.x86.R_EBP = regs->ebp; + M.x86.R_EFLG = regs->eflags | X86_EFLAGS_INTERRUPT | X86_EFLAGS_RESERVED1; + M.x86.R_EIP = bios_physical_address(state, halt); + M.x86.R_CS = 0x0; + M.x86.R_DS = regs->ds; + M.x86.R_ES = regs->es; + M.x86.R_FS = regs->fs; + M.x86.R_GS = regs->gs; + M.x86.R_SS = stackTop >> 4; + M.x86.R_ESP = stackTop - (M.x86.R_SS << 4); + + /* Run the interrupt. */ + X86EMU_setupPioFuncs(&x86emu_pio_funcs); + X86EMU_setupMemFuncs(&x86emu_mem_funcs); + X86EMU_prepareForInt(vector); + X86EMU_exec(); + + // Copy back modified data. + regs->eax = M.x86.R_EAX; + regs->ebx = M.x86.R_EBX; + regs->ecx = M.x86.R_ECX; + regs->edx = M.x86.R_EDX; + regs->edi = M.x86.R_EDI; + regs->esi = M.x86.R_ESI; + regs->ebp = M.x86.R_EBP; + regs->eflags = M.x86.R_EFLG; + regs->ds = M.x86.R_DS; + regs->es = M.x86.R_ES; + regs->fs = M.x86.R_FS; + regs->gs = M.x86.R_GS; + + return B_OK; +} + + +static void +bios_finish(bios_state* state) +{ + release_sem(sBIOSLock); + + delete state; +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + sBIOSLock = create_sem(1, "bios lock"); + if (sBIOSLock < B_OK) + return sBIOSLock; + + return B_OK; + case B_MODULE_UNINIT: + delete_sem(sBIOSLock); + return B_OK; + default: + return B_ERROR; + } +} + + +static bios_module_info sBIOSModule = { + { + B_BIOS_MODULE_NAME, + 0, + std_ops + }, + + bios_prepare, + bios_interrupt, + bios_finish, + bios_allocate_mem, + bios_physical_address, + bios_virtual_address +}; + + +module_info *modules[] = { + (module_info*)&sBIOSModule, + NULL +}; diff --git a/src/add-ons/kernel/generic/cpuidle/Jamfile b/src/add-ons/kernel/generic/cpuidle/Jamfile new file mode 100644 index 0000000000..bb7cdd2746 --- /dev/null +++ b/src/add-ons/kernel/generic/cpuidle/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src add-ons kernel generic cpuidle ; + +UsePrivateKernelHeaders ; + +KernelAddon cpuidle : + cpuidle.cpp + ; diff --git a/src/add-ons/kernel/generic/cpuidle/cpuidle.cpp b/src/add-ons/kernel/generic/cpuidle/cpuidle.cpp new file mode 100644 index 0000000000..cc17be8fac --- /dev/null +++ b/src/add-ons/kernel/generic/cpuidle/cpuidle.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Yongcong Du + */ + +#include +#include +#include + +#include +#include + + +static CpuidleInfo sPerCPU[B_MAX_CPU_COUNT]; +static CpuidleDevice *sDevice; +extern void (*gCpuIdleFunc)(void); + + +/* + * next cstate selection algorithm is based on NetBSD's + * it's simple, stupid + */ +static int32 +SelectCstate(CpuidleInfo *info) +{ + static const int32 csFactor = 3; + + for (int32 i = sDevice->cStateCount - 1; i > 0; i--) { + CpuidleCstate *cState = &sDevice->cStates[i]; + if (info->cstateSleep > cState->latency * csFactor) + return i; + } + + /* Choose C1 if there's no state found */ + return 1; +} + + +static inline void +EnterCstate(int32 state, CpuidleInfo *info) +{ + CpuidleCstate *cstate = &sDevice->cStates[state]; + bigtime_t now = system_time(); + int32 finalState = cstate->EnterIdle(state, sDevice); + if (finalState > 0) { + bigtime_t diff = system_time() - now; + info->cstateSleep = diff; + info->stats[finalState].usageCount++; + info->stats[finalState].usageTime += diff; + } else { + info->cstateSleep = 0; + } +} + + +static void +CpuCstateIdle(void) +{ + CpuidleInfo *info = &sPerCPU[smp_get_current_cpu()]; + int32 state = SelectCstate(info); + EnterCstate(state, info); +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + return B_OK; + case B_MODULE_UNINIT: + return B_OK; + } + + return B_ERROR; +} + + +status_t AddDevice(CpuidleDevice *device) +{ + sDevice = device; + memory_write_barrier(); + gCpuIdleFunc = CpuCstateIdle; + return B_OK; +} + + +static CpuidleModuleInfo sCpuidleModule = { + { + B_CPUIDLE_MODULE_NAME, + 0, + std_ops + }, + + AddDevice, +}; + + +module_info *modules[] = { + (module_info *)&sCpuidleModule, + NULL +}; diff --git a/src/add-ons/kernel/generic/scsi_periph/block.cpp b/src/add-ons/kernel/generic/scsi_periph/block.cpp index 7ef69fb507..3b3ac63747 100644 --- a/src/add-ons/kernel/generic/scsi_periph/block.cpp +++ b/src/add-ons/kernel/generic/scsi_periph/block.cpp @@ -92,7 +92,8 @@ periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *request) blockSize = 0; } - SHOW_FLOW(3, "capacity = %lld, block_size = %ld", capacity, blockSize); + SHOW_FLOW(3, "capacity = %" B_PRId64 ", block_size = %" B_PRId32, capacity, + blockSize); device->block_size = blockSize; diff --git a/src/add-ons/kernel/generic/scsi_periph/device.cpp b/src/add-ons/kernel/generic/scsi_periph/device.cpp index d83a2ab1bf..5d8ab33055 100644 --- a/src/add-ons/kernel/generic/scsi_periph/device.cpp +++ b/src/add-ons/kernel/generic/scsi_periph/device.cpp @@ -38,7 +38,7 @@ periph_compose_device_name(device_node *node, const char *prefix) // this is actually an IDE device, so we ignore the prefix // a bus device for those - snprintf(name, sizeof(name), "disk/ata%s/%ld/%s/raw", + snprintf(name, sizeof(name), "disk/ata%s/%" B_PRId32 "/%s/raw", type == scsi_dev_CDROM ? "pi" : "", channel, targetID == 0 ? "master" : "slave"); } else { diff --git a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp index 7b0714f4bb..e38c43326a 100644 --- a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp @@ -822,7 +822,7 @@ static void ndp_timer(struct net_timer* timer, void* data) { ndp_entry* entry = (ndp_entry*)data; - TRACE(("NDP timer %ld, entry %p!\n", entry->timer_state, entry)); + TRACE(("NDP timer %" B_PRId32 ", entry %p!\n", entry->timer_state, entry)); switch (entry->timer_state) { case NDP_NO_STATE: diff --git a/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp b/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp index d800811b31..4f2dd1d308 100644 --- a/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp +++ b/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp @@ -218,7 +218,8 @@ get_domain(struct net_buffer* buffer) status_t icmp6_receive_data(net_buffer *buffer) { - TRACE(("ICMPv6 received some data, buffer length %lu\n", buffer->size)); + TRACE(("ICMPv6 received some data, buffer length %" B_PRIu32 "\n", + buffer->size)); net_domain* domain = get_domain(buffer); if (domain == NULL) diff --git a/src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp b/src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp index 5a5b2ceca2..de83ba3b31 100644 --- a/src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp @@ -310,8 +310,8 @@ BufferQueue::Get(net_buffer *buffer, tcp_sequence sequence, size_t bytes) if (source == NULL) panic("we should have had that data..."); if (tcp_sequence(source->sequence) > sequence) { - panic("source %p, sequence = %lu (%lu)\n", source, source->sequence, - sequence.Number()); + panic("source %p, sequence = %" B_PRIu32 " (%" B_PRIu32 ")\n", source, + source->sequence, sequence.Number()); } // clone the data @@ -481,8 +481,8 @@ BufferQueue::Dump() const SegmentList::ConstIterator iterator = fList.GetIterator(); int32 number = 0; while (net_buffer* buffer = iterator.Next()) { - kprintf(" %ld. buffer %p, sequence %lu, size %lu\n", ++number, - buffer, buffer->sequence, buffer->size); + kprintf(" %" B_PRId32 ". buffer %p, sequence %" B_PRIu32 ", size %" + B_PRIu32 "\n", ++number, buffer, buffer->sequence, buffer->size); } } diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index c2a37db780..8c3fae30ab 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -2330,45 +2330,50 @@ TCPEndpoint::Dump() const { kprintf("TCP endpoint %p\n", this); kprintf(" state: %s\n", name_for_state(fState)); - kprintf(" flags: 0x%lx\n", fFlags); + kprintf(" flags: 0x%" B_PRIx32 "\n", fFlags); #if KDEBUG - kprintf(" lock: { %p, holder: %ld }\n", &fLock, fLock.holder); + kprintf(" lock: { %p, holder: %" B_PRId32 " }\n", &fLock, fLock.holder); #endif - kprintf(" accept sem: %ld\n", fAcceptSemaphore); - kprintf(" options: 0x%lx\n", (uint32)fOptions); + kprintf(" accept sem: %" B_PRId32 "\n", fAcceptSemaphore); + kprintf(" options: 0x%" B_PRIx32 "\n", (uint32)fOptions); kprintf(" send\n"); kprintf(" window shift: %u\n", fSendWindowShift); - kprintf(" unacknowledged: %lu\n", fSendUnacknowledged.Number()); - kprintf(" next: %lu\n", fSendNext.Number()); - kprintf(" max: %lu\n", fSendMax.Number()); - kprintf(" urgent offset: %lu\n", fSendUrgentOffset.Number()); - kprintf(" window: %lu\n", fSendWindow); - kprintf(" max window: %lu\n", fSendMaxWindow); - kprintf(" max segment size: %lu\n", fSendMaxSegmentSize); + kprintf(" unacknowledged: %" B_PRIu32 "\n", + fSendUnacknowledged.Number()); + kprintf(" next: %" B_PRIu32 "\n", fSendNext.Number()); + kprintf(" max: %" B_PRIu32 "\n", fSendMax.Number()); + kprintf(" urgent offset: %" B_PRIu32 "\n", fSendUrgentOffset.Number()); + kprintf(" window: %" B_PRIu32 "\n", fSendWindow); + kprintf(" max window: %" B_PRIu32 "\n", fSendMaxWindow); + kprintf(" max segment size: %" B_PRIu32 "\n", fSendMaxSegmentSize); kprintf(" queue: %lu / %lu\n", fSendQueue.Used(), fSendQueue.Size()); #if DEBUG_BUFFER_QUEUE fSendQueue.Dump(); #endif - kprintf(" last acknowledge sent: %lu\n", fLastAcknowledgeSent.Number()); - kprintf(" initial sequence: %lu\n", fInitialSendSequence.Number()); + kprintf(" last acknowledge sent: %" B_PRIu32 "\n", + fLastAcknowledgeSent.Number()); + kprintf(" initial sequence: %" B_PRIu32 "\n", + fInitialSendSequence.Number()); kprintf(" receive\n"); kprintf(" window shift: %u\n", fReceiveWindowShift); - kprintf(" next: %lu\n", fReceiveNext.Number()); - kprintf(" max advertised: %lu\n", fReceiveMaxAdvertised.Number()); - kprintf(" window: %lu\n", fReceiveWindow); - kprintf(" max segment size: %lu\n", fReceiveMaxSegmentSize); + kprintf(" next: %" B_PRIu32 "\n", fReceiveNext.Number()); + kprintf(" max advertised: %" B_PRIu32 "\n", + fReceiveMaxAdvertised.Number()); + kprintf(" window: %" B_PRIu32 "\n", fReceiveWindow); + kprintf(" max segment size: %" B_PRIu32 "\n", fReceiveMaxSegmentSize); kprintf(" queue: %lu / %lu\n", fReceiveQueue.Available(), fReceiveQueue.Size()); #if DEBUG_BUFFER_QUEUE fReceiveQueue.Dump(); #endif - kprintf(" initial sequence: %lu\n", fInitialReceiveSequence.Number()); - kprintf(" duplicate acknowledge count: %lu\n", + kprintf(" initial sequence: %" B_PRIu32 "\n", + fInitialReceiveSequence.Number()); + kprintf(" duplicate acknowledge count: %" B_PRIu32 "\n", fDuplicateAcknowledgeCount); - kprintf(" round trip time: %ld (deviation %ld)\n", fRoundTripTime, - fRoundTripDeviation); - kprintf(" retransmit timeout: %lld\n", fRetransmitTimeout); - kprintf(" congestion window: %lu\n", fCongestionWindow); - kprintf(" slow start threshold: %lu\n", fSlowStartThreshold); + kprintf(" round trip time: %" B_PRId32 " (deviation %" B_PRId32 ")\n", + fRoundTripTime, fRoundTripDeviation); + kprintf(" retransmit timeout: %" B_PRId64 "\n", fRetransmitTimeout); + kprintf(" congestion window: %" B_PRIu32 "\n", fCongestionWindow); + kprintf(" slow start threshold: %" B_PRIu32 "\n", fSlowStartThreshold); } diff --git a/src/add-ons/kernel/network/protocols/udp/udp.cpp b/src/add-ons/kernel/network/protocols/udp/udp.cpp index 78ef872ca8..0e921ae895 100644 --- a/src/add-ons/kernel/network/protocols/udp/udp.cpp +++ b/src/add-ons/kernel/network/protocols/udp/udp.cpp @@ -739,7 +739,7 @@ UdpEndpointManager::ReceiveError(status_t error, net_buffer* buffer) // original packet udp_header header; if (gBufferModule->read(buffer, 0, &header, - std::min(buffer->size, sizeof(udp_header))) != B_OK) + std::min((size_t)buffer->size, sizeof(udp_header))) != B_OK) return B_BAD_VALUE; net_domain* domain = buffer->interface_address->domain; diff --git a/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp b/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp index d92e2854a6..9a3154aca5 100644 --- a/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp +++ b/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp @@ -30,9 +30,11 @@ UnixAddress::ToString(char *buffer, size_t bufferSize) const if (!IsValid()) strlcpy(buffer, "", bufferSize); else if (IsInternalAddress()) - snprintf(buffer, bufferSize, "<%05lx>", fInternalID); - else - snprintf(buffer, bufferSize, "<%ld, %lld>", fVolumeID, fNodeID); + snprintf(buffer, bufferSize, "<%05" B_PRIx32 ">", fInternalID); + else { + snprintf(buffer, bufferSize, "<%" B_PRIdDEV ", %" B_PRIdINO ">", + fVolumeID, fNodeID); + } return buffer; } diff --git a/src/add-ons/kernel/network/protocols/unix/UnixEndpoint.cpp b/src/add-ons/kernel/network/protocols/unix/UnixEndpoint.cpp index fff75d0950..b2d12b5d56 100644 --- a/src/add-ons/kernel/network/protocols/unix/UnixEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/unix/UnixEndpoint.cpp @@ -182,7 +182,7 @@ UnixEndpoint::Bind(const struct sockaddr *_address) sockaddr_un* outAddress = (sockaddr_un*)&socket->address; outAddress->sun_path[0] = '\0'; - sprintf(outAddress->sun_path + 1, "%05lx", internalID); + sprintf(outAddress->sun_path + 1, "%05" B_PRIx32, internalID); outAddress->sun_len = INTERNAL_UNIX_ADDRESS_LEN; // null-byte + 5 hex digits diff --git a/src/add-ons/kernel/network/protocols/unix/UnixFifo.cpp b/src/add-ons/kernel/network/protocols/unix/UnixFifo.cpp index 579553c60d..22159f9f97 100644 --- a/src/add-ons/kernel/network/protocols/unix/UnixFifo.cpp +++ b/src/add-ons/kernel/network/protocols/unix/UnixFifo.cpp @@ -399,7 +399,7 @@ size_t UnixFifo::Readable() const { size_t readable = fBuffer.Readable(); - return readable > fReadRequested ? readable - fReadRequested : 0; + return (off_t)readable > fReadRequested ? readable - fReadRequested : 0; } @@ -407,7 +407,7 @@ size_t UnixFifo::Writable() const { size_t writable = fBuffer.Writable(); - return writable > fWriteRequested ? writable - fWriteRequested : 0; + return (off_t)writable > fWriteRequested ? writable - fWriteRequested : 0; } diff --git a/src/add-ons/kernel/network/stack/device_interfaces.cpp b/src/add-ons/kernel/network/stack/device_interfaces.cpp index 3d2db5201a..cce93f6bea 100644 --- a/src/add-ons/kernel/network/stack/device_interfaces.cpp +++ b/src/add-ons/kernel/network/stack/device_interfaces.cpp @@ -241,12 +241,12 @@ dump_device_interface(int argc, char** argv) = (net_device_interface*)parse_expression(argv[1]); kprintf("device: %p\n", interface->device); - kprintf("reader_thread: %ld\n", interface->reader_thread); + kprintf("reader_thread: %" B_PRId32 "\n", interface->reader_thread); kprintf("up_count: %" B_PRIu32 "\n", interface->up_count); kprintf("ref_count: %" B_PRId32 "\n", interface->ref_count); kprintf("deframe_func: %p\n", interface->deframe_func); kprintf("deframe_ref_count: %" B_PRId32 "\n", interface->ref_count); - kprintf("consumer_thread: %ld\n", interface->consumer_thread); + kprintf("consumer_thread: %" B_PRId32 "\n", interface->consumer_thread); kprintf("monitor_count: %" B_PRId32 "\n", interface->monitor_count); kprintf("monitor_lock: %p\n", &interface->monitor_lock); diff --git a/src/add-ons/kernel/network/stack/domains.cpp b/src/add-ons/kernel/network/stack/domains.cpp index b331172d83..0c581e9143 100644 --- a/src/add-ons/kernel/network/stack/domains.cpp +++ b/src/add-ons/kernel/network/stack/domains.cpp @@ -77,8 +77,8 @@ dump_domains(int argc, char** argv) RouteList::Iterator routeIterator = domain->routes.GetIterator(); while (net_route_private* route = routeIterator.Next()) { - kprintf(" %p: dest %s, mask %s, gw %s, flags %lx, address %p\n", - route, AddressString(domain, route->destination + kprintf(" %p: dest %s, mask %s, gw %s, flags %" B_PRIx32 ", " + "address %p\n", route, AddressString(domain, route->destination ? route->destination : NULL).Data(), AddressString(domain, route->mask ? route->mask : NULL).Data(), AddressString(domain, route->gateway diff --git a/src/add-ons/kernel/network/stack/interfaces.cpp b/src/add-ons/kernel/network/stack/interfaces.cpp index 96ed208b2c..9a3c73b1a5 100644 --- a/src/add-ons/kernel/network/stack/interfaces.cpp +++ b/src/add-ons/kernel/network/stack/interfaces.cpp @@ -148,7 +148,7 @@ dump_local(int argc, char** argv) size_t i = 0; while (InterfaceAddress* address = iterator.Next()) { address->Dump(++i); - dprintf(" hash: %lu\n", + dprintf(" hash: %" B_PRIu32 "\n", address->domain->address_module->hash_address(address->local, false)); } diff --git a/src/add-ons/kernel/network/stack/net_buffer.cpp b/src/add-ons/kernel/network/stack/net_buffer.cpp index 8f7a893210..d302c6a7e7 100644 --- a/src/add-ons/kernel/network/stack/net_buffer.cpp +++ b/src/add-ons/kernel/network/stack/net_buffer.cpp @@ -610,7 +610,7 @@ dump_buffer(net_buffer* _buffer) net_buffer_private* buffer = (net_buffer_private*)_buffer; dprintf("buffer %p, size %" B_PRIu32 ", flags %" B_PRIx32 ", stored header " - "%" B_PRIu32 ", interface address %p\n", buffer, buffer->size, + "%" B_PRIuSIZE ", interface address %p\n", buffer, buffer->size, buffer->flags, buffer->stored_header_length, buffer->interface_address); dump_address("source", buffer->source, buffer->interface_address); @@ -652,11 +652,11 @@ dump_net_buffer(int argc, char** argv) static int dump_net_buffer_stats(int argc, char** argv) { - kprintf("allocated data headers: %7ld / %7ld, peak %7ld\n", - sAllocatedDataHeaderCount, sEverAllocatedDataHeaderCount, + kprintf("allocated data headers: %7" B_PRId32 " / %7" B_PRId32 ", peak %7" + B_PRId32 "\n", sAllocatedDataHeaderCount, sEverAllocatedDataHeaderCount, sMaxAllocatedDataHeaderCount); - kprintf("allocated net buffers: %7ld / %7ld, peak %7ld\n", - sAllocatedNetBufferCount, sEverAllocatedNetBufferCount, + kprintf("allocated net buffers: %7" B_PRId32 " / %7" B_PRId32 ", peak %7" + B_PRId32 "\n", sAllocatedNetBufferCount, sEverAllocatedNetBufferCount, sMaxAllocatedNetBufferCount); return 0; } diff --git a/src/add-ons/kernel/network/stack/net_socket.cpp b/src/add-ons/kernel/network/stack/net_socket.cpp index 7346769f2a..9d5cfc9200 100644 --- a/src/add-ons/kernel/network/stack/net_socket.cpp +++ b/src/add-ons/kernel/network/stack/net_socket.cpp @@ -341,7 +341,7 @@ static void print_socket_line(net_socket_private* socket, const char* prefix) { BReference parent = socket->parent.GetReference(); - kprintf("%s%p %2d.%2d.%2d %6ld %p %p %p%s\n", prefix, socket, + kprintf("%s%p %2d.%2d.%2d %6" B_PRId32 " %p %p %p%s\n", prefix, socket, socket->family, socket->type, socket->protocol, socket->owner, socket->first_protocol, socket->first_info, parent.Get(), parent.Get() != NULL ? socket->is_connected ? " (c)" : " (p)" : ""); @@ -368,10 +368,10 @@ dump_socket(int argc, char** argv) kprintf(" options: %x\n", socket->options); kprintf(" linger: %d\n", socket->linger); kprintf(" bound to device: %" B_PRIu32 "\n", socket->bound_to_device); - kprintf(" owner: %ld\n", socket->owner); - kprintf(" max backlog: %ld\n", socket->max_backlog); + kprintf(" owner: %" B_PRId32 "\n", socket->owner); + kprintf(" max backlog: %" B_PRId32 "\n", socket->max_backlog); kprintf(" is connected: %d\n", socket->is_connected); - kprintf(" child_count: %lu\n", socket->child_count); + kprintf(" child_count: %" B_PRIu32 "\n", socket->child_count); if (socket->child_count == 0) return 0; diff --git a/src/add-ons/kernel/network/stack/stack.cpp b/src/add-ons/kernel/network/stack/stack.cpp index 70844689b2..4b2a0a1407 100644 --- a/src/add-ons/kernel/network/stack/stack.cpp +++ b/src/add-ons/kernel/network/stack/stack.cpp @@ -146,7 +146,7 @@ family::Release() family::Compare(void* _family, const void* _key) { struct family* family = (struct family*)_family; - int key = (int)_key; + int key = (addr_t)_key; if (family->type == key) return 0; @@ -159,7 +159,7 @@ family::Compare(void* _family, const void* _key) family::Hash(void* _family, const void* _key, uint32 range) { struct family* family = (struct family*)_family; - int key = (int)_key; + int key = (addr_t)_key; if (family != NULL) return family->type % range; @@ -171,7 +171,7 @@ family::Hash(void* _family, const void* _key, uint32 range) /*static*/ struct family* family::Lookup(int type) { - return (struct family*)hash_lookup(sFamilies, (void*)type); + return (struct family*)hash_lookup(sFamilies, (void*)(addr_t)type); } diff --git a/src/add-ons/kernel/network/stack/utility.cpp b/src/add-ons/kernel/network/stack/utility.cpp index c0ab7afdfe..b2a6f0e1ab 100644 --- a/src/add-ons/kernel/network/stack/utility.cpp +++ b/src/add-ons/kernel/network/stack/utility.cpp @@ -312,7 +312,7 @@ Fifo::Dequeue(bool clone) } -ssize_t +status_t Fifo::Clear() { return base_fifo_clear(this); @@ -632,7 +632,7 @@ dump_timer(int argc, char** argv) if (timer == NULL) break; - kprintf("%p %p %p %Ld\n", timer, timer->hook, timer->data, + kprintf("%p %p %p %" B_PRId64 "\n", timer, timer->hook, timer->data, timer->due > 0 ? timer->due - system_time() : -1); } diff --git a/src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp b/src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp index 66cd6b7aa9..4f600e8836 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp @@ -73,29 +73,30 @@ check_logical_location(const LogicalPartition* child, const PrimaryPartition* parent) { if (child->PartitionTableOffset() % child->BlockSize() != 0) { - TRACE(("check_logical_location() - PartitionTableOffset: %lld not a " - "multiple of media's block size: %ld\n", + TRACE(("check_logical_location() - PartitionTableOffset: %" B_PRId64 " " + "not a multiple of media's block size: %" B_PRId32 "\n", child->PartitionTableOffset(), child->BlockSize())); return false; } if (child->Offset() % child->BlockSize() != 0) { - TRACE(("check_logical_location() - Parition offset: %lld " - "is not a multiple of block size: %ld\n", child->Offset(), + TRACE(("check_logical_location() - Parition offset: %" B_PRId64 " " + "is not a multiple of block size: %" B_PRId32 "\n", child->Offset(), child->BlockSize())); return false; } if (child->Size() % child->BlockSize() != 0) { - TRACE(("check_logical_location() - Size: (%lld) is not a multiple of" - " block size: (%ld)\n", child->Size(), child->BlockSize())); + TRACE(("check_logical_location() - Size: (%" B_PRId64 ") is not a " + "multiple of block size: (%" B_PRId32 ")\n", child->Size(), + child->BlockSize())); return false; } if (child->PartitionTableOffset() < parent->Offset() || child->PartitionTableOffset() >= parent->Offset() + parent->Size()) { - TRACE(("check_logical_location() - Partition table: (%lld) not within " - "extended partition (start: %lld), (end: %lld)\n", - child->PartitionTableOffset(), parent->Offset(), parent->Offset() - + parent->Size())); + TRACE(("check_logical_location() - Partition table: (%" B_PRId64 ") not" + " within extended partition (start: %" B_PRId64 "), (end: " + "%" B_PRId64 ")\n", child->PartitionTableOffset(), parent->Offset(), + parent->Offset() + parent->Size())); return false; } if (child->Offset() + child->Size() > parent->Offset() + parent->Size()) { diff --git a/src/add-ons/kernel/partitioning_systems/intel/intel.cpp b/src/add-ons/kernel/partitioning_systems/intel/intel.cpp index a1387d6d9c..bd8370b620 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/intel.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/intel.cpp @@ -99,7 +99,7 @@ get_type_for_content_type(const char* contentType, char* type) static status_t pm_std_ops(int32 op, ...) { - TRACE(("intel: pm_std_ops(0x%lx)\n", op)); + TRACE(("intel: pm_std_ops(0x%" B_PRIx32 ")\n", op)); switch(op) { case B_MODULE_INIT: case B_MODULE_UNINIT: @@ -117,9 +117,9 @@ pm_identify_partition(int fd, partition_data* partition, void** cookie) if (fd < 0 || !partition || !cookie) return -1; - TRACE(("intel: pm_identify_partition(%d, %ld: %lld, %lld, %ld)\n", fd, - partition->id, partition->offset, partition->size, - partition->block_size)); + TRACE(("intel: pm_identify_partition(%d, %" B_PRId32 ": %" B_PRId64 ", " + "%" B_PRId64 ", %" B_PRId32 ")\n", fd, partition->id, partition->offset, + partition->size, partition->block_size)); // reject extended partitions if (partition->type && !strcmp(partition->type, kPartitionTypeIntelExtended)) { @@ -182,9 +182,9 @@ pm_scan_partition(int fd, partition_data* partition, void* cookie) if (fd < 0 || !partition || !cookie) return B_ERROR; - TRACE(("intel: pm_scan_partition(%d, %ld: %lld, %lld, %ld)\n", fd, - partition->id, partition->offset, partition->size, - partition->block_size)); + TRACE(("intel: pm_scan_partition(%d, %" B_PRId32 ": %" B_PRId64 ", " + "%" B_PRId64 ", %" B_PRId32 ")\n", fd, partition->id, partition->offset, + partition->size, partition->block_size)); PartitionMapCookie* map = (PartitionMapCookie*)cookie; // fill in the partition_data structure @@ -287,7 +287,7 @@ pm_free_partition_content_cookie(partition_data* partition) static status_t ep_std_ops(int32 op, ...) { - TRACE(("intel: ep_std_ops(0x%lx)\n", op)); + TRACE(("intel: ep_std_ops(0x%" B_PRIx32 ")\n", op)); switch(op) { case B_MODULE_INIT: case B_MODULE_UNINIT: @@ -305,8 +305,9 @@ ep_identify_partition(int fd, partition_data* partition, void** cookie) if (fd < 0 || !partition || !cookie || !partition->cookie) return -1; - TRACE(("intel: ep_identify_partition(%d, %lld, %lld, %ld)\n", fd, - partition->offset, partition->size, partition->block_size)); + TRACE(("intel: ep_identify_partition(%d, %" B_PRId64 ", %" B_PRId64 ", " + "%" B_PRId32 ")\n", fd, partition->offset, partition->size, + partition->block_size)); // our parent must be a intel partition map partition and we must have // extended partition type @@ -333,8 +334,9 @@ ep_scan_partition(int fd, partition_data* partition, void* cookie) if (fd < 0 || !partition || !partition->cookie) return B_ERROR; - TRACE(("intel: ep_scan_partition(%d, %lld, %lld, %ld)\n", fd, - partition->offset, partition->size, partition->block_size)); + TRACE(("intel: ep_scan_partition(%d, %" B_PRId64 ", %" B_PRId64 ", " + "%" B_PRId32 ")\n", fd, partition->offset, partition->size, + partition->block_size)); partition_data* parent = get_parent_partition(partition->id); if (!parent) @@ -373,7 +375,7 @@ ep_scan_partition(int fd, partition_data* partition, void* cookie) // parameters char buffer[128]; - sprintf(buffer, "active %s ;\npartition_table_offset %lld ;\n", + sprintf(buffer, "active %s ;\npartition_table_offset %" B_PRId64 " ;\n", logical->Active() ? "true" : "false", logical->PartitionTableOffset()); child->parameters = strdup(buffer); diff --git a/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp b/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp index a8ed002a83..b9d2bb0794 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp @@ -679,7 +679,8 @@ get_partitionable_spaces(partition_data* partition, if (positions) delete[] positions; - TRACE(("intel: get_partitionable_spaces - found: %ld\n", actualCount)); + TRACE(("intel: get_partitionable_spaces - found: %" B_PRId32 "\n", + actualCount)); *_actualCount = actualCount; @@ -752,8 +753,8 @@ status_t pm_shadow_changed(partition_data* partition, partition_data* child, uint32 operation) { - TRACE(("intel: pm_shadow_changed(%p, %p, %lu)\n", partition, child, - operation)); + TRACE(("intel: pm_shadow_changed(%p, %p, %" B_PRIu32 ")\n", partition, + child, operation)); switch (operation) { case B_PARTITION_SHADOW: @@ -763,14 +764,16 @@ pm_shadow_changed(partition_data* partition, partition_data* child, partition->id); if (!physicalPartition) { dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW): no " - "physical partition with ID %ld\n", partition->id); + "physical partition with ID %" B_PRId32 "\n", + partition->id); return B_ERROR; } // clone the map if (!physicalPartition->content_cookie) { dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW): no " - "content cookie, physical partition: %ld\n", partition->id); + "content cookie, physical partition: %" B_PRId32 "\n", + partition->id); return B_ERROR; } @@ -796,13 +799,14 @@ pm_shadow_changed(partition_data* partition, partition_data* child, partition_data* physical = get_partition(child->id); if (!physical) { dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW_CHILD): " - "no physical partition with ID %ld\n", child->id); + "no physical partition with ID %" B_PRId32 "\n", child->id); return B_ERROR; } if (!physical->cookie) { dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW_CHILD): " - "no cookie, physical partition: %ld\n", child->id); + "no cookie, physical partition: %" B_PRId32 "\n", + child->id); return B_ERROR; } @@ -811,7 +815,7 @@ pm_shadow_changed(partition_data* partition, partition_data* child, if (!partition->content_cookie) { dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW_CHILD): " - "no content cookie, physical partition: %ld\n", + "no content cookie, physical partition: %" B_PRId32 "\n", partition->id); return B_ERROR; } @@ -823,8 +827,8 @@ pm_shadow_changed(partition_data* partition, partition_data* child, if (!primary || primary->IsEmpty()) { dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW_CHILD): " - "partition %ld is empty, primary index: %ld\n", child->id, - index); + "partition %" B_PRId32 " is empty, primary index: " + "%" B_PRId32 "\n", child->id, index); return B_BAD_VALUE; } @@ -849,7 +853,8 @@ pm_shadow_changed(partition_data* partition, partition_data* child, { if (!partition->content_cookie) { dprintf("intel: pm_shadow_changed(B_PARTITION_CREATE_CHILD): " - "no content cookie, partition: %ld\n", partition->id); + "no content cookie, partition: %" B_PRId32 "\n", + partition->id); return B_ERROR; } @@ -867,7 +872,8 @@ pm_shadow_changed(partition_data* partition, partition_data* child, if (!primary) { dprintf("intel: pm_shadow_changed(B_PARTITION_CREATE_CHILD): " - "no empty primary slot, partition: %ld\n", partition->id); + "no empty primary slot, partition: %" B_PRId32 "\n", + partition->id); return B_ERROR; } @@ -876,7 +882,8 @@ pm_shadow_changed(partition_data* partition, partition_data* child, type.SetType(child->type); if (!type.IsValid()) { dprintf("intel: pm_shadow_changed(B_PARTITION_CREATE_CHILD): " - "invalid partition type, partition: %ld\n", partition->id); + "invalid partition type, partition: %" B_PRId32 "\n", + partition->id); return B_ERROR; } @@ -1065,7 +1072,7 @@ move_block(int fd, off_t fromOffset, off_t toOffset, uint8* buffer, int32 size) error = errno; if (error == B_OK) error = B_IO_ERROR; - TRACE(("intel: move_block(): reading failed: %lx\n", error)); + TRACE(("intel: move_block(): reading failed: %" B_PRIx32 "\n", error)); return error; } @@ -1074,7 +1081,7 @@ move_block(int fd, off_t fromOffset, off_t toOffset, uint8* buffer, int32 size) error = errno; if (error == B_OK) error = B_IO_ERROR; - TRACE(("intel: move_block(): writing failed: %lx\n", error)); + TRACE(("intel: move_block(): writing failed: %" B_PRIx32 "\n", error)); } return error; @@ -1520,9 +1527,9 @@ ep_is_sub_system_for(partition_data* partition) if (partition == NULL) return false; - TRACE(("intel: ep_is_sub_system_for(%ld: %lld, %lld, %ld, %s)\n", - partition->id, partition->offset, partition->size, - partition->block_size, partition->content_type)); + TRACE(("intel: ep_is_sub_system_for(%" B_PRId32 ": %" B_PRId64 ", " + "%" B_PRId64 ", %" B_PRId32 ", %s)\n", partition->id, partition->offset, + partition->size, partition->block_size, partition->content_type)); // Intel Extended Partition can live in child partition of Intel Partition // Map @@ -2280,8 +2287,8 @@ ep_delete_child(int fd, partition_id partitionID, partition_id childID, if (get_partition_from_offset_ep(partition, next->Offset(), &nextSibling)) { char buffer[128]; - sprintf(buffer, "active %s ;\npartition_table_offset %lld ;\n", - next->Active() ? "true" : "false", + sprintf(buffer, "active %s ;\npartition_table_offset %" B_PRId64 + " ;\n", next->Active() ? "true" : "false", next->PartitionTableOffset()); nextSibling->parameters = strdup(buffer); } diff --git a/src/add-ons/screen_savers/flurry/Jamfile b/src/add-ons/screen_savers/flurry/Jamfile index 54357c262c..18e487b6cb 100644 --- a/src/add-ons/screen_savers/flurry/Jamfile +++ b/src/add-ons/screen_savers/flurry/Jamfile @@ -1,4 +1,5 @@ SubDir HAIKU_TOP src add-ons screen_savers flurry ; +SubDirSysHdrs $(HAIKU_GLU_HEADERS) ; SubDirSysHdrs $(HAIKU_MESA_HEADERS) ; # For GCC2 diff --git a/src/add-ons/screen_savers/glife/Jamfile b/src/add-ons/screen_savers/glife/Jamfile index 0b9d9b09d8..23010df29b 100644 --- a/src/add-ons/screen_savers/glife/Jamfile +++ b/src/add-ons/screen_savers/glife/Jamfile @@ -1,4 +1,5 @@ SubDir HAIKU_TOP src add-ons screen_savers glife ; +SubDirSysHdrs $(HAIKU_GLU_HEADERS) ; SubDirSysHdrs $(HAIKU_MESA_HEADERS) ; SetSubDirSupportedPlatformsBeOSCompatible ; diff --git a/src/add-ons/translators/bmp/BMPTranslator.cpp b/src/add-ons/translators/bmp/BMPTranslator.cpp index 75f51d9ba6..ee1e78a188 100644 --- a/src/add-ons/translators/bmp/BMPTranslator.cpp +++ b/src/add-ons/translators/bmp/BMPTranslator.cpp @@ -648,7 +648,8 @@ BPositionIO *outDestination, color_space fromspace, MSInfoHeader &msheader) } } while (rd == static_cast(bitsRowBytes)) { - printf("translate_from_bits_to_bmp24() bmppixrow %ld\n", bmppixrow); + printf("translate_from_bits_to_bmp24() bmppixrow %" B_PRId32 "\n", + bmppixrow); for (int32 i = 0; i < msheader.width; i++) { uint8 *bitspixel, *bmppixel; @@ -1734,12 +1735,12 @@ BMPTranslator::translate_from_bmp(BPositionIO *inSource, uint32 outType, if (!frommsformat && os2skip) inSource->Seek(os2skip, SEEK_CUR); - rd = min((size_t)1024, fileHeader.fileSize - rdtotal); + rd = min((uint32)1024, fileHeader.fileSize - rdtotal); rd = inSource->Read(buf, rd); while (rd > 0) { outDestination->Write(buf, rd); rdtotal += rd; - rd = min((size_t)1024, fileHeader.fileSize - rdtotal); + rd = min((uint32)1024, fileHeader.fileSize - rdtotal); rd = inSource->Read(buf, rd); } if (rd == 0) diff --git a/src/add-ons/translators/gif/SFHash.cpp b/src/add-ons/translators/gif/SFHash.cpp index 005c156f02..e2a4586cbb 100644 --- a/src/add-ons/translators/gif/SFHash.cpp +++ b/src/add-ons/translators/gif/SFHash.cpp @@ -23,7 +23,7 @@ SFHash::SFHash(int size) { fatalerror = false; this->size = size; iterate_pos = iterate_depth = 0; - main_array = (HashItem **)malloc(this->size * 4); + main_array = (HashItem **)malloc(this->size * sizeof(HashItem *)); if (main_array == NULL) { fatalerror = true; diff --git a/src/add-ons/translators/gif/SavePalette.cpp b/src/add-ons/translators/gif/SavePalette.cpp index 82ab952f67..eb1ffb1284 100644 --- a/src/add-ons/translators/gif/SavePalette.cpp +++ b/src/add-ons/translators/gif/SavePalette.cpp @@ -324,7 +324,7 @@ SavePalette::SavePalette(BBitmap *bitmap, int32 maxSizeInBits) fSizeInBits++; fSize = 1 << fSizeInBits; - ColorItem **topcolors = (ColorItem **)malloc(fSize * 4); + ColorItem **topcolors = (ColorItem **)malloc(fSize * sizeof(ColorItem *)); if (topcolors == NULL) { if (debug) printf("Out of memory in SavePalette(BBitmap *)\n"); fFatalError = true; diff --git a/src/add-ons/translators/jpeg2000/JPEG2000Translator.cpp b/src/add-ons/translators/jpeg2000/JPEG2000Translator.cpp index dd9249ff9c..bb2f3ac44b 100644 --- a/src/add-ons/translators/jpeg2000/JPEG2000Translator.cpp +++ b/src/add-ons/translators/jpeg2000/JPEG2000Translator.cpp @@ -545,7 +545,7 @@ SSlider::SSlider(const char* name, const char* label, const char* SSlider::UpdateText() const { - snprintf(fStatusLabel, sizeof(fStatusLabel), "%ld", Value()); + snprintf(fStatusLabel, sizeof(fStatusLabel), "%" B_PRId32, Value()); return fStatusLabel; } diff --git a/src/add-ons/translators/raw/RAW.cpp b/src/add-ons/translators/raw/RAW.cpp index 8329016768..7d5304d817 100644 --- a/src/add-ons/translators/raw/RAW.cpp +++ b/src/add-ons/translators/raw/RAW.cpp @@ -2658,7 +2658,7 @@ DCRaw::_LoadRAW(const image_data_info& image) break; default: - fprintf(stderr, "DCRaw: unknown compression: %ld\n", + fprintf(stderr, "DCRaw: unknown compression: %" B_PRId32 "\n", image.compression); throw (status_t)B_NO_TRANSLATOR; break; @@ -3504,7 +3504,7 @@ DCRaw::Identify() if (fMeta.maximum == 0) fMeta.maximum = (1 << _Raw().bits_per_sample) - 1; - if (fFilters == ~0UL) + if (fFilters == ~(uint32)0) fFilters = 0x94949494; if (fFilters && fColors == 3) { for (int32 i = 0; i < 32; i += 4) { diff --git a/src/add-ons/translators/rtf/RTF.cpp b/src/add-ons/translators/rtf/RTF.cpp index a1fe3eed1b..ea4663ce55 100644 --- a/src/add-ons/translators/rtf/RTF.cpp +++ b/src/add-ons/translators/rtf/RTF.cpp @@ -104,16 +104,16 @@ string_array_compare(const char *key, const char **array) static void dump(Element &element, int32 level = 0) { - printf("%03ld (%p):", level, &element); + printf("%03" B_PRId32 " (%p):", level, &element); for (int32 i = 0; i < level; i++) printf(" "); if (RTF::Header *header = dynamic_cast(&element)) { - printf("\n", header->Version()); + printf("\n", header->Version()); } else if (RTF::Command *command = dynamic_cast(&element)) { printf("Name()); if (command->HasOption()) - printf(", Option %ld", command->Option()); + printf(", Option %" B_PRId32, command->Option()); puts(">"); } else if (RTF::Text *text = dynamic_cast(&element)) { printf(""); @@ -285,7 +285,7 @@ Group::Group() Group::~Group() { Element *element; - while ((element = (Element *)fElements.RemoveItem(0L)) != NULL) { + while ((element = (Element *)fElements.RemoveItem((int32)0)) != NULL) { delete element; } } diff --git a/src/add-ons/translators/rtf/convert.cpp b/src/add-ons/translators/rtf/convert.cpp index 74f5a178ad..ea897e66ab 100644 --- a/src/add-ons/translators/rtf/convert.cpp +++ b/src/add-ons/translators/rtf/convert.cpp @@ -214,7 +214,7 @@ process_command(conversion_context &context, RTF::Command *command, if (!strcmp(name, "sectnum")) { char buffer[64]; - snprintf(buffer, sizeof(buffer), "%ld", context.section); + snprintf(buffer, sizeof(buffer), "%" B_PRId32, context.section); return write_text(context, buffer, target); } if (!strcmp(name, "pgnstarts")) { @@ -227,7 +227,7 @@ process_command(conversion_context &context, RTF::Command *command, } if (!strcmp(name, "chpgn")) { char buffer[64]; - snprintf(buffer, sizeof(buffer), "%ld", context.page); + snprintf(buffer, sizeof(buffer), "%" B_PRId32, context.page); return write_text(context, buffer, target); } return 0; @@ -354,7 +354,7 @@ TextOutput::FlattenedRunArray(int32 &_size) array->count = fRuns.CountItems(); for (int32 i = 0; i < array->count; i++) { - text_run *run = (text_run *)fRuns.RemoveItem(0L); + text_run *run = (text_run *)fRuns.RemoveItem((int32)0); array->runs[i] = *run; delete run; } diff --git a/src/add-ons/translators/shared/BaseTranslator.cpp b/src/add-ons/translators/shared/BaseTranslator.cpp index 3397a3857c..b8eb064929 100644 --- a/src/add-ons/translators/shared/BaseTranslator.cpp +++ b/src/add-ons/translators/shared/BaseTranslator.cpp @@ -549,7 +549,7 @@ BaseTranslator::translate_from_bits_to_bits(BPositionIO *inSource, if (writ < 0) break; remaining -= static_cast(writ); - rd = inSource->Read(buf, std::min(1024UL, + rd = inSource->Read(buf, std::min((uint32)1024, remaining)); } diff --git a/src/add-ons/translators/stxt/STXTTranslator.cpp b/src/add-ons/translators/stxt/STXTTranslator.cpp index 124c8d6cda..77b500e6f9 100644 --- a/src/add-ons/translators/stxt/STXTTranslator.cpp +++ b/src/add-ons/translators/stxt/STXTTranslator.cpp @@ -982,7 +982,7 @@ translate_from_stxt(BPositionIO *inSource, BPositionIO *outDestination, // of the data from inSource has been read and written. if (btoplain) nreed = min((size_t)READ_BUFFER_SIZE, - txtheader.header.data_size - ntotalread); + (size_t)txtheader.header.data_size - ntotalread); else nreed = READ_BUFFER_SIZE; nread = inSource->Read(buffer, nreed); @@ -994,7 +994,7 @@ translate_from_stxt(BPositionIO *inSource, BPositionIO *outDestination, if (btoplain) { ntotalread += nread; nreed = min((size_t)READ_BUFFER_SIZE, - txtheader.header.data_size - ntotalread); + (size_t)txtheader.header.data_size - ntotalread); } else nreed = READ_BUFFER_SIZE; nread = inSource->Read(buffer, nreed); diff --git a/src/add-ons/translators/wonderbrush/WonderBrushImage.cpp b/src/add-ons/translators/wonderbrush/WonderBrushImage.cpp index 6d497b40b8..8f32235493 100644 --- a/src/add-ons/translators/wonderbrush/WonderBrushImage.cpp +++ b/src/add-ons/translators/wonderbrush/WonderBrushImage.cpp @@ -11,7 +11,7 @@ #include "Canvas.h" WonderBrushImage::WonderBrushImage() - : fArchive(0UL) + : fArchive((uint32)0) { } diff --git a/src/apps/aboutsystem/AboutSystem.cpp b/src/apps/aboutsystem/AboutSystem.cpp index c3c4a05ee7..5ed73039c6 100644 --- a/src/apps/aboutsystem/AboutSystem.cpp +++ b/src/apps/aboutsystem/AboutSystem.cpp @@ -978,7 +978,7 @@ AboutView::_CreateCreditsView() if (year < 2008) year = 2008; snprintf(string, sizeof(string), - COPYRIGHT_STRING "2001-%ld The Haiku project. ", year); + COPYRIGHT_STRING "2001-%" B_PRId32 " The Haiku project. ", year); fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); fCreditsView->Insert(string); diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 3eb68ae8c2..a1a1ddbe13 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -72,6 +72,7 @@ Application Debugger : CpuStateX86.cpp # controllers + DebugReportGenerator.cpp TeamDebugger.cpp ThreadHandler.cpp diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index b3e0f9717b..610935a959 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -55,7 +55,8 @@ enum { MSG_INSPECT_ADDRESS = 'isad', MSG_SHOW_TYPECAST_NODE_PROMPT = 'stnp', MSG_TYPECAST_NODE = 'tyno', - MSG_SHOW_WATCH_VARIABLE_PROMPT = 'swvp' + MSG_SHOW_WATCH_VARIABLE_PROMPT = 'swvp', + MSG_GENERATE_DEBUG_REPORT = 'gdrp' }; diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp new file mode 100644 index 0000000000..30dd8d84c3 --- /dev/null +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -0,0 +1,197 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "DebugReportGenerator.h" + +#include +#include + +#include "Architecture.h" +#include "CpuState.h" +#include "Image.h" +#include "Register.h" +#include "StackFrame.h" +#include "StackTrace.h" +#include "StringUtils.h" +#include "Team.h" +#include "Thread.h" +#include "UiUtils.h" + + +DebugReportGenerator::DebugReportGenerator(::Team* team) + : + BReferenceable(), + fTeam(team), + fArchitecture(team->GetArchitecture()) +{ + fArchitecture->AcquireReference(); +} + + +DebugReportGenerator::~DebugReportGenerator() +{ + fArchitecture->ReleaseReference(); +} + + +status_t +DebugReportGenerator::Init() +{ + // TODO: anything needed here? + return B_OK; +} + + +DebugReportGenerator* +DebugReportGenerator::Create(::Team* team) +{ + DebugReportGenerator* self = new DebugReportGenerator(team); + + try { + self->Init(); + } catch (...) { + delete self; + throw; + } + + return self; +} + + +status_t +DebugReportGenerator::GenerateReport(const entry_ref& outputPath) +{ + BFile file(&outputPath, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + status_t result = file.InitCheck(); + if (result != B_OK) + return result; + + BString output; + result = _GenerateReportHeader(output); + if (result != B_OK); + return result; + + result = _DumpLoadedImages(output); + if (result != B_OK) + return result; + + result = _DumpRunningThreads(output); + if (result != B_OK) + return result; + + result = file.Write(output.String(), output.Length()); + if (result < 0) + return result; + + return B_OK; +} + + +status_t +DebugReportGenerator::_GenerateReportHeader(BString& _output) +{ + AutoLocker locker(fTeam); + + BString data; + data.SetToFormat("Debug information for team %s (%" B_PRId32 "):\n\n"); + _output << data; + + return B_OK; +} + + +status_t +DebugReportGenerator::_DumpLoadedImages(BString& _output) +{ + AutoLocker locker(fTeam); + + BString data; + for (ImageList::ConstIterator it = fTeam->Images().GetIterator(); + Image* image = it.Next();) { + const ImageInfo& info = image->Info(); + try { + data.SetToFormat("\t%s, id: %" B_PRId32", type: %" B_PRId32 ", " + "Text: 0x%" B_PRIx64 ", %" B_PRIu64 " bytes, Data: 0x%" + B_PRIx64 ", %" B_PRIu64 " bytes\n", info.Name().String(), + info.ImageID(), info.Type(), info.TextBase(), info.TextSize(), + info.DataBase(), info.DataSize()); + + _output << data; + } catch (...) { + return B_NO_MEMORY; + } + } + + return B_OK; +} + + +status_t +DebugReportGenerator::_DumpRunningThreads(BString& _output) +{ + AutoLocker locker(fTeam); + + BString data; + status_t result = B_OK; + for (ThreadList::ConstIterator it = fTeam->Threads().GetIterator(); + Thread* thread = it.Next();) { + try { + data.SetToFormat("\t%s %s, id: %" B_PRId32", state: %" B_PRId32 + "\n", thread->Name(), thread->IsMainThread() + ? "(main)" : "", UiUtils::ThreadStateToString( + thread->State(), thread->StoppedReason())); + + _output << data; + + if (thread->State() == THREAD_STATE_STOPPED) + result = _DumpDebuggedThreadInfo(_output, thread); + if (result != B_OK) + return result; + } catch (...) { + return B_NO_MEMORY; + } + } + + return B_OK; +} + + +status_t +DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, Thread* thread) +{ + AutoLocker locker(fTeam); + + StackTrace* trace = thread->GetStackTrace(); + if (trace == NULL) + return B_OK; + + BString data; + for (int32 i = 0; StackFrame* frame = trace->FrameAt(i); i++) { + char functionName[512]; + data.SetToFormat("0x%" B_PRIx64 "\t0x%" B_PRIx64 "\t%s\n", + frame->FrameAddress(), frame->InstructionPointer(), + UiUtils::FunctionNameForFrame(frame, functionName, + sizeof(functionName))); + + _output << data; + } + + _output << "\nRegisters:\n\n"; + + CpuState* state = thread->GetCpuState(); + BVariant value; + for (int32 i = 0; i < fArchitecture->CountRegisters(); i++) { + const Register* reg = fArchitecture->Registers() + i; + state->GetRegisterValue(reg, value); + + char buffer[64]; + data.SetToFormat("%s\t%0x%s\n", reg->Name(), + UiUtils::VariantToString(value, buffer, sizeof(buffer))); + _output << data; + } + + return B_OK; +} diff --git a/src/apps/debugger/controllers/DebugReportGenerator.h b/src/apps/debugger/controllers/DebugReportGenerator.h new file mode 100644 index 0000000000..a05ac5925b --- /dev/null +++ b/src/apps/debugger/controllers/DebugReportGenerator.h @@ -0,0 +1,42 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef DEBUG_REPORT_GENERATOR_H +#define DEBUG_GENERATOR_H + +#include + + +class entry_ref; +class Architecture; +class BString; +class Team; +class Thread; + + +class DebugReportGenerator : public BReferenceable +{ +public: + DebugReportGenerator(::Team* team); + ~DebugReportGenerator(); + + status_t Init(); + + static DebugReportGenerator* Create(::Team* team); + + status_t GenerateReport(const entry_ref& outputPath); + +private: + status_t _GenerateReportHeader(BString& output); + status_t _DumpLoadedImages(BString& output); + status_t _DumpRunningThreads(BString& output); + status_t _DumpDebuggedThreadInfo(BString& output, + Thread* thread); + +private: + ::Team* fTeam; + Architecture* fArchitecture; +}; + +#endif // DEBUG_REPORT_GENERATOR_H diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index e316d8b7f8..d0865ec68c 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -12,6 +12,7 @@ #include +#include #include #include @@ -22,6 +23,7 @@ #include "BreakpointSetting.h" #include "CpuState.h" #include "DebuggerInterface.h" +#include "DebugReportGenerator.h" #include "FileManager.h" #include "Function.h" #include "FunctionID.h" @@ -146,6 +148,7 @@ TeamDebugger::TeamDebugger(Listener* listener, UserInterface* userInterface, fBreakpointManager(NULL), fWatchpointManager(NULL), fMemoryBlockManager(NULL), + fReportGenerator(NULL), fDebugEventListener(-1), fUserInterface(userInterface), fTerminating(false), @@ -204,6 +207,7 @@ TeamDebugger::~TeamDebugger() delete fBreakpointManager; delete fWatchpointManager; delete fMemoryBlockManager; + delete fReportGenerator; delete fWorker; delete fTeam; delete fFileManager; @@ -327,6 +331,15 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) if (error != B_OK) return error; + // create the debug report generator + fReportGenerator = new(std::nothrow) DebugReportGenerator(fTeam); + if (fReportGenerator == NULL) + return B_NO_MEMORY; + + error = fReportGenerator->Init(); + if (error != B_OK) + return error; + // set team debugging flags fDebuggerInterface->SetTeamDebuggingFlags( B_TEAM_DEBUG_THREADS | B_TEAM_DEBUG_IMAGES); @@ -535,6 +548,14 @@ TeamDebugger::MessageReceived(BMessage* message) break; } + case MSG_GENERATE_DEBUG_REPORT: + { + entry_ref ref; + if (message->FindRef("target", &ref) == B_OK) + _HandleGenerateDebugReport(ref); + break; + } + case MSG_THREAD_STATE_CHANGED: { int32 threadID; @@ -809,6 +830,15 @@ TeamDebugger::InspectRequested(target_addr_t address, } +void +TeamDebugger::DebugReportRequested(entry_ref* targetPath) +{ + BMessage message(MSG_GENERATE_DEBUG_REPORT); + message.AddRef("target", targetPath); + PostMessage(&message); +} + + bool TeamDebugger::UserInterfaceQuitRequested(QuitOption quitOption) { @@ -1502,6 +1532,13 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address, } +void +TeamDebugger::_HandleGenerateDebugReport(const entry_ref& ref) +{ + fReportGenerator->GenerateReport(ref); +} + + ThreadHandler* TeamDebugger::_GetThreadHandler(thread_id threadID) { diff --git a/src/apps/debugger/controllers/TeamDebugger.h b/src/apps/debugger/controllers/TeamDebugger.h index b66d5405d8..8607aae119 100644 --- a/src/apps/debugger/controllers/TeamDebugger.h +++ b/src/apps/debugger/controllers/TeamDebugger.h @@ -20,6 +20,7 @@ class DebuggerInterface; +class DebugReportGenerator; class FileManager; class SettingsManager; class TeamDebugInfo; @@ -78,6 +79,9 @@ private: virtual void InspectRequested(target_addr_t address, TeamMemoryBlock::Listener* listener); + + virtual void DebugReportRequested(entry_ref* targetPath); + virtual bool UserInterfaceQuitRequested( QuitOption quitOption); @@ -143,6 +147,9 @@ private: target_addr_t address, TeamMemoryBlock::Listener* listener); + void _HandleGenerateDebugReport( + const entry_ref& target); + ThreadHandler* _GetThreadHandler(thread_id threadID); status_t _AddImage(const ImageInfo& imageInfo, @@ -170,6 +177,8 @@ private: WatchpointManager* fWatchpointManager; TeamMemoryBlockManager* fMemoryBlockManager; + DebugReportGenerator* + fReportGenerator; thread_id fDebugEventListener; UserInterface* fUserInterface; volatile bool fTerminating; diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index a69303711d..9ed4657440 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -14,6 +14,8 @@ #include "Types.h" +class entry_ref; + class CpuState; class FunctionInstance; class Image; @@ -116,6 +118,8 @@ public: target_addr_t address, TeamMemoryBlock::Listener* listener) = 0; + virtual void DebugReportRequested(entry_ref* path) = 0; + virtual bool UserInterfaceQuitRequested( QuitOption quitOption = QUIT_OPTION_ASK_USER) = 0; diff --git a/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp b/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp index b6e0c0dd8b..239b6f5738 100644 --- a/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp @@ -18,6 +18,7 @@ #include "CpuState.h" #include "GuiSettingsUtils.h" #include "Register.h" +#include "UiUtils.h" // #pragma mark - RegisterValueColumn @@ -39,7 +40,7 @@ protected: { char buffer[64]; return StringTableColumn::PrepareField( - BVariant(_ToString(value, buffer, sizeof(buffer)), + BVariant(UiUtils::VariantToString(value, buffer, sizeof(buffer)), B_VARIANT_DONT_COPY_DATA)); } @@ -53,9 +54,11 @@ protected: char bufferA[64]; char bufferB[64]; return StringTableColumn::CompareValues( - BVariant(_ToString(a, bufferA, sizeof(bufferA)), + BVariant(UiUtils::VariantToString(a, bufferA, + sizeof(bufferA)), B_VARIANT_DONT_COPY_DATA), - BVariant(_ToString(b, bufferB, sizeof(bufferB)), + BVariant(UiUtils::VariantToString(b, bufferB, + sizeof(bufferB)), B_VARIANT_DONT_COPY_DATA)); } @@ -73,42 +76,6 @@ protected: uint64 valueB = b.ToUInt64(); return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1); } - -private: - const char* _ToString(const BVariant& value, char* buffer, - size_t bufferSize) const - { - if (!value.IsNumber()) - return value.ToString(); - - switch (value.Type()) { - case B_FLOAT_TYPE: - case B_DOUBLE_TYPE: - snprintf(buffer, bufferSize, "%g", value.ToDouble()); - break; - case B_INT8_TYPE: - case B_UINT8_TYPE: - snprintf(buffer, bufferSize, "0x%02x", value.ToUInt8()); - break; - case B_INT16_TYPE: - case B_UINT16_TYPE: - snprintf(buffer, bufferSize, "0x%04x", value.ToUInt16()); - break; - case B_INT32_TYPE: - case B_UINT32_TYPE: - snprintf(buffer, bufferSize, "0x%08" B_PRIx32, - value.ToUInt32()); - break; - case B_INT64_TYPE: - case B_UINT64_TYPE: - default: - snprintf(buffer, bufferSize, "0x%016" B_PRIx64, - value.ToUInt64()); - break; - } - - return buffer; - } }; diff --git a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp index 698c9a2f8a..c36ac9b742 100644 --- a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp @@ -20,6 +20,7 @@ #include "Image.h" #include "StackTrace.h" #include "TargetAddressTableColumn.h" +#include "UiUtils.h" // #pragma mark - FramesTableModel @@ -77,30 +78,9 @@ public: return true; case 2: { - Image* image = frame->GetImage(); - FunctionInstance* function = frame->Function(); - if (image == NULL && function == NULL) { - value.SetTo("?", B_VARIANT_DONT_COPY_DATA); - return true; - } - - BString name; - target_addr_t baseAddress; - if (function != NULL) { - name = function->PrettyName(); - baseAddress = function->Address(); - } else { - name = image->Name(); - baseAddress = image->Info().TextBase(); - } - - char offset[32]; - snprintf(offset, sizeof(offset), " + %#" B_PRIx64, - frame->InstructionPointer() - baseAddress); - - name << offset; - value.SetTo(name.String()); - + char buffer[512]; + value.SetTo(UiUtils::FunctionNameForFrame(frame, buffer, + sizeof(buffer))); return true; } default: diff --git a/src/apps/debugger/user_interface/util/UiUtils.cpp b/src/apps/debugger/user_interface/util/UiUtils.cpp index e92d4bdb4f..4c955c40af 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.cpp +++ b/src/apps/debugger/user_interface/util/UiUtils.cpp @@ -6,6 +6,15 @@ #include "UiUtils.h" +#include + +#include + +#include "FunctionInstance.h" +#include "Image.h" +#include "StackFrame.h" +#include "Thread.h" + /*static*/ const char* UiUtils::ThreadStateToString(int state, int stoppedReason) @@ -35,3 +44,68 @@ UiUtils::ThreadStateToString(int state, int stoppedReason) return "Debugged"; } } + + +/*static*/ const char* +UiUtils::VariantToString(const BVariant& value, char* buffer, + size_t bufferSize) +{ + if (!value.IsNumber()) + return value.ToString(); + + switch (value.Type()) { + case B_FLOAT_TYPE: + case B_DOUBLE_TYPE: + snprintf(buffer, bufferSize, "%g", value.ToDouble()); + break; + case B_INT8_TYPE: + case B_UINT8_TYPE: + snprintf(buffer, bufferSize, "0x%02x", value.ToUInt8()); + break; + case B_INT16_TYPE: + case B_UINT16_TYPE: + snprintf(buffer, bufferSize, "0x%04x", value.ToUInt16()); + break; + case B_INT32_TYPE: + case B_UINT32_TYPE: + snprintf(buffer, bufferSize, "0x%08" B_PRIx32, + value.ToUInt32()); + break; + case B_INT64_TYPE: + case B_UINT64_TYPE: + default: + snprintf(buffer, bufferSize, "0x%016" B_PRIx64, + value.ToUInt64()); + break; + } + + return buffer; +} + + +/*static*/ const char* +UiUtils::FunctionNameForFrame(StackFrame* frame, char* buffer, + size_t bufferSize) +{ + Image* image = frame->GetImage(); + FunctionInstance* function = frame->Function(); + if (image == NULL && function == NULL) { + snprintf(buffer, bufferSize, "?"); + return buffer; + } + + BString name; + target_addr_t baseAddress; + if (function != NULL) { + name = function->PrettyName(); + baseAddress = function->Address(); + } else { + name = image->Name(); + baseAddress = image->Info().TextBase(); + } + + snprintf(buffer, bufferSize, "%s + %#" B_PRIx64, + name.String(), frame->InstructionPointer() - baseAddress); + + return buffer; +} diff --git a/src/apps/debugger/user_interface/util/UiUtils.h b/src/apps/debugger/user_interface/util/UiUtils.h index a7f74b4d54..8ac0743816 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.h +++ b/src/apps/debugger/user_interface/util/UiUtils.h @@ -5,14 +5,24 @@ #ifndef UI_UTILS_H #define UI_UTILS_H +#include -#include "Thread.h" + +class StackFrame; + + +class BVariant; class UiUtils { public: static const char* ThreadStateToString(int state, int stoppedReason); + + static const char* VariantToString(const BVariant& value, + char* buffer, size_t bufferSize); + static const char* FunctionNameForFrame(StackFrame* frame, + char* buffer, size_t bufferSize); }; diff --git a/src/apps/deskbar/BarApp.cpp b/src/apps/deskbar/BarApp.cpp index f5080da752..42160e01eb 100644 --- a/src/apps/deskbar/BarApp.cpp +++ b/src/apps/deskbar/BarApp.cpp @@ -116,7 +116,7 @@ TBarApp::TBarApp() numTeams = teamList.CountItems(); for (int32 i = 0; i < numTeams; i++) { app_info appInfo; - team_id tID = (team_id)teamList.ItemAt(i); + team_id tID = (addr_t)teamList.ItemAt(i); if (be_roster->GetRunningAppInfo(tID, &appInfo) == B_OK) { AddTeam(appInfo.team, appInfo.flags, appInfo.signature, &appInfo.ref); @@ -454,7 +454,7 @@ TBarApp::MessageReceived(BMessage* message) message->FindInt32("be:team", &team); uint32 flags = 0; - message->FindInt32("be:flags", (long*)&flags); + message->FindInt32("be:flags", (int32*)&flags); const char* sig = NULL; message->FindString("be:signature", &sig); @@ -717,14 +717,14 @@ TBarApp::AddTeam(team_id team, uint32 flags, const char* sig, entry_ref* ref) int32 teamCount = sBarTeamInfoList.CountItems(); for (int32 i = 0; i < teamCount; i++) { BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); - if (barInfo->teams->HasItem((void*)team)) + if (barInfo->teams->HasItem((void*)(addr_t)team)) return; if (strcasecmp(barInfo->sig, sig) == 0) multiLaunchTeam = barInfo; } if (multiLaunchTeam != NULL) { - multiLaunchTeam->teams->AddItem((void*)team); + multiLaunchTeam->teams->AddItem((void*)(addr_t)team); int32 subsCount = sSubscribers.CountItems(); if (subsCount > 0) { @@ -756,7 +756,7 @@ TBarApp::AddTeam(team_id team, uint32 flags, const char* sig, entry_ref* ref) FetchAppIcon(barInfo->sig, barInfo->icon); } - barInfo->teams->AddItem((void*)team); + barInfo->teams->AddItem((void*)(addr_t)team); sBarTeamInfoList.AddItem(barInfo); @@ -797,7 +797,7 @@ TBarApp::RemoveTeam(team_id team) int32 teamCount = sBarTeamInfoList.CountItems(); for (int32 i = 0; i < teamCount; i++) { BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); - if (barInfo->teams->HasItem((void*)team)) { + if (barInfo->teams->HasItem((void*)(addr_t)team)) { int32 subsCount = sSubscribers.CountItems(); if (subsCount > 0) { BMessage message((barInfo->teams->CountItems() == 1) @@ -810,7 +810,7 @@ TBarApp::RemoveTeam(team_id team) } } - barInfo->teams->RemoveItem((void*)team); + barInfo->teams->RemoveItem((void*)(addr_t)team); if (barInfo->teams->CountItems() < 1) { delete (BarTeamInfo*)sBarTeamInfoList.RemoveItem(i); return; diff --git a/src/apps/deskbar/BarMenuBar.cpp b/src/apps/deskbar/BarMenuBar.cpp index 173b5d9709..1383bd68e2 100644 --- a/src/apps/deskbar/BarMenuBar.cpp +++ b/src/apps/deskbar/BarMenuBar.cpp @@ -56,7 +56,8 @@ const float kSepItemWidth = 5.0f; TBarMenuBar::TBarMenuBar(TBarView* bar, BRect frame, const char* name) : BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false), fBarView(bar), - fAppListMenuItem(NULL) + fAppListMenuItem(NULL), + fSeparatorItem(NULL) { SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/src/apps/deskbar/BarView.cpp b/src/apps/deskbar/BarView.cpp index 07f28782a7..6f89271aa1 100644 --- a/src/apps/deskbar/BarView.cpp +++ b/src/apps/deskbar/BarView.cpp @@ -160,6 +160,7 @@ TBarView::~TBarView() { delete fDragMessage; delete fCachedTypesList; + delete fBarMenuBar; RemoveExpandedItems(); } diff --git a/src/apps/deskbar/BarWindow.cpp b/src/apps/deskbar/BarWindow.cpp index b691f06ae9..addf402f8e 100644 --- a/src/apps/deskbar/BarWindow.cpp +++ b/src/apps/deskbar/BarWindow.cpp @@ -72,7 +72,11 @@ All rights reserved. #elif __GNUC__ <= 2 #define BMenuBar_StartMenuBar_Hack StartMenuBar__8BMenuBarlbT2P5BRect #elif __GNUC__ > 2 - #define BMenuBar_StartMenuBar_Hack _ZN8BMenuBar12StartMenuBarElbbP5BRect + #if B_HAIKU_64_BIT + #define BMenuBar_StartMenuBar_Hack _ZN8BMenuBar12StartMenuBarEibbP5BRect + #else + #define BMenuBar_StartMenuBar_Hack _ZN8BMenuBar12StartMenuBarElbbP5BRect + #endif #else # error "You may want to port this ugly hack to your compiler ABI" #endif diff --git a/src/apps/deskbar/ExpandoMenuBar.cpp b/src/apps/deskbar/ExpandoMenuBar.cpp index 91f4cfa2be..310d5ab9d4 100644 --- a/src/apps/deskbar/ExpandoMenuBar.cpp +++ b/src/apps/deskbar/ExpandoMenuBar.cpp @@ -350,7 +350,7 @@ TExpandoMenuBar::MouseDown(BPoint where) team_id teamID; for (int32 team = 0; team < teamCount; team++) { - teamID = (team_id)teams->ItemAt(team); + teamID = (addr_t)teams->ItemAt(team); kill_team(teamID); // remove the team immediately from display RemoveTeam(teamID, false); @@ -390,7 +390,7 @@ TExpandoMenuBar::MouseDown(BPoint where) if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1 && item == menuItem && item == fLastClickItem) { // activate this team - be_roster->ActivateApp((team_id)item->Teams()->ItemAt(0)); + be_roster->ActivateApp((addr_t)item->Teams()->ItemAt(0)); return; } @@ -633,8 +633,8 @@ TExpandoMenuBar::AddTeam(team_id team, const char* signature) // Only add to team menu items if (TTeamMenuItem* item = dynamic_cast(ItemAt(i))) { if (strcasecmp(item->Signature(), signature) == 0) { - if (!(item->Teams()->HasItem((void*)team))) - item->Teams()->AddItem((void*)team); + if (!(item->Teams()->HasItem((void*)(addr_t)team))) + item->Teams()->AddItem((void*)(addr_t)team); break; } } @@ -648,7 +648,7 @@ TExpandoMenuBar::RemoveTeam(team_id team, bool partial) int32 count = CountItems(); for (int32 i = 0; i < count; i++) { if (TTeamMenuItem* item = dynamic_cast(ItemAt(i))) { - if (item->Teams()->HasItem((void*)team)) { + if (item->Teams()->HasItem((void*)(addr_t)team)) { item->Teams()->RemoveItem(team); if (partial) @@ -864,7 +864,7 @@ TExpandoMenuBar::monitor_team_windows(void* arg) for (int32 j = 0; j < teamCount; j++) { // The following code is almost a copy/paste from // WindowMenu.cpp - team_id theTeam = (team_id)teamItem->Teams()->ItemAt(j); + team_id theTeam = (addr_t)teamItem->Teams()->ItemAt(j); int32 count = 0; int32* tokens = get_token_list(theTeam, &count); diff --git a/src/apps/deskbar/ShowHideMenuItem.cpp b/src/apps/deskbar/ShowHideMenuItem.cpp index 2c7019750c..e195eb7625 100644 --- a/src/apps/deskbar/ShowHideMenuItem.cpp +++ b/src/apps/deskbar/ShowHideMenuItem.cpp @@ -115,7 +115,7 @@ TShowHideMenuItem::TeamShowHideCommon(int32 action, const BList* teamList, int32 count = teamList->CountItems(); for (int32 index = 0; index < count; index++) { - team_id team = (team_id)teamList->ItemAt(index); + team_id team = (addr_t)teamList->ItemAt(index); switch (action) { case B_MINIMIZE_WINDOW: diff --git a/src/apps/deskbar/StatusView.cpp b/src/apps/deskbar/StatusView.cpp index 4b2df60065..fcea955957 100644 --- a/src/apps/deskbar/StatusView.cpp +++ b/src/apps/deskbar/StatusView.cpp @@ -95,10 +95,11 @@ float sMinimumWindowWidth = kGutter + kMinimumTrayWidth + kDragRegionWidth; static void DumpItem(DeskbarItemInfo* item) { - printf("is addon: %i, id: %li\n", item->isAddOn, item->id); - printf("entry_ref: %ld, %Ld, %s\n", item->entryRef.device, - item->entryRef.directory, item->entryRef.name); - printf("node_ref: %ld, %Ld\n", item->nodeRef.device, item->nodeRef.node); + printf("is addon: %i, id: %" B_PRId32 "\n", item->isAddOn, item->id); + printf("entry_ref: %" B_PRIdDEV ", %" B_PRIdINO ", %s\n", + item->entryRef.device, item->entryRef.directory, item->entryRef.name); + printf("node_ref: %" B_PRIdDEV ", %" B_PRIdINO "\n", item->nodeRef.device, + item->nodeRef.node); } @@ -1428,7 +1429,7 @@ TDragRegion::DragRegion() const void TDragRegion::MouseDown(BPoint thePoint) { - ulong buttons; + uint32 buttons; BPoint where; BRect dragRegion(DragRegion()); diff --git a/src/apps/deskbar/Switcher.cpp b/src/apps/deskbar/Switcher.cpp index 7ba23b27b4..59963f66d1 100644 --- a/src/apps/deskbar/Switcher.cpp +++ b/src/apps/deskbar/Switcher.cpp @@ -486,7 +486,7 @@ TSwitchManager::MessageReceived(BMessage* message) message->FindInt32("team", &teamID); while ((tinfo = (TTeamGroup*)fGroupList.ItemAt(i)) != NULL) { - if (tinfo->TeamList()->HasItem((void*)teamID)) { + if (tinfo->TeamList()->HasItem((void*)(addr_t)teamID)) { fGroupList.RemoveItem(i); if (OKToUse(tinfo)) { @@ -555,8 +555,8 @@ TSwitchManager::MessageReceived(BMessage* message) for (int32 i = 0; i < fGroupList.CountItems(); i++) { TTeamGroup* tinfo = (TTeamGroup*)fGroupList.ItemAt(i); if (strcasecmp(tinfo->Signature(), signature) == 0) { - if (!(tinfo->TeamList()->HasItem((void*)team))) - tinfo->TeamList()->AddItem((void*)team); + if (!(tinfo->TeamList()->HasItem((void*)(addr_t)team))) + tinfo->TeamList()->AddItem((void*)(addr_t)team); break; } } @@ -569,8 +569,8 @@ TSwitchManager::MessageReceived(BMessage* message) for (int32 i = 0; i < fGroupList.CountItems(); i++) { TTeamGroup* tinfo = (TTeamGroup*)fGroupList.ItemAt(i); - if (tinfo->TeamList()->HasItem((void*)team)) { - tinfo->TeamList()->RemoveItem((void*)team); + if (tinfo->TeamList()->HasItem((void*)(addr_t)team)) { + tinfo->TeamList()->RemoveItem((void*)(addr_t)team); break; } } @@ -638,7 +638,7 @@ TSwitchManager::_SortApps() // find team TTeamGroup* info = NULL; for (int32 j = 0; (info = (TTeamGroup*)groups.ItemAt(j)) != NULL; j++) { - if (info->TeamList()->HasItem((void*)teams[i])) { + if (info->TeamList()->HasItem((void*)(addr_t)teams[i])) { groups.RemoveItem(j); break; } @@ -720,7 +720,7 @@ TSwitchManager::FindTeam(team_id teamID, int32* index) int i = 0; TTeamGroup* info; while ((info = (TTeamGroup*)fGroupList.ItemAt(i)) != NULL) { - if (info->TeamList()->HasItem((void*)teamID)) { + if (info->TeamList()->HasItem((void*)(addr_t)teamID)) { *index = i; return info; } @@ -953,7 +953,7 @@ TSwitchManager::ActivateApp(bool forceShow, bool allowWorkspaceSwitch) result = false; } else { result = true; - be_roster->ActivateApp((team_id)teamGroup->TeamList()->ItemAt(0)); + be_roster->ActivateApp((addr_t)teamGroup->TeamList()->ItemAt(0)); } ASSERT(windowInfo); @@ -1013,8 +1013,8 @@ TSwitchManager::ActivateApp(bool forceShow, bool allowWorkspaceSwitch) break; } if (matchWindowInfo->server_token != windowInfo->server_token - && teamGroup->TeamList()->HasItem((void*)matchWindowInfo->team)) - windowsToActivate.AddItem((void*)matchWindowInfo->server_token); + && teamGroup->TeamList()->HasItem((void*)(addr_t)matchWindowInfo->team)) + windowsToActivate.AddItem((void*)(addr_t)matchWindowInfo->server_token); free(matchWindowInfo); } @@ -1025,7 +1025,7 @@ TSwitchManager::ActivateApp(bool forceShow, bool allowWorkspaceSwitch) // order. int32 i = windowsToActivate.CountItems() - 1; for (; i >= 0; i--) { - int32 wid = (int32) windowsToActivate.ItemAt(i); + int32 wid = (addr_t)windowsToActivate.ItemAt(i); do_window_action(wid, B_BRING_TO_FRONT, BRect(0, 0, 0, 0), false); } @@ -1068,7 +1068,7 @@ TSwitchManager::QuitApp() // send the quit request to all teams in this group for (int32 i = teamGroup->TeamList()->CountItems(); i-- > 0;) { - team_id team = (team_id)teamGroup->TeamList()->ItemAt(i); + team_id team = (addr_t)teamGroup->TeamList()->ItemAt(i); app_info info; if (be_roster->GetRunningAppInfo(team, &info) == B_OK) { if (!strcasecmp(info.signature, kTrackerSignature)) { @@ -1091,7 +1091,7 @@ TSwitchManager::HideApp() TTeamGroup* teamGroup = (TTeamGroup*)fGroupList.ItemAt(fCurrentIndex); for (int32 i = teamGroup->TeamList()->CountItems(); i-- > 0;) { - team_id team = (team_id)teamGroup->TeamList()->ItemAt(i); + team_id team = (addr_t)teamGroup->TeamList()->ItemAt(i); app_info info; if (be_roster->GetRunningAppInfo(team, &info) == B_OK) do_minimize_team(BRect(), team, false); @@ -1124,7 +1124,7 @@ TSwitchManager::WindowInfo(int32 groupIndex, int32 windowIndex) if (windowInfo) { // skip hidden/special windows if (IsWindowOK(windowInfo) - && (teamGroup->TeamList()->HasItem((void*)windowInfo->team))) { + && (teamGroup->TeamList()->HasItem((void*)(addr_t)windowInfo->team))) { // this window belongs to the team! if (matches == windowIndex) { // we found it! @@ -1154,7 +1154,7 @@ TSwitchManager::CountWindows(int32 groupIndex, bool ) int32 result = 0; for (int32 i = 0; ; i++) { - team_id teamID = (team_id)teamGroup->TeamList()->ItemAt(i); + team_id teamID = (addr_t)teamGroup->TeamList()->ItemAt(i); if (teamID == 0) break; @@ -1206,7 +1206,7 @@ TSwitchManager::SwitchWindow(team_id team, bool, bool activate) for (int32 i = count - 1; i >= 0; i--) { client_window_info* windowInfo = get_window_info(tokens[i]); if (windowInfo && IsVisibleInCurrentWorkspace(windowInfo) - && teamGroup->TeamList()->HasItem((void*)windowInfo->team)) { + && teamGroup->TeamList()->HasItem((void*)(addr_t)windowInfo->team)) { fWindowID = windowInfo->server_token; if (activate) ActivateWindow(windowInfo->server_token); diff --git a/src/apps/deskbar/TeamMenuItem.cpp b/src/apps/deskbar/TeamMenuItem.cpp index 1d33cf66a1..8a7474bebf 100644 --- a/src/apps/deskbar/TeamMenuItem.cpp +++ b/src/apps/deskbar/TeamMenuItem.cpp @@ -90,7 +90,7 @@ TTeamMenuItem::InitData(BList* team, BBitmap* icon, char* name, char* sig, fSig = sig; if (fName == NULL) { char temp[32]; - snprintf(temp, sizeof(temp), "team %ld", (int32)team->ItemAt(0)); + snprintf(temp, sizeof(temp), "team %ld", (addr_t)team->ItemAt(0)); fName = strdup(temp); } diff --git a/src/apps/deskbar/TimeView.cpp b/src/apps/deskbar/TimeView.cpp index 014cb9a1bc..a3102db955 100644 --- a/src/apps/deskbar/TimeView.cpp +++ b/src/apps/deskbar/TimeView.cpp @@ -88,7 +88,6 @@ TTimeView::TTimeView(float maxWidth, float height, bool use24HourClock, fLastTimeStr[0] = 0; fLastDateStr[0] = 0; fNeedToUpdate = true; - UpdateTimeFormat(); fLocale = *BLocale::Default(); } @@ -385,16 +384,38 @@ TTimeView::ShowCalendar(BPoint where) void TTimeView::GetCurrentTime() { - fLocale.FormatTime(fCurrentTimeStr, 64, fCurrentTime, fTimeFormat); + ssize_t offset = 0; + + // ToDo: Check to see if we should write day of week after time for locale + + if (fShowDayOfWeek) { + BString timeFormat("eee "); + offset = fLocale.FormatTime(fCurrentTimeStr, sizeof(fCurrentTimeStr), + fCurrentTime, timeFormat); + + if (offset < 0) { + // error occured, attempt to overwrite with current time + // (this should not ever happen) + fLocale.FormatTime(fCurrentTimeStr, sizeof(fCurrentTimeStr), + fCurrentTime, + fShowSeconds ? B_MEDIUM_TIME_FORMAT : B_SHORT_TIME_FORMAT); + return; + } + } + + fLocale.FormatTime(fCurrentTimeStr + offset, + sizeof(fCurrentTimeStr) - offset, fCurrentTime, + fShowSeconds ? B_MEDIUM_TIME_FORMAT : B_SHORT_TIME_FORMAT); } void TTimeView::GetCurrentDate() { - char tmp[64]; + char tmp[sizeof(fCurrentDateStr)]; - fLocale.FormatDate(tmp, 64, fCurrentTime, B_FULL_DATE_FORMAT); + fLocale.FormatDate(tmp, sizeof(fCurrentDateStr), fCurrentTime, + B_FULL_DATE_FORMAT); // remove leading 0 from date when month is less than 10 (MM/DD/YY) // or remove leading 0 from date when day is less than 10 (DD/MM/YY) @@ -460,7 +481,6 @@ void TTimeView::Update() { fLocale = *BLocale::Default(); - UpdateTimeFormat(); GetCurrentTime(); GetCurrentDate(); @@ -472,26 +492,3 @@ TTimeView::Update() if (fParent != NULL) fParent->Invalidate(); } - - -void -TTimeView::UpdateTimeFormat() -{ - BString timeFormat; - - if (fShowDayOfWeek) - timeFormat.Append("eee "); - - if (fUse24HourClock) - timeFormat.Append("H:mm"); - else - timeFormat.Append("h:mm"); - - if (fShowSeconds) - timeFormat.Append(":ss"); - - if (!fUse24HourClock) - timeFormat.Append(" a"); - - fTimeFormat = timeFormat; -} diff --git a/src/apps/deskbar/TimeView.h b/src/apps/deskbar/TimeView.h index 24c5495502..f273a10869 100644 --- a/src/apps/deskbar/TimeView.h +++ b/src/apps/deskbar/TimeView.h @@ -96,7 +96,6 @@ private: void CalculateTextPlacement(); void ShowTimeOptions(BPoint); void Update(); - void UpdateTimeFormat(); BView* fParent; bool fNeedToUpdate; diff --git a/src/apps/deskbar/WindowMenu.cpp b/src/apps/deskbar/WindowMenu.cpp index dbde4aca81..42279f79d2 100644 --- a/src/apps/deskbar/WindowMenu.cpp +++ b/src/apps/deskbar/WindowMenu.cpp @@ -120,7 +120,7 @@ TWindowMenu::AttachedToWindow() int32 teamCount = fTeam->CountItems(); for (int32 i = 0; i < teamCount; i++) { - team_id theTeam = (team_id)fTeam->ItemAt(i); + team_id theTeam = (addr_t)fTeam->ItemAt(i); int32 tokenCount = 0; int32* tokens = get_token_list(theTeam, &tokenCount); diff --git a/src/apps/diskusage/ControlsView.cpp b/src/apps/diskusage/ControlsView.cpp index dcb1c00d81..b5d222af63 100644 --- a/src/apps/diskusage/ControlsView.cpp +++ b/src/apps/diskusage/ControlsView.cpp @@ -73,8 +73,8 @@ VolumeTab::IconWidth() const void VolumeTab::DrawLabel(BView* owner, BRect frame) { - owner->SetDrawingMode(B_OP_OVER); if (fIcon != NULL) { + owner->SetDrawingMode(B_OP_OVER); owner->MovePenTo(frame.left + kSmallHMargin, (frame.top + frame.bottom - fIcon->Bounds().Height()) / 2.0); owner->DrawBitmap(fIcon); @@ -188,13 +188,9 @@ ControlsView::VolumeTabView::TabFrame(int32 index) const oldToShave = toShave; for (int32 i = 0; i < countTabs; i++) { float iconWidth = ((VolumeTab*)TabAt(i))->IconWidth(); - float newMargin = margins[i] - averageToShave; - - toShave -= averageToShave; - if (newMargin < minimumMargin + iconWidth) { - toShave += minimumMargin - newMargin + iconWidth; - newMargin = minimumMargin + iconWidth; - } + float newMargin = max_c(margins[i] - averageToShave, + minimumMargin + iconWidth); + toShave -= margins[i] - newMargin; margins[i] = newMargin; } } while (toShave > 0 && oldToShave != toShave); diff --git a/src/apps/drivesetup/DriveSetup.cpp b/src/apps/drivesetup/DriveSetup.cpp index 06d4d64e63..bff334f172 100644 --- a/src/apps/drivesetup/DriveSetup.cpp +++ b/src/apps/drivesetup/DriveSetup.cpp @@ -23,7 +23,7 @@ DriveSetup::DriveSetup() : BApplication("application/x-vnd.Haiku-DriveSetup"), fWindow(NULL), - fSettings(0UL) + fSettings((uint32)0) { } diff --git a/src/apps/drivesetup/MainWindow.cpp b/src/apps/drivesetup/MainWindow.cpp index c8ab45f0a5..f97a8696a5 100644 --- a/src/apps/drivesetup/MainWindow.cpp +++ b/src/apps/drivesetup/MainWindow.cpp @@ -518,9 +518,9 @@ void MainWindow::_UpdateMenus(BDiskDevice* disk, partition_id selectedPartition, partition_id parentID) { - while (BMenuItem* item = fFormatMenu->RemoveItem(0L)) + while (BMenuItem* item = fFormatMenu->RemoveItem((int32)0)) delete item; - while (BMenuItem* item = fDiskInitMenu->RemoveItem(0L)) + while (BMenuItem* item = fDiskInitMenu->RemoveItem((int32)0)) delete item; fCreateMI->SetEnabled(false); diff --git a/src/apps/drivesetup/Support.cpp b/src/apps/drivesetup/Support.cpp index 3b4f45bc81..e33c445752 100644 --- a/src/apps/drivesetup/Support.cpp +++ b/src/apps/drivesetup/Support.cpp @@ -28,14 +28,14 @@ void dump_partition_info(const BPartition* partition) { char size[1024]; - printf("\tOffset(): %Ld\n", partition->Offset()); + printf("\tOffset(): %" B_PRIdOFF "\n", partition->Offset()); printf("\tSize(): %s\n", string_for_size(partition->Size(), size, sizeof(size))); printf("\tContentSize(): %s\n", string_for_size(partition->ContentSize(), size, sizeof(size))); - printf("\tBlockSize(): %ld\n", partition->BlockSize()); - printf("\tIndex(): %ld\n", partition->Index()); - printf("\tStatus(): %ld\n\n", partition->Status()); + printf("\tBlockSize(): %" B_PRId32 "\n", partition->BlockSize()); + printf("\tIndex(): %" B_PRId32 "\n", partition->Index()); + printf("\tStatus(): %" B_PRId32 "\n\n", partition->Status()); printf("\tContainsFileSystem(): %s\n", partition->ContainsFileSystem() ? "true" : "false"); printf("\tContainsPartitioningSystem(): %s\n\n", @@ -44,12 +44,12 @@ dump_partition_info(const BPartition* partition) printf("\tIsReadOnly(): %s\n", partition->IsReadOnly() ? "true" : "false"); printf("\tIsMounted(): %s\n", partition->IsMounted() ? "true" : "false"); printf("\tIsBusy(): %s\n\n", partition->IsBusy() ? "true" : "false"); - printf("\tFlags(): %lx\n\n", partition->Flags()); + printf("\tFlags(): %" B_PRIx32 "\n\n", partition->Flags()); printf("\tName(): %s\n", partition->Name()); printf("\tContentName(): %s\n", partition->ContentName()); printf("\tType(): %s\n", partition->Type()); printf("\tContentType(): %s\n", partition->ContentType()); - printf("\tID(): %lx\n\n", partition->ID()); + printf("\tID(): %" B_PRIx32 "\n\n", partition->ID()); } diff --git a/src/apps/glteapot/Jamfile b/src/apps/glteapot/Jamfile index d496758179..ce1b93fcf8 100644 --- a/src/apps/glteapot/Jamfile +++ b/src/apps/glteapot/Jamfile @@ -1,4 +1,5 @@ SubDir HAIKU_TOP src apps glteapot ; +SubDirSysHdrs $(HAIKU_GLU_HEADERS) ; SubDirSysHdrs $(HAIKU_MESA_HEADERS) ; SetSubDirSupportedPlatformsBeOSCompatible ; diff --git a/src/apps/installer/ProgressReporter.cpp b/src/apps/installer/ProgressReporter.cpp index af764fca41..9c95fa92cc 100644 --- a/src/apps/installer/ProgressReporter.cpp +++ b/src/apps/installer/ProgressReporter.cpp @@ -69,8 +69,8 @@ ProgressReporter::StartTimer() { fStartTime = system_time(); - printf("%lld bytes to write in %lld files\n", fBytesToWrite, - fItemsToWrite); + printf("%" B_PRIdOFF " bytes to write in %" B_PRId64 " files\n", + fBytesToWrite, fItemsToWrite); if (fMessage) { BMessage message(*fMessage); diff --git a/src/apps/installer/UnzipEngine.cpp b/src/apps/installer/UnzipEngine.cpp index d2f5426d02..7bf767c9bc 100644 --- a/src/apps/installer/UnzipEngine.cpp +++ b/src/apps/installer/UnzipEngine.cpp @@ -83,7 +83,7 @@ UnzipEngine::SetTo(const char* pathToPackage, const char* destinationFolder) ret = commandPipe.ReadLines(stdOutAndErrPipe, this); fRetrievingListing = false; - printf("%llu items in %llu bytes\n", fItemsToUncompress, + printf("%" B_PRIu64 " items in %" B_PRIdOFF " bytes\n", fItemsToUncompress, fBytesToUncompress); return ret; diff --git a/src/apps/processcontroller/MemoryBarMenuItem.cpp b/src/apps/processcontroller/MemoryBarMenuItem.cpp index c51cd750be..34fca14177 100644 --- a/src/apps/processcontroller/MemoryBarMenuItem.cpp +++ b/src/apps/processcontroller/MemoryBarMenuItem.cpp @@ -246,7 +246,7 @@ void MemoryBarMenuItem::BarUpdate() { area_info areaInfo; - int32 cookie = 0; + ssize_t cookie = 0; int64 lram_size = 0; int64 lwram_size = 0; bool exists = false; diff --git a/src/apps/processcontroller/PCWorld.cpp b/src/apps/processcontroller/PCWorld.cpp index d97d8b542f..e54bd4a5e6 100644 --- a/src/apps/processcontroller/PCWorld.cpp +++ b/src/apps/processcontroller/PCWorld.cpp @@ -115,10 +115,10 @@ PCApplication::ReadyToRun() // quit other eventually running instances BList list; be_roster->GetAppList(kSignature, &list); - long count = list.CountItems(); + int32 count = list.CountItems(); if (count > 1) { - for (long i = 0; i < count - 1; i++) { - BMessenger* otherme = new BMessenger(NULL, (team_id)list.ItemAt(i)); + for (int32 i = 0; i < count - 1; i++) { + BMessenger* otherme = new BMessenger(NULL, (addr_t)list.ItemAt(i)); BMessage* message = new BMessage(B_QUIT_REQUESTED); otherme->SendMessage(message); delete otherme; diff --git a/src/apps/processcontroller/ProcessController.cpp b/src/apps/processcontroller/ProcessController.cpp index 28e708db40..fbf3127848 100644 --- a/src/apps/processcontroller/ProcessController.cpp +++ b/src/apps/processcontroller/ProcessController.cpp @@ -90,7 +90,7 @@ bool gInDeskbar = false; #define addtopbottom(x) if (top) popup->AddItem(x); else popup->AddItem(x, 0) -long thread_popup(void *arg); +status_t thread_popup(void *arg); int32 gPopupFlag = 0; thread_id gPopupThreadID = 0; @@ -103,8 +103,8 @@ typedef struct { #define DEBUG_THREADS 1 -long thread_quit_application(void *arg); -long thread_debug_thread(void *arg); +status_t thread_quit_application(void *arg); +status_t thread_debug_thread(void *arg); typedef struct { thread_id thread; @@ -262,7 +262,7 @@ ProcessController::MessageReceived(BMessage *message) if (message->FindInt32("team", &team) == B_OK) { resume_thread(spawn_thread(thread_quit_application, B_TRANSLATE("Quit application"), B_NORMAL_PRIORITY, - (void*) team)); + (void*)(addr_t)team)); } break; @@ -314,7 +314,7 @@ ProcessController::MessageReceived(BMessage *message) B_TRANSLATE("Cancel"), B_TRANSLATE("Kill this thread!"), NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT); alert->SetShortcut(0, B_ESCAPE); - + #define KILL 1 #endif alert->SetShortcut(0, B_ESCAPE); @@ -347,7 +347,7 @@ ProcessController::MessageReceived(BMessage *message) case 'PrTh': if (message->FindInt32("thread", &thread) == B_OK) { - long new_priority; + int32 new_priority; if (message->FindInt32("priority", &new_priority) == B_OK) set_thread_priority(thread, new_priority); } @@ -682,7 +682,7 @@ ProcessController::Update() // #pragma mark - -long +status_t thread_popup(void *arg) { Tpopup_param* param = (Tpopup_param*) arg; @@ -846,16 +846,16 @@ thread_popup(void *arg) } -long +status_t thread_quit_application(void *arg) { - BMessenger messenger(NULL, (team_id)arg); + BMessenger messenger(NULL, (addr_t)arg); messenger.SendMessage(B_QUIT_REQUESTED); return B_OK; } -long +status_t thread_debug_thread(void *arg) { Tdebug_thead_param* param = (Tdebug_thead_param*) arg; diff --git a/src/apps/processcontroller/QuitMenu.cpp b/src/apps/processcontroller/QuitMenu.cpp index a5f466f41f..1ed69b0a7d 100644 --- a/src/apps/processcontroller/QuitMenu.cpp +++ b/src/apps/processcontroller/QuitMenu.cpp @@ -72,13 +72,13 @@ QuitMenu::AttachedToWindow() for (int t = CountItems() - 1; t >= 0; t--) { QuitMenuItem* item = (QuitMenuItem*)ItemAt(t); bool found = false; - for (int a = 0; !found && (tmid = (team_id)apps.ItemAt(a)) != 0; a++) + for (int a = 0; !found && (tmid = (team_id)(addr_t)apps.ItemAt(a)) != 0; a++) if (item->Team() == tmid) found = true; if (!found) RemoveItem(t); } - for (int a = 0; (tmid = (team_id) apps.ItemAt(a)) != 0; a++) { + for (int a = 0; (tmid = (team_id)(addr_t) apps.ItemAt(a)) != 0; a++) { AddTeam(tmid); } diff --git a/src/apps/processcontroller/Utilities.cpp b/src/apps/processcontroller/Utilities.cpp index f9652b706e..cb7e64b304 100644 --- a/src/apps/processcontroller/Utilities.cpp +++ b/src/apps/processcontroller/Utilities.cpp @@ -134,10 +134,10 @@ find_self(entry_ref& ref) int32 cookie = 0; image_info info; while (get_next_image_info (0, &cookie, &info) == B_OK) { - if (((uint32)info.text <= (uint32)move_to_deskbar - && (uint32)info.text + (uint32)info.text_size > (uint32)move_to_deskbar) - || ((uint32)info.data <= (uint32)move_to_deskbar - && (uint32)info.data + (uint32)info.data_size > (uint32)move_to_deskbar)) { + if (((addr_t)info.text <= (addr_t)move_to_deskbar + && (addr_t)info.text + (size_t)info.text_size > (addr_t)move_to_deskbar) + || ((addr_t)info.data <= (addr_t)move_to_deskbar + && (addr_t)info.data + (size_t)info.data_size > (addr_t)move_to_deskbar)) { if (get_ref_for_path (info.name, &ref) == B_OK) return; } diff --git a/src/apps/readonlybootprompt/BootPromptWindow.cpp b/src/apps/readonlybootprompt/BootPromptWindow.cpp index 25dbfbc5a1..12611894cc 100644 --- a/src/apps/readonlybootprompt/BootPromptWindow.cpp +++ b/src/apps/readonlybootprompt/BootPromptWindow.cpp @@ -224,10 +224,10 @@ BootPromptWindow::MessageReceived(BMessage* message) // Select default keymap by language BLanguage language(item->Language()); - BMenuItem* item = _KeymapItemForLanguage(language); - if (item != NULL) { - item->SetMarked(true); - _ActivateKeymap(item->Message()); + BMenuItem* keymapItem = _KeymapItemForLanguage(language); + if (keymapItem != NULL) { + keymapItem->SetMarked(true); + _ActivateKeymap(keymapItem->Message()); } } // Calling it here is a cheap way of preventing the user to have diff --git a/src/apps/stylededit/StyledEditWindow.cpp b/src/apps/stylededit/StyledEditWindow.cpp index 0789d3a754..3ba782cd57 100644 --- a/src/apps/stylededit/StyledEditWindow.cpp +++ b/src/apps/stylededit/StyledEditWindow.cpp @@ -1118,7 +1118,7 @@ StyledEditWindow::_InitWindow(uint32 encoding) fontMessage->AddFloat("size", fontSizes[i]); char label[64]; - snprintf(label, sizeof(label), "%ld", fontSizes[i]); + snprintf(label, sizeof(label), "%" B_PRId32, fontSizes[i]); fFontSizeMenu->AddItem(menuItem = new BMenuItem(label, fontMessage)); if (fontSizes[i] == (int32)be_plain_font->Size()) @@ -1451,7 +1451,7 @@ StyledEditWindow::_Search(BString string, bool caseSensitive, bool wrap, if (start != B_ERROR) { finish = start + length; fTextView->Select(start, finish); - + if (scrollToOccurence) fTextView->ScrollToSelection(); return true; @@ -1505,7 +1505,7 @@ StyledEditWindow::_ReplaceAll(BString findThis, BString replaceWith, { bool first = true; fTextView->SetSuppressChanges(true); - + // start from the beginning of text fTextView->Select(0, 0); @@ -1517,11 +1517,11 @@ StyledEditWindow::_ReplaceAll(BString findThis, BString replaceWith, } int32 start; int32 finish; - + fTextView->GetSelection(&start, &finish); fTextView->Delete(start, start + findThis.Length()); fTextView->Insert(start, replaceWith.String(), replaceWith.Length()); - + // advance the caret behind the inserted text start += replaceWith.Length(); fTextView->Select(start, start); @@ -1641,7 +1641,7 @@ StyledEditWindow::_ShowStatistics() BAlert* alert = new BAlert("Statistics", result, B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_INFO_ALERT); alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); - + return alert->Go(); } diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index e5600c3b87..0ae798a326 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -386,7 +386,7 @@ TermParse::EscParse() int32 srcLen = sizeof(cbuf); int32 dstLen = sizeof(dstbuf); - long dummyState = 0; + int32 dummyState = 0; int width = 1; BAutolock locker(fBuffer); @@ -1250,7 +1250,7 @@ TermParse::_DeviceStatusReport(int n) } case 6: // Cursor position report requested - len = sprintf(sbuf, "\033[%ld;%ldR", + len = sprintf(sbuf, "\033[%" B_PRId32 ";%" B_PRId32 "R", fBuffer->Cursor().y + 1, fBuffer->Cursor().x + 1); write(fFd, sbuf, len); diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index 7e7c089933..e0fbb41eb8 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -1563,7 +1563,7 @@ TermView::KeyDown(const char *bytes, int32 numBytes) if (fEncoding != M_UTF8) { char destBuffer[16]; int32 destLen = sizeof(destBuffer); - long state = 0; + int32 state = 0; convert_from_utf8(fEncoding, bytes, &numBytes, destBuffer, &destLen, &state, '?'); _ScrollTo(0, true); @@ -1761,7 +1761,7 @@ TermView::MessageReceived(BMessage *msg) if (msg->WasDropped() && (msg->what == B_SIMPLE_DATA || msg->what == B_MIME_DATA)) { char *text; - int32 numBytes; + ssize_t numBytes; //rgb_color *color; int32 i = 0; diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 19cdf278d7..5902eceb3d 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -1566,7 +1566,7 @@ TermWindow::_MakeWindowSizeMenu() char label[32]; int32 columns = windowSizes[i][0]; int32 rows = windowSizes[i][1]; - snprintf(label, sizeof(label), "%ldx%ld", columns, rows); + snprintf(label, sizeof(label), "%" B_PRId32 "x%" B_PRId32, columns, rows); BMessage* message = new BMessage(MSG_COLS_CHANGED); message->AddInt32("columns", columns); message->AddInt32("rows", rows); diff --git a/src/bin/bfs_tools/lib/Stack.h b/src/bin/bfs_tools/lib/Stack.h index d42908f56b..60a8e02c09 100644 --- a/src/bin/bfs_tools/lib/Stack.h +++ b/src/bin/bfs_tools/lib/Stack.h @@ -6,6 +6,8 @@ */ +#include + #include diff --git a/src/bin/catattr.cpp b/src/bin/catattr.cpp index 568c0031cc..eab474f8e8 100644 --- a/src/bin/catattr.cpp +++ b/src/bin/catattr.cpp @@ -43,7 +43,7 @@ dumpRawData(const char *buffer, size_t size) while (dumpPosition < size) { // Position for this line - printf("0x%06lx: ", dumpPosition); + printf("0x%06" B_PRIx32 ": ", dumpPosition); // Print the bytes in form of hexadecimal numbers for (uint32 i = 0; i < kChunkSize; i++) { @@ -88,7 +88,7 @@ type_to_string(uint32 type) sprintf(buffer, "'%c%c%c%c'", value[0], value[1], value[2], value[3]); } else - sprintf(buffer, "0x%08lx", type); + sprintf(buffer, "0x%08" B_PRIx32, type); return buffer; } @@ -218,28 +218,28 @@ catAttr(const char *attribute, const char *fileName, bool keepRaw, switch (info.type) { case B_INT8_TYPE: - printf("%d\n", *((int8*)buffer)); + printf("%" B_PRId8 "\n", *((int8*)buffer)); break; case B_UINT8_TYPE: - printf("%u\n", *((uint8*)buffer)); + printf("%" B_PRIu8 "\n", *((uint8*)buffer)); break; case B_INT16_TYPE: - printf("%d\n", *((int16*)buffer)); + printf("%" B_PRId16 "\n", *((int16*)buffer)); break; case B_UINT16_TYPE: - printf("%u\n", *((uint16*)buffer)); + printf("%" B_PRIu16 "\n", *((uint16*)buffer)); break; case B_INT32_TYPE: - printf("%ld\n", *((int32*)buffer)); + printf("%" B_PRId32 "\n", *((int32*)buffer)); break; case B_UINT32_TYPE: - printf("%lu\n", *((uint32*)buffer)); + printf("%" B_PRIu32 "\n", *((uint32*)buffer)); break; case B_INT64_TYPE: - printf("%Ld\n", *((int64*)buffer)); + printf("%" B_PRId64 "\n", *((int64*)buffer)); break; case B_UINT64_TYPE: - printf("%Lu\n", *((uint64*)buffer)); + printf("%" B_PRIu64 "\n", *((uint64*)buffer)); break; case B_FLOAT_TYPE: printf("%f\n", *((float*)buffer)); diff --git a/src/bin/clockconfig.cpp b/src/bin/clockconfig.cpp index 8acb56afc9..78c73520f7 100644 --- a/src/bin/clockconfig.cpp +++ b/src/bin/clockconfig.cpp @@ -73,7 +73,7 @@ setTimeZoneOffset(BPath path) _kern_set_timezone(timeZoneOffset, timeZoneID.String(), timeZoneID.Length()); - printf("timezone is %s, offset is %ld seconds from GMT.\n", + printf("timezone is %s, offset is %" B_PRId32 " seconds from GMT.\n", timeZoneID.String(), timeZoneOffset); } diff --git a/src/bin/consoled/consoled.cpp b/src/bin/consoled/consoled.cpp index 3a1497fed9..1b38c04151 100644 --- a/src/bin/consoled/consoled.cpp +++ b/src/bin/consoled/consoled.cpp @@ -223,9 +223,18 @@ stop_keyboards(struct console* con) static struct keyboard* open_keyboards(int target, const char* start, struct keyboard* previous) { - DIR* dir = opendir(start); - if (dir == NULL) - return NULL; + // Wait for the directory to appear, if we're loaded early in boot + // it may take a while for it to appear while the drivers load. + DIR* dir; + int32 tries = 0; + while (true) { + dir = opendir(start); + if (dir != NULL) + break; + if(++tries == 10) + return NULL; + sleep(1); + } struct keyboard* keyboard = previous; diff --git a/src/bin/coreutils/lib/Jamfile b/src/bin/coreutils/lib/Jamfile index 0c8785cc08..76bc1ff10c 100644 --- a/src/bin/coreutils/lib/Jamfile +++ b/src/bin/coreutils/lib/Jamfile @@ -9,7 +9,7 @@ SubDirCcFlags -DHAVE_CONFIG_H -DB_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT ; SubDirSysHdrs $(SUBDIR) ; #SubDirSysHdrs $(SUBDIR) $(DOTDOT) ; -StaticLibrary libfetish.a : +local libSources = # __fpending.c # acl.c # alloca.c @@ -167,7 +167,6 @@ StaticLibrary libfetish.a : readtokens.c readtokens0.c # realloc.c -# regex.c rename.c root-dev-ino.c # rmdir.c @@ -243,4 +242,17 @@ StaticLibrary libfetish.a : yesno.c ; +# For non-GCC 2 builds use the included regex implementation. The sources get +# built against the included regex.h rather than the one from libroot. On +# 32-bit this isn't problematic as they're compatible, but they are not for 64. +# GCC 2 cannot compile the included implementation, so just link to libroot's +# one there. +if $(HAIKU_GCC_VERSION[1]) != 2 { + libSources += regex.c ; +} + +StaticLibrary libfetish.a : + $(libSources) +; + SEARCH on [ FGristFiles u8-uctomb.c u8-uctomb-aux.c ] = [ FDirName $(SUBDIR) unistr ] ; diff --git a/src/bin/coreutils/lib/stdint.h b/src/bin/coreutils/lib/stdint.h index c8802b1c35..f14ef4b635 100644 --- a/src/bin/coreutils/lib/stdint.h +++ b/src/bin/coreutils/lib/stdint.h @@ -447,10 +447,17 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - # define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) # endif #else -# define PTRDIFF_MIN \ +# ifdef __x86_64__ +# define PTRDIFF_MIN \ + _STDINT_MIN (1, 64, 0l) +# define PTRDIFF_MAX \ + _STDINT_MAX (1, 64, 0l) +# else +# define PTRDIFF_MIN \ _STDINT_MIN (1, 32, 0l) -# define PTRDIFF_MAX \ +# define PTRDIFF_MAX \ _STDINT_MAX (1, 32, 0l) +# endif #endif /* sig_atomic_t limits */ @@ -473,7 +480,11 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - # define SIZE_MAX _STDINT_MAX (0, 32, 0ul) # endif #else -# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# ifdef __x86_64__ +# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# else +# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# endif #endif /* wchar_t limits */ diff --git a/src/bin/debug/strace/Context.cpp b/src/bin/debug/strace/Context.cpp index 11212f876e..9a9eb828bb 100644 --- a/src/bin/debug/strace/Context.cpp +++ b/src/bin/debug/strace/Context.cpp @@ -20,13 +20,13 @@ Context::FormatSigned(int64 value, int bytes) const // decimal if (fDecimal) { - snprintf(tmp, sizeof(tmp), "%lld", value); + snprintf(tmp, sizeof(tmp), "%" B_PRId64, value); return tmp; } // hex - snprintf(tmp, sizeof(tmp), "0x%llx", value); + snprintf(tmp, sizeof(tmp), "0x%" B_PRIx64, value); // Negative numbers are expanded when being converted to int64. Hence // we skip all but the last 2 * bytes hex digits to retain the original @@ -49,7 +49,7 @@ string Context::FormatUnsigned(uint64 value) const { char tmp[32]; - snprintf(tmp, sizeof(tmp), fDecimal ? "%llu" : "0x%llx", value); + snprintf(tmp, sizeof(tmp), fDecimal ? "%" B_PRIu64 : "0x%" B_PRIx64, value); return tmp; } @@ -57,7 +57,7 @@ string Context::FormatFlags(uint64 value) const { char tmp[32]; - snprintf(tmp, sizeof(tmp), "0x%llx", value); + snprintf(tmp, sizeof(tmp), "0x%" B_PRIx64, value); return tmp; } diff --git a/src/bin/debug/strace/strace.cpp b/src/bin/debug/strace/strace.cpp index dbb332f2fb..046efbdf13 100644 --- a/src/bin/debug/strace/strace.cpp +++ b/src/bin/debug/strace/strace.cpp @@ -528,8 +528,8 @@ main(int argc, const char *const *argv) thread_info threadInfo; status_t error = get_thread_info(threadID, &threadInfo); if (error != B_OK) { - fprintf(stderr, "%s: Failed to get info for thread %ld: %s\n", - kCommandName, threadID, strerror(error)); + fprintf(stderr, "%s: Failed to get info for thread %" B_PRId32 + ": %s\n", kCommandName, threadID, strerror(error)); exit(1); } teamID = threadInfo.team; diff --git a/src/bin/error.c b/src/bin/error.c index ff2b98c8d5..c18a71e237 100644 --- a/src/bin/error.c +++ b/src/bin/error.c @@ -320,7 +320,7 @@ print_error(char *number) error = p->value; } - printf("0x%lx: %s\n", error, strerror(error)); + printf("0x%" B_PRIx32 ": %s\n", error, strerror(error)); } diff --git a/src/bin/gdb/bfd/Jamfile b/src/bin/gdb/bfd/Jamfile index 5335660a0d..34eb556ab0 100644 --- a/src/bin/gdb/bfd/Jamfile +++ b/src/bin/gdb/bfd/Jamfile @@ -8,6 +8,9 @@ SubDirSysHdrs [ FDirName $(HAIKU_TOP) src bin gawk intl ] ; SubDirCcFlags -DHAVE_CONFIG_H -D_GNU_SOURCE ; +local bfd32SelectVecs = &bfd_elf32_little_generic_vec,&bfd_elf32_big_generic_vec ; +local bfd64SelectVecs = &bfd_elf64_little_generic_vec,&bfd_elf64_big_generic_vec ; + # architecture specific sources local bfdArchSources ; if $(TARGET_ARCH) = x86 { @@ -20,7 +23,7 @@ if $(TARGET_ARCH) = x86 { ObjectCcFlags archures.c targets.c : -DDEFAULT_VECTOR=bfd_elf32_i386_vec - -DSELECT_VECS=\"&bfd_elf32_i386_vec,&i386pe_vec,&i386pei_vec,&bfd_elf32_little_generic_vec,&bfd_elf32_big_generic_vec\" + -DSELECT_VECS=\"&bfd_elf32_i386_vec,&i386pe_vec,&i386pei_vec,$(bfd32SelectVecs)\" -DSELECT_ARCHITECTURES=\"&bfd_i386_arch\" -DHAVE_bfd_elf32_i386_vec -DHAVE_i386pe_vec @@ -28,6 +31,26 @@ if $(TARGET_ARCH) = x86 { -DHAVE_bfd_elf32_little_generic_vec -DHAVE_bfd_elf32_big_generic_vec ; +} else if $(TARGET_ARCH) = x86_64 { + bfdArchSources = + cpu-i386.c + elf64-x86-64.c + elf32-i386.c + elf64.c + elf64-gen.c + ; + + ObjectCcFlags archures.c targets.c : + -DDEFAULT_VECTOR=bfd_elf64_x86_64_vec + -DSELECT_VECS=\"&bfd_elf64_x86_64_vec,&bfd_elf32_i386_vec,$(bfd32SelectVecs),$(bfd64SelectVecs)\" + -DSELECT_ARCHITECTURES=\"&bfd_i386_arch\" + -DHAVE_bfd_elf64_x86_64_vec + -DHAVE_bfd_elf32_i386_vec + -DHAVE_bfd_elf64_little_generic_vec + -DHAVE_bfd_elf64_big_generic_vec + -DHAVE_bfd_elf32_little_generic_vec + -DHAVE_bfd_elf32_big_generic_vec + ; } else if $(TARGET_ARCH) = ppc { bfdArchSources = cpu-powerpc.c @@ -81,7 +104,10 @@ local bfdGenericSources = elf-strtab.c ; -local bfdGeneratedSources = peigen.c ; +local bfdGeneratedSources ; +if $(TARGET_ARCH) != x86_64 { + bfdGeneratedSources = peigen.c ; +} local bfdAllSources = $(bfdBaseSources) @@ -167,6 +193,7 @@ local bfdHeadersToCopy = BFDSimpleSed peigen.c : peXXigen.c : s/XX/pe/g ; BFDSimpleSed elf32-target.h : elfxx-target.h : s/NN/32/g ; +BFDSimpleSed elf64-target.h : elfxx-target.h : s/NN/64/g ; BFDFileSed targmatch.h : config.bfd : targmatch.sed ; BFDCopyConfigHeaders $(bfdHeadersToCopy) ; @@ -174,7 +201,8 @@ BFDCopyConfigHeaders $(bfdHeadersToCopy) ; # depend on them. local bfdGeneratedHeaders - = [ FGristFiles $(bfdHeadersToCopy) elf32-target.h targmatch.h ] ; + = [ FGristFiles $(bfdHeadersToCopy) elf32-target.h elf64-target.h + targmatch.h ] ; Depends gdb-bfd-generated-headers : $(bfdGeneratedHeaders) ; NotFile gdb-bfd-generated-headers ; diff --git a/src/bin/gdb/bfd/config-x86_64/bfd-in3.h b/src/bin/gdb/bfd/config-x86_64/bfd-in3.h new file mode 100644 index 0000000000..ba10b2889f --- /dev/null +++ b/src/bin/gdb/bfd/config-x86_64/bfd-in3.h @@ -0,0 +1,4645 @@ +/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically + generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c", + "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c", + "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c", + "linker.c" and "simple.c". + Run "make headers" in your build bfd/ to regenerate. */ + +/* Main header file for the bfd library -- portable access to object files. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + Contributed by Cygnus Support. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef __BFD_H_SEEN__ +#define __BFD_H_SEEN__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ansidecl.h" +#include "symcat.h" +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#ifndef SABER +/* This hack is to avoid a problem with some strict ANSI C preprocessors. + The problem is, "32_" is not a valid preprocessing token, and we don't + want extra underscores (e.g., "nlm_32_"). The XCONCAT2 macro will + cause the inner CONCAT2 macros to be evaluated first, producing + still-valid pp-tokens. Then the final concatenation can be done. */ +#undef CONCAT4 +#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d)) +#endif +#endif + +/* The word size used by BFD on the host. This may be 64 with a 32 + bit target if the host is 64 bit, or if other 64 bit targets have + been selected with --enable-targets, or if --enable-64-bit-bfd. */ +#define BFD_ARCH_SIZE 64 + +/* The word size of the default bfd target. */ +#define BFD_DEFAULT_TARGET_SIZE 64 + +#define BFD_HOST_64BIT_LONG 1 +#define BFD_HOST_LONG_LONG 1 +#define BFD_HOST_64_BIT long +#define BFD_HOST_U_64_BIT unsigned long +typedef BFD_HOST_64_BIT bfd_int64_t; +typedef BFD_HOST_U_64_BIT bfd_uint64_t; + +#if BFD_ARCH_SIZE >= 64 +#define BFD64 +#endif + +#ifndef INLINE +#if __GNUC__ >= 2 +#define INLINE __inline__ +#else +#define INLINE +#endif +#endif + +/* Forward declaration. */ +typedef struct bfd bfd; + +/* Boolean type used in bfd. Too many systems define their own + versions of "boolean" for us to safely typedef a "boolean" of + our own. Using an enum for "bfd_boolean" has its own set of + problems, with strange looking casts required to avoid warnings + on some older compilers. Thus we just use an int. + + General rule: Functions which are bfd_boolean return TRUE on + success and FALSE on failure (unless they're a predicate). */ + +typedef int bfd_boolean; +#undef FALSE +#undef TRUE +#define FALSE 0 +#define TRUE 1 + +#if 0 +/* Poison. */ +#undef false +#undef true +#define false dont_use_false_in_bfd +#define true dont_use_true_in_bfd +#endif + +#ifdef BFD64 + +#ifndef BFD_HOST_64_BIT + #error No 64 bit integer type available +#endif /* ! defined (BFD_HOST_64_BIT) */ + +typedef BFD_HOST_U_64_BIT bfd_vma; +typedef BFD_HOST_64_BIT bfd_signed_vma; +typedef BFD_HOST_U_64_BIT bfd_size_type; +typedef BFD_HOST_U_64_BIT symvalue; + +#ifndef fprintf_vma +#if BFD_HOST_64BIT_LONG +#define sprintf_vma(s,x) sprintf (s, "%016lx", x) +#define fprintf_vma(f,x) fprintf (f, "%016lx", x) +#else +#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) +#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) +#define fprintf_vma(s,x) \ + fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) +#define sprintf_vma(s,x) \ + sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) +#endif +#endif + +#else /* not BFD64 */ + +/* Represent a target address. Also used as a generic unsigned type + which is guaranteed to be big enough to hold any arithmetic types + we need to deal with. */ +typedef unsigned long bfd_vma; + +/* A generic signed type which is guaranteed to be big enough to hold any + arithmetic types we need to deal with. Can be assumed to be compatible + with bfd_vma in the same way that signed and unsigned ints are compatible + (as parameters, in assignment, etc). */ +typedef long bfd_signed_vma; + +typedef unsigned long symvalue; +typedef unsigned long bfd_size_type; + +/* Print a bfd_vma x on stream s. */ +#define fprintf_vma(s,x) fprintf (s, "%08lx", x) +#define sprintf_vma(s,x) sprintf (s, "%08lx", x) + +#endif /* not BFD64 */ + +#ifndef BFD_HOST_64_BIT +/* Fall back on a 32 bit type. The idea is to make these types always + available for function return types, but in the case that + BFD_HOST_64_BIT is undefined such a function should abort or + otherwise signal an error. */ +typedef bfd_signed_vma bfd_int64_t; +typedef bfd_vma bfd_uint64_t; +#endif + +/* An offset into a file. BFD always uses the largest possible offset + based on the build time availability of fseek, fseeko, or fseeko64. */ +typedef BFD_HOST_64_BIT file_ptr; +typedef unsigned BFD_HOST_64_BIT ufile_ptr; + +extern void bfd_sprintf_vma (bfd *, char *, bfd_vma); +extern void bfd_fprintf_vma (bfd *, void *, bfd_vma); + +#define printf_vma(x) fprintf_vma(stdout,x) +#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x) + +typedef unsigned int flagword; /* 32 bits of flags */ +typedef unsigned char bfd_byte; + +/* File formats. */ + +typedef enum bfd_format +{ + bfd_unknown = 0, /* File format is unknown. */ + bfd_object, /* Linker/assembler/compiler output. */ + bfd_archive, /* Object archive file. */ + bfd_core, /* Core dump. */ + bfd_type_end /* Marks the end; don't use it! */ +} +bfd_format; + +/* Values that may appear in the flags field of a BFD. These also + appear in the object_flags field of the bfd_target structure, where + they indicate the set of flags used by that backend (not all flags + are meaningful for all object file formats) (FIXME: at the moment, + the object_flags values have mostly just been copied from backend + to another, and are not necessarily correct). */ + +/* No flags. */ +#define BFD_NO_FLAGS 0x00 + +/* BFD contains relocation entries. */ +#define HAS_RELOC 0x01 + +/* BFD is directly executable. */ +#define EXEC_P 0x02 + +/* BFD has line number information (basically used for F_LNNO in a + COFF header). */ +#define HAS_LINENO 0x04 + +/* BFD has debugging information. */ +#define HAS_DEBUG 0x08 + +/* BFD has symbols. */ +#define HAS_SYMS 0x10 + +/* BFD has local symbols (basically used for F_LSYMS in a COFF + header). */ +#define HAS_LOCALS 0x20 + +/* BFD is a dynamic object. */ +#define DYNAMIC 0x40 + +/* Text section is write protected (if D_PAGED is not set, this is + like an a.out NMAGIC file) (the linker sets this by default, but + clears it for -r or -N). */ +#define WP_TEXT 0x80 + +/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the + linker sets this by default, but clears it for -r or -n or -N). */ +#define D_PAGED 0x100 + +/* BFD is relaxable (this means that bfd_relax_section may be able to + do something) (sometimes bfd_relax_section can do something even if + this is not set). */ +#define BFD_IS_RELAXABLE 0x200 + +/* This may be set before writing out a BFD to request using a + traditional format. For example, this is used to request that when + writing out an a.out object the symbols not be hashed to eliminate + duplicates. */ +#define BFD_TRADITIONAL_FORMAT 0x400 + +/* This flag indicates that the BFD contents are actually cached in + memory. If this is set, iostream points to a bfd_in_memory struct. */ +#define BFD_IN_MEMORY 0x800 + +/* The sections in this BFD specify a memory page. */ +#define HAS_LOAD_PAGE 0x1000 + +/* Symbols and relocation. */ + +/* A count of carsyms (canonical archive symbols). */ +typedef unsigned long symindex; + +/* How to perform a relocation. */ +typedef const struct reloc_howto_struct reloc_howto_type; + +#define BFD_NO_MORE_SYMBOLS ((symindex) ~0) + +/* General purpose part of a symbol X; + target specific parts are in libcoff.h, libaout.h, etc. */ + +#define bfd_get_section(x) ((x)->section) +#define bfd_get_output_section(x) ((x)->section->output_section) +#define bfd_set_section(x,y) ((x)->section) = (y) +#define bfd_asymbol_base(x) ((x)->section->vma) +#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value) +#define bfd_asymbol_name(x) ((x)->name) +/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ +#define bfd_asymbol_bfd(x) ((x)->the_bfd) +#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour) + +/* A canonical archive symbol. */ +/* This is a type pun with struct ranlib on purpose! */ +typedef struct carsym +{ + char *name; + file_ptr file_offset; /* Look here to find the file. */ +} +carsym; /* To make these you call a carsymogen. */ + +/* Used in generating armaps (archive tables of contents). + Perhaps just a forward definition would do? */ +struct orl /* Output ranlib. */ +{ + char **name; /* Symbol name. */ + union + { + file_ptr pos; + bfd *abfd; + } u; /* bfd* or file position. */ + int namidx; /* Index into string table. */ +}; + +/* Linenumber stuff. */ +typedef struct lineno_cache_entry +{ + unsigned int line_number; /* Linenumber from start of function. */ + union + { + struct bfd_symbol *sym; /* Function name. */ + bfd_vma offset; /* Offset into section. */ + } u; +} +alent; + +/* Object and core file sections. */ + +#define align_power(addr, align) \ + (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align))) + +typedef struct bfd_section *sec_ptr; + +#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0) +#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0) +#define bfd_get_section_lma(bfd, ptr) ((ptr)->lma + 0) +#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0) +#define bfd_section_name(bfd, ptr) ((ptr)->name) +#define bfd_section_size(bfd, ptr) ((ptr)->size) +#define bfd_get_section_size(ptr) ((ptr)->size) +#define bfd_section_vma(bfd, ptr) ((ptr)->vma) +#define bfd_section_lma(bfd, ptr) ((ptr)->lma) +#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power) +#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0) +#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata) + +#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) + +#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) +#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) +#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) +/* Find the address one past the end of SEC. */ +#define bfd_get_section_limit(bfd, sec) \ + (((sec)->rawsize ? (sec)->rawsize : (sec)->size) \ + / bfd_octets_per_byte (bfd)) + +typedef struct stat stat_type; + +typedef enum bfd_print_symbol +{ + bfd_print_symbol_name, + bfd_print_symbol_more, + bfd_print_symbol_all +} bfd_print_symbol_type; + +/* Information about a symbol that nm needs. */ + +typedef struct _symbol_info +{ + symvalue value; + char type; + const char *name; /* Symbol name. */ + unsigned char stab_type; /* Stab type. */ + char stab_other; /* Stab other. */ + short stab_desc; /* Stab desc. */ + const char *stab_name; /* String for stab type. */ +} symbol_info; + +/* Get the name of a stabs type code. */ + +extern const char *bfd_get_stab_name (int); + +/* Hash table routines. There is no way to free up a hash table. */ + +/* An element in the hash table. Most uses will actually use a larger + structure, and an instance of this will be the first field. */ + +struct bfd_hash_entry +{ + /* Next entry for this hash code. */ + struct bfd_hash_entry *next; + /* String being hashed. */ + const char *string; + /* Hash code. This is the full hash code, not the index into the + table. */ + unsigned long hash; +}; + +/* A hash table. */ + +struct bfd_hash_table +{ + /* The hash array. */ + struct bfd_hash_entry **table; + /* The number of slots in the hash table. */ + unsigned int size; + /* A function used to create new elements in the hash table. The + first entry is itself a pointer to an element. When this + function is first invoked, this pointer will be NULL. However, + having the pointer permits a hierarchy of method functions to be + built each of which calls the function in the superclass. Thus + each function should be written to allocate a new block of memory + only if the argument is NULL. */ + struct bfd_hash_entry *(*newfunc) + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); + /* An objalloc for this hash table. This is a struct objalloc *, + but we use void * to avoid requiring the inclusion of objalloc.h. */ + void *memory; +}; + +/* Initialize a hash table. */ +extern bfd_boolean bfd_hash_table_init + (struct bfd_hash_table *, + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, + struct bfd_hash_table *, + const char *)); + +/* Initialize a hash table specifying a size. */ +extern bfd_boolean bfd_hash_table_init_n + (struct bfd_hash_table *, + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, + struct bfd_hash_table *, + const char *), + unsigned int size); + +/* Free up a hash table. */ +extern void bfd_hash_table_free + (struct bfd_hash_table *); + +/* Look up a string in a hash table. If CREATE is TRUE, a new entry + will be created for this string if one does not already exist. The + COPY argument must be TRUE if this routine should copy the string + into newly allocated memory when adding an entry. */ +extern struct bfd_hash_entry *bfd_hash_lookup + (struct bfd_hash_table *, const char *, bfd_boolean create, + bfd_boolean copy); + +/* Replace an entry in a hash table. */ +extern void bfd_hash_replace + (struct bfd_hash_table *, struct bfd_hash_entry *old, + struct bfd_hash_entry *nw); + +/* Base method for creating a hash table entry. */ +extern struct bfd_hash_entry *bfd_hash_newfunc + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); + +/* Grab some space for a hash table entry. */ +extern void *bfd_hash_allocate + (struct bfd_hash_table *, unsigned int); + +/* Traverse a hash table in a random order, calling a function on each + element. If the function returns FALSE, the traversal stops. The + INFO argument is passed to the function. */ +extern void bfd_hash_traverse + (struct bfd_hash_table *, + bfd_boolean (*) (struct bfd_hash_entry *, void *), + void *info); + +/* Allows the default size of a hash table to be configured. New hash + tables allocated using bfd_hash_table_init will be created with + this size. */ +extern void bfd_hash_set_default_size (bfd_size_type); + +/* This structure is used to keep track of stabs in sections + information while linking. */ + +struct stab_info +{ + /* A hash table used to hold stabs strings. */ + struct bfd_strtab_hash *strings; + /* The header file hash table. */ + struct bfd_hash_table includes; + /* The first .stabstr section. */ + struct bfd_section *stabstr; +}; + +#define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table + +/* User program access to BFD facilities. */ + +/* Direct I/O routines, for programs which know more about the object + file than BFD does. Use higher level routines if possible. */ + +extern bfd_size_type bfd_bread (void *, bfd_size_type, bfd *); +extern bfd_size_type bfd_bwrite (const void *, bfd_size_type, bfd *); +extern int bfd_seek (bfd *, file_ptr, int); +extern file_ptr bfd_tell (bfd *); +extern int bfd_flush (bfd *); +extern int bfd_stat (bfd *, struct stat *); + +/* Deprecated old routines. */ +#if __GNUC__ +#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ + (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__), \ + bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) +#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ + (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__), \ + bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) +#else +#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ + (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \ + bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) +#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ + (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\ + bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) +#endif +extern void warn_deprecated (const char *, const char *, int, const char *); + +/* Cast from const char * to char * so that caller can assign to + a char * without a warning. */ +#define bfd_get_filename(abfd) ((char *) (abfd)->filename) +#define bfd_get_cacheable(abfd) ((abfd)->cacheable) +#define bfd_get_format(abfd) ((abfd)->format) +#define bfd_get_target(abfd) ((abfd)->xvec->name) +#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) +#define bfd_family_coff(abfd) \ + (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \ + bfd_get_flavour (abfd) == bfd_target_xcoff_flavour) +#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) +#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) +#define bfd_header_big_endian(abfd) \ + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) +#define bfd_header_little_endian(abfd) \ + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) +#define bfd_get_file_flags(abfd) ((abfd)->flags) +#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) +#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) +#define bfd_my_archive(abfd) ((abfd)->my_archive) +#define bfd_has_map(abfd) ((abfd)->has_armap) + +#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types) +#define bfd_usrdata(abfd) ((abfd)->usrdata) + +#define bfd_get_start_address(abfd) ((abfd)->start_address) +#define bfd_get_symcount(abfd) ((abfd)->symcount) +#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols) +#define bfd_count_sections(abfd) ((abfd)->section_count) + +#define bfd_get_dynamic_symcount(abfd) ((abfd)->dynsymcount) + +#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) + +#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) + +extern bfd_boolean bfd_cache_close + (bfd *abfd); +/* NB: This declaration should match the autogenerated one in libbfd.h. */ + +extern bfd_boolean bfd_cache_close_all (void); + +extern bfd_boolean bfd_record_phdr + (bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma, + bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **); + +/* Byte swapping routines. */ + +bfd_uint64_t bfd_getb64 (const void *); +bfd_uint64_t bfd_getl64 (const void *); +bfd_int64_t bfd_getb_signed_64 (const void *); +bfd_int64_t bfd_getl_signed_64 (const void *); +bfd_vma bfd_getb32 (const void *); +bfd_vma bfd_getl32 (const void *); +bfd_signed_vma bfd_getb_signed_32 (const void *); +bfd_signed_vma bfd_getl_signed_32 (const void *); +bfd_vma bfd_getb16 (const void *); +bfd_vma bfd_getl16 (const void *); +bfd_signed_vma bfd_getb_signed_16 (const void *); +bfd_signed_vma bfd_getl_signed_16 (const void *); +void bfd_putb64 (bfd_uint64_t, void *); +void bfd_putl64 (bfd_uint64_t, void *); +void bfd_putb32 (bfd_vma, void *); +void bfd_putl32 (bfd_vma, void *); +void bfd_putb16 (bfd_vma, void *); +void bfd_putl16 (bfd_vma, void *); + +/* Byte swapping routines which take size and endiannes as arguments. */ + +bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean); +void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean); + +extern bfd_boolean bfd_section_already_linked_table_init (void); +extern void bfd_section_already_linked_table_free (void); + +/* Externally visible ECOFF routines. */ + +#if defined(__STDC__) || defined(ALMOST_STDC) +struct ecoff_debug_info; +struct ecoff_debug_swap; +struct ecoff_extr; +struct bfd_symbol; +struct bfd_link_info; +struct bfd_link_hash_entry; +struct bfd_elf_version_tree; +#endif +extern bfd_vma bfd_ecoff_get_gp_value + (bfd * abfd); +extern bfd_boolean bfd_ecoff_set_gp_value + (bfd *abfd, bfd_vma gp_value); +extern bfd_boolean bfd_ecoff_set_regmasks + (bfd *abfd, unsigned long gprmask, unsigned long fprmask, + unsigned long *cprmask); +extern void *bfd_ecoff_debug_init + (bfd *output_bfd, struct ecoff_debug_info *output_debug, + const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); +extern void bfd_ecoff_debug_free + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, + const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); +extern bfd_boolean bfd_ecoff_debug_accumulate + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, + const struct ecoff_debug_swap *output_swap, bfd *input_bfd, + struct ecoff_debug_info *input_debug, + const struct ecoff_debug_swap *input_swap, struct bfd_link_info *); +extern bfd_boolean bfd_ecoff_debug_accumulate_other + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, + const struct ecoff_debug_swap *output_swap, bfd *input_bfd, + struct bfd_link_info *); +extern bfd_boolean bfd_ecoff_debug_externals + (bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap, bfd_boolean relocatable, + bfd_boolean (*get_extr) (struct bfd_symbol *, struct ecoff_extr *), + void (*set_index) (struct bfd_symbol *, bfd_size_type)); +extern bfd_boolean bfd_ecoff_debug_one_external + (bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap, const char *name, + struct ecoff_extr *esym); +extern bfd_size_type bfd_ecoff_debug_size + (bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap); +extern bfd_boolean bfd_ecoff_write_debug + (bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap, file_ptr where); +extern bfd_boolean bfd_ecoff_write_accumulated_debug + (void *handle, bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap, + struct bfd_link_info *info, file_ptr where); + +/* Externally visible ELF routines. */ + +struct bfd_link_needed_list +{ + struct bfd_link_needed_list *next; + bfd *by; + const char *name; +}; + +enum dynamic_lib_link_class { + DYN_NORMAL = 0, + DYN_AS_NEEDED = 1, + DYN_DT_NEEDED = 2, + DYN_NO_ADD_NEEDED = 4, + DYN_NO_NEEDED = 8 +}; + +extern bfd_boolean bfd_elf_record_link_assignment + (bfd *, struct bfd_link_info *, const char *, bfd_boolean); +extern struct bfd_link_needed_list *bfd_elf_get_needed_list + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_elf_get_bfd_needed_list + (bfd *, struct bfd_link_needed_list **); +extern bfd_boolean bfd_elf_size_dynamic_sections + (bfd *, const char *, const char *, const char *, const char * const *, + struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *); +extern void bfd_elf_set_dt_needed_name + (bfd *, const char *); +extern const char *bfd_elf_get_dt_soname + (bfd *); +extern void bfd_elf_set_dyn_lib_class + (bfd *, int); +extern int bfd_elf_get_dyn_lib_class + (bfd *); +extern struct bfd_link_needed_list *bfd_elf_get_runpath_list + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_elf_discard_info + (bfd *, struct bfd_link_info *); + +/* Return an upper bound on the number of bytes required to store a + copy of ABFD's program header table entries. Return -1 if an error + occurs; bfd_get_error will return an appropriate code. */ +extern long bfd_get_elf_phdr_upper_bound + (bfd *abfd); + +/* Copy ABFD's program header table entries to *PHDRS. The entries + will be stored as an array of Elf_Internal_Phdr structures, as + defined in include/elf/internal.h. To find out how large the + buffer needs to be, call bfd_get_elf_phdr_upper_bound. + + Return the number of program header table entries read, or -1 if an + error occurs; bfd_get_error will return an appropriate code. */ +extern int bfd_get_elf_phdrs + (bfd *abfd, void *phdrs); + +/* Create a new BFD as if by bfd_openr. Rather than opening a file, + reconstruct an ELF file by reading the segments out of remote memory + based on the ELF file header at EHDR_VMA and the ELF program headers it + points to. If not null, *LOADBASEP is filled in with the difference + between the VMAs from which the segments were read, and the VMAs the + file headers (and hence BFD's idea of each section's VMA) put them at. + + The function TARGET_READ_MEMORY is called to copy LEN bytes from the + remote memory at target address VMA into the local buffer at MYADDR; it + should return zero on success or an `errno' code on failure. TEMPL must + be a BFD for an ELF target with the word size and byte order found in + the remote memory. */ +extern bfd *bfd_elf_bfd_from_remote_memory + (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, + int (*target_read_memory) (bfd_vma vma, char *myaddr, int len)); + +/* Return the arch_size field of an elf bfd, or -1 if not elf. */ +extern int bfd_get_arch_size + (bfd *); + +/* Return TRUE if address "naturally" sign extends, or -1 if not elf. */ +extern int bfd_get_sign_extend_vma + (bfd *); + +extern struct bfd_section *_bfd_elf_tls_setup + (bfd *, struct bfd_link_info *); + +extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs + (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **); + +/* SunOS shared library support routines for the linker. */ + +extern struct bfd_link_needed_list *bfd_sunos_get_needed_list + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_sunos_record_link_assignment + (bfd *, struct bfd_link_info *, const char *); +extern bfd_boolean bfd_sunos_size_dynamic_sections + (bfd *, struct bfd_link_info *, struct bfd_section **, struct bfd_section **, struct bfd_section **); + +/* Linux shared library support routines for the linker. */ + +extern bfd_boolean bfd_i386linux_size_dynamic_sections + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_m68klinux_size_dynamic_sections + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_sparclinux_size_dynamic_sections + (bfd *, struct bfd_link_info *); + +/* mmap hacks */ + +struct _bfd_window_internal; +typedef struct _bfd_window_internal bfd_window_internal; + +typedef struct _bfd_window +{ + /* What the user asked for. */ + void *data; + bfd_size_type size; + /* The actual window used by BFD. Small user-requested read-only + regions sharing a page may share a single window into the object + file. Read-write versions shouldn't until I've fixed things to + keep track of which portions have been claimed by the + application; don't want to give the same region back when the + application wants two writable copies! */ + struct _bfd_window_internal *i; +} +bfd_window; + +extern void bfd_init_window + (bfd_window *); +extern void bfd_free_window + (bfd_window *); +extern bfd_boolean bfd_get_file_window + (bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean); + +/* XCOFF support routines for the linker. */ + +extern bfd_boolean bfd_xcoff_link_record_set + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_size_type); +extern bfd_boolean bfd_xcoff_import_symbol + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_vma, + const char *, const char *, const char *, unsigned int); +extern bfd_boolean bfd_xcoff_export_symbol + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *); +extern bfd_boolean bfd_xcoff_link_count_reloc + (bfd *, struct bfd_link_info *, const char *); +extern bfd_boolean bfd_xcoff_record_link_assignment + (bfd *, struct bfd_link_info *, const char *); +extern bfd_boolean bfd_xcoff_size_dynamic_sections + (bfd *, struct bfd_link_info *, const char *, const char *, + unsigned long, unsigned long, unsigned long, bfd_boolean, + int, bfd_boolean, bfd_boolean, struct bfd_section **, bfd_boolean); +extern bfd_boolean bfd_xcoff_link_generate_rtinit + (bfd *, const char *, const char *, bfd_boolean); + +/* XCOFF support routines for ar. */ +extern bfd_boolean bfd_xcoff_ar_archive_set_magic + (bfd *, char *); + +/* Externally visible COFF routines. */ + +#if defined(__STDC__) || defined(ALMOST_STDC) +struct internal_syment; +union internal_auxent; +#endif + +extern bfd_boolean bfd_coff_get_syment + (bfd *, struct bfd_symbol *, struct internal_syment *); + +extern bfd_boolean bfd_coff_get_auxent + (bfd *, struct bfd_symbol *, int, union internal_auxent *); + +extern bfd_boolean bfd_coff_set_symbol_class + (bfd *, struct bfd_symbol *, unsigned int); + +extern bfd_boolean bfd_m68k_coff_create_embedded_relocs + (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **); + +/* ARM Interworking support. Called from linker. */ +extern bfd_boolean bfd_arm_allocate_interworking_sections + (struct bfd_link_info *); + +extern bfd_boolean bfd_arm_process_before_allocation + (bfd *, struct bfd_link_info *, int); + +extern bfd_boolean bfd_arm_get_bfd_for_interworking + (bfd *, struct bfd_link_info *); + +/* PE ARM Interworking support. Called from linker. */ +extern bfd_boolean bfd_arm_pe_allocate_interworking_sections + (struct bfd_link_info *); + +extern bfd_boolean bfd_arm_pe_process_before_allocation + (bfd *, struct bfd_link_info *, int); + +extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking + (bfd *, struct bfd_link_info *); + +/* ELF ARM Interworking support. Called from linker. */ +extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections + (struct bfd_link_info *); + +extern bfd_boolean bfd_elf32_arm_process_before_allocation + (bfd *, struct bfd_link_info *, int, int); + +void bfd_elf32_arm_set_target_relocs + (struct bfd_link_info *, int, char *); + +extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking + (bfd *, struct bfd_link_info *); + +extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd + (bfd *, struct bfd_link_info *); + +/* ARM Note section processing. */ +extern bfd_boolean bfd_arm_merge_machines + (bfd *, bfd *); + +extern bfd_boolean bfd_arm_update_notes + (bfd *, const char *); + +extern unsigned int bfd_arm_get_mach_from_notes + (bfd *, const char *); + +/* TI COFF load page support. */ +extern void bfd_ticoff_set_section_load_page + (struct bfd_section *, int); + +extern int bfd_ticoff_get_section_load_page + (struct bfd_section *); + +/* H8/300 functions. */ +extern bfd_vma bfd_h8300_pad_address + (bfd *, bfd_vma); + +/* IA64 Itanium code generation. Called from linker. */ +extern void bfd_elf32_ia64_after_parse + (int); + +extern void bfd_elf64_ia64_after_parse + (int); + +/* This structure is used for a comdat section, as in PE. A comdat + section is associated with a particular symbol. When the linker + sees a comdat section, it keeps only one of the sections with a + given name and associated with a given symbol. */ + +struct coff_comdat_info +{ + /* The name of the symbol associated with a comdat section. */ + const char *name; + + /* The local symbol table index of the symbol associated with a + comdat section. This is only meaningful to the object file format + specific code; it is not an index into the list returned by + bfd_canonicalize_symtab. */ + long symbol; +}; + +extern struct coff_comdat_info *bfd_coff_get_comdat_section + (bfd *, struct bfd_section *); + +/* Extracted from init.c. */ +void bfd_init (void); + +/* Extracted from opncls.c. */ +bfd *bfd_openr (const char *filename, const char *target); + +bfd *bfd_fdopenr (const char *filename, const char *target, int fd); + +bfd *bfd_openstreamr (const char *, const char *, void *); + +bfd *bfd_openr_iovec (const char *filename, const char *target, + void *(*open) (struct bfd *nbfd, + void *open_closure), + void *open_closure, + file_ptr (*pread) (struct bfd *nbfd, + void *stream, + void *buf, + file_ptr nbytes, + file_ptr offset), + int (*close) (struct bfd *nbfd, + void *stream)); + +bfd *bfd_openw (const char *filename, const char *target); + +bfd_boolean bfd_close (bfd *abfd); + +bfd_boolean bfd_close_all_done (bfd *); + +bfd *bfd_create (const char *filename, bfd *templ); + +bfd_boolean bfd_make_writable (bfd *abfd); + +bfd_boolean bfd_make_readable (bfd *abfd); + +unsigned long bfd_calc_gnu_debuglink_crc32 + (unsigned long crc, const unsigned char *buf, bfd_size_type len); + +char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir); + +struct bfd_section *bfd_create_gnu_debuglink_section + (bfd *abfd, const char *filename); + +bfd_boolean bfd_fill_in_gnu_debuglink_section + (bfd *abfd, struct bfd_section *sect, const char *filename); + +/* Extracted from libbfd.c. */ + +/* Byte swapping macros for user section data. */ + +#define bfd_put_8(abfd, val, ptr) \ + ((void) (*((unsigned char *) (ptr)) = (val) & 0xff)) +#define bfd_put_signed_8 \ + bfd_put_8 +#define bfd_get_8(abfd, ptr) \ + (*(unsigned char *) (ptr) & 0xff) +#define bfd_get_signed_8(abfd, ptr) \ + (((*(unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) + +#define bfd_put_16(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) +#define bfd_put_signed_16 \ + bfd_put_16 +#define bfd_get_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx16, (ptr)) +#define bfd_get_signed_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) + +#define bfd_put_32(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) +#define bfd_put_signed_32 \ + bfd_put_32 +#define bfd_get_32(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx32, (ptr)) +#define bfd_get_signed_32(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) + +#define bfd_put_64(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) +#define bfd_put_signed_64 \ + bfd_put_64 +#define bfd_get_64(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx64, (ptr)) +#define bfd_get_signed_64(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) + +#define bfd_get(bits, abfd, ptr) \ + ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ + : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ + : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ + : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ + : (abort (), (bfd_vma) - 1)) + +#define bfd_put(bits, abfd, val, ptr) \ + ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ + : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ + : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ + : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ + : (abort (), (void) 0)) + + +/* Byte swapping macros for file header data. */ + +#define bfd_h_put_8(abfd, val, ptr) \ + bfd_put_8 (abfd, val, ptr) +#define bfd_h_put_signed_8(abfd, val, ptr) \ + bfd_put_8 (abfd, val, ptr) +#define bfd_h_get_8(abfd, ptr) \ + bfd_get_8 (abfd, ptr) +#define bfd_h_get_signed_8(abfd, ptr) \ + bfd_get_signed_8 (abfd, ptr) + +#define bfd_h_put_16(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) +#define bfd_h_put_signed_16 \ + bfd_h_put_16 +#define bfd_h_get_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx16, (ptr)) +#define bfd_h_get_signed_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) + +#define bfd_h_put_32(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) +#define bfd_h_put_signed_32 \ + bfd_h_put_32 +#define bfd_h_get_32(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx32, (ptr)) +#define bfd_h_get_signed_32(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) + +#define bfd_h_put_64(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) +#define bfd_h_put_signed_64 \ + bfd_h_put_64 +#define bfd_h_get_64(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx64, (ptr)) +#define bfd_h_get_signed_64(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) + +/* Aliases for the above, which should eventually go away. */ + +#define H_PUT_64 bfd_h_put_64 +#define H_PUT_32 bfd_h_put_32 +#define H_PUT_16 bfd_h_put_16 +#define H_PUT_8 bfd_h_put_8 +#define H_PUT_S64 bfd_h_put_signed_64 +#define H_PUT_S32 bfd_h_put_signed_32 +#define H_PUT_S16 bfd_h_put_signed_16 +#define H_PUT_S8 bfd_h_put_signed_8 +#define H_GET_64 bfd_h_get_64 +#define H_GET_32 bfd_h_get_32 +#define H_GET_16 bfd_h_get_16 +#define H_GET_8 bfd_h_get_8 +#define H_GET_S64 bfd_h_get_signed_64 +#define H_GET_S32 bfd_h_get_signed_32 +#define H_GET_S16 bfd_h_get_signed_16 +#define H_GET_S8 bfd_h_get_signed_8 + + +/* Extracted from bfdio.c. */ +long bfd_get_mtime (bfd *abfd); + +long bfd_get_size (bfd *abfd); + +/* Extracted from bfdwin.c. */ +/* Extracted from section.c. */ +typedef struct bfd_section +{ + /* The name of the section; the name isn't a copy, the pointer is + the same as that passed to bfd_make_section. */ + const char *name; + + /* A unique sequence number. */ + int id; + + /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */ + int index; + + /* The next section in the list belonging to the BFD, or NULL. */ + struct bfd_section *next; + + /* The field flags contains attributes of the section. Some + flags are read in from the object file, and some are + synthesized from other information. */ + flagword flags; + +#define SEC_NO_FLAGS 0x000 + + /* Tells the OS to allocate space for this section when loading. + This is clear for a section containing debug information only. */ +#define SEC_ALLOC 0x001 + + /* Tells the OS to load the section from the file when loading. + This is clear for a .bss section. */ +#define SEC_LOAD 0x002 + + /* The section contains data still to be relocated, so there is + some relocation information too. */ +#define SEC_RELOC 0x004 + + /* ELF reserves 4 processor specific bits and 8 operating system + specific bits in sh_flags; at present we can get away with just + one in communicating between the assembler and BFD, but this + isn't a good long-term solution. */ +#define SEC_ARCH_BIT_0 0x008 + + /* A signal to the OS that the section contains read only data. */ +#define SEC_READONLY 0x010 + + /* The section contains code only. */ +#define SEC_CODE 0x020 + + /* The section contains data only. */ +#define SEC_DATA 0x040 + + /* The section will reside in ROM. */ +#define SEC_ROM 0x080 + + /* The section contains constructor information. This section + type is used by the linker to create lists of constructors and + destructors used by <>. When a back end sees a symbol + which should be used in a constructor list, it creates a new + section for the type of name (e.g., <<__CTOR_LIST__>>), attaches + the symbol to it, and builds a relocation. To build the lists + of constructors, all the linker has to do is catenate all the + sections called <<__CTOR_LIST__>> and relocate the data + contained within - exactly the operations it would peform on + standard data. */ +#define SEC_CONSTRUCTOR 0x100 + + /* The section has contents - a data section could be + <> | <>; a debug section could be + <> */ +#define SEC_HAS_CONTENTS 0x200 + + /* An instruction to the linker to not output the section + even if it has information which would normally be written. */ +#define SEC_NEVER_LOAD 0x400 + + /* The section is a COFF shared library section. This flag is + only for the linker. If this type of section appears in + the input file, the linker must copy it to the output file + without changing the vma or size. FIXME: Although this + was originally intended to be general, it really is COFF + specific (and the flag was renamed to indicate this). It + might be cleaner to have some more general mechanism to + allow the back end to control what the linker does with + sections. */ +#define SEC_COFF_SHARED_LIBRARY 0x800 + + /* The section contains thread local data. */ +#define SEC_THREAD_LOCAL 0x1000 + + /* The section has GOT references. This flag is only for the + linker, and is currently only used by the elf32-hppa back end. + It will be set if global offset table references were detected + in this section, which indicate to the linker that the section + contains PIC code, and must be handled specially when doing a + static link. */ +#define SEC_HAS_GOT_REF 0x4000 + + /* The section contains common symbols (symbols may be defined + multiple times, the value of a symbol is the amount of + space it requires, and the largest symbol value is the one + used). Most targets have exactly one of these (which we + translate to bfd_com_section_ptr), but ECOFF has two. */ +#define SEC_IS_COMMON 0x8000 + + /* The section contains only debugging information. For + example, this is set for ELF .debug and .stab sections. + strip tests this flag to see if a section can be + discarded. */ +#define SEC_DEBUGGING 0x10000 + + /* The contents of this section are held in memory pointed to + by the contents field. This is checked by bfd_get_section_contents, + and the data is retrieved from memory if appropriate. */ +#define SEC_IN_MEMORY 0x20000 + + /* The contents of this section are to be excluded by the + linker for executable and shared objects unless those + objects are to be further relocated. */ +#define SEC_EXCLUDE 0x40000 + + /* The contents of this section are to be sorted based on the sum of + the symbol and addend values specified by the associated relocation + entries. Entries without associated relocation entries will be + appended to the end of the section in an unspecified order. */ +#define SEC_SORT_ENTRIES 0x80000 + + /* When linking, duplicate sections of the same name should be + discarded, rather than being combined into a single section as + is usually done. This is similar to how common symbols are + handled. See SEC_LINK_DUPLICATES below. */ +#define SEC_LINK_ONCE 0x100000 + + /* If SEC_LINK_ONCE is set, this bitfield describes how the linker + should handle duplicate sections. */ +#define SEC_LINK_DUPLICATES 0x600000 + + /* This value for SEC_LINK_DUPLICATES means that duplicate + sections with the same name should simply be discarded. */ +#define SEC_LINK_DUPLICATES_DISCARD 0x0 + + /* This value for SEC_LINK_DUPLICATES means that the linker + should warn if there are any duplicate sections, although + it should still only link one copy. */ +#define SEC_LINK_DUPLICATES_ONE_ONLY 0x200000 + + /* This value for SEC_LINK_DUPLICATES means that the linker + should warn if any duplicate sections are a different size. */ +#define SEC_LINK_DUPLICATES_SAME_SIZE 0x400000 + + /* This value for SEC_LINK_DUPLICATES means that the linker + should warn if any duplicate sections contain different + contents. */ +#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000 + + /* This section was created by the linker as part of dynamic + relocation or other arcane processing. It is skipped when + going through the first-pass output, trusting that someone + else up the line will take care of it later. */ +#define SEC_LINKER_CREATED 0x800000 + + /* This section should not be subject to garbage collection. */ +#define SEC_KEEP 0x1000000 + + /* This section contains "short" data, and should be placed + "near" the GP. */ +#define SEC_SMALL_DATA 0x2000000 + + /* This section contains data which may be shared with other + executables or shared objects. */ +#define SEC_SHARED 0x4000000 + + /* When a section with this flag is being linked, then if the size of + the input section is less than a page, it should not cross a page + boundary. If the size of the input section is one page or more, it + should be aligned on a page boundary. */ +#define SEC_BLOCK 0x8000000 + + /* Conditionally link this section; do not link if there are no + references found to any symbol in the section. */ +#define SEC_CLINK 0x10000000 + + /* Attempt to merge identical entities in the section. + Entity size is given in the entsize field. */ +#define SEC_MERGE 0x20000000 + + /* If given with SEC_MERGE, entities to merge are zero terminated + strings where entsize specifies character size instead of fixed + size entries. */ +#define SEC_STRINGS 0x40000000 + + /* This section contains data about section groups. */ +#define SEC_GROUP 0x80000000 + + /* End of section flags. */ + + /* Some internal packed boolean fields. */ + + /* See the vma field. */ + unsigned int user_set_vma : 1; + + /* A mark flag used by some of the linker backends. */ + unsigned int linker_mark : 1; + + /* Another mark flag used by some of the linker backends. Set for + output sections that have an input section. */ + unsigned int linker_has_input : 1; + + /* A mark flag used by some linker backends for garbage collection. */ + unsigned int gc_mark : 1; + + /* The following flags are used by the ELF linker. */ + + /* Mark sections which have been allocated to segments. */ + unsigned int segment_mark : 1; + + /* Type of sec_info information. */ + unsigned int sec_info_type:3; +#define ELF_INFO_TYPE_NONE 0 +#define ELF_INFO_TYPE_STABS 1 +#define ELF_INFO_TYPE_MERGE 2 +#define ELF_INFO_TYPE_EH_FRAME 3 +#define ELF_INFO_TYPE_JUST_SYMS 4 + + /* Nonzero if this section uses RELA relocations, rather than REL. */ + unsigned int use_rela_p:1; + + /* Bits used by various backends. */ + + /* Nonzero if this section has TLS related relocations. */ + unsigned int has_tls_reloc:1; + + /* Nonzero if this section has a gp reloc. */ + unsigned int has_gp_reloc:1; + + /* Nonzero if this section needs the relax finalize pass. */ + unsigned int need_finalize_relax:1; + + /* Whether relocations have been processed. */ + unsigned int reloc_done : 1; + + /* End of internal packed boolean fields. */ + + /* The virtual memory address of the section - where it will be + at run time. The symbols are relocated against this. The + user_set_vma flag is maintained by bfd; if it's not set, the + backend can assign addresses (for example, in <>, where + the default address for <<.data>> is dependent on the specific + target and various flags). */ + bfd_vma vma; + + /* The load address of the section - where it would be in a + rom image; really only used for writing section header + information. */ + bfd_vma lma; + + /* The size of the section in octets, as it will be output. + Contains a value even if the section has no contents (e.g., the + size of <<.bss>>). */ + bfd_size_type size; + + /* For input sections, the original size on disk of the section, in + octets. This field is used by the linker relaxation code. It is + currently only set for sections where the linker relaxation scheme + doesn't cache altered section and reloc contents (stabs, eh_frame, + SEC_MERGE, some coff relaxing targets), and thus the original size + needs to be kept to read the section multiple times. + For output sections, rawsize holds the section size calculated on + a previous linker relaxation pass. */ + bfd_size_type rawsize; + + /* If this section is going to be output, then this value is the + offset in *bytes* into the output section of the first byte in the + input section (byte ==> smallest addressable unit on the + target). In most cases, if this was going to start at the + 100th octet (8-bit quantity) in the output section, this value + would be 100. However, if the target byte size is 16 bits + (bfd_octets_per_byte is "2"), this value would be 50. */ + bfd_vma output_offset; + + /* The output section through which to map on output. */ + struct bfd_section *output_section; + + /* The alignment requirement of the section, as an exponent of 2 - + e.g., 3 aligns to 2^3 (or 8). */ + unsigned int alignment_power; + + /* If an input section, a pointer to a vector of relocation + records for the data in this section. */ + struct reloc_cache_entry *relocation; + + /* If an output section, a pointer to a vector of pointers to + relocation records for the data in this section. */ + struct reloc_cache_entry **orelocation; + + /* The number of relocation records in one of the above. */ + unsigned reloc_count; + + /* Information below is back end specific - and not always used + or updated. */ + + /* File position of section data. */ + file_ptr filepos; + + /* File position of relocation info. */ + file_ptr rel_filepos; + + /* File position of line data. */ + file_ptr line_filepos; + + /* Pointer to data for applications. */ + void *userdata; + + /* If the SEC_IN_MEMORY flag is set, this points to the actual + contents. */ + unsigned char *contents; + + /* Attached line number information. */ + alent *lineno; + + /* Number of line number records. */ + unsigned int lineno_count; + + /* Entity size for merging purposes. */ + unsigned int entsize; + + /* Points to the kept section if this section is a link-once section, + and is discarded. */ + struct bfd_section *kept_section; + + /* When a section is being output, this value changes as more + linenumbers are written out. */ + file_ptr moving_line_filepos; + + /* What the section number is in the target world. */ + int target_index; + + void *used_by_bfd; + + /* If this is a constructor section then here is a list of the + relocations created to relocate items within it. */ + struct relent_chain *constructor_chain; + + /* The BFD which owns the section. */ + bfd *owner; + + /* A symbol which points at this section only. */ + struct bfd_symbol *symbol; + struct bfd_symbol **symbol_ptr_ptr; + + struct bfd_link_order *link_order_head; + struct bfd_link_order *link_order_tail; +} asection; + +/* These sections are global, and are managed by BFD. The application + and target back end are not permitted to change the values in + these sections. New code should use the section_ptr macros rather + than referring directly to the const sections. The const sections + may eventually vanish. */ +#define BFD_ABS_SECTION_NAME "*ABS*" +#define BFD_UND_SECTION_NAME "*UND*" +#define BFD_COM_SECTION_NAME "*COM*" +#define BFD_IND_SECTION_NAME "*IND*" + +/* The absolute section. */ +extern asection bfd_abs_section; +#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) +#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) +/* Pointer to the undefined section. */ +extern asection bfd_und_section; +#define bfd_und_section_ptr ((asection *) &bfd_und_section) +#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) +/* Pointer to the common section. */ +extern asection bfd_com_section; +#define bfd_com_section_ptr ((asection *) &bfd_com_section) +/* Pointer to the indirect section. */ +extern asection bfd_ind_section; +#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) +#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) + +#define bfd_is_const_section(SEC) \ + ( ((SEC) == bfd_abs_section_ptr) \ + || ((SEC) == bfd_und_section_ptr) \ + || ((SEC) == bfd_com_section_ptr) \ + || ((SEC) == bfd_ind_section_ptr)) + +extern const struct bfd_symbol * const bfd_abs_symbol; +extern const struct bfd_symbol * const bfd_com_symbol; +extern const struct bfd_symbol * const bfd_und_symbol; +extern const struct bfd_symbol * const bfd_ind_symbol; + +/* Macros to handle insertion and deletion of a bfd's sections. These + only handle the list pointers, ie. do not adjust section_count, + target_index etc. */ +#define bfd_section_list_remove(ABFD, PS) \ + do \ + { \ + asection **_ps = PS; \ + asection *_s = *_ps; \ + *_ps = _s->next; \ + if (_s->next == NULL) \ + (ABFD)->section_tail = _ps; \ + } \ + while (0) +#define bfd_section_list_insert(ABFD, PS, S) \ + do \ + { \ + asection **_ps = PS; \ + asection *_s = S; \ + _s->next = *_ps; \ + *_ps = _s; \ + if (_s->next == NULL) \ + (ABFD)->section_tail = &_s->next; \ + } \ + while (0) + +void bfd_section_list_clear (bfd *); + +asection *bfd_get_section_by_name (bfd *abfd, const char *name); + +asection *bfd_get_section_by_name_if + (bfd *abfd, + const char *name, + bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), + void *obj); + +char *bfd_get_unique_section_name + (bfd *abfd, const char *templat, int *count); + +asection *bfd_make_section_old_way (bfd *abfd, const char *name); + +asection *bfd_make_section_anyway (bfd *abfd, const char *name); + +asection *bfd_make_section (bfd *, const char *name); + +bfd_boolean bfd_set_section_flags + (bfd *abfd, asection *sec, flagword flags); + +void bfd_map_over_sections + (bfd *abfd, + void (*func) (bfd *abfd, asection *sect, void *obj), + void *obj); + +asection *bfd_sections_find_if + (bfd *abfd, + bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), + void *obj); + +bfd_boolean bfd_set_section_size + (bfd *abfd, asection *sec, bfd_size_type val); + +bfd_boolean bfd_set_section_contents + (bfd *abfd, asection *section, const void *data, + file_ptr offset, bfd_size_type count); + +bfd_boolean bfd_get_section_contents + (bfd *abfd, asection *section, void *location, file_ptr offset, + bfd_size_type count); + +bfd_boolean bfd_malloc_and_get_section + (bfd *abfd, asection *section, bfd_byte **buf); + +bfd_boolean bfd_copy_private_section_data + (bfd *ibfd, asection *isec, bfd *obfd, asection *osec); + +#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ + BFD_SEND (obfd, _bfd_copy_private_section_data, \ + (ibfd, isection, obfd, osection)) +void _bfd_strip_section_from_output + (struct bfd_link_info *info, asection *section); + +bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); + +bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); + +/* Extracted from archures.c. */ +enum bfd_architecture +{ + bfd_arch_unknown, /* File arch not known. */ + bfd_arch_obscure, /* Arch known, not one of these. */ + bfd_arch_m68k, /* Motorola 68xxx */ +#define bfd_mach_m68000 1 +#define bfd_mach_m68008 2 +#define bfd_mach_m68010 3 +#define bfd_mach_m68020 4 +#define bfd_mach_m68030 5 +#define bfd_mach_m68040 6 +#define bfd_mach_m68060 7 +#define bfd_mach_cpu32 8 +#define bfd_mach_mcf5200 9 +#define bfd_mach_mcf5206e 10 +#define bfd_mach_mcf5307 11 +#define bfd_mach_mcf5407 12 +#define bfd_mach_mcf528x 13 +#define bfd_mach_mcfv4e 14 +#define bfd_mach_mcf521x 15 +#define bfd_mach_mcf5249 16 +#define bfd_mach_mcf547x 17 +#define bfd_mach_mcf548x 18 + bfd_arch_vax, /* DEC Vax */ + bfd_arch_i960, /* Intel 960 */ + /* The order of the following is important. + lower number indicates a machine type that + only accepts a subset of the instructions + available to machines with higher numbers. + The exception is the "ca", which is + incompatible with all other machines except + "core". */ + +#define bfd_mach_i960_core 1 +#define bfd_mach_i960_ka_sa 2 +#define bfd_mach_i960_kb_sb 3 +#define bfd_mach_i960_mc 4 +#define bfd_mach_i960_xa 5 +#define bfd_mach_i960_ca 6 +#define bfd_mach_i960_jx 7 +#define bfd_mach_i960_hx 8 + + bfd_arch_or32, /* OpenRISC 32 */ + + bfd_arch_a29k, /* AMD 29000 */ + bfd_arch_sparc, /* SPARC */ +#define bfd_mach_sparc 1 +/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ +#define bfd_mach_sparc_sparclet 2 +#define bfd_mach_sparc_sparclite 3 +#define bfd_mach_sparc_v8plus 4 +#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ +#define bfd_mach_sparc_sparclite_le 6 +#define bfd_mach_sparc_v9 7 +#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ +#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ +#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ +/* Nonzero if MACH has the v9 instruction set. */ +#define bfd_mach_sparc_v9_p(mach) \ + ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ + && (mach) != bfd_mach_sparc_sparclite_le) +/* Nonzero if MACH is a 64 bit sparc architecture. */ +#define bfd_mach_sparc_64bit_p(mach) \ + ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb) + bfd_arch_mips, /* MIPS Rxxxx */ +#define bfd_mach_mips3000 3000 +#define bfd_mach_mips3900 3900 +#define bfd_mach_mips4000 4000 +#define bfd_mach_mips4010 4010 +#define bfd_mach_mips4100 4100 +#define bfd_mach_mips4111 4111 +#define bfd_mach_mips4120 4120 +#define bfd_mach_mips4300 4300 +#define bfd_mach_mips4400 4400 +#define bfd_mach_mips4600 4600 +#define bfd_mach_mips4650 4650 +#define bfd_mach_mips5000 5000 +#define bfd_mach_mips5400 5400 +#define bfd_mach_mips5500 5500 +#define bfd_mach_mips6000 6000 +#define bfd_mach_mips7000 7000 +#define bfd_mach_mips8000 8000 +#define bfd_mach_mips10000 10000 +#define bfd_mach_mips12000 12000 +#define bfd_mach_mips16 16 +#define bfd_mach_mips5 5 +#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ +#define bfd_mach_mipsisa32 32 +#define bfd_mach_mipsisa32r2 33 +#define bfd_mach_mipsisa64 64 +#define bfd_mach_mipsisa64r2 65 + bfd_arch_i386, /* Intel 386 */ +#define bfd_mach_i386_i386 1 +#define bfd_mach_i386_i8086 2 +#define bfd_mach_i386_i386_intel_syntax 3 +#define bfd_mach_x86_64 64 +#define bfd_mach_x86_64_intel_syntax 65 + bfd_arch_we32k, /* AT&T WE32xxx */ + bfd_arch_tahoe, /* CCI/Harris Tahoe */ + bfd_arch_i860, /* Intel 860 */ + bfd_arch_i370, /* IBM 360/370 Mainframes */ + bfd_arch_romp, /* IBM ROMP PC/RT */ + bfd_arch_alliant, /* Alliant */ + bfd_arch_convex, /* Convex */ + bfd_arch_m88k, /* Motorola 88xxx */ + bfd_arch_m98k, /* Motorola 98xxx */ + bfd_arch_pyramid, /* Pyramid Technology */ + bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */ +#define bfd_mach_h8300 1 +#define bfd_mach_h8300h 2 +#define bfd_mach_h8300s 3 +#define bfd_mach_h8300hn 4 +#define bfd_mach_h8300sn 5 +#define bfd_mach_h8300sx 6 +#define bfd_mach_h8300sxn 7 + bfd_arch_pdp11, /* DEC PDP-11 */ + bfd_arch_powerpc, /* PowerPC */ +#define bfd_mach_ppc 32 +#define bfd_mach_ppc64 64 +#define bfd_mach_ppc_403 403 +#define bfd_mach_ppc_403gc 4030 +#define bfd_mach_ppc_505 505 +#define bfd_mach_ppc_601 601 +#define bfd_mach_ppc_602 602 +#define bfd_mach_ppc_603 603 +#define bfd_mach_ppc_ec603e 6031 +#define bfd_mach_ppc_604 604 +#define bfd_mach_ppc_620 620 +#define bfd_mach_ppc_630 630 +#define bfd_mach_ppc_750 750 +#define bfd_mach_ppc_860 860 +#define bfd_mach_ppc_a35 35 +#define bfd_mach_ppc_rs64ii 642 +#define bfd_mach_ppc_rs64iii 643 +#define bfd_mach_ppc_7400 7400 +#define bfd_mach_ppc_e500 500 + bfd_arch_rs6000, /* IBM RS/6000 */ +#define bfd_mach_rs6k 6000 +#define bfd_mach_rs6k_rs1 6001 +#define bfd_mach_rs6k_rsc 6003 +#define bfd_mach_rs6k_rs2 6002 + bfd_arch_hppa, /* HP PA RISC */ +#define bfd_mach_hppa10 10 +#define bfd_mach_hppa11 11 +#define bfd_mach_hppa20 20 +#define bfd_mach_hppa20w 25 + bfd_arch_d10v, /* Mitsubishi D10V */ +#define bfd_mach_d10v 1 +#define bfd_mach_d10v_ts2 2 +#define bfd_mach_d10v_ts3 3 + bfd_arch_d30v, /* Mitsubishi D30V */ + bfd_arch_dlx, /* DLX */ + bfd_arch_m68hc11, /* Motorola 68HC11 */ + bfd_arch_m68hc12, /* Motorola 68HC12 */ +#define bfd_mach_m6812_default 0 +#define bfd_mach_m6812 1 +#define bfd_mach_m6812s 2 + bfd_arch_z8k, /* Zilog Z8000 */ +#define bfd_mach_z8001 1 +#define bfd_mach_z8002 2 + bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */ + bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */ +#define bfd_mach_sh 1 +#define bfd_mach_sh2 0x20 +#define bfd_mach_sh_dsp 0x2d +#define bfd_mach_sh2a 0x2a +#define bfd_mach_sh2a_nofpu 0x2b +#define bfd_mach_sh2e 0x2e +#define bfd_mach_sh3 0x30 +#define bfd_mach_sh3_nommu 0x31 +#define bfd_mach_sh3_dsp 0x3d +#define bfd_mach_sh3e 0x3e +#define bfd_mach_sh4 0x40 +#define bfd_mach_sh4_nofpu 0x41 +#define bfd_mach_sh4_nommu_nofpu 0x42 +#define bfd_mach_sh4a 0x4a +#define bfd_mach_sh4a_nofpu 0x4b +#define bfd_mach_sh4al_dsp 0x4d +#define bfd_mach_sh5 0x50 + bfd_arch_alpha, /* Dec Alpha */ +#define bfd_mach_alpha_ev4 0x10 +#define bfd_mach_alpha_ev5 0x20 +#define bfd_mach_alpha_ev6 0x30 + bfd_arch_arm, /* Advanced Risc Machines ARM. */ +#define bfd_mach_arm_unknown 0 +#define bfd_mach_arm_2 1 +#define bfd_mach_arm_2a 2 +#define bfd_mach_arm_3 3 +#define bfd_mach_arm_3M 4 +#define bfd_mach_arm_4 5 +#define bfd_mach_arm_4T 6 +#define bfd_mach_arm_5 7 +#define bfd_mach_arm_5T 8 +#define bfd_mach_arm_5TE 9 +#define bfd_mach_arm_XScale 10 +#define bfd_mach_arm_ep9312 11 +#define bfd_mach_arm_iWMMXt 12 + bfd_arch_ns32k, /* National Semiconductors ns32000 */ + bfd_arch_w65, /* WDC 65816 */ + bfd_arch_tic30, /* Texas Instruments TMS320C30 */ + bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */ +#define bfd_mach_tic3x 30 +#define bfd_mach_tic4x 40 + bfd_arch_tic54x, /* Texas Instruments TMS320C54X */ + bfd_arch_tic80, /* TI TMS320c80 (MVP) */ + bfd_arch_v850, /* NEC V850 */ +#define bfd_mach_v850 1 +#define bfd_mach_v850e 'E' +#define bfd_mach_v850e1 '1' + bfd_arch_arc, /* ARC Cores */ +#define bfd_mach_arc_5 5 +#define bfd_mach_arc_6 6 +#define bfd_mach_arc_7 7 +#define bfd_mach_arc_8 8 + bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */ +#define bfd_mach_m32r 1 /* For backwards compatibility. */ +#define bfd_mach_m32rx 'x' +#define bfd_mach_m32r2 '2' + bfd_arch_mn10200, /* Matsushita MN10200 */ + bfd_arch_mn10300, /* Matsushita MN10300 */ +#define bfd_mach_mn10300 300 +#define bfd_mach_am33 330 +#define bfd_mach_am33_2 332 + bfd_arch_fr30, +#define bfd_mach_fr30 0x46523330 + bfd_arch_frv, +#define bfd_mach_frv 1 +#define bfd_mach_frvsimple 2 +#define bfd_mach_fr300 300 +#define bfd_mach_fr400 400 +#define bfd_mach_fr450 450 +#define bfd_mach_frvtomcat 499 /* fr500 prototype */ +#define bfd_mach_fr500 500 +#define bfd_mach_fr550 550 + bfd_arch_mcore, + bfd_arch_ia64, /* HP/Intel ia64 */ +#define bfd_mach_ia64_elf64 64 +#define bfd_mach_ia64_elf32 32 + bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */ +#define bfd_mach_ip2022 1 +#define bfd_mach_ip2022ext 2 + bfd_arch_iq2000, /* Vitesse IQ2000. */ +#define bfd_mach_iq2000 1 +#define bfd_mach_iq10 2 + bfd_arch_pj, + bfd_arch_avr, /* Atmel AVR microcontrollers. */ +#define bfd_mach_avr1 1 +#define bfd_mach_avr2 2 +#define bfd_mach_avr3 3 +#define bfd_mach_avr4 4 +#define bfd_mach_avr5 5 + bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ +#define bfd_mach_cr16c 1 + bfd_arch_crx, /* National Semiconductor CRX. */ +#define bfd_mach_crx 1 + bfd_arch_cris, /* Axis CRIS */ + bfd_arch_s390, /* IBM s390 */ +#define bfd_mach_s390_31 31 +#define bfd_mach_s390_64 64 + bfd_arch_openrisc, /* OpenRISC */ + bfd_arch_mmix, /* Donald Knuth's educational processor. */ + bfd_arch_xstormy16, +#define bfd_mach_xstormy16 1 + bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */ +#define bfd_mach_msp11 11 +#define bfd_mach_msp110 110 +#define bfd_mach_msp12 12 +#define bfd_mach_msp13 13 +#define bfd_mach_msp14 14 +#define bfd_mach_msp15 15 +#define bfd_mach_msp16 16 +#define bfd_mach_msp31 31 +#define bfd_mach_msp32 32 +#define bfd_mach_msp33 33 +#define bfd_mach_msp41 41 +#define bfd_mach_msp42 42 +#define bfd_mach_msp43 43 +#define bfd_mach_msp44 44 + bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ +#define bfd_mach_xtensa 1 + bfd_arch_last + }; + +typedef struct bfd_arch_info +{ + int bits_per_word; + int bits_per_address; + int bits_per_byte; + enum bfd_architecture arch; + unsigned long mach; + const char *arch_name; + const char *printable_name; + unsigned int section_align_power; + /* TRUE if this is the default machine for the architecture. + The default arch should be the first entry for an arch so that + all the entries for that arch can be accessed via <>. */ + bfd_boolean the_default; + const struct bfd_arch_info * (*compatible) + (const struct bfd_arch_info *a, const struct bfd_arch_info *b); + + bfd_boolean (*scan) (const struct bfd_arch_info *, const char *); + + const struct bfd_arch_info *next; +} +bfd_arch_info_type; + +const char *bfd_printable_name (bfd *abfd); + +const bfd_arch_info_type *bfd_scan_arch (const char *string); + +const char **bfd_arch_list (void); + +const bfd_arch_info_type *bfd_arch_get_compatible + (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns); + +void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg); + +enum bfd_architecture bfd_get_arch (bfd *abfd); + +unsigned long bfd_get_mach (bfd *abfd); + +unsigned int bfd_arch_bits_per_byte (bfd *abfd); + +unsigned int bfd_arch_bits_per_address (bfd *abfd); + +const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd); + +const bfd_arch_info_type *bfd_lookup_arch + (enum bfd_architecture arch, unsigned long machine); + +const char *bfd_printable_arch_mach + (enum bfd_architecture arch, unsigned long machine); + +unsigned int bfd_octets_per_byte (bfd *abfd); + +unsigned int bfd_arch_mach_octets_per_byte + (enum bfd_architecture arch, unsigned long machine); + +/* Extracted from reloc.c. */ +typedef enum bfd_reloc_status +{ + /* No errors detected. */ + bfd_reloc_ok, + + /* The relocation was performed, but there was an overflow. */ + bfd_reloc_overflow, + + /* The address to relocate was not within the section supplied. */ + bfd_reloc_outofrange, + + /* Used by special functions. */ + bfd_reloc_continue, + + /* Unsupported relocation size requested. */ + bfd_reloc_notsupported, + + /* Unused. */ + bfd_reloc_other, + + /* The symbol to relocate against was undefined. */ + bfd_reloc_undefined, + + /* The relocation was performed, but may not be ok - presently + generated only when linking i960 coff files with i960 b.out + symbols. If this type is returned, the error_message argument + to bfd_perform_relocation will be set. */ + bfd_reloc_dangerous + } + bfd_reloc_status_type; + + +typedef struct reloc_cache_entry +{ + /* A pointer into the canonical table of pointers. */ + struct bfd_symbol **sym_ptr_ptr; + + /* offset in section. */ + bfd_size_type address; + + /* addend for relocation value. */ + bfd_vma addend; + + /* Pointer to how to perform the required relocation. */ + reloc_howto_type *howto; + +} +arelent; + +enum complain_overflow +{ + /* Do not complain on overflow. */ + complain_overflow_dont, + + /* Complain if the bitfield overflows, whether it is considered + as signed or unsigned. */ + complain_overflow_bitfield, + + /* Complain if the value overflows when considered as signed + number. */ + complain_overflow_signed, + + /* Complain if the value overflows when considered as an + unsigned number. */ + complain_overflow_unsigned +}; + +struct reloc_howto_struct +{ + /* The type field has mainly a documentary use - the back end can + do what it wants with it, though normally the back end's + external idea of what a reloc number is stored + in this field. For example, a PC relative word relocation + in a coff environment has the type 023 - because that's + what the outside world calls a R_PCRWORD reloc. */ + unsigned int type; + + /* The value the final relocation is shifted right by. This drops + unwanted data from the relocation. */ + unsigned int rightshift; + + /* The size of the item to be relocated. This is *not* a + power-of-two measure. To get the number of bytes operated + on by a type of relocation, use bfd_get_reloc_size. */ + int size; + + /* The number of bits in the item to be relocated. This is used + when doing overflow checking. */ + unsigned int bitsize; + + /* Notes that the relocation is relative to the location in the + data section of the addend. The relocation function will + subtract from the relocation value the address of the location + being relocated. */ + bfd_boolean pc_relative; + + /* The bit position of the reloc value in the destination. + The relocated value is left shifted by this amount. */ + unsigned int bitpos; + + /* What type of overflow error should be checked for when + relocating. */ + enum complain_overflow complain_on_overflow; + + /* If this field is non null, then the supplied function is + called rather than the normal function. This allows really + strange relocation methods to be accommodated (e.g., i960 callj + instructions). */ + bfd_reloc_status_type (*special_function) + (bfd *, arelent *, struct bfd_symbol *, void *, asection *, + bfd *, char **); + + /* The textual name of the relocation type. */ + char *name; + + /* Some formats record a relocation addend in the section contents + rather than with the relocation. For ELF formats this is the + distinction between USE_REL and USE_RELA (though the code checks + for USE_REL == 1/0). The value of this field is TRUE if the + addend is recorded with the section contents; when performing a + partial link (ld -r) the section contents (the data) will be + modified. The value of this field is FALSE if addends are + recorded with the relocation (in arelent.addend); when performing + a partial link the relocation will be modified. + All relocations for all ELF USE_RELA targets should set this field + to FALSE (values of TRUE should be looked on with suspicion). + However, the converse is not true: not all relocations of all ELF + USE_REL targets set this field to TRUE. Why this is so is peculiar + to each particular target. For relocs that aren't used in partial + links (e.g. GOT stuff) it doesn't matter what this is set to. */ + bfd_boolean partial_inplace; + + /* src_mask selects the part of the instruction (or data) to be used + in the relocation sum. If the target relocations don't have an + addend in the reloc, eg. ELF USE_REL, src_mask will normally equal + dst_mask to extract the addend from the section contents. If + relocations do have an addend in the reloc, eg. ELF USE_RELA, this + field should be zero. Non-zero values for ELF USE_RELA targets are + bogus as in those cases the value in the dst_mask part of the + section contents should be treated as garbage. */ + bfd_vma src_mask; + + /* dst_mask selects which parts of the instruction (or data) are + replaced with a relocated value. */ + bfd_vma dst_mask; + + /* When some formats create PC relative instructions, they leave + the value of the pc of the place being relocated in the offset + slot of the instruction, so that a PC relative relocation can + be made just by adding in an ordinary offset (e.g., sun3 a.out). + Some formats leave the displacement part of an instruction + empty (e.g., m88k bcs); this flag signals the fact. */ + bfd_boolean pcrel_offset; +}; + +#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ + { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC } +#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ + HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ + NAME, FALSE, 0, 0, IN) + +#define EMPTY_HOWTO(C) \ + HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ + NULL, FALSE, 0, 0, FALSE) + +#define HOWTO_PREPARE(relocation, symbol) \ + { \ + if (symbol != NULL) \ + { \ + if (bfd_is_com_section (symbol->section)) \ + { \ + relocation = 0; \ + } \ + else \ + { \ + relocation = symbol->value; \ + } \ + } \ + } + +unsigned int bfd_get_reloc_size (reloc_howto_type *); + +typedef struct relent_chain +{ + arelent relent; + struct relent_chain *next; +} +arelent_chain; + +bfd_reloc_status_type bfd_check_overflow + (enum complain_overflow how, + unsigned int bitsize, + unsigned int rightshift, + unsigned int addrsize, + bfd_vma relocation); + +bfd_reloc_status_type bfd_perform_relocation + (bfd *abfd, + arelent *reloc_entry, + void *data, + asection *input_section, + bfd *output_bfd, + char **error_message); + +bfd_reloc_status_type bfd_install_relocation + (bfd *abfd, + arelent *reloc_entry, + void *data, bfd_vma data_start, + asection *input_section, + char **error_message); + +enum bfd_reloc_code_real { + _dummy_first_bfd_reloc_code_real, + + +/* Basic absolute relocations of N bits. */ + BFD_RELOC_64, + BFD_RELOC_32, + BFD_RELOC_26, + BFD_RELOC_24, + BFD_RELOC_16, + BFD_RELOC_14, + BFD_RELOC_8, + +/* PC-relative relocations. Sometimes these are relative to the address +of the relocation itself; sometimes they are relative to the start of +the section containing the relocation. It depends on the specific target. + +The 24-bit relocation is used in some Intel 960 configurations. */ + BFD_RELOC_64_PCREL, + BFD_RELOC_32_PCREL, + BFD_RELOC_24_PCREL, + BFD_RELOC_16_PCREL, + BFD_RELOC_12_PCREL, + BFD_RELOC_8_PCREL, + +/* Section relative relocations. Some targets need this for DWARF2. */ + BFD_RELOC_32_SECREL, + +/* For ELF. */ + BFD_RELOC_32_GOT_PCREL, + BFD_RELOC_16_GOT_PCREL, + BFD_RELOC_8_GOT_PCREL, + BFD_RELOC_32_GOTOFF, + BFD_RELOC_16_GOTOFF, + BFD_RELOC_LO16_GOTOFF, + BFD_RELOC_HI16_GOTOFF, + BFD_RELOC_HI16_S_GOTOFF, + BFD_RELOC_8_GOTOFF, + BFD_RELOC_64_PLT_PCREL, + BFD_RELOC_32_PLT_PCREL, + BFD_RELOC_24_PLT_PCREL, + BFD_RELOC_16_PLT_PCREL, + BFD_RELOC_8_PLT_PCREL, + BFD_RELOC_64_PLTOFF, + BFD_RELOC_32_PLTOFF, + BFD_RELOC_16_PLTOFF, + BFD_RELOC_LO16_PLTOFF, + BFD_RELOC_HI16_PLTOFF, + BFD_RELOC_HI16_S_PLTOFF, + BFD_RELOC_8_PLTOFF, + +/* Relocations used by 68K ELF. */ + BFD_RELOC_68K_GLOB_DAT, + BFD_RELOC_68K_JMP_SLOT, + BFD_RELOC_68K_RELATIVE, + +/* Linkage-table relative. */ + BFD_RELOC_32_BASEREL, + BFD_RELOC_16_BASEREL, + BFD_RELOC_LO16_BASEREL, + BFD_RELOC_HI16_BASEREL, + BFD_RELOC_HI16_S_BASEREL, + BFD_RELOC_8_BASEREL, + BFD_RELOC_RVA, + +/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */ + BFD_RELOC_8_FFnn, + +/* These PC-relative relocations are stored as word displacements -- +i.e., byte displacements shifted right two bits. The 30-bit word +displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the +SPARC. (SPARC tools generally refer to this as <>.) The +signed 16-bit displacement is used on the MIPS, and the 23-bit +displacement is used on the Alpha. */ + BFD_RELOC_32_PCREL_S2, + BFD_RELOC_16_PCREL_S2, + BFD_RELOC_23_PCREL_S2, + +/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of +the target word. These are used on the SPARC. */ + BFD_RELOC_HI22, + BFD_RELOC_LO10, + +/* For systems that allocate a Global Pointer register, these are +displacements off that register. These relocation types are +handled specially, because the value the register will have is +decided relatively late. */ + BFD_RELOC_GPREL16, + BFD_RELOC_GPREL32, + +/* Reloc types used for i960/b.out. */ + BFD_RELOC_I960_CALLJ, + +/* SPARC ELF relocations. There is probably some overlap with other +relocation types already defined. */ + BFD_RELOC_NONE, + BFD_RELOC_SPARC_WDISP22, + BFD_RELOC_SPARC22, + BFD_RELOC_SPARC13, + BFD_RELOC_SPARC_GOT10, + BFD_RELOC_SPARC_GOT13, + BFD_RELOC_SPARC_GOT22, + BFD_RELOC_SPARC_PC10, + BFD_RELOC_SPARC_PC22, + BFD_RELOC_SPARC_WPLT30, + BFD_RELOC_SPARC_COPY, + BFD_RELOC_SPARC_GLOB_DAT, + BFD_RELOC_SPARC_JMP_SLOT, + BFD_RELOC_SPARC_RELATIVE, + BFD_RELOC_SPARC_UA16, + BFD_RELOC_SPARC_UA32, + BFD_RELOC_SPARC_UA64, + +/* I think these are specific to SPARC a.out (e.g., Sun 4). */ + BFD_RELOC_SPARC_BASE13, + BFD_RELOC_SPARC_BASE22, + +/* SPARC64 relocations */ +#define BFD_RELOC_SPARC_64 BFD_RELOC_64 + BFD_RELOC_SPARC_10, + BFD_RELOC_SPARC_11, + BFD_RELOC_SPARC_OLO10, + BFD_RELOC_SPARC_HH22, + BFD_RELOC_SPARC_HM10, + BFD_RELOC_SPARC_LM22, + BFD_RELOC_SPARC_PC_HH22, + BFD_RELOC_SPARC_PC_HM10, + BFD_RELOC_SPARC_PC_LM22, + BFD_RELOC_SPARC_WDISP16, + BFD_RELOC_SPARC_WDISP19, + BFD_RELOC_SPARC_7, + BFD_RELOC_SPARC_6, + BFD_RELOC_SPARC_5, +#define BFD_RELOC_SPARC_DISP64 BFD_RELOC_64_PCREL + BFD_RELOC_SPARC_PLT32, + BFD_RELOC_SPARC_PLT64, + BFD_RELOC_SPARC_HIX22, + BFD_RELOC_SPARC_LOX10, + BFD_RELOC_SPARC_H44, + BFD_RELOC_SPARC_M44, + BFD_RELOC_SPARC_L44, + BFD_RELOC_SPARC_REGISTER, + +/* SPARC little endian relocation */ + BFD_RELOC_SPARC_REV32, + +/* SPARC TLS relocations */ + BFD_RELOC_SPARC_TLS_GD_HI22, + BFD_RELOC_SPARC_TLS_GD_LO10, + BFD_RELOC_SPARC_TLS_GD_ADD, + BFD_RELOC_SPARC_TLS_GD_CALL, + BFD_RELOC_SPARC_TLS_LDM_HI22, + BFD_RELOC_SPARC_TLS_LDM_LO10, + BFD_RELOC_SPARC_TLS_LDM_ADD, + BFD_RELOC_SPARC_TLS_LDM_CALL, + BFD_RELOC_SPARC_TLS_LDO_HIX22, + BFD_RELOC_SPARC_TLS_LDO_LOX10, + BFD_RELOC_SPARC_TLS_LDO_ADD, + BFD_RELOC_SPARC_TLS_IE_HI22, + BFD_RELOC_SPARC_TLS_IE_LO10, + BFD_RELOC_SPARC_TLS_IE_LD, + BFD_RELOC_SPARC_TLS_IE_LDX, + BFD_RELOC_SPARC_TLS_IE_ADD, + BFD_RELOC_SPARC_TLS_LE_HIX22, + BFD_RELOC_SPARC_TLS_LE_LOX10, + BFD_RELOC_SPARC_TLS_DTPMOD32, + BFD_RELOC_SPARC_TLS_DTPMOD64, + BFD_RELOC_SPARC_TLS_DTPOFF32, + BFD_RELOC_SPARC_TLS_DTPOFF64, + BFD_RELOC_SPARC_TLS_TPOFF32, + BFD_RELOC_SPARC_TLS_TPOFF64, + +/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or +"addend" in some special way. +For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when +writing; when reading, it will be the absolute section symbol. The +addend is the displacement in bytes of the "lda" instruction from +the "ldah" instruction (which is at the address of this reloc). */ + BFD_RELOC_ALPHA_GPDISP_HI16, + +/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as +with GPDISP_HI16 relocs. The addend is ignored when writing the +relocations out, and is filled in with the file's GP value on +reading, for convenience. */ + BFD_RELOC_ALPHA_GPDISP_LO16, + +/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 +relocation except that there is no accompanying GPDISP_LO16 +relocation. */ + BFD_RELOC_ALPHA_GPDISP, + +/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; +the assembler turns it into a LDQ instruction to load the address of +the symbol, and then fills in a register in the real instruction. + +The LITERAL reloc, at the LDQ instruction, refers to the .lita +section symbol. The addend is ignored when writing, but is filled +in with the file's GP value on reading, for convenience, as with the +GPDISP_LO16 reloc. + +The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16. +It should refer to the symbol to be referenced, as with 16_GOTOFF, +but it generates output not based on the position within the .got +section, but relative to the GP value chosen for the file during the +final link stage. + +The LITUSE reloc, on the instruction using the loaded address, gives +information to the linker that it might be able to use to optimize +away some literal section references. The symbol is ignored (read +as the absolute section symbol), and the "addend" indicates the type +of instruction using the register: +1 - "memory" fmt insn +2 - byte-manipulation (byte offset reg) +3 - jsr (target of branch) */ + BFD_RELOC_ALPHA_LITERAL, + BFD_RELOC_ALPHA_ELF_LITERAL, + BFD_RELOC_ALPHA_LITUSE, + +/* The HINT relocation indicates a value that should be filled into the +"hint" field of a jmp/jsr/ret instruction, for possible branch- +prediction logic which may be provided on some processors. */ + BFD_RELOC_ALPHA_HINT, + +/* The LINKAGE relocation outputs a linkage pair in the object file, +which is filled by the linker. */ + BFD_RELOC_ALPHA_LINKAGE, + +/* The CODEADDR relocation outputs a STO_CA in the object file, +which is filled by the linker. */ + BFD_RELOC_ALPHA_CODEADDR, + +/* The GPREL_HI/LO relocations together form a 32-bit offset from the +GP register. */ + BFD_RELOC_ALPHA_GPREL_HI16, + BFD_RELOC_ALPHA_GPREL_LO16, + +/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must +share a common GP, and the target address is adjusted for +STO_ALPHA_STD_GPLOAD. */ + BFD_RELOC_ALPHA_BRSGP, + +/* Alpha thread-local storage relocations. */ + BFD_RELOC_ALPHA_TLSGD, + BFD_RELOC_ALPHA_TLSLDM, + BFD_RELOC_ALPHA_DTPMOD64, + BFD_RELOC_ALPHA_GOTDTPREL16, + BFD_RELOC_ALPHA_DTPREL64, + BFD_RELOC_ALPHA_DTPREL_HI16, + BFD_RELOC_ALPHA_DTPREL_LO16, + BFD_RELOC_ALPHA_DTPREL16, + BFD_RELOC_ALPHA_GOTTPREL16, + BFD_RELOC_ALPHA_TPREL64, + BFD_RELOC_ALPHA_TPREL_HI16, + BFD_RELOC_ALPHA_TPREL_LO16, + BFD_RELOC_ALPHA_TPREL16, + +/* Bits 27..2 of the relocation address shifted right 2 bits; +simple reloc otherwise. */ + BFD_RELOC_MIPS_JMP, + +/* The MIPS16 jump instruction. */ + BFD_RELOC_MIPS16_JMP, + +/* MIPS16 GP relative reloc. */ + BFD_RELOC_MIPS16_GPREL, + +/* High 16 bits of 32-bit value; simple reloc. */ + BFD_RELOC_HI16, + +/* High 16 bits of 32-bit value but the low 16 bits will be sign +extended and added to form the final result. If the low 16 +bits form a negative number, we need to add one to the high value +to compensate for the borrow when the low bits are added. */ + BFD_RELOC_HI16_S, + +/* Low 16 bits. */ + BFD_RELOC_LO16, + +/* Relocation against a MIPS literal section. */ + BFD_RELOC_MIPS_LITERAL, + +/* MIPS ELF relocations. */ + BFD_RELOC_MIPS_GOT16, + BFD_RELOC_MIPS_CALL16, + BFD_RELOC_MIPS_GOT_HI16, + BFD_RELOC_MIPS_GOT_LO16, + BFD_RELOC_MIPS_CALL_HI16, + BFD_RELOC_MIPS_CALL_LO16, + BFD_RELOC_MIPS_SUB, + BFD_RELOC_MIPS_GOT_PAGE, + BFD_RELOC_MIPS_GOT_OFST, + BFD_RELOC_MIPS_GOT_DISP, + BFD_RELOC_MIPS_SHIFT5, + BFD_RELOC_MIPS_SHIFT6, + BFD_RELOC_MIPS_INSERT_A, + BFD_RELOC_MIPS_INSERT_B, + BFD_RELOC_MIPS_DELETE, + BFD_RELOC_MIPS_HIGHEST, + BFD_RELOC_MIPS_HIGHER, + BFD_RELOC_MIPS_SCN_DISP, + BFD_RELOC_MIPS_REL16, + BFD_RELOC_MIPS_RELGOT, + BFD_RELOC_MIPS_JALR, + + +/* Fujitsu Frv Relocations. */ + BFD_RELOC_FRV_LABEL16, + BFD_RELOC_FRV_LABEL24, + BFD_RELOC_FRV_LO16, + BFD_RELOC_FRV_HI16, + BFD_RELOC_FRV_GPREL12, + BFD_RELOC_FRV_GPRELU12, + BFD_RELOC_FRV_GPREL32, + BFD_RELOC_FRV_GPRELHI, + BFD_RELOC_FRV_GPRELLO, + BFD_RELOC_FRV_GOT12, + BFD_RELOC_FRV_GOTHI, + BFD_RELOC_FRV_GOTLO, + BFD_RELOC_FRV_FUNCDESC, + BFD_RELOC_FRV_FUNCDESC_GOT12, + BFD_RELOC_FRV_FUNCDESC_GOTHI, + BFD_RELOC_FRV_FUNCDESC_GOTLO, + BFD_RELOC_FRV_FUNCDESC_VALUE, + BFD_RELOC_FRV_FUNCDESC_GOTOFF12, + BFD_RELOC_FRV_FUNCDESC_GOTOFFHI, + BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, + BFD_RELOC_FRV_GOTOFF12, + BFD_RELOC_FRV_GOTOFFHI, + BFD_RELOC_FRV_GOTOFFLO, + + +/* This is a 24bit GOT-relative reloc for the mn10300. */ + BFD_RELOC_MN10300_GOTOFF24, + +/* This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes +in the instruction. */ + BFD_RELOC_MN10300_GOT32, + +/* This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes +in the instruction. */ + BFD_RELOC_MN10300_GOT24, + +/* This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes +in the instruction. */ + BFD_RELOC_MN10300_GOT16, + +/* Copy symbol at runtime. */ + BFD_RELOC_MN10300_COPY, + +/* Create GOT entry. */ + BFD_RELOC_MN10300_GLOB_DAT, + +/* Create PLT entry. */ + BFD_RELOC_MN10300_JMP_SLOT, + +/* Adjust by program base. */ + BFD_RELOC_MN10300_RELATIVE, + + +/* i386/elf relocations */ + BFD_RELOC_386_GOT32, + BFD_RELOC_386_PLT32, + BFD_RELOC_386_COPY, + BFD_RELOC_386_GLOB_DAT, + BFD_RELOC_386_JUMP_SLOT, + BFD_RELOC_386_RELATIVE, + BFD_RELOC_386_GOTOFF, + BFD_RELOC_386_GOTPC, + BFD_RELOC_386_TLS_TPOFF, + BFD_RELOC_386_TLS_IE, + BFD_RELOC_386_TLS_GOTIE, + BFD_RELOC_386_TLS_LE, + BFD_RELOC_386_TLS_GD, + BFD_RELOC_386_TLS_LDM, + BFD_RELOC_386_TLS_LDO_32, + BFD_RELOC_386_TLS_IE_32, + BFD_RELOC_386_TLS_LE_32, + BFD_RELOC_386_TLS_DTPMOD32, + BFD_RELOC_386_TLS_DTPOFF32, + BFD_RELOC_386_TLS_TPOFF32, + +/* x86-64/elf relocations */ + BFD_RELOC_X86_64_GOT32, + BFD_RELOC_X86_64_PLT32, + BFD_RELOC_X86_64_COPY, + BFD_RELOC_X86_64_GLOB_DAT, + BFD_RELOC_X86_64_JUMP_SLOT, + BFD_RELOC_X86_64_RELATIVE, + BFD_RELOC_X86_64_GOTPCREL, + BFD_RELOC_X86_64_32S, + BFD_RELOC_X86_64_DTPMOD64, + BFD_RELOC_X86_64_DTPOFF64, + BFD_RELOC_X86_64_TPOFF64, + BFD_RELOC_X86_64_TLSGD, + BFD_RELOC_X86_64_TLSLD, + BFD_RELOC_X86_64_DTPOFF32, + BFD_RELOC_X86_64_GOTTPOFF, + BFD_RELOC_X86_64_TPOFF32, + +/* ns32k relocations */ + BFD_RELOC_NS32K_IMM_8, + BFD_RELOC_NS32K_IMM_16, + BFD_RELOC_NS32K_IMM_32, + BFD_RELOC_NS32K_IMM_8_PCREL, + BFD_RELOC_NS32K_IMM_16_PCREL, + BFD_RELOC_NS32K_IMM_32_PCREL, + BFD_RELOC_NS32K_DISP_8, + BFD_RELOC_NS32K_DISP_16, + BFD_RELOC_NS32K_DISP_32, + BFD_RELOC_NS32K_DISP_8_PCREL, + BFD_RELOC_NS32K_DISP_16_PCREL, + BFD_RELOC_NS32K_DISP_32_PCREL, + +/* PDP11 relocations */ + BFD_RELOC_PDP11_DISP_8_PCREL, + BFD_RELOC_PDP11_DISP_6_PCREL, + +/* Picojava relocs. Not all of these appear in object files. */ + BFD_RELOC_PJ_CODE_HI16, + BFD_RELOC_PJ_CODE_LO16, + BFD_RELOC_PJ_CODE_DIR16, + BFD_RELOC_PJ_CODE_DIR32, + BFD_RELOC_PJ_CODE_REL16, + BFD_RELOC_PJ_CODE_REL32, + +/* Power(rs6000) and PowerPC relocations. */ + BFD_RELOC_PPC_B26, + BFD_RELOC_PPC_BA26, + BFD_RELOC_PPC_TOC16, + BFD_RELOC_PPC_B16, + BFD_RELOC_PPC_B16_BRTAKEN, + BFD_RELOC_PPC_B16_BRNTAKEN, + BFD_RELOC_PPC_BA16, + BFD_RELOC_PPC_BA16_BRTAKEN, + BFD_RELOC_PPC_BA16_BRNTAKEN, + BFD_RELOC_PPC_COPY, + BFD_RELOC_PPC_GLOB_DAT, + BFD_RELOC_PPC_JMP_SLOT, + BFD_RELOC_PPC_RELATIVE, + BFD_RELOC_PPC_LOCAL24PC, + BFD_RELOC_PPC_EMB_NADDR32, + BFD_RELOC_PPC_EMB_NADDR16, + BFD_RELOC_PPC_EMB_NADDR16_LO, + BFD_RELOC_PPC_EMB_NADDR16_HI, + BFD_RELOC_PPC_EMB_NADDR16_HA, + BFD_RELOC_PPC_EMB_SDAI16, + BFD_RELOC_PPC_EMB_SDA2I16, + BFD_RELOC_PPC_EMB_SDA2REL, + BFD_RELOC_PPC_EMB_SDA21, + BFD_RELOC_PPC_EMB_MRKREF, + BFD_RELOC_PPC_EMB_RELSEC16, + BFD_RELOC_PPC_EMB_RELST_LO, + BFD_RELOC_PPC_EMB_RELST_HI, + BFD_RELOC_PPC_EMB_RELST_HA, + BFD_RELOC_PPC_EMB_BIT_FLD, + BFD_RELOC_PPC_EMB_RELSDA, + BFD_RELOC_PPC64_HIGHER, + BFD_RELOC_PPC64_HIGHER_S, + BFD_RELOC_PPC64_HIGHEST, + BFD_RELOC_PPC64_HIGHEST_S, + BFD_RELOC_PPC64_TOC16_LO, + BFD_RELOC_PPC64_TOC16_HI, + BFD_RELOC_PPC64_TOC16_HA, + BFD_RELOC_PPC64_TOC, + BFD_RELOC_PPC64_PLTGOT16, + BFD_RELOC_PPC64_PLTGOT16_LO, + BFD_RELOC_PPC64_PLTGOT16_HI, + BFD_RELOC_PPC64_PLTGOT16_HA, + BFD_RELOC_PPC64_ADDR16_DS, + BFD_RELOC_PPC64_ADDR16_LO_DS, + BFD_RELOC_PPC64_GOT16_DS, + BFD_RELOC_PPC64_GOT16_LO_DS, + BFD_RELOC_PPC64_PLT16_LO_DS, + BFD_RELOC_PPC64_SECTOFF_DS, + BFD_RELOC_PPC64_SECTOFF_LO_DS, + BFD_RELOC_PPC64_TOC16_DS, + BFD_RELOC_PPC64_TOC16_LO_DS, + BFD_RELOC_PPC64_PLTGOT16_DS, + BFD_RELOC_PPC64_PLTGOT16_LO_DS, + +/* PowerPC and PowerPC64 thread-local storage relocations. */ + BFD_RELOC_PPC_TLS, + BFD_RELOC_PPC_DTPMOD, + BFD_RELOC_PPC_TPREL16, + BFD_RELOC_PPC_TPREL16_LO, + BFD_RELOC_PPC_TPREL16_HI, + BFD_RELOC_PPC_TPREL16_HA, + BFD_RELOC_PPC_TPREL, + BFD_RELOC_PPC_DTPREL16, + BFD_RELOC_PPC_DTPREL16_LO, + BFD_RELOC_PPC_DTPREL16_HI, + BFD_RELOC_PPC_DTPREL16_HA, + BFD_RELOC_PPC_DTPREL, + BFD_RELOC_PPC_GOT_TLSGD16, + BFD_RELOC_PPC_GOT_TLSGD16_LO, + BFD_RELOC_PPC_GOT_TLSGD16_HI, + BFD_RELOC_PPC_GOT_TLSGD16_HA, + BFD_RELOC_PPC_GOT_TLSLD16, + BFD_RELOC_PPC_GOT_TLSLD16_LO, + BFD_RELOC_PPC_GOT_TLSLD16_HI, + BFD_RELOC_PPC_GOT_TLSLD16_HA, + BFD_RELOC_PPC_GOT_TPREL16, + BFD_RELOC_PPC_GOT_TPREL16_LO, + BFD_RELOC_PPC_GOT_TPREL16_HI, + BFD_RELOC_PPC_GOT_TPREL16_HA, + BFD_RELOC_PPC_GOT_DTPREL16, + BFD_RELOC_PPC_GOT_DTPREL16_LO, + BFD_RELOC_PPC_GOT_DTPREL16_HI, + BFD_RELOC_PPC_GOT_DTPREL16_HA, + BFD_RELOC_PPC64_TPREL16_DS, + BFD_RELOC_PPC64_TPREL16_LO_DS, + BFD_RELOC_PPC64_TPREL16_HIGHER, + BFD_RELOC_PPC64_TPREL16_HIGHERA, + BFD_RELOC_PPC64_TPREL16_HIGHEST, + BFD_RELOC_PPC64_TPREL16_HIGHESTA, + BFD_RELOC_PPC64_DTPREL16_DS, + BFD_RELOC_PPC64_DTPREL16_LO_DS, + BFD_RELOC_PPC64_DTPREL16_HIGHER, + BFD_RELOC_PPC64_DTPREL16_HIGHERA, + BFD_RELOC_PPC64_DTPREL16_HIGHEST, + BFD_RELOC_PPC64_DTPREL16_HIGHESTA, + +/* IBM 370/390 relocations */ + BFD_RELOC_I370_D12, + +/* The type of reloc used to build a constructor table - at the moment +probably a 32 bit wide absolute relocation, but the target can choose. +It generally does map to one of the other relocation types. */ + BFD_RELOC_CTOR, + +/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are +not stored in the instruction. */ + BFD_RELOC_ARM_PCREL_BRANCH, + +/* ARM 26 bit pc-relative branch. The lowest bit must be zero and is +not stored in the instruction. The 2nd lowest bit comes from a 1 bit +field in the instruction. */ + BFD_RELOC_ARM_PCREL_BLX, + +/* Thumb 22 bit pc-relative branch. The lowest bit must be zero and is +not stored in the instruction. The 2nd lowest bit comes from a 1 bit +field in the instruction. */ + BFD_RELOC_THUMB_PCREL_BLX, + +/* These relocs are only used within the ARM assembler. They are not +(at present) written to any object files. */ + BFD_RELOC_ARM_IMMEDIATE, + BFD_RELOC_ARM_ADRL_IMMEDIATE, + BFD_RELOC_ARM_OFFSET_IMM, + BFD_RELOC_ARM_SHIFT_IMM, + BFD_RELOC_ARM_SMI, + BFD_RELOC_ARM_SWI, + BFD_RELOC_ARM_MULTI, + BFD_RELOC_ARM_CP_OFF_IMM, + BFD_RELOC_ARM_CP_OFF_IMM_S2, + BFD_RELOC_ARM_ADR_IMM, + BFD_RELOC_ARM_LDR_IMM, + BFD_RELOC_ARM_LITERAL, + BFD_RELOC_ARM_IN_POOL, + BFD_RELOC_ARM_OFFSET_IMM8, + BFD_RELOC_ARM_HWLITERAL, + BFD_RELOC_ARM_THUMB_ADD, + BFD_RELOC_ARM_THUMB_IMM, + BFD_RELOC_ARM_THUMB_SHIFT, + BFD_RELOC_ARM_THUMB_OFFSET, + BFD_RELOC_ARM_GOT12, + BFD_RELOC_ARM_GOT32, + BFD_RELOC_ARM_JUMP_SLOT, + BFD_RELOC_ARM_COPY, + BFD_RELOC_ARM_GLOB_DAT, + BFD_RELOC_ARM_PLT32, + BFD_RELOC_ARM_RELATIVE, + BFD_RELOC_ARM_GOTOFF, + BFD_RELOC_ARM_GOTPC, + +/* Pc-relative or absolute relocation depending on target. Used for +entries in .init_array sections. */ + BFD_RELOC_ARM_TARGET1, + +/* Read-only segment base relative address. */ + BFD_RELOC_ARM_ROSEGREL32, + +/* Data segment base relative address. */ + BFD_RELOC_ARM_SBREL32, + +/* This reloc is used for References to RTTI dta from exception handling +tables. The actual definition depends on the target. It may be a +pc-relative or some form of GOT-indirect relocation. */ + BFD_RELOC_ARM_TARGET2, + +/* 31-bit PC relative address. */ + BFD_RELOC_ARM_PREL31, + +/* Renesas / SuperH SH relocs. Not all of these appear in object files. */ + BFD_RELOC_SH_PCDISP8BY2, + BFD_RELOC_SH_PCDISP12BY2, + BFD_RELOC_SH_IMM3, + BFD_RELOC_SH_IMM3U, + BFD_RELOC_SH_DISP12, + BFD_RELOC_SH_DISP12BY2, + BFD_RELOC_SH_DISP12BY4, + BFD_RELOC_SH_DISP12BY8, + BFD_RELOC_SH_DISP20, + BFD_RELOC_SH_DISP20BY8, + BFD_RELOC_SH_IMM4, + BFD_RELOC_SH_IMM4BY2, + BFD_RELOC_SH_IMM4BY4, + BFD_RELOC_SH_IMM8, + BFD_RELOC_SH_IMM8BY2, + BFD_RELOC_SH_IMM8BY4, + BFD_RELOC_SH_PCRELIMM8BY2, + BFD_RELOC_SH_PCRELIMM8BY4, + BFD_RELOC_SH_SWITCH16, + BFD_RELOC_SH_SWITCH32, + BFD_RELOC_SH_USES, + BFD_RELOC_SH_COUNT, + BFD_RELOC_SH_ALIGN, + BFD_RELOC_SH_CODE, + BFD_RELOC_SH_DATA, + BFD_RELOC_SH_LABEL, + BFD_RELOC_SH_LOOP_START, + BFD_RELOC_SH_LOOP_END, + BFD_RELOC_SH_COPY, + BFD_RELOC_SH_GLOB_DAT, + BFD_RELOC_SH_JMP_SLOT, + BFD_RELOC_SH_RELATIVE, + BFD_RELOC_SH_GOTPC, + BFD_RELOC_SH_GOT_LOW16, + BFD_RELOC_SH_GOT_MEDLOW16, + BFD_RELOC_SH_GOT_MEDHI16, + BFD_RELOC_SH_GOT_HI16, + BFD_RELOC_SH_GOTPLT_LOW16, + BFD_RELOC_SH_GOTPLT_MEDLOW16, + BFD_RELOC_SH_GOTPLT_MEDHI16, + BFD_RELOC_SH_GOTPLT_HI16, + BFD_RELOC_SH_PLT_LOW16, + BFD_RELOC_SH_PLT_MEDLOW16, + BFD_RELOC_SH_PLT_MEDHI16, + BFD_RELOC_SH_PLT_HI16, + BFD_RELOC_SH_GOTOFF_LOW16, + BFD_RELOC_SH_GOTOFF_MEDLOW16, + BFD_RELOC_SH_GOTOFF_MEDHI16, + BFD_RELOC_SH_GOTOFF_HI16, + BFD_RELOC_SH_GOTPC_LOW16, + BFD_RELOC_SH_GOTPC_MEDLOW16, + BFD_RELOC_SH_GOTPC_MEDHI16, + BFD_RELOC_SH_GOTPC_HI16, + BFD_RELOC_SH_COPY64, + BFD_RELOC_SH_GLOB_DAT64, + BFD_RELOC_SH_JMP_SLOT64, + BFD_RELOC_SH_RELATIVE64, + BFD_RELOC_SH_GOT10BY4, + BFD_RELOC_SH_GOT10BY8, + BFD_RELOC_SH_GOTPLT10BY4, + BFD_RELOC_SH_GOTPLT10BY8, + BFD_RELOC_SH_GOTPLT32, + BFD_RELOC_SH_SHMEDIA_CODE, + BFD_RELOC_SH_IMMU5, + BFD_RELOC_SH_IMMS6, + BFD_RELOC_SH_IMMS6BY32, + BFD_RELOC_SH_IMMU6, + BFD_RELOC_SH_IMMS10, + BFD_RELOC_SH_IMMS10BY2, + BFD_RELOC_SH_IMMS10BY4, + BFD_RELOC_SH_IMMS10BY8, + BFD_RELOC_SH_IMMS16, + BFD_RELOC_SH_IMMU16, + BFD_RELOC_SH_IMM_LOW16, + BFD_RELOC_SH_IMM_LOW16_PCREL, + BFD_RELOC_SH_IMM_MEDLOW16, + BFD_RELOC_SH_IMM_MEDLOW16_PCREL, + BFD_RELOC_SH_IMM_MEDHI16, + BFD_RELOC_SH_IMM_MEDHI16_PCREL, + BFD_RELOC_SH_IMM_HI16, + BFD_RELOC_SH_IMM_HI16_PCREL, + BFD_RELOC_SH_PT_16, + BFD_RELOC_SH_TLS_GD_32, + BFD_RELOC_SH_TLS_LD_32, + BFD_RELOC_SH_TLS_LDO_32, + BFD_RELOC_SH_TLS_IE_32, + BFD_RELOC_SH_TLS_LE_32, + BFD_RELOC_SH_TLS_DTPMOD32, + BFD_RELOC_SH_TLS_DTPOFF32, + BFD_RELOC_SH_TLS_TPOFF32, + +/* Thumb 23-, 12- and 9-bit pc-relative branches. The lowest bit must +be zero and is not stored in the instruction. */ + BFD_RELOC_THUMB_PCREL_BRANCH9, + BFD_RELOC_THUMB_PCREL_BRANCH12, + BFD_RELOC_THUMB_PCREL_BRANCH23, + +/* ARC Cores relocs. +ARC 22 bit pc-relative branch. The lowest two bits must be zero and are +not stored in the instruction. The high 20 bits are installed in bits 26 +through 7 of the instruction. */ + BFD_RELOC_ARC_B22_PCREL, + +/* ARC 26 bit absolute branch. The lowest two bits must be zero and are not +stored in the instruction. The high 24 bits are installed in bits 23 +through 0. */ + BFD_RELOC_ARC_B26, + +/* Mitsubishi D10V relocs. +This is a 10-bit reloc with the right 2 bits +assumed to be 0. */ + BFD_RELOC_D10V_10_PCREL_R, + +/* Mitsubishi D10V relocs. +This is a 10-bit reloc with the right 2 bits +assumed to be 0. This is the same as the previous reloc +except it is in the left container, i.e., +shifted left 15 bits. */ + BFD_RELOC_D10V_10_PCREL_L, + +/* This is an 18-bit reloc with the right 2 bits +assumed to be 0. */ + BFD_RELOC_D10V_18, + +/* This is an 18-bit reloc with the right 2 bits +assumed to be 0. */ + BFD_RELOC_D10V_18_PCREL, + +/* Mitsubishi D30V relocs. +This is a 6-bit absolute reloc. */ + BFD_RELOC_D30V_6, + +/* This is a 6-bit pc-relative reloc with +the right 3 bits assumed to be 0. */ + BFD_RELOC_D30V_9_PCREL, + +/* This is a 6-bit pc-relative reloc with +the right 3 bits assumed to be 0. Same +as the previous reloc but on the right side +of the container. */ + BFD_RELOC_D30V_9_PCREL_R, + +/* This is a 12-bit absolute reloc with the +right 3 bitsassumed to be 0. */ + BFD_RELOC_D30V_15, + +/* This is a 12-bit pc-relative reloc with +the right 3 bits assumed to be 0. */ + BFD_RELOC_D30V_15_PCREL, + +/* This is a 12-bit pc-relative reloc with +the right 3 bits assumed to be 0. Same +as the previous reloc but on the right side +of the container. */ + BFD_RELOC_D30V_15_PCREL_R, + +/* This is an 18-bit absolute reloc with +the right 3 bits assumed to be 0. */ + BFD_RELOC_D30V_21, + +/* This is an 18-bit pc-relative reloc with +the right 3 bits assumed to be 0. */ + BFD_RELOC_D30V_21_PCREL, + +/* This is an 18-bit pc-relative reloc with +the right 3 bits assumed to be 0. Same +as the previous reloc but on the right side +of the container. */ + BFD_RELOC_D30V_21_PCREL_R, + +/* This is a 32-bit absolute reloc. */ + BFD_RELOC_D30V_32, + +/* This is a 32-bit pc-relative reloc. */ + BFD_RELOC_D30V_32_PCREL, + +/* DLX relocs */ + BFD_RELOC_DLX_HI16_S, + +/* DLX relocs */ + BFD_RELOC_DLX_LO16, + +/* DLX relocs */ + BFD_RELOC_DLX_JMP26, + +/* Renesas M32R (formerly Mitsubishi M32R) relocs. +This is a 24 bit absolute address. */ + BFD_RELOC_M32R_24, + +/* This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. */ + BFD_RELOC_M32R_10_PCREL, + +/* This is an 18-bit reloc with the right 2 bits assumed to be 0. */ + BFD_RELOC_M32R_18_PCREL, + +/* This is a 26-bit reloc with the right 2 bits assumed to be 0. */ + BFD_RELOC_M32R_26_PCREL, + +/* This is a 16-bit reloc containing the high 16 bits of an address +used when the lower 16 bits are treated as unsigned. */ + BFD_RELOC_M32R_HI16_ULO, + +/* This is a 16-bit reloc containing the high 16 bits of an address +used when the lower 16 bits are treated as signed. */ + BFD_RELOC_M32R_HI16_SLO, + +/* This is a 16-bit reloc containing the lower 16 bits of an address. */ + BFD_RELOC_M32R_LO16, + +/* This is a 16-bit reloc containing the small data area offset for use in +add3, load, and store instructions. */ + BFD_RELOC_M32R_SDA16, + +/* For PIC. */ + BFD_RELOC_M32R_GOT24, + BFD_RELOC_M32R_26_PLTREL, + BFD_RELOC_M32R_COPY, + BFD_RELOC_M32R_GLOB_DAT, + BFD_RELOC_M32R_JMP_SLOT, + BFD_RELOC_M32R_RELATIVE, + BFD_RELOC_M32R_GOTOFF, + BFD_RELOC_M32R_GOTOFF_HI_ULO, + BFD_RELOC_M32R_GOTOFF_HI_SLO, + BFD_RELOC_M32R_GOTOFF_LO, + BFD_RELOC_M32R_GOTPC24, + BFD_RELOC_M32R_GOT16_HI_ULO, + BFD_RELOC_M32R_GOT16_HI_SLO, + BFD_RELOC_M32R_GOT16_LO, + BFD_RELOC_M32R_GOTPC_HI_ULO, + BFD_RELOC_M32R_GOTPC_HI_SLO, + BFD_RELOC_M32R_GOTPC_LO, + +/* This is a 9-bit reloc */ + BFD_RELOC_V850_9_PCREL, + +/* This is a 22-bit reloc */ + BFD_RELOC_V850_22_PCREL, + +/* This is a 16 bit offset from the short data area pointer. */ + BFD_RELOC_V850_SDA_16_16_OFFSET, + +/* This is a 16 bit offset (of which only 15 bits are used) from the +short data area pointer. */ + BFD_RELOC_V850_SDA_15_16_OFFSET, + +/* This is a 16 bit offset from the zero data area pointer. */ + BFD_RELOC_V850_ZDA_16_16_OFFSET, + +/* This is a 16 bit offset (of which only 15 bits are used) from the +zero data area pointer. */ + BFD_RELOC_V850_ZDA_15_16_OFFSET, + +/* This is an 8 bit offset (of which only 6 bits are used) from the +tiny data area pointer. */ + BFD_RELOC_V850_TDA_6_8_OFFSET, + +/* This is an 8bit offset (of which only 7 bits are used) from the tiny +data area pointer. */ + BFD_RELOC_V850_TDA_7_8_OFFSET, + +/* This is a 7 bit offset from the tiny data area pointer. */ + BFD_RELOC_V850_TDA_7_7_OFFSET, + +/* This is a 16 bit offset from the tiny data area pointer. */ + BFD_RELOC_V850_TDA_16_16_OFFSET, + +/* This is a 5 bit offset (of which only 4 bits are used) from the tiny +data area pointer. */ + BFD_RELOC_V850_TDA_4_5_OFFSET, + +/* This is a 4 bit offset from the tiny data area pointer. */ + BFD_RELOC_V850_TDA_4_4_OFFSET, + +/* This is a 16 bit offset from the short data area pointer, with the +bits placed non-contiguously in the instruction. */ + BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, + +/* This is a 16 bit offset from the zero data area pointer, with the +bits placed non-contiguously in the instruction. */ + BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, + +/* This is a 6 bit offset from the call table base pointer. */ + BFD_RELOC_V850_CALLT_6_7_OFFSET, + +/* This is a 16 bit offset from the call table base pointer. */ + BFD_RELOC_V850_CALLT_16_16_OFFSET, + +/* Used for relaxing indirect function calls. */ + BFD_RELOC_V850_LONGCALL, + +/* Used for relaxing indirect jumps. */ + BFD_RELOC_V850_LONGJUMP, + +/* Used to maintain alignment whilst relaxing. */ + BFD_RELOC_V850_ALIGN, + +/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the +instruction. */ + BFD_RELOC_MN10300_32_PCREL, + +/* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the +instruction. */ + BFD_RELOC_MN10300_16_PCREL, + +/* This is a 8bit DP reloc for the tms320c30, where the most +significant 8 bits of a 24 bit word are placed into the least +significant 8 bits of the opcode. */ + BFD_RELOC_TIC30_LDP, + +/* This is a 7bit reloc for the tms320c54x, where the least +significant 7 bits of a 16 bit word are placed into the least +significant 7 bits of the opcode. */ + BFD_RELOC_TIC54X_PARTLS7, + +/* This is a 9bit DP reloc for the tms320c54x, where the most +significant 9 bits of a 16 bit word are placed into the least +significant 9 bits of the opcode. */ + BFD_RELOC_TIC54X_PARTMS9, + +/* This is an extended address 23-bit reloc for the tms320c54x. */ + BFD_RELOC_TIC54X_23, + +/* This is a 16-bit reloc for the tms320c54x, where the least +significant 16 bits of a 23-bit extended address are placed into +the opcode. */ + BFD_RELOC_TIC54X_16_OF_23, + +/* This is a reloc for the tms320c54x, where the most +significant 7 bits of a 23-bit extended address are placed into +the opcode. */ + BFD_RELOC_TIC54X_MS7_OF_23, + +/* This is a 48 bit reloc for the FR30 that stores 32 bits. */ + BFD_RELOC_FR30_48, + +/* This is a 32 bit reloc for the FR30 that stores 20 bits split up into +two sections. */ + BFD_RELOC_FR30_20, + +/* This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in +4 bits. */ + BFD_RELOC_FR30_6_IN_4, + +/* This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset +into 8 bits. */ + BFD_RELOC_FR30_8_IN_8, + +/* This is a 16 bit reloc for the FR30 that stores a 9 bit short offset +into 8 bits. */ + BFD_RELOC_FR30_9_IN_8, + +/* This is a 16 bit reloc for the FR30 that stores a 10 bit word offset +into 8 bits. */ + BFD_RELOC_FR30_10_IN_8, + +/* This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative +short offset into 8 bits. */ + BFD_RELOC_FR30_9_PCREL, + +/* This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative +short offset into 11 bits. */ + BFD_RELOC_FR30_12_PCREL, + +/* Motorola Mcore relocations. */ + BFD_RELOC_MCORE_PCREL_IMM8BY4, + BFD_RELOC_MCORE_PCREL_IMM11BY2, + BFD_RELOC_MCORE_PCREL_IMM4BY2, + BFD_RELOC_MCORE_PCREL_32, + BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, + BFD_RELOC_MCORE_RVA, + +/* These are relocations for the GETA instruction. */ + BFD_RELOC_MMIX_GETA, + BFD_RELOC_MMIX_GETA_1, + BFD_RELOC_MMIX_GETA_2, + BFD_RELOC_MMIX_GETA_3, + +/* These are relocations for a conditional branch instruction. */ + BFD_RELOC_MMIX_CBRANCH, + BFD_RELOC_MMIX_CBRANCH_J, + BFD_RELOC_MMIX_CBRANCH_1, + BFD_RELOC_MMIX_CBRANCH_2, + BFD_RELOC_MMIX_CBRANCH_3, + +/* These are relocations for the PUSHJ instruction. */ + BFD_RELOC_MMIX_PUSHJ, + BFD_RELOC_MMIX_PUSHJ_1, + BFD_RELOC_MMIX_PUSHJ_2, + BFD_RELOC_MMIX_PUSHJ_3, + BFD_RELOC_MMIX_PUSHJ_STUBBABLE, + +/* These are relocations for the JMP instruction. */ + BFD_RELOC_MMIX_JMP, + BFD_RELOC_MMIX_JMP_1, + BFD_RELOC_MMIX_JMP_2, + BFD_RELOC_MMIX_JMP_3, + +/* This is a relocation for a relative address as in a GETA instruction or +a branch. */ + BFD_RELOC_MMIX_ADDR19, + +/* This is a relocation for a relative address as in a JMP instruction. */ + BFD_RELOC_MMIX_ADDR27, + +/* This is a relocation for an instruction field that may be a general +register or a value 0..255. */ + BFD_RELOC_MMIX_REG_OR_BYTE, + +/* This is a relocation for an instruction field that may be a general +register. */ + BFD_RELOC_MMIX_REG, + +/* This is a relocation for two instruction fields holding a register and +an offset, the equivalent of the relocation. */ + BFD_RELOC_MMIX_BASE_PLUS_OFFSET, + +/* This relocation is an assertion that the expression is not allocated as +a global register. It does not modify contents. */ + BFD_RELOC_MMIX_LOCAL, + +/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative +short offset into 7 bits. */ + BFD_RELOC_AVR_7_PCREL, + +/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative +short offset into 12 bits. */ + BFD_RELOC_AVR_13_PCREL, + +/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually +program memory address) into 16 bits. */ + BFD_RELOC_AVR_16_PM, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually +data memory address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_LO8_LDI, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit +of data memory address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_HI8_LDI, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit +of program memory address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_HH8_LDI, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(usually data memory address) into 8 bit immediate value of SUBI insn. */ + BFD_RELOC_AVR_LO8_LDI_NEG, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(high 8 bit of data memory address) into 8 bit immediate value of +SUBI insn. */ + BFD_RELOC_AVR_HI8_LDI_NEG, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(most high 8 bit of program memory address) into 8 bit immediate value +of LDI or SUBI insn. */ + BFD_RELOC_AVR_HH8_LDI_NEG, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually +command address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_LO8_LDI_PM, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit +of command address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_HI8_LDI_PM, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit +of command address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_HH8_LDI_PM, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(usually command address) into 8 bit immediate value of SUBI insn. */ + BFD_RELOC_AVR_LO8_LDI_PM_NEG, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(high 8 bit of 16 bit command address) into 8 bit immediate value +of SUBI insn. */ + BFD_RELOC_AVR_HI8_LDI_PM_NEG, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(high 6 bit of 22 bit command address) into 8 bit immediate +value of SUBI insn. */ + BFD_RELOC_AVR_HH8_LDI_PM_NEG, + +/* This is a 32 bit reloc for the AVR that stores 23 bit value +into 22 bits. */ + BFD_RELOC_AVR_CALL, + +/* Direct 12 bit. */ + BFD_RELOC_390_12, + +/* 12 bit GOT offset. */ + BFD_RELOC_390_GOT12, + +/* 32 bit PC relative PLT address. */ + BFD_RELOC_390_PLT32, + +/* Copy symbol at runtime. */ + BFD_RELOC_390_COPY, + +/* Create GOT entry. */ + BFD_RELOC_390_GLOB_DAT, + +/* Create PLT entry. */ + BFD_RELOC_390_JMP_SLOT, + +/* Adjust by program base. */ + BFD_RELOC_390_RELATIVE, + +/* 32 bit PC relative offset to GOT. */ + BFD_RELOC_390_GOTPC, + +/* 16 bit GOT offset. */ + BFD_RELOC_390_GOT16, + +/* PC relative 16 bit shifted by 1. */ + BFD_RELOC_390_PC16DBL, + +/* 16 bit PC rel. PLT shifted by 1. */ + BFD_RELOC_390_PLT16DBL, + +/* PC relative 32 bit shifted by 1. */ + BFD_RELOC_390_PC32DBL, + +/* 32 bit PC rel. PLT shifted by 1. */ + BFD_RELOC_390_PLT32DBL, + +/* 32 bit PC rel. GOT shifted by 1. */ + BFD_RELOC_390_GOTPCDBL, + +/* 64 bit GOT offset. */ + BFD_RELOC_390_GOT64, + +/* 64 bit PC relative PLT address. */ + BFD_RELOC_390_PLT64, + +/* 32 bit rel. offset to GOT entry. */ + BFD_RELOC_390_GOTENT, + +/* 64 bit offset to GOT. */ + BFD_RELOC_390_GOTOFF64, + +/* 12-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLT12, + +/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLT16, + +/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLT32, + +/* 64-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLT64, + +/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLTENT, + +/* 16-bit rel. offset from the GOT to a PLT entry. */ + BFD_RELOC_390_PLTOFF16, + +/* 32-bit rel. offset from the GOT to a PLT entry. */ + BFD_RELOC_390_PLTOFF32, + +/* 64-bit rel. offset from the GOT to a PLT entry. */ + BFD_RELOC_390_PLTOFF64, + +/* s390 tls relocations. */ + BFD_RELOC_390_TLS_LOAD, + BFD_RELOC_390_TLS_GDCALL, + BFD_RELOC_390_TLS_LDCALL, + BFD_RELOC_390_TLS_GD32, + BFD_RELOC_390_TLS_GD64, + BFD_RELOC_390_TLS_GOTIE12, + BFD_RELOC_390_TLS_GOTIE32, + BFD_RELOC_390_TLS_GOTIE64, + BFD_RELOC_390_TLS_LDM32, + BFD_RELOC_390_TLS_LDM64, + BFD_RELOC_390_TLS_IE32, + BFD_RELOC_390_TLS_IE64, + BFD_RELOC_390_TLS_IEENT, + BFD_RELOC_390_TLS_LE32, + BFD_RELOC_390_TLS_LE64, + BFD_RELOC_390_TLS_LDO32, + BFD_RELOC_390_TLS_LDO64, + BFD_RELOC_390_TLS_DTPMOD, + BFD_RELOC_390_TLS_DTPOFF, + BFD_RELOC_390_TLS_TPOFF, + +/* Long displacement extension. */ + BFD_RELOC_390_20, + BFD_RELOC_390_GOT20, + BFD_RELOC_390_GOTPLT20, + BFD_RELOC_390_TLS_GOTIE20, + +/* Scenix IP2K - 9-bit register number / data address */ + BFD_RELOC_IP2K_FR9, + +/* Scenix IP2K - 4-bit register/data bank number */ + BFD_RELOC_IP2K_BANK, + +/* Scenix IP2K - low 13 bits of instruction word address */ + BFD_RELOC_IP2K_ADDR16CJP, + +/* Scenix IP2K - high 3 bits of instruction word address */ + BFD_RELOC_IP2K_PAGE3, + +/* Scenix IP2K - ext/low/high 8 bits of data address */ + BFD_RELOC_IP2K_LO8DATA, + BFD_RELOC_IP2K_HI8DATA, + BFD_RELOC_IP2K_EX8DATA, + +/* Scenix IP2K - low/high 8 bits of instruction word address */ + BFD_RELOC_IP2K_LO8INSN, + BFD_RELOC_IP2K_HI8INSN, + +/* Scenix IP2K - even/odd PC modifier to modify snb pcl.0 */ + BFD_RELOC_IP2K_PC_SKIP, + +/* Scenix IP2K - 16 bit word address in text section. */ + BFD_RELOC_IP2K_TEXT, + +/* Scenix IP2K - 7-bit sp or dp offset */ + BFD_RELOC_IP2K_FR_OFFSET, + +/* Scenix VPE4K coprocessor - data/insn-space addressing */ + BFD_RELOC_VPE4KMATH_DATA, + BFD_RELOC_VPE4KMATH_INSN, + +/* These two relocations are used by the linker to determine which of +the entries in a C++ virtual function table are actually used. When +the --gc-sections option is given, the linker will zero out the entries +that are not used, so that the code for those functions need not be +included in the output. + +VTABLE_INHERIT is a zero-space relocation used to describe to the +linker the inheritance tree of a C++ virtual function table. The +relocation's symbol should be the parent class' vtable, and the +relocation should be located at the child vtable. + +VTABLE_ENTRY is a zero-space relocation that describes the use of a +virtual function table entry. The reloc's symbol should refer to the +table of the class mentioned in the code. Off of that base, an offset +describes the entry that is being used. For Rela hosts, this offset +is stored in the reloc's addend. For Rel hosts, we are forced to put +this offset in the reloc's section offset. */ + BFD_RELOC_VTABLE_INHERIT, + BFD_RELOC_VTABLE_ENTRY, + +/* Intel IA64 Relocations. */ + BFD_RELOC_IA64_IMM14, + BFD_RELOC_IA64_IMM22, + BFD_RELOC_IA64_IMM64, + BFD_RELOC_IA64_DIR32MSB, + BFD_RELOC_IA64_DIR32LSB, + BFD_RELOC_IA64_DIR64MSB, + BFD_RELOC_IA64_DIR64LSB, + BFD_RELOC_IA64_GPREL22, + BFD_RELOC_IA64_GPREL64I, + BFD_RELOC_IA64_GPREL32MSB, + BFD_RELOC_IA64_GPREL32LSB, + BFD_RELOC_IA64_GPREL64MSB, + BFD_RELOC_IA64_GPREL64LSB, + BFD_RELOC_IA64_LTOFF22, + BFD_RELOC_IA64_LTOFF64I, + BFD_RELOC_IA64_PLTOFF22, + BFD_RELOC_IA64_PLTOFF64I, + BFD_RELOC_IA64_PLTOFF64MSB, + BFD_RELOC_IA64_PLTOFF64LSB, + BFD_RELOC_IA64_FPTR64I, + BFD_RELOC_IA64_FPTR32MSB, + BFD_RELOC_IA64_FPTR32LSB, + BFD_RELOC_IA64_FPTR64MSB, + BFD_RELOC_IA64_FPTR64LSB, + BFD_RELOC_IA64_PCREL21B, + BFD_RELOC_IA64_PCREL21BI, + BFD_RELOC_IA64_PCREL21M, + BFD_RELOC_IA64_PCREL21F, + BFD_RELOC_IA64_PCREL22, + BFD_RELOC_IA64_PCREL60B, + BFD_RELOC_IA64_PCREL64I, + BFD_RELOC_IA64_PCREL32MSB, + BFD_RELOC_IA64_PCREL32LSB, + BFD_RELOC_IA64_PCREL64MSB, + BFD_RELOC_IA64_PCREL64LSB, + BFD_RELOC_IA64_LTOFF_FPTR22, + BFD_RELOC_IA64_LTOFF_FPTR64I, + BFD_RELOC_IA64_LTOFF_FPTR32MSB, + BFD_RELOC_IA64_LTOFF_FPTR32LSB, + BFD_RELOC_IA64_LTOFF_FPTR64MSB, + BFD_RELOC_IA64_LTOFF_FPTR64LSB, + BFD_RELOC_IA64_SEGREL32MSB, + BFD_RELOC_IA64_SEGREL32LSB, + BFD_RELOC_IA64_SEGREL64MSB, + BFD_RELOC_IA64_SEGREL64LSB, + BFD_RELOC_IA64_SECREL32MSB, + BFD_RELOC_IA64_SECREL32LSB, + BFD_RELOC_IA64_SECREL64MSB, + BFD_RELOC_IA64_SECREL64LSB, + BFD_RELOC_IA64_REL32MSB, + BFD_RELOC_IA64_REL32LSB, + BFD_RELOC_IA64_REL64MSB, + BFD_RELOC_IA64_REL64LSB, + BFD_RELOC_IA64_LTV32MSB, + BFD_RELOC_IA64_LTV32LSB, + BFD_RELOC_IA64_LTV64MSB, + BFD_RELOC_IA64_LTV64LSB, + BFD_RELOC_IA64_IPLTMSB, + BFD_RELOC_IA64_IPLTLSB, + BFD_RELOC_IA64_COPY, + BFD_RELOC_IA64_LTOFF22X, + BFD_RELOC_IA64_LDXMOV, + BFD_RELOC_IA64_TPREL14, + BFD_RELOC_IA64_TPREL22, + BFD_RELOC_IA64_TPREL64I, + BFD_RELOC_IA64_TPREL64MSB, + BFD_RELOC_IA64_TPREL64LSB, + BFD_RELOC_IA64_LTOFF_TPREL22, + BFD_RELOC_IA64_DTPMOD64MSB, + BFD_RELOC_IA64_DTPMOD64LSB, + BFD_RELOC_IA64_LTOFF_DTPMOD22, + BFD_RELOC_IA64_DTPREL14, + BFD_RELOC_IA64_DTPREL22, + BFD_RELOC_IA64_DTPREL64I, + BFD_RELOC_IA64_DTPREL32MSB, + BFD_RELOC_IA64_DTPREL32LSB, + BFD_RELOC_IA64_DTPREL64MSB, + BFD_RELOC_IA64_DTPREL64LSB, + BFD_RELOC_IA64_LTOFF_DTPREL22, + +/* Motorola 68HC11 reloc. +This is the 8 bit high part of an absolute address. */ + BFD_RELOC_M68HC11_HI8, + +/* Motorola 68HC11 reloc. +This is the 8 bit low part of an absolute address. */ + BFD_RELOC_M68HC11_LO8, + +/* Motorola 68HC11 reloc. +This is the 3 bit of a value. */ + BFD_RELOC_M68HC11_3B, + +/* Motorola 68HC11 reloc. +This reloc marks the beginning of a jump/call instruction. +It is used for linker relaxation to correctly identify beginning +of instruction and change some branches to use PC-relative +addressing mode. */ + BFD_RELOC_M68HC11_RL_JUMP, + +/* Motorola 68HC11 reloc. +This reloc marks a group of several instructions that gcc generates +and for which the linker relaxation pass can modify and/or remove +some of them. */ + BFD_RELOC_M68HC11_RL_GROUP, + +/* Motorola 68HC11 reloc. +This is the 16-bit lower part of an address. It is used for 'call' +instruction to specify the symbol address without any special +transformation (due to memory bank window). */ + BFD_RELOC_M68HC11_LO16, + +/* Motorola 68HC11 reloc. +This is a 8-bit reloc that specifies the page number of an address. +It is used by 'call' instruction to specify the page number of +the symbol. */ + BFD_RELOC_M68HC11_PAGE, + +/* Motorola 68HC11 reloc. +This is a 24-bit reloc that represents the address with a 16-bit +value and a 8-bit page number. The symbol address is transformed +to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */ + BFD_RELOC_M68HC11_24, + +/* Motorola 68HC12 reloc. +This is the 5 bits of a value. */ + BFD_RELOC_M68HC12_5B, + +/* NS CR16C Relocations. */ + BFD_RELOC_16C_NUM08, + BFD_RELOC_16C_NUM08_C, + BFD_RELOC_16C_NUM16, + BFD_RELOC_16C_NUM16_C, + BFD_RELOC_16C_NUM32, + BFD_RELOC_16C_NUM32_C, + BFD_RELOC_16C_DISP04, + BFD_RELOC_16C_DISP04_C, + BFD_RELOC_16C_DISP08, + BFD_RELOC_16C_DISP08_C, + BFD_RELOC_16C_DISP16, + BFD_RELOC_16C_DISP16_C, + BFD_RELOC_16C_DISP24, + BFD_RELOC_16C_DISP24_C, + BFD_RELOC_16C_DISP24a, + BFD_RELOC_16C_DISP24a_C, + BFD_RELOC_16C_REG04, + BFD_RELOC_16C_REG04_C, + BFD_RELOC_16C_REG04a, + BFD_RELOC_16C_REG04a_C, + BFD_RELOC_16C_REG14, + BFD_RELOC_16C_REG14_C, + BFD_RELOC_16C_REG16, + BFD_RELOC_16C_REG16_C, + BFD_RELOC_16C_REG20, + BFD_RELOC_16C_REG20_C, + BFD_RELOC_16C_ABS20, + BFD_RELOC_16C_ABS20_C, + BFD_RELOC_16C_ABS24, + BFD_RELOC_16C_ABS24_C, + BFD_RELOC_16C_IMM04, + BFD_RELOC_16C_IMM04_C, + BFD_RELOC_16C_IMM16, + BFD_RELOC_16C_IMM16_C, + BFD_RELOC_16C_IMM20, + BFD_RELOC_16C_IMM20_C, + BFD_RELOC_16C_IMM24, + BFD_RELOC_16C_IMM24_C, + BFD_RELOC_16C_IMM32, + BFD_RELOC_16C_IMM32_C, + +/* NS CRX Relocations. */ + BFD_RELOC_CRX_REL4, + BFD_RELOC_CRX_REL8, + BFD_RELOC_CRX_REL8_CMP, + BFD_RELOC_CRX_REL16, + BFD_RELOC_CRX_REL24, + BFD_RELOC_CRX_REL32, + BFD_RELOC_CRX_REGREL12, + BFD_RELOC_CRX_REGREL22, + BFD_RELOC_CRX_REGREL28, + BFD_RELOC_CRX_REGREL32, + BFD_RELOC_CRX_ABS16, + BFD_RELOC_CRX_ABS32, + BFD_RELOC_CRX_NUM8, + BFD_RELOC_CRX_NUM16, + BFD_RELOC_CRX_NUM32, + BFD_RELOC_CRX_IMM16, + BFD_RELOC_CRX_IMM32, + BFD_RELOC_CRX_SWITCH8, + BFD_RELOC_CRX_SWITCH16, + BFD_RELOC_CRX_SWITCH32, + +/* These relocs are only used within the CRIS assembler. They are not +(at present) written to any object files. */ + BFD_RELOC_CRIS_BDISP8, + BFD_RELOC_CRIS_UNSIGNED_5, + BFD_RELOC_CRIS_SIGNED_6, + BFD_RELOC_CRIS_UNSIGNED_6, + BFD_RELOC_CRIS_UNSIGNED_4, + +/* Relocs used in ELF shared libraries for CRIS. */ + BFD_RELOC_CRIS_COPY, + BFD_RELOC_CRIS_GLOB_DAT, + BFD_RELOC_CRIS_JUMP_SLOT, + BFD_RELOC_CRIS_RELATIVE, + +/* 32-bit offset to symbol-entry within GOT. */ + BFD_RELOC_CRIS_32_GOT, + +/* 16-bit offset to symbol-entry within GOT. */ + BFD_RELOC_CRIS_16_GOT, + +/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_CRIS_32_GOTPLT, + +/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_CRIS_16_GOTPLT, + +/* 32-bit offset to symbol, relative to GOT. */ + BFD_RELOC_CRIS_32_GOTREL, + +/* 32-bit offset to symbol with PLT entry, relative to GOT. */ + BFD_RELOC_CRIS_32_PLT_GOTREL, + +/* 32-bit offset to symbol with PLT entry, relative to this relocation. */ + BFD_RELOC_CRIS_32_PLT_PCREL, + +/* Intel i860 Relocations. */ + BFD_RELOC_860_COPY, + BFD_RELOC_860_GLOB_DAT, + BFD_RELOC_860_JUMP_SLOT, + BFD_RELOC_860_RELATIVE, + BFD_RELOC_860_PC26, + BFD_RELOC_860_PLT26, + BFD_RELOC_860_PC16, + BFD_RELOC_860_LOW0, + BFD_RELOC_860_SPLIT0, + BFD_RELOC_860_LOW1, + BFD_RELOC_860_SPLIT1, + BFD_RELOC_860_LOW2, + BFD_RELOC_860_SPLIT2, + BFD_RELOC_860_LOW3, + BFD_RELOC_860_LOGOT0, + BFD_RELOC_860_SPGOT0, + BFD_RELOC_860_LOGOT1, + BFD_RELOC_860_SPGOT1, + BFD_RELOC_860_LOGOTOFF0, + BFD_RELOC_860_SPGOTOFF0, + BFD_RELOC_860_LOGOTOFF1, + BFD_RELOC_860_SPGOTOFF1, + BFD_RELOC_860_LOGOTOFF2, + BFD_RELOC_860_LOGOTOFF3, + BFD_RELOC_860_LOPC, + BFD_RELOC_860_HIGHADJ, + BFD_RELOC_860_HAGOT, + BFD_RELOC_860_HAGOTOFF, + BFD_RELOC_860_HAPC, + BFD_RELOC_860_HIGH, + BFD_RELOC_860_HIGOT, + BFD_RELOC_860_HIGOTOFF, + +/* OpenRISC Relocations. */ + BFD_RELOC_OPENRISC_ABS_26, + BFD_RELOC_OPENRISC_REL_26, + +/* H8 elf Relocations. */ + BFD_RELOC_H8_DIR16A8, + BFD_RELOC_H8_DIR16R8, + BFD_RELOC_H8_DIR24A8, + BFD_RELOC_H8_DIR24R8, + BFD_RELOC_H8_DIR32A16, + +/* Sony Xstormy16 Relocations. */ + BFD_RELOC_XSTORMY16_REL_12, + BFD_RELOC_XSTORMY16_12, + BFD_RELOC_XSTORMY16_24, + BFD_RELOC_XSTORMY16_FPTR16, + +/* Relocations used by VAX ELF. */ + BFD_RELOC_VAX_GLOB_DAT, + BFD_RELOC_VAX_JMP_SLOT, + BFD_RELOC_VAX_RELATIVE, + +/* msp430 specific relocation codes */ + BFD_RELOC_MSP430_10_PCREL, + BFD_RELOC_MSP430_16_PCREL, + BFD_RELOC_MSP430_16, + BFD_RELOC_MSP430_16_PCREL_BYTE, + BFD_RELOC_MSP430_16_BYTE, + BFD_RELOC_MSP430_2X_PCREL, + BFD_RELOC_MSP430_RL_PCREL, + +/* IQ2000 Relocations. */ + BFD_RELOC_IQ2000_OFFSET_16, + BFD_RELOC_IQ2000_OFFSET_21, + BFD_RELOC_IQ2000_UHI16, + +/* Special Xtensa relocation used only by PLT entries in ELF shared +objects to indicate that the runtime linker should set the value +to one of its own internal functions or data structures. */ + BFD_RELOC_XTENSA_RTLD, + +/* Xtensa relocations for ELF shared objects. */ + BFD_RELOC_XTENSA_GLOB_DAT, + BFD_RELOC_XTENSA_JMP_SLOT, + BFD_RELOC_XTENSA_RELATIVE, + +/* Xtensa relocation used in ELF object files for symbols that may require +PLT entries. Otherwise, this is just a generic 32-bit relocation. */ + BFD_RELOC_XTENSA_PLT, + +/* Xtensa relocations to mark the difference of two local symbols. +These are only needed to support linker relaxation and can be ignored +when not relaxing. The field is set to the value of the difference +assuming no relaxation. The relocation encodes the position of the +first symbol so the linker can determine whether to adjust the field +value. */ + BFD_RELOC_XTENSA_DIFF8, + BFD_RELOC_XTENSA_DIFF16, + BFD_RELOC_XTENSA_DIFF32, + +/* Generic Xtensa relocations for instruction operands. Only the slot +number is encoded in the relocation. The relocation applies to the +last PC-relative immediate operand, or if there are no PC-relative +immediates, to the last immediate operand. */ + BFD_RELOC_XTENSA_SLOT0_OP, + BFD_RELOC_XTENSA_SLOT1_OP, + BFD_RELOC_XTENSA_SLOT2_OP, + BFD_RELOC_XTENSA_SLOT3_OP, + BFD_RELOC_XTENSA_SLOT4_OP, + BFD_RELOC_XTENSA_SLOT5_OP, + BFD_RELOC_XTENSA_SLOT6_OP, + BFD_RELOC_XTENSA_SLOT7_OP, + BFD_RELOC_XTENSA_SLOT8_OP, + BFD_RELOC_XTENSA_SLOT9_OP, + BFD_RELOC_XTENSA_SLOT10_OP, + BFD_RELOC_XTENSA_SLOT11_OP, + BFD_RELOC_XTENSA_SLOT12_OP, + BFD_RELOC_XTENSA_SLOT13_OP, + BFD_RELOC_XTENSA_SLOT14_OP, + +/* Alternate Xtensa relocations. Only the slot is encoded in the +relocation. The meaning of these relocations is opcode-specific. */ + BFD_RELOC_XTENSA_SLOT0_ALT, + BFD_RELOC_XTENSA_SLOT1_ALT, + BFD_RELOC_XTENSA_SLOT2_ALT, + BFD_RELOC_XTENSA_SLOT3_ALT, + BFD_RELOC_XTENSA_SLOT4_ALT, + BFD_RELOC_XTENSA_SLOT5_ALT, + BFD_RELOC_XTENSA_SLOT6_ALT, + BFD_RELOC_XTENSA_SLOT7_ALT, + BFD_RELOC_XTENSA_SLOT8_ALT, + BFD_RELOC_XTENSA_SLOT9_ALT, + BFD_RELOC_XTENSA_SLOT10_ALT, + BFD_RELOC_XTENSA_SLOT11_ALT, + BFD_RELOC_XTENSA_SLOT12_ALT, + BFD_RELOC_XTENSA_SLOT13_ALT, + BFD_RELOC_XTENSA_SLOT14_ALT, + +/* Xtensa relocations for backward compatibility. These have all been +replaced by BFD_RELOC_XTENSA_SLOT0_OP. */ + BFD_RELOC_XTENSA_OP0, + BFD_RELOC_XTENSA_OP1, + BFD_RELOC_XTENSA_OP2, + +/* Xtensa relocation to mark that the assembler expanded the +instructions from an original target. The expansion size is +encoded in the reloc size. */ + BFD_RELOC_XTENSA_ASM_EXPAND, + +/* Xtensa relocation to mark that the linker should simplify +assembler-expanded instructions. This is commonly used +internally by the linker after analysis of a +BFD_RELOC_XTENSA_ASM_EXPAND. */ + BFD_RELOC_XTENSA_ASM_SIMPLIFY, + BFD_RELOC_UNUSED }; +typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; +reloc_howto_type *bfd_reloc_type_lookup + (bfd *abfd, bfd_reloc_code_real_type code); + +const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); + +/* Extracted from syms.c. */ + +typedef struct bfd_symbol +{ + /* A pointer to the BFD which owns the symbol. This information + is necessary so that a back end can work out what additional + information (invisible to the application writer) is carried + with the symbol. + + This field is *almost* redundant, since you can use section->owner + instead, except that some symbols point to the global sections + bfd_{abs,com,und}_section. This could be fixed by making + these globals be per-bfd (or per-target-flavor). FIXME. */ + struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ + + /* The text of the symbol. The name is left alone, and not copied; the + application may not alter it. */ + const char *name; + + /* The value of the symbol. This really should be a union of a + numeric value with a pointer, since some flags indicate that + a pointer to another symbol is stored here. */ + symvalue value; + + /* Attributes of a symbol. */ +#define BSF_NO_FLAGS 0x00 + + /* The symbol has local scope; <> in <>. The value + is the offset into the section of the data. */ +#define BSF_LOCAL 0x01 + + /* The symbol has global scope; initialized data in <>. The + value is the offset into the section of the data. */ +#define BSF_GLOBAL 0x02 + + /* The symbol has global scope and is exported. The value is + the offset into the section of the data. */ +#define BSF_EXPORT BSF_GLOBAL /* No real difference. */ + + /* A normal C symbol would be one of: + <>, <>, <> or + <>. */ + + /* The symbol is a debugging record. The value has an arbitrary + meaning, unless BSF_DEBUGGING_RELOC is also set. */ +#define BSF_DEBUGGING 0x08 + + /* The symbol denotes a function entry point. Used in ELF, + perhaps others someday. */ +#define BSF_FUNCTION 0x10 + + /* Used by the linker. */ +#define BSF_KEEP 0x20 +#define BSF_KEEP_G 0x40 + + /* A weak global symbol, overridable without warnings by + a regular global symbol of the same name. */ +#define BSF_WEAK 0x80 + + /* This symbol was created to point to a section, e.g. ELF's + STT_SECTION symbols. */ +#define BSF_SECTION_SYM 0x100 + + /* The symbol used to be a common symbol, but now it is + allocated. */ +#define BSF_OLD_COMMON 0x200 + + /* The default value for common data. */ +#define BFD_FORT_COMM_DEFAULT_VALUE 0 + + /* In some files the type of a symbol sometimes alters its + location in an output file - ie in coff a <> symbol + which is also <> symbol appears where it was + declared and not at the end of a section. This bit is set + by the target BFD part to convey this information. */ +#define BSF_NOT_AT_END 0x400 + + /* Signal that the symbol is the label of constructor section. */ +#define BSF_CONSTRUCTOR 0x800 + + /* Signal that the symbol is a warning symbol. The name is a + warning. The name of the next symbol is the one to warn about; + if a reference is made to a symbol with the same name as the next + symbol, a warning is issued by the linker. */ +#define BSF_WARNING 0x1000 + + /* Signal that the symbol is indirect. This symbol is an indirect + pointer to the symbol with the same name as the next symbol. */ +#define BSF_INDIRECT 0x2000 + + /* BSF_FILE marks symbols that contain a file name. This is used + for ELF STT_FILE symbols. */ +#define BSF_FILE 0x4000 + + /* Symbol is from dynamic linking information. */ +#define BSF_DYNAMIC 0x8000 + + /* The symbol denotes a data object. Used in ELF, and perhaps + others someday. */ +#define BSF_OBJECT 0x10000 + + /* This symbol is a debugging symbol. The value is the offset + into the section of the data. BSF_DEBUGGING should be set + as well. */ +#define BSF_DEBUGGING_RELOC 0x20000 + + /* This symbol is thread local. Used in ELF. */ +#define BSF_THREAD_LOCAL 0x40000 + + flagword flags; + + /* A pointer to the section to which this symbol is + relative. This will always be non NULL, there are special + sections for undefined and absolute symbols. */ + struct bfd_section *section; + + /* Back end special data. */ + union + { + void *p; + bfd_vma i; + } + udata; +} +asymbol; + +#define bfd_get_symtab_upper_bound(abfd) \ + BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) + +bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym); + +bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name); + +#define bfd_is_local_label_name(abfd, name) \ + BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) + +bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); + +#define bfd_is_target_special_symbol(abfd, sym) \ + BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) + +#define bfd_canonicalize_symtab(abfd, location) \ + BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) + +bfd_boolean bfd_set_symtab + (bfd *abfd, asymbol **location, unsigned int count); + +void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); + +#define bfd_make_empty_symbol(abfd) \ + BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) + +asymbol *_bfd_generic_make_empty_symbol (bfd *); + +#define bfd_make_debug_symbol(abfd,ptr,size) \ + BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) + +int bfd_decode_symclass (asymbol *symbol); + +bfd_boolean bfd_is_undefined_symclass (int symclass); + +void bfd_symbol_info (asymbol *symbol, symbol_info *ret); + +bfd_boolean bfd_copy_private_symbol_data + (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); + +#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ + BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ + (ibfd, isymbol, obfd, osymbol)) + +/* Extracted from bfd.c. */ +struct bfd +{ + /* A unique identifier of the BFD */ + unsigned int id; + + /* The filename the application opened the BFD with. */ + const char *filename; + + /* A pointer to the target jump table. */ + const struct bfd_target *xvec; + + /* The IOSTREAM, and corresponding IO vector that provide access + to the file backing the BFD. */ + void *iostream; + const struct bfd_iovec *iovec; + + /* Is the file descriptor being cached? That is, can it be closed as + needed, and re-opened when accessed later? */ + bfd_boolean cacheable; + + /* Marks whether there was a default target specified when the + BFD was opened. This is used to select which matching algorithm + to use to choose the back end. */ + bfd_boolean target_defaulted; + + /* The caching routines use these to maintain a + least-recently-used list of BFDs. */ + struct bfd *lru_prev, *lru_next; + + /* When a file is closed by the caching routines, BFD retains + state information on the file here... */ + ufile_ptr where; + + /* ... and here: (``once'' means at least once). */ + bfd_boolean opened_once; + + /* Set if we have a locally maintained mtime value, rather than + getting it from the file each time. */ + bfd_boolean mtime_set; + + /* File modified time, if mtime_set is TRUE. */ + long mtime; + + /* Reserved for an unimplemented file locking extension. */ + int ifd; + + /* The format which belongs to the BFD. (object, core, etc.) */ + bfd_format format; + + /* The direction with which the BFD was opened. */ + enum bfd_direction + { + no_direction = 0, + read_direction = 1, + write_direction = 2, + both_direction = 3 + } + direction; + + /* Format_specific flags. */ + flagword flags; + + /* Currently my_archive is tested before adding origin to + anything. I believe that this can become always an add of + origin, with origin set to 0 for non archive files. */ + ufile_ptr origin; + + /* Remember when output has begun, to stop strange things + from happening. */ + bfd_boolean output_has_begun; + + /* A hash table for section names. */ + struct bfd_hash_table section_htab; + + /* Pointer to linked list of sections. */ + struct bfd_section *sections; + + /* The place where we add to the section list. */ + struct bfd_section **section_tail; + + /* The number of sections. */ + unsigned int section_count; + + /* Stuff only useful for object files: + The start address. */ + bfd_vma start_address; + + /* Used for input and output. */ + unsigned int symcount; + + /* Symbol table for output BFD (with symcount entries). */ + struct bfd_symbol **outsymbols; + + /* Used for slurped dynamic symbol tables. */ + unsigned int dynsymcount; + + /* Pointer to structure which contains architecture information. */ + const struct bfd_arch_info *arch_info; + + /* Flag set if symbols from this BFD should not be exported. */ + bfd_boolean no_export; + + /* Stuff only useful for archives. */ + void *arelt_data; + struct bfd *my_archive; /* The containing archive BFD. */ + struct bfd *next; /* The next BFD in the archive. */ + struct bfd *archive_head; /* The first BFD in the archive. */ + bfd_boolean has_armap; + + /* A chain of BFD structures involved in a link. */ + struct bfd *link_next; + + /* A field used by _bfd_generic_link_add_archive_symbols. This will + be used only for archive elements. */ + int archive_pass; + + /* Used by the back end to hold private data. */ + union + { + struct aout_data_struct *aout_data; + struct artdata *aout_ar_data; + struct _oasys_data *oasys_obj_data; + struct _oasys_ar_data *oasys_ar_data; + struct coff_tdata *coff_obj_data; + struct pe_tdata *pe_obj_data; + struct xcoff_tdata *xcoff_obj_data; + struct ecoff_tdata *ecoff_obj_data; + struct ieee_data_struct *ieee_data; + struct ieee_ar_data_struct *ieee_ar_data; + struct srec_data_struct *srec_data; + struct ihex_data_struct *ihex_data; + struct tekhex_data_struct *tekhex_data; + struct elf_obj_tdata *elf_obj_data; + struct nlm_obj_tdata *nlm_obj_data; + struct bout_data_struct *bout_data; + struct mmo_data_struct *mmo_data; + struct sun_core_struct *sun_core_data; + struct sco5_core_struct *sco5_core_data; + struct trad_core_struct *trad_core_data; + struct som_data_struct *som_data; + struct hpux_core_struct *hpux_core_data; + struct hppabsd_core_struct *hppabsd_core_data; + struct sgi_core_struct *sgi_core_data; + struct lynx_core_struct *lynx_core_data; + struct osf_core_struct *osf_core_data; + struct cisco_core_struct *cisco_core_data; + struct versados_data_struct *versados_data; + struct netbsd_core_struct *netbsd_core_data; + struct mach_o_data_struct *mach_o_data; + struct mach_o_fat_data_struct *mach_o_fat_data; + struct bfd_pef_data_struct *pef_data; + struct bfd_pef_xlib_data_struct *pef_xlib_data; + struct bfd_sym_data_struct *sym_data; + void *any; + } + tdata; + + /* Used by the application to hold private data. */ + void *usrdata; + + /* Where all the allocated stuff under this BFD goes. This is a + struct objalloc *, but we use void * to avoid requiring the inclusion + of objalloc.h. */ + void *memory; +}; + +typedef enum bfd_error +{ + bfd_error_no_error = 0, + bfd_error_system_call, + bfd_error_invalid_target, + bfd_error_wrong_format, + bfd_error_wrong_object_format, + bfd_error_invalid_operation, + bfd_error_no_memory, + bfd_error_no_symbols, + bfd_error_no_armap, + bfd_error_no_more_archived_files, + bfd_error_malformed_archive, + bfd_error_file_not_recognized, + bfd_error_file_ambiguously_recognized, + bfd_error_no_contents, + bfd_error_nonrepresentable_section, + bfd_error_no_debug_section, + bfd_error_bad_value, + bfd_error_file_truncated, + bfd_error_file_too_big, + bfd_error_invalid_error_code +} +bfd_error_type; + +bfd_error_type bfd_get_error (void); + +void bfd_set_error (bfd_error_type error_tag); + +const char *bfd_errmsg (bfd_error_type error_tag); + +void bfd_perror (const char *message); + +typedef void (*bfd_error_handler_type) (const char *, ...); + +bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); + +void bfd_set_error_program_name (const char *); + +bfd_error_handler_type bfd_get_error_handler (void); + +long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect); + +long bfd_canonicalize_reloc + (bfd *abfd, asection *sec, arelent **loc, asymbol **syms); + +void bfd_set_reloc + (bfd *abfd, asection *sec, arelent **rel, unsigned int count); + +bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags); + +int bfd_get_arch_size (bfd *abfd); + +int bfd_get_sign_extend_vma (bfd *abfd); + +bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma); + +unsigned int bfd_get_gp_size (bfd *abfd); + +void bfd_set_gp_size (bfd *abfd, unsigned int i); + +bfd_vma bfd_scan_vma (const char *string, const char **end, int base); + +bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd); + +#define bfd_copy_private_header_data(ibfd, obfd) \ + BFD_SEND (obfd, _bfd_copy_private_header_data, \ + (ibfd, obfd)) +bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd); + +#define bfd_copy_private_bfd_data(ibfd, obfd) \ + BFD_SEND (obfd, _bfd_copy_private_bfd_data, \ + (ibfd, obfd)) +bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd); + +#define bfd_merge_private_bfd_data(ibfd, obfd) \ + BFD_SEND (obfd, _bfd_merge_private_bfd_data, \ + (ibfd, obfd)) +bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); + +#define bfd_set_private_flags(abfd, flags) \ + BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags)) +#define bfd_sizeof_headers(abfd, reloc) \ + BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) + +#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ + BFD_SEND (abfd, _bfd_find_nearest_line, \ + (abfd, sec, syms, off, file, func, line)) + +#define bfd_debug_info_start(abfd) \ + BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) + +#define bfd_debug_info_end(abfd) \ + BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) + +#define bfd_debug_info_accumulate(abfd, section) \ + BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) + +#define bfd_stat_arch_elt(abfd, stat) \ + BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) + +#define bfd_update_armap_timestamp(abfd) \ + BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) + +#define bfd_set_arch_mach(abfd, arch, mach)\ + BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) + +#define bfd_relax_section(abfd, section, link_info, again) \ + BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) + +#define bfd_gc_sections(abfd, link_info) \ + BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) + +#define bfd_merge_sections(abfd, link_info) \ + BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) + +#define bfd_is_group_section(abfd, sec) \ + BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec)) + +#define bfd_discard_group(abfd, sec) \ + BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) + +#define bfd_link_hash_table_create(abfd) \ + BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) + +#define bfd_link_hash_table_free(abfd, hash) \ + BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) + +#define bfd_link_add_symbols(abfd, info) \ + BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) + +#define bfd_link_just_syms(sec, info) \ + BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) + +#define bfd_final_link(abfd, info) \ + BFD_SEND (abfd, _bfd_final_link, (abfd, info)) + +#define bfd_free_cached_info(abfd) \ + BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) + +#define bfd_get_dynamic_symtab_upper_bound(abfd) \ + BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) + +#define bfd_print_private_bfd_data(abfd, file)\ + BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) + +#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ + BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) + +#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ + BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ + dyncount, dynsyms, ret)) + +#define bfd_get_dynamic_reloc_upper_bound(abfd) \ + BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) + +#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ + BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) + +extern bfd_byte *bfd_get_relocated_section_contents + (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, + bfd_boolean, asymbol **); + +bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative); + +struct bfd_preserve +{ + void *marker; + void *tdata; + flagword flags; + const struct bfd_arch_info *arch_info; + struct bfd_section *sections; + struct bfd_section **section_tail; + unsigned int section_count; + struct bfd_hash_table section_htab; +}; + +bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *); + +void bfd_preserve_restore (bfd *, struct bfd_preserve *); + +void bfd_preserve_finish (bfd *, struct bfd_preserve *); + +/* Extracted from archive.c. */ +symindex bfd_get_next_mapent + (bfd *abfd, symindex previous, carsym **sym); + +bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); + +bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); + +/* Extracted from corefile.c. */ +const char *bfd_core_file_failing_command (bfd *abfd); + +int bfd_core_file_failing_signal (bfd *abfd); + +bfd_boolean core_file_matches_executable_p + (bfd *core_bfd, bfd *exec_bfd); + +/* Extracted from targets.c. */ +#define BFD_SEND(bfd, message, arglist) \ + ((*((bfd)->xvec->message)) arglist) + +#ifdef DEBUG_BFD_SEND +#undef BFD_SEND +#define BFD_SEND(bfd, message, arglist) \ + (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ + ((*((bfd)->xvec->message)) arglist) : \ + (bfd_assert (__FILE__,__LINE__), NULL)) +#endif +#define BFD_SEND_FMT(bfd, message, arglist) \ + (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) + +#ifdef DEBUG_BFD_SEND +#undef BFD_SEND_FMT +#define BFD_SEND_FMT(bfd, message, arglist) \ + (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ + (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \ + (bfd_assert (__FILE__,__LINE__), NULL)) +#endif + +enum bfd_flavour +{ + bfd_target_unknown_flavour, + bfd_target_aout_flavour, + bfd_target_coff_flavour, + bfd_target_ecoff_flavour, + bfd_target_xcoff_flavour, + bfd_target_elf_flavour, + bfd_target_ieee_flavour, + bfd_target_nlm_flavour, + bfd_target_oasys_flavour, + bfd_target_tekhex_flavour, + bfd_target_srec_flavour, + bfd_target_ihex_flavour, + bfd_target_som_flavour, + bfd_target_os9k_flavour, + bfd_target_versados_flavour, + bfd_target_msdos_flavour, + bfd_target_ovax_flavour, + bfd_target_evax_flavour, + bfd_target_mmo_flavour, + bfd_target_mach_o_flavour, + bfd_target_pef_flavour, + bfd_target_pef_xlib_flavour, + bfd_target_sym_flavour +}; + +enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; + +/* Forward declaration. */ +typedef struct bfd_link_info _bfd_link_info; + +typedef struct bfd_target +{ + /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */ + char *name; + + /* The "flavour" of a back end is a general indication about + the contents of a file. */ + enum bfd_flavour flavour; + + /* The order of bytes within the data area of a file. */ + enum bfd_endian byteorder; + + /* The order of bytes within the header parts of a file. */ + enum bfd_endian header_byteorder; + + /* A mask of all the flags which an executable may have set - + from the set <>, <>, ...<>. */ + flagword object_flags; + + /* A mask of all the flags which a section may have set - from + the set <>, <>, ...<>. */ + flagword section_flags; + + /* The character normally found at the front of a symbol. + (if any), perhaps `_'. */ + char symbol_leading_char; + + /* The pad character for file names within an archive header. */ + char ar_pad_char; + + /* The maximum number of characters in an archive header. */ + unsigned short ar_max_namelen; + + /* Entries for byte swapping for data. These are different from the + other entry points, since they don't take a BFD asthe first argument. + Certain other handlers could do the same. */ + bfd_uint64_t (*bfd_getx64) (const void *); + bfd_int64_t (*bfd_getx_signed_64) (const void *); + void (*bfd_putx64) (bfd_uint64_t, void *); + bfd_vma (*bfd_getx32) (const void *); + bfd_signed_vma (*bfd_getx_signed_32) (const void *); + void (*bfd_putx32) (bfd_vma, void *); + bfd_vma (*bfd_getx16) (const void *); + bfd_signed_vma (*bfd_getx_signed_16) (const void *); + void (*bfd_putx16) (bfd_vma, void *); + + /* Byte swapping for the headers. */ + bfd_uint64_t (*bfd_h_getx64) (const void *); + bfd_int64_t (*bfd_h_getx_signed_64) (const void *); + void (*bfd_h_putx64) (bfd_uint64_t, void *); + bfd_vma (*bfd_h_getx32) (const void *); + bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); + void (*bfd_h_putx32) (bfd_vma, void *); + bfd_vma (*bfd_h_getx16) (const void *); + bfd_signed_vma (*bfd_h_getx_signed_16) (const void *); + void (*bfd_h_putx16) (bfd_vma, void *); + + /* Format dependent routines: these are vectors of entry points + within the target vector structure, one for each format to check. */ + + /* Check the format of a file being read. Return a <> or zero. */ + const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *); + + /* Set the format of a file being written. */ + bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *); + + /* Write cached information into a file being written, at <>. */ + bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *); + + + /* Generic entry points. */ +#define BFD_JUMP_TABLE_GENERIC(NAME) \ + NAME##_close_and_cleanup, \ + NAME##_bfd_free_cached_info, \ + NAME##_new_section_hook, \ + NAME##_get_section_contents, \ + NAME##_get_section_contents_in_window + + /* Called when the BFD is being closed to do any necessary cleanup. */ + bfd_boolean (*_close_and_cleanup) (bfd *); + /* Ask the BFD to free all cached information. */ + bfd_boolean (*_bfd_free_cached_info) (bfd *); + /* Called when a new section is created. */ + bfd_boolean (*_new_section_hook) (bfd *, sec_ptr); + /* Read the contents of a section. */ + bfd_boolean (*_bfd_get_section_contents) + (bfd *, sec_ptr, void *, file_ptr, bfd_size_type); + bfd_boolean (*_bfd_get_section_contents_in_window) + (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type); + + /* Entry points to copy private data. */ +#define BFD_JUMP_TABLE_COPY(NAME) \ + NAME##_bfd_copy_private_bfd_data, \ + NAME##_bfd_merge_private_bfd_data, \ + NAME##_bfd_copy_private_section_data, \ + NAME##_bfd_copy_private_symbol_data, \ + NAME##_bfd_copy_private_header_data, \ + NAME##_bfd_set_private_flags, \ + NAME##_bfd_print_private_bfd_data + + /* Called to copy BFD general private data from one object file + to another. */ + bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *); + /* Called to merge BFD general private data from one object file + to a common output file when linking. */ + bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); + /* Called to copy BFD private section data from one object file + to another. */ + bfd_boolean (*_bfd_copy_private_section_data) + (bfd *, sec_ptr, bfd *, sec_ptr); + /* Called to copy BFD private symbol data from one symbol + to another. */ + bfd_boolean (*_bfd_copy_private_symbol_data) + (bfd *, asymbol *, bfd *, asymbol *); + /* Called to copy BFD private header data from one object file + to another. */ + bfd_boolean (*_bfd_copy_private_header_data) + (bfd *, bfd *); + /* Called to set private backend flags. */ + bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword); + + /* Called to print private BFD data. */ + bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *); + + /* Core file entry points. */ +#define BFD_JUMP_TABLE_CORE(NAME) \ + NAME##_core_file_failing_command, \ + NAME##_core_file_failing_signal, \ + NAME##_core_file_matches_executable_p + + char * (*_core_file_failing_command) (bfd *); + int (*_core_file_failing_signal) (bfd *); + bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *); + + /* Archive entry points. */ +#define BFD_JUMP_TABLE_ARCHIVE(NAME) \ + NAME##_slurp_armap, \ + NAME##_slurp_extended_name_table, \ + NAME##_construct_extended_name_table, \ + NAME##_truncate_arname, \ + NAME##_write_armap, \ + NAME##_read_ar_hdr, \ + NAME##_openr_next_archived_file, \ + NAME##_get_elt_at_index, \ + NAME##_generic_stat_arch_elt, \ + NAME##_update_armap_timestamp + + bfd_boolean (*_bfd_slurp_armap) (bfd *); + bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *); + bfd_boolean (*_bfd_construct_extended_name_table) + (bfd *, char **, bfd_size_type *, const char **); + void (*_bfd_truncate_arname) (bfd *, const char *, char *); + bfd_boolean (*write_armap) + (bfd *, unsigned int, struct orl *, unsigned int, int); + void * (*_bfd_read_ar_hdr_fn) (bfd *); + bfd * (*openr_next_archived_file) (bfd *, bfd *); +#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i)) + bfd * (*_bfd_get_elt_at_index) (bfd *, symindex); + int (*_bfd_stat_arch_elt) (bfd *, struct stat *); + bfd_boolean (*_bfd_update_armap_timestamp) (bfd *); + + /* Entry points used for symbols. */ +#define BFD_JUMP_TABLE_SYMBOLS(NAME) \ + NAME##_get_symtab_upper_bound, \ + NAME##_canonicalize_symtab, \ + NAME##_make_empty_symbol, \ + NAME##_print_symbol, \ + NAME##_get_symbol_info, \ + NAME##_bfd_is_local_label_name, \ + NAME##_bfd_is_target_special_symbol, \ + NAME##_get_lineno, \ + NAME##_find_nearest_line, \ + NAME##_bfd_make_debug_symbol, \ + NAME##_read_minisymbols, \ + NAME##_minisymbol_to_symbol + + long (*_bfd_get_symtab_upper_bound) (bfd *); + long (*_bfd_canonicalize_symtab) + (bfd *, struct bfd_symbol **); + struct bfd_symbol * + (*_bfd_make_empty_symbol) (bfd *); + void (*_bfd_print_symbol) + (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type); +#define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e)) + void (*_bfd_get_symbol_info) + (bfd *, struct bfd_symbol *, symbol_info *); +#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e)) + bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *); + bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *); + alent * (*_get_lineno) (bfd *, struct bfd_symbol *); + bfd_boolean (*_bfd_find_nearest_line) + (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, + const char **, const char **, unsigned int *); + /* Back-door to allow format-aware applications to create debug symbols + while using BFD for everything else. Currently used by the assembler + when creating COFF files. */ + asymbol * (*_bfd_make_debug_symbol) + (bfd *, void *, unsigned long size); +#define bfd_read_minisymbols(b, d, m, s) \ + BFD_SEND (b, _read_minisymbols, (b, d, m, s)) + long (*_read_minisymbols) + (bfd *, bfd_boolean, void **, unsigned int *); +#define bfd_minisymbol_to_symbol(b, d, m, f) \ + BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) + asymbol * (*_minisymbol_to_symbol) + (bfd *, bfd_boolean, const void *, asymbol *); + + /* Routines for relocs. */ +#define BFD_JUMP_TABLE_RELOCS(NAME) \ + NAME##_get_reloc_upper_bound, \ + NAME##_canonicalize_reloc, \ + NAME##_bfd_reloc_type_lookup + + long (*_get_reloc_upper_bound) (bfd *, sec_ptr); + long (*_bfd_canonicalize_reloc) + (bfd *, sec_ptr, arelent **, struct bfd_symbol **); + /* See documentation on reloc types. */ + reloc_howto_type * + (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type); + + /* Routines used when writing an object file. */ +#define BFD_JUMP_TABLE_WRITE(NAME) \ + NAME##_set_arch_mach, \ + NAME##_set_section_contents + + bfd_boolean (*_bfd_set_arch_mach) + (bfd *, enum bfd_architecture, unsigned long); + bfd_boolean (*_bfd_set_section_contents) + (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); + + /* Routines used by the linker. */ +#define BFD_JUMP_TABLE_LINK(NAME) \ + NAME##_sizeof_headers, \ + NAME##_bfd_get_relocated_section_contents, \ + NAME##_bfd_relax_section, \ + NAME##_bfd_link_hash_table_create, \ + NAME##_bfd_link_hash_table_free, \ + NAME##_bfd_link_add_symbols, \ + NAME##_bfd_link_just_syms, \ + NAME##_bfd_final_link, \ + NAME##_bfd_link_split_section, \ + NAME##_bfd_gc_sections, \ + NAME##_bfd_merge_sections, \ + NAME##_bfd_is_group_section, \ + NAME##_bfd_discard_group, \ + NAME##_section_already_linked \ + + int (*_bfd_sizeof_headers) (bfd *, bfd_boolean); + bfd_byte * (*_bfd_get_relocated_section_contents) + (bfd *, struct bfd_link_info *, struct bfd_link_order *, + bfd_byte *, bfd_boolean, struct bfd_symbol **); + + bfd_boolean (*_bfd_relax_section) + (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *); + + /* Create a hash table for the linker. Different backends store + different information in this table. */ + struct bfd_link_hash_table * + (*_bfd_link_hash_table_create) (bfd *); + + /* Release the memory associated with the linker hash table. */ + void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *); + + /* Add symbols from this object file into the hash table. */ + bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *); + + /* Indicate that we are only retrieving symbol values from this section. */ + void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); + + /* Do a link based on the link_order structures attached to each + section of the BFD. */ + bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *); + + /* Should this section be split up into smaller pieces during linking. */ + bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *); + + /* Remove sections that are not referenced from the output. */ + bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); + + /* Attempt to merge SEC_MERGE sections. */ + bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); + + /* Is this section a member of a group? */ + bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *); + + /* Discard members of a group. */ + bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); + + /* Check if SEC has been already linked during a reloceatable or + final link. */ + void (*_section_already_linked) (bfd *, struct bfd_section *); + + /* Routines to handle dynamic symbols and relocs. */ +#define BFD_JUMP_TABLE_DYNAMIC(NAME) \ + NAME##_get_dynamic_symtab_upper_bound, \ + NAME##_canonicalize_dynamic_symtab, \ + NAME##_get_synthetic_symtab, \ + NAME##_get_dynamic_reloc_upper_bound, \ + NAME##_canonicalize_dynamic_reloc + + /* Get the amount of memory required to hold the dynamic symbols. */ + long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *); + /* Read in the dynamic symbols. */ + long (*_bfd_canonicalize_dynamic_symtab) + (bfd *, struct bfd_symbol **); + /* Create synthetized symbols. */ + long (*_bfd_get_synthetic_symtab) + (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, + struct bfd_symbol **); + /* Get the amount of memory required to hold the dynamic relocs. */ + long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); + /* Read in the dynamic relocs. */ + long (*_bfd_canonicalize_dynamic_reloc) + (bfd *, arelent **, struct bfd_symbol **); + + /* Opposite endian version of this target. */ + const struct bfd_target * alternative_target; + + /* Data for use by back-end routines, which isn't + generic enough to belong in this structure. */ + const void *backend_data; + +} bfd_target; + +bfd_boolean bfd_set_default_target (const char *name); + +const bfd_target *bfd_find_target (const char *target_name, bfd *abfd); + +const char ** bfd_target_list (void); + +const bfd_target *bfd_search_for_target + (int (*search_func) (const bfd_target *, void *), + void *); + +/* Extracted from format.c. */ +bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); + +bfd_boolean bfd_check_format_matches + (bfd *abfd, bfd_format format, char ***matching); + +bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); + +const char *bfd_format_string (bfd_format format); + +/* Extracted from linker.c. */ +bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); + +#define bfd_link_split_section(abfd, sec) \ + BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) + +void bfd_section_already_linked (bfd *abfd, asection *sec); + +#define bfd_section_already_linked(abfd, sec) \ + BFD_SEND (abfd, _section_already_linked, (abfd, sec)) + +/* Extracted from simple.c. */ +bfd_byte *bfd_simple_get_relocated_section_contents + (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/bin/gdb/bfd/config-x86_64/bfd.h b/src/bin/gdb/bfd/config-x86_64/bfd.h new file mode 100644 index 0000000000..ba10b2889f --- /dev/null +++ b/src/bin/gdb/bfd/config-x86_64/bfd.h @@ -0,0 +1,4645 @@ +/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically + generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c", + "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c", + "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c", + "linker.c" and "simple.c". + Run "make headers" in your build bfd/ to regenerate. */ + +/* Main header file for the bfd library -- portable access to object files. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + Contributed by Cygnus Support. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef __BFD_H_SEEN__ +#define __BFD_H_SEEN__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ansidecl.h" +#include "symcat.h" +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#ifndef SABER +/* This hack is to avoid a problem with some strict ANSI C preprocessors. + The problem is, "32_" is not a valid preprocessing token, and we don't + want extra underscores (e.g., "nlm_32_"). The XCONCAT2 macro will + cause the inner CONCAT2 macros to be evaluated first, producing + still-valid pp-tokens. Then the final concatenation can be done. */ +#undef CONCAT4 +#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d)) +#endif +#endif + +/* The word size used by BFD on the host. This may be 64 with a 32 + bit target if the host is 64 bit, or if other 64 bit targets have + been selected with --enable-targets, or if --enable-64-bit-bfd. */ +#define BFD_ARCH_SIZE 64 + +/* The word size of the default bfd target. */ +#define BFD_DEFAULT_TARGET_SIZE 64 + +#define BFD_HOST_64BIT_LONG 1 +#define BFD_HOST_LONG_LONG 1 +#define BFD_HOST_64_BIT long +#define BFD_HOST_U_64_BIT unsigned long +typedef BFD_HOST_64_BIT bfd_int64_t; +typedef BFD_HOST_U_64_BIT bfd_uint64_t; + +#if BFD_ARCH_SIZE >= 64 +#define BFD64 +#endif + +#ifndef INLINE +#if __GNUC__ >= 2 +#define INLINE __inline__ +#else +#define INLINE +#endif +#endif + +/* Forward declaration. */ +typedef struct bfd bfd; + +/* Boolean type used in bfd. Too many systems define their own + versions of "boolean" for us to safely typedef a "boolean" of + our own. Using an enum for "bfd_boolean" has its own set of + problems, with strange looking casts required to avoid warnings + on some older compilers. Thus we just use an int. + + General rule: Functions which are bfd_boolean return TRUE on + success and FALSE on failure (unless they're a predicate). */ + +typedef int bfd_boolean; +#undef FALSE +#undef TRUE +#define FALSE 0 +#define TRUE 1 + +#if 0 +/* Poison. */ +#undef false +#undef true +#define false dont_use_false_in_bfd +#define true dont_use_true_in_bfd +#endif + +#ifdef BFD64 + +#ifndef BFD_HOST_64_BIT + #error No 64 bit integer type available +#endif /* ! defined (BFD_HOST_64_BIT) */ + +typedef BFD_HOST_U_64_BIT bfd_vma; +typedef BFD_HOST_64_BIT bfd_signed_vma; +typedef BFD_HOST_U_64_BIT bfd_size_type; +typedef BFD_HOST_U_64_BIT symvalue; + +#ifndef fprintf_vma +#if BFD_HOST_64BIT_LONG +#define sprintf_vma(s,x) sprintf (s, "%016lx", x) +#define fprintf_vma(f,x) fprintf (f, "%016lx", x) +#else +#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) +#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) +#define fprintf_vma(s,x) \ + fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) +#define sprintf_vma(s,x) \ + sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) +#endif +#endif + +#else /* not BFD64 */ + +/* Represent a target address. Also used as a generic unsigned type + which is guaranteed to be big enough to hold any arithmetic types + we need to deal with. */ +typedef unsigned long bfd_vma; + +/* A generic signed type which is guaranteed to be big enough to hold any + arithmetic types we need to deal with. Can be assumed to be compatible + with bfd_vma in the same way that signed and unsigned ints are compatible + (as parameters, in assignment, etc). */ +typedef long bfd_signed_vma; + +typedef unsigned long symvalue; +typedef unsigned long bfd_size_type; + +/* Print a bfd_vma x on stream s. */ +#define fprintf_vma(s,x) fprintf (s, "%08lx", x) +#define sprintf_vma(s,x) sprintf (s, "%08lx", x) + +#endif /* not BFD64 */ + +#ifndef BFD_HOST_64_BIT +/* Fall back on a 32 bit type. The idea is to make these types always + available for function return types, but in the case that + BFD_HOST_64_BIT is undefined such a function should abort or + otherwise signal an error. */ +typedef bfd_signed_vma bfd_int64_t; +typedef bfd_vma bfd_uint64_t; +#endif + +/* An offset into a file. BFD always uses the largest possible offset + based on the build time availability of fseek, fseeko, or fseeko64. */ +typedef BFD_HOST_64_BIT file_ptr; +typedef unsigned BFD_HOST_64_BIT ufile_ptr; + +extern void bfd_sprintf_vma (bfd *, char *, bfd_vma); +extern void bfd_fprintf_vma (bfd *, void *, bfd_vma); + +#define printf_vma(x) fprintf_vma(stdout,x) +#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x) + +typedef unsigned int flagword; /* 32 bits of flags */ +typedef unsigned char bfd_byte; + +/* File formats. */ + +typedef enum bfd_format +{ + bfd_unknown = 0, /* File format is unknown. */ + bfd_object, /* Linker/assembler/compiler output. */ + bfd_archive, /* Object archive file. */ + bfd_core, /* Core dump. */ + bfd_type_end /* Marks the end; don't use it! */ +} +bfd_format; + +/* Values that may appear in the flags field of a BFD. These also + appear in the object_flags field of the bfd_target structure, where + they indicate the set of flags used by that backend (not all flags + are meaningful for all object file formats) (FIXME: at the moment, + the object_flags values have mostly just been copied from backend + to another, and are not necessarily correct). */ + +/* No flags. */ +#define BFD_NO_FLAGS 0x00 + +/* BFD contains relocation entries. */ +#define HAS_RELOC 0x01 + +/* BFD is directly executable. */ +#define EXEC_P 0x02 + +/* BFD has line number information (basically used for F_LNNO in a + COFF header). */ +#define HAS_LINENO 0x04 + +/* BFD has debugging information. */ +#define HAS_DEBUG 0x08 + +/* BFD has symbols. */ +#define HAS_SYMS 0x10 + +/* BFD has local symbols (basically used for F_LSYMS in a COFF + header). */ +#define HAS_LOCALS 0x20 + +/* BFD is a dynamic object. */ +#define DYNAMIC 0x40 + +/* Text section is write protected (if D_PAGED is not set, this is + like an a.out NMAGIC file) (the linker sets this by default, but + clears it for -r or -N). */ +#define WP_TEXT 0x80 + +/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the + linker sets this by default, but clears it for -r or -n or -N). */ +#define D_PAGED 0x100 + +/* BFD is relaxable (this means that bfd_relax_section may be able to + do something) (sometimes bfd_relax_section can do something even if + this is not set). */ +#define BFD_IS_RELAXABLE 0x200 + +/* This may be set before writing out a BFD to request using a + traditional format. For example, this is used to request that when + writing out an a.out object the symbols not be hashed to eliminate + duplicates. */ +#define BFD_TRADITIONAL_FORMAT 0x400 + +/* This flag indicates that the BFD contents are actually cached in + memory. If this is set, iostream points to a bfd_in_memory struct. */ +#define BFD_IN_MEMORY 0x800 + +/* The sections in this BFD specify a memory page. */ +#define HAS_LOAD_PAGE 0x1000 + +/* Symbols and relocation. */ + +/* A count of carsyms (canonical archive symbols). */ +typedef unsigned long symindex; + +/* How to perform a relocation. */ +typedef const struct reloc_howto_struct reloc_howto_type; + +#define BFD_NO_MORE_SYMBOLS ((symindex) ~0) + +/* General purpose part of a symbol X; + target specific parts are in libcoff.h, libaout.h, etc. */ + +#define bfd_get_section(x) ((x)->section) +#define bfd_get_output_section(x) ((x)->section->output_section) +#define bfd_set_section(x,y) ((x)->section) = (y) +#define bfd_asymbol_base(x) ((x)->section->vma) +#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value) +#define bfd_asymbol_name(x) ((x)->name) +/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ +#define bfd_asymbol_bfd(x) ((x)->the_bfd) +#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour) + +/* A canonical archive symbol. */ +/* This is a type pun with struct ranlib on purpose! */ +typedef struct carsym +{ + char *name; + file_ptr file_offset; /* Look here to find the file. */ +} +carsym; /* To make these you call a carsymogen. */ + +/* Used in generating armaps (archive tables of contents). + Perhaps just a forward definition would do? */ +struct orl /* Output ranlib. */ +{ + char **name; /* Symbol name. */ + union + { + file_ptr pos; + bfd *abfd; + } u; /* bfd* or file position. */ + int namidx; /* Index into string table. */ +}; + +/* Linenumber stuff. */ +typedef struct lineno_cache_entry +{ + unsigned int line_number; /* Linenumber from start of function. */ + union + { + struct bfd_symbol *sym; /* Function name. */ + bfd_vma offset; /* Offset into section. */ + } u; +} +alent; + +/* Object and core file sections. */ + +#define align_power(addr, align) \ + (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align))) + +typedef struct bfd_section *sec_ptr; + +#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0) +#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0) +#define bfd_get_section_lma(bfd, ptr) ((ptr)->lma + 0) +#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0) +#define bfd_section_name(bfd, ptr) ((ptr)->name) +#define bfd_section_size(bfd, ptr) ((ptr)->size) +#define bfd_get_section_size(ptr) ((ptr)->size) +#define bfd_section_vma(bfd, ptr) ((ptr)->vma) +#define bfd_section_lma(bfd, ptr) ((ptr)->lma) +#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power) +#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0) +#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata) + +#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) + +#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) +#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) +#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) +/* Find the address one past the end of SEC. */ +#define bfd_get_section_limit(bfd, sec) \ + (((sec)->rawsize ? (sec)->rawsize : (sec)->size) \ + / bfd_octets_per_byte (bfd)) + +typedef struct stat stat_type; + +typedef enum bfd_print_symbol +{ + bfd_print_symbol_name, + bfd_print_symbol_more, + bfd_print_symbol_all +} bfd_print_symbol_type; + +/* Information about a symbol that nm needs. */ + +typedef struct _symbol_info +{ + symvalue value; + char type; + const char *name; /* Symbol name. */ + unsigned char stab_type; /* Stab type. */ + char stab_other; /* Stab other. */ + short stab_desc; /* Stab desc. */ + const char *stab_name; /* String for stab type. */ +} symbol_info; + +/* Get the name of a stabs type code. */ + +extern const char *bfd_get_stab_name (int); + +/* Hash table routines. There is no way to free up a hash table. */ + +/* An element in the hash table. Most uses will actually use a larger + structure, and an instance of this will be the first field. */ + +struct bfd_hash_entry +{ + /* Next entry for this hash code. */ + struct bfd_hash_entry *next; + /* String being hashed. */ + const char *string; + /* Hash code. This is the full hash code, not the index into the + table. */ + unsigned long hash; +}; + +/* A hash table. */ + +struct bfd_hash_table +{ + /* The hash array. */ + struct bfd_hash_entry **table; + /* The number of slots in the hash table. */ + unsigned int size; + /* A function used to create new elements in the hash table. The + first entry is itself a pointer to an element. When this + function is first invoked, this pointer will be NULL. However, + having the pointer permits a hierarchy of method functions to be + built each of which calls the function in the superclass. Thus + each function should be written to allocate a new block of memory + only if the argument is NULL. */ + struct bfd_hash_entry *(*newfunc) + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); + /* An objalloc for this hash table. This is a struct objalloc *, + but we use void * to avoid requiring the inclusion of objalloc.h. */ + void *memory; +}; + +/* Initialize a hash table. */ +extern bfd_boolean bfd_hash_table_init + (struct bfd_hash_table *, + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, + struct bfd_hash_table *, + const char *)); + +/* Initialize a hash table specifying a size. */ +extern bfd_boolean bfd_hash_table_init_n + (struct bfd_hash_table *, + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, + struct bfd_hash_table *, + const char *), + unsigned int size); + +/* Free up a hash table. */ +extern void bfd_hash_table_free + (struct bfd_hash_table *); + +/* Look up a string in a hash table. If CREATE is TRUE, a new entry + will be created for this string if one does not already exist. The + COPY argument must be TRUE if this routine should copy the string + into newly allocated memory when adding an entry. */ +extern struct bfd_hash_entry *bfd_hash_lookup + (struct bfd_hash_table *, const char *, bfd_boolean create, + bfd_boolean copy); + +/* Replace an entry in a hash table. */ +extern void bfd_hash_replace + (struct bfd_hash_table *, struct bfd_hash_entry *old, + struct bfd_hash_entry *nw); + +/* Base method for creating a hash table entry. */ +extern struct bfd_hash_entry *bfd_hash_newfunc + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); + +/* Grab some space for a hash table entry. */ +extern void *bfd_hash_allocate + (struct bfd_hash_table *, unsigned int); + +/* Traverse a hash table in a random order, calling a function on each + element. If the function returns FALSE, the traversal stops. The + INFO argument is passed to the function. */ +extern void bfd_hash_traverse + (struct bfd_hash_table *, + bfd_boolean (*) (struct bfd_hash_entry *, void *), + void *info); + +/* Allows the default size of a hash table to be configured. New hash + tables allocated using bfd_hash_table_init will be created with + this size. */ +extern void bfd_hash_set_default_size (bfd_size_type); + +/* This structure is used to keep track of stabs in sections + information while linking. */ + +struct stab_info +{ + /* A hash table used to hold stabs strings. */ + struct bfd_strtab_hash *strings; + /* The header file hash table. */ + struct bfd_hash_table includes; + /* The first .stabstr section. */ + struct bfd_section *stabstr; +}; + +#define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table + +/* User program access to BFD facilities. */ + +/* Direct I/O routines, for programs which know more about the object + file than BFD does. Use higher level routines if possible. */ + +extern bfd_size_type bfd_bread (void *, bfd_size_type, bfd *); +extern bfd_size_type bfd_bwrite (const void *, bfd_size_type, bfd *); +extern int bfd_seek (bfd *, file_ptr, int); +extern file_ptr bfd_tell (bfd *); +extern int bfd_flush (bfd *); +extern int bfd_stat (bfd *, struct stat *); + +/* Deprecated old routines. */ +#if __GNUC__ +#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ + (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__), \ + bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) +#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ + (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__), \ + bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) +#else +#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ + (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \ + bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) +#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ + (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\ + bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) +#endif +extern void warn_deprecated (const char *, const char *, int, const char *); + +/* Cast from const char * to char * so that caller can assign to + a char * without a warning. */ +#define bfd_get_filename(abfd) ((char *) (abfd)->filename) +#define bfd_get_cacheable(abfd) ((abfd)->cacheable) +#define bfd_get_format(abfd) ((abfd)->format) +#define bfd_get_target(abfd) ((abfd)->xvec->name) +#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) +#define bfd_family_coff(abfd) \ + (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \ + bfd_get_flavour (abfd) == bfd_target_xcoff_flavour) +#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) +#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) +#define bfd_header_big_endian(abfd) \ + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) +#define bfd_header_little_endian(abfd) \ + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) +#define bfd_get_file_flags(abfd) ((abfd)->flags) +#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) +#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) +#define bfd_my_archive(abfd) ((abfd)->my_archive) +#define bfd_has_map(abfd) ((abfd)->has_armap) + +#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types) +#define bfd_usrdata(abfd) ((abfd)->usrdata) + +#define bfd_get_start_address(abfd) ((abfd)->start_address) +#define bfd_get_symcount(abfd) ((abfd)->symcount) +#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols) +#define bfd_count_sections(abfd) ((abfd)->section_count) + +#define bfd_get_dynamic_symcount(abfd) ((abfd)->dynsymcount) + +#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) + +#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) + +extern bfd_boolean bfd_cache_close + (bfd *abfd); +/* NB: This declaration should match the autogenerated one in libbfd.h. */ + +extern bfd_boolean bfd_cache_close_all (void); + +extern bfd_boolean bfd_record_phdr + (bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma, + bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **); + +/* Byte swapping routines. */ + +bfd_uint64_t bfd_getb64 (const void *); +bfd_uint64_t bfd_getl64 (const void *); +bfd_int64_t bfd_getb_signed_64 (const void *); +bfd_int64_t bfd_getl_signed_64 (const void *); +bfd_vma bfd_getb32 (const void *); +bfd_vma bfd_getl32 (const void *); +bfd_signed_vma bfd_getb_signed_32 (const void *); +bfd_signed_vma bfd_getl_signed_32 (const void *); +bfd_vma bfd_getb16 (const void *); +bfd_vma bfd_getl16 (const void *); +bfd_signed_vma bfd_getb_signed_16 (const void *); +bfd_signed_vma bfd_getl_signed_16 (const void *); +void bfd_putb64 (bfd_uint64_t, void *); +void bfd_putl64 (bfd_uint64_t, void *); +void bfd_putb32 (bfd_vma, void *); +void bfd_putl32 (bfd_vma, void *); +void bfd_putb16 (bfd_vma, void *); +void bfd_putl16 (bfd_vma, void *); + +/* Byte swapping routines which take size and endiannes as arguments. */ + +bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean); +void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean); + +extern bfd_boolean bfd_section_already_linked_table_init (void); +extern void bfd_section_already_linked_table_free (void); + +/* Externally visible ECOFF routines. */ + +#if defined(__STDC__) || defined(ALMOST_STDC) +struct ecoff_debug_info; +struct ecoff_debug_swap; +struct ecoff_extr; +struct bfd_symbol; +struct bfd_link_info; +struct bfd_link_hash_entry; +struct bfd_elf_version_tree; +#endif +extern bfd_vma bfd_ecoff_get_gp_value + (bfd * abfd); +extern bfd_boolean bfd_ecoff_set_gp_value + (bfd *abfd, bfd_vma gp_value); +extern bfd_boolean bfd_ecoff_set_regmasks + (bfd *abfd, unsigned long gprmask, unsigned long fprmask, + unsigned long *cprmask); +extern void *bfd_ecoff_debug_init + (bfd *output_bfd, struct ecoff_debug_info *output_debug, + const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); +extern void bfd_ecoff_debug_free + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, + const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); +extern bfd_boolean bfd_ecoff_debug_accumulate + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, + const struct ecoff_debug_swap *output_swap, bfd *input_bfd, + struct ecoff_debug_info *input_debug, + const struct ecoff_debug_swap *input_swap, struct bfd_link_info *); +extern bfd_boolean bfd_ecoff_debug_accumulate_other + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, + const struct ecoff_debug_swap *output_swap, bfd *input_bfd, + struct bfd_link_info *); +extern bfd_boolean bfd_ecoff_debug_externals + (bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap, bfd_boolean relocatable, + bfd_boolean (*get_extr) (struct bfd_symbol *, struct ecoff_extr *), + void (*set_index) (struct bfd_symbol *, bfd_size_type)); +extern bfd_boolean bfd_ecoff_debug_one_external + (bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap, const char *name, + struct ecoff_extr *esym); +extern bfd_size_type bfd_ecoff_debug_size + (bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap); +extern bfd_boolean bfd_ecoff_write_debug + (bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap, file_ptr where); +extern bfd_boolean bfd_ecoff_write_accumulated_debug + (void *handle, bfd *abfd, struct ecoff_debug_info *debug, + const struct ecoff_debug_swap *swap, + struct bfd_link_info *info, file_ptr where); + +/* Externally visible ELF routines. */ + +struct bfd_link_needed_list +{ + struct bfd_link_needed_list *next; + bfd *by; + const char *name; +}; + +enum dynamic_lib_link_class { + DYN_NORMAL = 0, + DYN_AS_NEEDED = 1, + DYN_DT_NEEDED = 2, + DYN_NO_ADD_NEEDED = 4, + DYN_NO_NEEDED = 8 +}; + +extern bfd_boolean bfd_elf_record_link_assignment + (bfd *, struct bfd_link_info *, const char *, bfd_boolean); +extern struct bfd_link_needed_list *bfd_elf_get_needed_list + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_elf_get_bfd_needed_list + (bfd *, struct bfd_link_needed_list **); +extern bfd_boolean bfd_elf_size_dynamic_sections + (bfd *, const char *, const char *, const char *, const char * const *, + struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *); +extern void bfd_elf_set_dt_needed_name + (bfd *, const char *); +extern const char *bfd_elf_get_dt_soname + (bfd *); +extern void bfd_elf_set_dyn_lib_class + (bfd *, int); +extern int bfd_elf_get_dyn_lib_class + (bfd *); +extern struct bfd_link_needed_list *bfd_elf_get_runpath_list + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_elf_discard_info + (bfd *, struct bfd_link_info *); + +/* Return an upper bound on the number of bytes required to store a + copy of ABFD's program header table entries. Return -1 if an error + occurs; bfd_get_error will return an appropriate code. */ +extern long bfd_get_elf_phdr_upper_bound + (bfd *abfd); + +/* Copy ABFD's program header table entries to *PHDRS. The entries + will be stored as an array of Elf_Internal_Phdr structures, as + defined in include/elf/internal.h. To find out how large the + buffer needs to be, call bfd_get_elf_phdr_upper_bound. + + Return the number of program header table entries read, or -1 if an + error occurs; bfd_get_error will return an appropriate code. */ +extern int bfd_get_elf_phdrs + (bfd *abfd, void *phdrs); + +/* Create a new BFD as if by bfd_openr. Rather than opening a file, + reconstruct an ELF file by reading the segments out of remote memory + based on the ELF file header at EHDR_VMA and the ELF program headers it + points to. If not null, *LOADBASEP is filled in with the difference + between the VMAs from which the segments were read, and the VMAs the + file headers (and hence BFD's idea of each section's VMA) put them at. + + The function TARGET_READ_MEMORY is called to copy LEN bytes from the + remote memory at target address VMA into the local buffer at MYADDR; it + should return zero on success or an `errno' code on failure. TEMPL must + be a BFD for an ELF target with the word size and byte order found in + the remote memory. */ +extern bfd *bfd_elf_bfd_from_remote_memory + (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, + int (*target_read_memory) (bfd_vma vma, char *myaddr, int len)); + +/* Return the arch_size field of an elf bfd, or -1 if not elf. */ +extern int bfd_get_arch_size + (bfd *); + +/* Return TRUE if address "naturally" sign extends, or -1 if not elf. */ +extern int bfd_get_sign_extend_vma + (bfd *); + +extern struct bfd_section *_bfd_elf_tls_setup + (bfd *, struct bfd_link_info *); + +extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs + (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **); + +/* SunOS shared library support routines for the linker. */ + +extern struct bfd_link_needed_list *bfd_sunos_get_needed_list + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_sunos_record_link_assignment + (bfd *, struct bfd_link_info *, const char *); +extern bfd_boolean bfd_sunos_size_dynamic_sections + (bfd *, struct bfd_link_info *, struct bfd_section **, struct bfd_section **, struct bfd_section **); + +/* Linux shared library support routines for the linker. */ + +extern bfd_boolean bfd_i386linux_size_dynamic_sections + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_m68klinux_size_dynamic_sections + (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_sparclinux_size_dynamic_sections + (bfd *, struct bfd_link_info *); + +/* mmap hacks */ + +struct _bfd_window_internal; +typedef struct _bfd_window_internal bfd_window_internal; + +typedef struct _bfd_window +{ + /* What the user asked for. */ + void *data; + bfd_size_type size; + /* The actual window used by BFD. Small user-requested read-only + regions sharing a page may share a single window into the object + file. Read-write versions shouldn't until I've fixed things to + keep track of which portions have been claimed by the + application; don't want to give the same region back when the + application wants two writable copies! */ + struct _bfd_window_internal *i; +} +bfd_window; + +extern void bfd_init_window + (bfd_window *); +extern void bfd_free_window + (bfd_window *); +extern bfd_boolean bfd_get_file_window + (bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean); + +/* XCOFF support routines for the linker. */ + +extern bfd_boolean bfd_xcoff_link_record_set + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_size_type); +extern bfd_boolean bfd_xcoff_import_symbol + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_vma, + const char *, const char *, const char *, unsigned int); +extern bfd_boolean bfd_xcoff_export_symbol + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *); +extern bfd_boolean bfd_xcoff_link_count_reloc + (bfd *, struct bfd_link_info *, const char *); +extern bfd_boolean bfd_xcoff_record_link_assignment + (bfd *, struct bfd_link_info *, const char *); +extern bfd_boolean bfd_xcoff_size_dynamic_sections + (bfd *, struct bfd_link_info *, const char *, const char *, + unsigned long, unsigned long, unsigned long, bfd_boolean, + int, bfd_boolean, bfd_boolean, struct bfd_section **, bfd_boolean); +extern bfd_boolean bfd_xcoff_link_generate_rtinit + (bfd *, const char *, const char *, bfd_boolean); + +/* XCOFF support routines for ar. */ +extern bfd_boolean bfd_xcoff_ar_archive_set_magic + (bfd *, char *); + +/* Externally visible COFF routines. */ + +#if defined(__STDC__) || defined(ALMOST_STDC) +struct internal_syment; +union internal_auxent; +#endif + +extern bfd_boolean bfd_coff_get_syment + (bfd *, struct bfd_symbol *, struct internal_syment *); + +extern bfd_boolean bfd_coff_get_auxent + (bfd *, struct bfd_symbol *, int, union internal_auxent *); + +extern bfd_boolean bfd_coff_set_symbol_class + (bfd *, struct bfd_symbol *, unsigned int); + +extern bfd_boolean bfd_m68k_coff_create_embedded_relocs + (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **); + +/* ARM Interworking support. Called from linker. */ +extern bfd_boolean bfd_arm_allocate_interworking_sections + (struct bfd_link_info *); + +extern bfd_boolean bfd_arm_process_before_allocation + (bfd *, struct bfd_link_info *, int); + +extern bfd_boolean bfd_arm_get_bfd_for_interworking + (bfd *, struct bfd_link_info *); + +/* PE ARM Interworking support. Called from linker. */ +extern bfd_boolean bfd_arm_pe_allocate_interworking_sections + (struct bfd_link_info *); + +extern bfd_boolean bfd_arm_pe_process_before_allocation + (bfd *, struct bfd_link_info *, int); + +extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking + (bfd *, struct bfd_link_info *); + +/* ELF ARM Interworking support. Called from linker. */ +extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections + (struct bfd_link_info *); + +extern bfd_boolean bfd_elf32_arm_process_before_allocation + (bfd *, struct bfd_link_info *, int, int); + +void bfd_elf32_arm_set_target_relocs + (struct bfd_link_info *, int, char *); + +extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking + (bfd *, struct bfd_link_info *); + +extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd + (bfd *, struct bfd_link_info *); + +/* ARM Note section processing. */ +extern bfd_boolean bfd_arm_merge_machines + (bfd *, bfd *); + +extern bfd_boolean bfd_arm_update_notes + (bfd *, const char *); + +extern unsigned int bfd_arm_get_mach_from_notes + (bfd *, const char *); + +/* TI COFF load page support. */ +extern void bfd_ticoff_set_section_load_page + (struct bfd_section *, int); + +extern int bfd_ticoff_get_section_load_page + (struct bfd_section *); + +/* H8/300 functions. */ +extern bfd_vma bfd_h8300_pad_address + (bfd *, bfd_vma); + +/* IA64 Itanium code generation. Called from linker. */ +extern void bfd_elf32_ia64_after_parse + (int); + +extern void bfd_elf64_ia64_after_parse + (int); + +/* This structure is used for a comdat section, as in PE. A comdat + section is associated with a particular symbol. When the linker + sees a comdat section, it keeps only one of the sections with a + given name and associated with a given symbol. */ + +struct coff_comdat_info +{ + /* The name of the symbol associated with a comdat section. */ + const char *name; + + /* The local symbol table index of the symbol associated with a + comdat section. This is only meaningful to the object file format + specific code; it is not an index into the list returned by + bfd_canonicalize_symtab. */ + long symbol; +}; + +extern struct coff_comdat_info *bfd_coff_get_comdat_section + (bfd *, struct bfd_section *); + +/* Extracted from init.c. */ +void bfd_init (void); + +/* Extracted from opncls.c. */ +bfd *bfd_openr (const char *filename, const char *target); + +bfd *bfd_fdopenr (const char *filename, const char *target, int fd); + +bfd *bfd_openstreamr (const char *, const char *, void *); + +bfd *bfd_openr_iovec (const char *filename, const char *target, + void *(*open) (struct bfd *nbfd, + void *open_closure), + void *open_closure, + file_ptr (*pread) (struct bfd *nbfd, + void *stream, + void *buf, + file_ptr nbytes, + file_ptr offset), + int (*close) (struct bfd *nbfd, + void *stream)); + +bfd *bfd_openw (const char *filename, const char *target); + +bfd_boolean bfd_close (bfd *abfd); + +bfd_boolean bfd_close_all_done (bfd *); + +bfd *bfd_create (const char *filename, bfd *templ); + +bfd_boolean bfd_make_writable (bfd *abfd); + +bfd_boolean bfd_make_readable (bfd *abfd); + +unsigned long bfd_calc_gnu_debuglink_crc32 + (unsigned long crc, const unsigned char *buf, bfd_size_type len); + +char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir); + +struct bfd_section *bfd_create_gnu_debuglink_section + (bfd *abfd, const char *filename); + +bfd_boolean bfd_fill_in_gnu_debuglink_section + (bfd *abfd, struct bfd_section *sect, const char *filename); + +/* Extracted from libbfd.c. */ + +/* Byte swapping macros for user section data. */ + +#define bfd_put_8(abfd, val, ptr) \ + ((void) (*((unsigned char *) (ptr)) = (val) & 0xff)) +#define bfd_put_signed_8 \ + bfd_put_8 +#define bfd_get_8(abfd, ptr) \ + (*(unsigned char *) (ptr) & 0xff) +#define bfd_get_signed_8(abfd, ptr) \ + (((*(unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) + +#define bfd_put_16(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) +#define bfd_put_signed_16 \ + bfd_put_16 +#define bfd_get_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx16, (ptr)) +#define bfd_get_signed_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) + +#define bfd_put_32(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) +#define bfd_put_signed_32 \ + bfd_put_32 +#define bfd_get_32(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx32, (ptr)) +#define bfd_get_signed_32(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) + +#define bfd_put_64(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) +#define bfd_put_signed_64 \ + bfd_put_64 +#define bfd_get_64(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx64, (ptr)) +#define bfd_get_signed_64(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) + +#define bfd_get(bits, abfd, ptr) \ + ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ + : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ + : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ + : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ + : (abort (), (bfd_vma) - 1)) + +#define bfd_put(bits, abfd, val, ptr) \ + ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ + : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ + : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ + : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ + : (abort (), (void) 0)) + + +/* Byte swapping macros for file header data. */ + +#define bfd_h_put_8(abfd, val, ptr) \ + bfd_put_8 (abfd, val, ptr) +#define bfd_h_put_signed_8(abfd, val, ptr) \ + bfd_put_8 (abfd, val, ptr) +#define bfd_h_get_8(abfd, ptr) \ + bfd_get_8 (abfd, ptr) +#define bfd_h_get_signed_8(abfd, ptr) \ + bfd_get_signed_8 (abfd, ptr) + +#define bfd_h_put_16(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) +#define bfd_h_put_signed_16 \ + bfd_h_put_16 +#define bfd_h_get_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx16, (ptr)) +#define bfd_h_get_signed_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) + +#define bfd_h_put_32(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) +#define bfd_h_put_signed_32 \ + bfd_h_put_32 +#define bfd_h_get_32(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx32, (ptr)) +#define bfd_h_get_signed_32(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) + +#define bfd_h_put_64(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) +#define bfd_h_put_signed_64 \ + bfd_h_put_64 +#define bfd_h_get_64(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx64, (ptr)) +#define bfd_h_get_signed_64(abfd, ptr) \ + BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) + +/* Aliases for the above, which should eventually go away. */ + +#define H_PUT_64 bfd_h_put_64 +#define H_PUT_32 bfd_h_put_32 +#define H_PUT_16 bfd_h_put_16 +#define H_PUT_8 bfd_h_put_8 +#define H_PUT_S64 bfd_h_put_signed_64 +#define H_PUT_S32 bfd_h_put_signed_32 +#define H_PUT_S16 bfd_h_put_signed_16 +#define H_PUT_S8 bfd_h_put_signed_8 +#define H_GET_64 bfd_h_get_64 +#define H_GET_32 bfd_h_get_32 +#define H_GET_16 bfd_h_get_16 +#define H_GET_8 bfd_h_get_8 +#define H_GET_S64 bfd_h_get_signed_64 +#define H_GET_S32 bfd_h_get_signed_32 +#define H_GET_S16 bfd_h_get_signed_16 +#define H_GET_S8 bfd_h_get_signed_8 + + +/* Extracted from bfdio.c. */ +long bfd_get_mtime (bfd *abfd); + +long bfd_get_size (bfd *abfd); + +/* Extracted from bfdwin.c. */ +/* Extracted from section.c. */ +typedef struct bfd_section +{ + /* The name of the section; the name isn't a copy, the pointer is + the same as that passed to bfd_make_section. */ + const char *name; + + /* A unique sequence number. */ + int id; + + /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */ + int index; + + /* The next section in the list belonging to the BFD, or NULL. */ + struct bfd_section *next; + + /* The field flags contains attributes of the section. Some + flags are read in from the object file, and some are + synthesized from other information. */ + flagword flags; + +#define SEC_NO_FLAGS 0x000 + + /* Tells the OS to allocate space for this section when loading. + This is clear for a section containing debug information only. */ +#define SEC_ALLOC 0x001 + + /* Tells the OS to load the section from the file when loading. + This is clear for a .bss section. */ +#define SEC_LOAD 0x002 + + /* The section contains data still to be relocated, so there is + some relocation information too. */ +#define SEC_RELOC 0x004 + + /* ELF reserves 4 processor specific bits and 8 operating system + specific bits in sh_flags; at present we can get away with just + one in communicating between the assembler and BFD, but this + isn't a good long-term solution. */ +#define SEC_ARCH_BIT_0 0x008 + + /* A signal to the OS that the section contains read only data. */ +#define SEC_READONLY 0x010 + + /* The section contains code only. */ +#define SEC_CODE 0x020 + + /* The section contains data only. */ +#define SEC_DATA 0x040 + + /* The section will reside in ROM. */ +#define SEC_ROM 0x080 + + /* The section contains constructor information. This section + type is used by the linker to create lists of constructors and + destructors used by <>. When a back end sees a symbol + which should be used in a constructor list, it creates a new + section for the type of name (e.g., <<__CTOR_LIST__>>), attaches + the symbol to it, and builds a relocation. To build the lists + of constructors, all the linker has to do is catenate all the + sections called <<__CTOR_LIST__>> and relocate the data + contained within - exactly the operations it would peform on + standard data. */ +#define SEC_CONSTRUCTOR 0x100 + + /* The section has contents - a data section could be + <> | <>; a debug section could be + <> */ +#define SEC_HAS_CONTENTS 0x200 + + /* An instruction to the linker to not output the section + even if it has information which would normally be written. */ +#define SEC_NEVER_LOAD 0x400 + + /* The section is a COFF shared library section. This flag is + only for the linker. If this type of section appears in + the input file, the linker must copy it to the output file + without changing the vma or size. FIXME: Although this + was originally intended to be general, it really is COFF + specific (and the flag was renamed to indicate this). It + might be cleaner to have some more general mechanism to + allow the back end to control what the linker does with + sections. */ +#define SEC_COFF_SHARED_LIBRARY 0x800 + + /* The section contains thread local data. */ +#define SEC_THREAD_LOCAL 0x1000 + + /* The section has GOT references. This flag is only for the + linker, and is currently only used by the elf32-hppa back end. + It will be set if global offset table references were detected + in this section, which indicate to the linker that the section + contains PIC code, and must be handled specially when doing a + static link. */ +#define SEC_HAS_GOT_REF 0x4000 + + /* The section contains common symbols (symbols may be defined + multiple times, the value of a symbol is the amount of + space it requires, and the largest symbol value is the one + used). Most targets have exactly one of these (which we + translate to bfd_com_section_ptr), but ECOFF has two. */ +#define SEC_IS_COMMON 0x8000 + + /* The section contains only debugging information. For + example, this is set for ELF .debug and .stab sections. + strip tests this flag to see if a section can be + discarded. */ +#define SEC_DEBUGGING 0x10000 + + /* The contents of this section are held in memory pointed to + by the contents field. This is checked by bfd_get_section_contents, + and the data is retrieved from memory if appropriate. */ +#define SEC_IN_MEMORY 0x20000 + + /* The contents of this section are to be excluded by the + linker for executable and shared objects unless those + objects are to be further relocated. */ +#define SEC_EXCLUDE 0x40000 + + /* The contents of this section are to be sorted based on the sum of + the symbol and addend values specified by the associated relocation + entries. Entries without associated relocation entries will be + appended to the end of the section in an unspecified order. */ +#define SEC_SORT_ENTRIES 0x80000 + + /* When linking, duplicate sections of the same name should be + discarded, rather than being combined into a single section as + is usually done. This is similar to how common symbols are + handled. See SEC_LINK_DUPLICATES below. */ +#define SEC_LINK_ONCE 0x100000 + + /* If SEC_LINK_ONCE is set, this bitfield describes how the linker + should handle duplicate sections. */ +#define SEC_LINK_DUPLICATES 0x600000 + + /* This value for SEC_LINK_DUPLICATES means that duplicate + sections with the same name should simply be discarded. */ +#define SEC_LINK_DUPLICATES_DISCARD 0x0 + + /* This value for SEC_LINK_DUPLICATES means that the linker + should warn if there are any duplicate sections, although + it should still only link one copy. */ +#define SEC_LINK_DUPLICATES_ONE_ONLY 0x200000 + + /* This value for SEC_LINK_DUPLICATES means that the linker + should warn if any duplicate sections are a different size. */ +#define SEC_LINK_DUPLICATES_SAME_SIZE 0x400000 + + /* This value for SEC_LINK_DUPLICATES means that the linker + should warn if any duplicate sections contain different + contents. */ +#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000 + + /* This section was created by the linker as part of dynamic + relocation or other arcane processing. It is skipped when + going through the first-pass output, trusting that someone + else up the line will take care of it later. */ +#define SEC_LINKER_CREATED 0x800000 + + /* This section should not be subject to garbage collection. */ +#define SEC_KEEP 0x1000000 + + /* This section contains "short" data, and should be placed + "near" the GP. */ +#define SEC_SMALL_DATA 0x2000000 + + /* This section contains data which may be shared with other + executables or shared objects. */ +#define SEC_SHARED 0x4000000 + + /* When a section with this flag is being linked, then if the size of + the input section is less than a page, it should not cross a page + boundary. If the size of the input section is one page or more, it + should be aligned on a page boundary. */ +#define SEC_BLOCK 0x8000000 + + /* Conditionally link this section; do not link if there are no + references found to any symbol in the section. */ +#define SEC_CLINK 0x10000000 + + /* Attempt to merge identical entities in the section. + Entity size is given in the entsize field. */ +#define SEC_MERGE 0x20000000 + + /* If given with SEC_MERGE, entities to merge are zero terminated + strings where entsize specifies character size instead of fixed + size entries. */ +#define SEC_STRINGS 0x40000000 + + /* This section contains data about section groups. */ +#define SEC_GROUP 0x80000000 + + /* End of section flags. */ + + /* Some internal packed boolean fields. */ + + /* See the vma field. */ + unsigned int user_set_vma : 1; + + /* A mark flag used by some of the linker backends. */ + unsigned int linker_mark : 1; + + /* Another mark flag used by some of the linker backends. Set for + output sections that have an input section. */ + unsigned int linker_has_input : 1; + + /* A mark flag used by some linker backends for garbage collection. */ + unsigned int gc_mark : 1; + + /* The following flags are used by the ELF linker. */ + + /* Mark sections which have been allocated to segments. */ + unsigned int segment_mark : 1; + + /* Type of sec_info information. */ + unsigned int sec_info_type:3; +#define ELF_INFO_TYPE_NONE 0 +#define ELF_INFO_TYPE_STABS 1 +#define ELF_INFO_TYPE_MERGE 2 +#define ELF_INFO_TYPE_EH_FRAME 3 +#define ELF_INFO_TYPE_JUST_SYMS 4 + + /* Nonzero if this section uses RELA relocations, rather than REL. */ + unsigned int use_rela_p:1; + + /* Bits used by various backends. */ + + /* Nonzero if this section has TLS related relocations. */ + unsigned int has_tls_reloc:1; + + /* Nonzero if this section has a gp reloc. */ + unsigned int has_gp_reloc:1; + + /* Nonzero if this section needs the relax finalize pass. */ + unsigned int need_finalize_relax:1; + + /* Whether relocations have been processed. */ + unsigned int reloc_done : 1; + + /* End of internal packed boolean fields. */ + + /* The virtual memory address of the section - where it will be + at run time. The symbols are relocated against this. The + user_set_vma flag is maintained by bfd; if it's not set, the + backend can assign addresses (for example, in <>, where + the default address for <<.data>> is dependent on the specific + target and various flags). */ + bfd_vma vma; + + /* The load address of the section - where it would be in a + rom image; really only used for writing section header + information. */ + bfd_vma lma; + + /* The size of the section in octets, as it will be output. + Contains a value even if the section has no contents (e.g., the + size of <<.bss>>). */ + bfd_size_type size; + + /* For input sections, the original size on disk of the section, in + octets. This field is used by the linker relaxation code. It is + currently only set for sections where the linker relaxation scheme + doesn't cache altered section and reloc contents (stabs, eh_frame, + SEC_MERGE, some coff relaxing targets), and thus the original size + needs to be kept to read the section multiple times. + For output sections, rawsize holds the section size calculated on + a previous linker relaxation pass. */ + bfd_size_type rawsize; + + /* If this section is going to be output, then this value is the + offset in *bytes* into the output section of the first byte in the + input section (byte ==> smallest addressable unit on the + target). In most cases, if this was going to start at the + 100th octet (8-bit quantity) in the output section, this value + would be 100. However, if the target byte size is 16 bits + (bfd_octets_per_byte is "2"), this value would be 50. */ + bfd_vma output_offset; + + /* The output section through which to map on output. */ + struct bfd_section *output_section; + + /* The alignment requirement of the section, as an exponent of 2 - + e.g., 3 aligns to 2^3 (or 8). */ + unsigned int alignment_power; + + /* If an input section, a pointer to a vector of relocation + records for the data in this section. */ + struct reloc_cache_entry *relocation; + + /* If an output section, a pointer to a vector of pointers to + relocation records for the data in this section. */ + struct reloc_cache_entry **orelocation; + + /* The number of relocation records in one of the above. */ + unsigned reloc_count; + + /* Information below is back end specific - and not always used + or updated. */ + + /* File position of section data. */ + file_ptr filepos; + + /* File position of relocation info. */ + file_ptr rel_filepos; + + /* File position of line data. */ + file_ptr line_filepos; + + /* Pointer to data for applications. */ + void *userdata; + + /* If the SEC_IN_MEMORY flag is set, this points to the actual + contents. */ + unsigned char *contents; + + /* Attached line number information. */ + alent *lineno; + + /* Number of line number records. */ + unsigned int lineno_count; + + /* Entity size for merging purposes. */ + unsigned int entsize; + + /* Points to the kept section if this section is a link-once section, + and is discarded. */ + struct bfd_section *kept_section; + + /* When a section is being output, this value changes as more + linenumbers are written out. */ + file_ptr moving_line_filepos; + + /* What the section number is in the target world. */ + int target_index; + + void *used_by_bfd; + + /* If this is a constructor section then here is a list of the + relocations created to relocate items within it. */ + struct relent_chain *constructor_chain; + + /* The BFD which owns the section. */ + bfd *owner; + + /* A symbol which points at this section only. */ + struct bfd_symbol *symbol; + struct bfd_symbol **symbol_ptr_ptr; + + struct bfd_link_order *link_order_head; + struct bfd_link_order *link_order_tail; +} asection; + +/* These sections are global, and are managed by BFD. The application + and target back end are not permitted to change the values in + these sections. New code should use the section_ptr macros rather + than referring directly to the const sections. The const sections + may eventually vanish. */ +#define BFD_ABS_SECTION_NAME "*ABS*" +#define BFD_UND_SECTION_NAME "*UND*" +#define BFD_COM_SECTION_NAME "*COM*" +#define BFD_IND_SECTION_NAME "*IND*" + +/* The absolute section. */ +extern asection bfd_abs_section; +#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) +#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) +/* Pointer to the undefined section. */ +extern asection bfd_und_section; +#define bfd_und_section_ptr ((asection *) &bfd_und_section) +#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) +/* Pointer to the common section. */ +extern asection bfd_com_section; +#define bfd_com_section_ptr ((asection *) &bfd_com_section) +/* Pointer to the indirect section. */ +extern asection bfd_ind_section; +#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) +#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) + +#define bfd_is_const_section(SEC) \ + ( ((SEC) == bfd_abs_section_ptr) \ + || ((SEC) == bfd_und_section_ptr) \ + || ((SEC) == bfd_com_section_ptr) \ + || ((SEC) == bfd_ind_section_ptr)) + +extern const struct bfd_symbol * const bfd_abs_symbol; +extern const struct bfd_symbol * const bfd_com_symbol; +extern const struct bfd_symbol * const bfd_und_symbol; +extern const struct bfd_symbol * const bfd_ind_symbol; + +/* Macros to handle insertion and deletion of a bfd's sections. These + only handle the list pointers, ie. do not adjust section_count, + target_index etc. */ +#define bfd_section_list_remove(ABFD, PS) \ + do \ + { \ + asection **_ps = PS; \ + asection *_s = *_ps; \ + *_ps = _s->next; \ + if (_s->next == NULL) \ + (ABFD)->section_tail = _ps; \ + } \ + while (0) +#define bfd_section_list_insert(ABFD, PS, S) \ + do \ + { \ + asection **_ps = PS; \ + asection *_s = S; \ + _s->next = *_ps; \ + *_ps = _s; \ + if (_s->next == NULL) \ + (ABFD)->section_tail = &_s->next; \ + } \ + while (0) + +void bfd_section_list_clear (bfd *); + +asection *bfd_get_section_by_name (bfd *abfd, const char *name); + +asection *bfd_get_section_by_name_if + (bfd *abfd, + const char *name, + bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), + void *obj); + +char *bfd_get_unique_section_name + (bfd *abfd, const char *templat, int *count); + +asection *bfd_make_section_old_way (bfd *abfd, const char *name); + +asection *bfd_make_section_anyway (bfd *abfd, const char *name); + +asection *bfd_make_section (bfd *, const char *name); + +bfd_boolean bfd_set_section_flags + (bfd *abfd, asection *sec, flagword flags); + +void bfd_map_over_sections + (bfd *abfd, + void (*func) (bfd *abfd, asection *sect, void *obj), + void *obj); + +asection *bfd_sections_find_if + (bfd *abfd, + bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), + void *obj); + +bfd_boolean bfd_set_section_size + (bfd *abfd, asection *sec, bfd_size_type val); + +bfd_boolean bfd_set_section_contents + (bfd *abfd, asection *section, const void *data, + file_ptr offset, bfd_size_type count); + +bfd_boolean bfd_get_section_contents + (bfd *abfd, asection *section, void *location, file_ptr offset, + bfd_size_type count); + +bfd_boolean bfd_malloc_and_get_section + (bfd *abfd, asection *section, bfd_byte **buf); + +bfd_boolean bfd_copy_private_section_data + (bfd *ibfd, asection *isec, bfd *obfd, asection *osec); + +#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ + BFD_SEND (obfd, _bfd_copy_private_section_data, \ + (ibfd, isection, obfd, osection)) +void _bfd_strip_section_from_output + (struct bfd_link_info *info, asection *section); + +bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); + +bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); + +/* Extracted from archures.c. */ +enum bfd_architecture +{ + bfd_arch_unknown, /* File arch not known. */ + bfd_arch_obscure, /* Arch known, not one of these. */ + bfd_arch_m68k, /* Motorola 68xxx */ +#define bfd_mach_m68000 1 +#define bfd_mach_m68008 2 +#define bfd_mach_m68010 3 +#define bfd_mach_m68020 4 +#define bfd_mach_m68030 5 +#define bfd_mach_m68040 6 +#define bfd_mach_m68060 7 +#define bfd_mach_cpu32 8 +#define bfd_mach_mcf5200 9 +#define bfd_mach_mcf5206e 10 +#define bfd_mach_mcf5307 11 +#define bfd_mach_mcf5407 12 +#define bfd_mach_mcf528x 13 +#define bfd_mach_mcfv4e 14 +#define bfd_mach_mcf521x 15 +#define bfd_mach_mcf5249 16 +#define bfd_mach_mcf547x 17 +#define bfd_mach_mcf548x 18 + bfd_arch_vax, /* DEC Vax */ + bfd_arch_i960, /* Intel 960 */ + /* The order of the following is important. + lower number indicates a machine type that + only accepts a subset of the instructions + available to machines with higher numbers. + The exception is the "ca", which is + incompatible with all other machines except + "core". */ + +#define bfd_mach_i960_core 1 +#define bfd_mach_i960_ka_sa 2 +#define bfd_mach_i960_kb_sb 3 +#define bfd_mach_i960_mc 4 +#define bfd_mach_i960_xa 5 +#define bfd_mach_i960_ca 6 +#define bfd_mach_i960_jx 7 +#define bfd_mach_i960_hx 8 + + bfd_arch_or32, /* OpenRISC 32 */ + + bfd_arch_a29k, /* AMD 29000 */ + bfd_arch_sparc, /* SPARC */ +#define bfd_mach_sparc 1 +/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ +#define bfd_mach_sparc_sparclet 2 +#define bfd_mach_sparc_sparclite 3 +#define bfd_mach_sparc_v8plus 4 +#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ +#define bfd_mach_sparc_sparclite_le 6 +#define bfd_mach_sparc_v9 7 +#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ +#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ +#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ +/* Nonzero if MACH has the v9 instruction set. */ +#define bfd_mach_sparc_v9_p(mach) \ + ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ + && (mach) != bfd_mach_sparc_sparclite_le) +/* Nonzero if MACH is a 64 bit sparc architecture. */ +#define bfd_mach_sparc_64bit_p(mach) \ + ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb) + bfd_arch_mips, /* MIPS Rxxxx */ +#define bfd_mach_mips3000 3000 +#define bfd_mach_mips3900 3900 +#define bfd_mach_mips4000 4000 +#define bfd_mach_mips4010 4010 +#define bfd_mach_mips4100 4100 +#define bfd_mach_mips4111 4111 +#define bfd_mach_mips4120 4120 +#define bfd_mach_mips4300 4300 +#define bfd_mach_mips4400 4400 +#define bfd_mach_mips4600 4600 +#define bfd_mach_mips4650 4650 +#define bfd_mach_mips5000 5000 +#define bfd_mach_mips5400 5400 +#define bfd_mach_mips5500 5500 +#define bfd_mach_mips6000 6000 +#define bfd_mach_mips7000 7000 +#define bfd_mach_mips8000 8000 +#define bfd_mach_mips10000 10000 +#define bfd_mach_mips12000 12000 +#define bfd_mach_mips16 16 +#define bfd_mach_mips5 5 +#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ +#define bfd_mach_mipsisa32 32 +#define bfd_mach_mipsisa32r2 33 +#define bfd_mach_mipsisa64 64 +#define bfd_mach_mipsisa64r2 65 + bfd_arch_i386, /* Intel 386 */ +#define bfd_mach_i386_i386 1 +#define bfd_mach_i386_i8086 2 +#define bfd_mach_i386_i386_intel_syntax 3 +#define bfd_mach_x86_64 64 +#define bfd_mach_x86_64_intel_syntax 65 + bfd_arch_we32k, /* AT&T WE32xxx */ + bfd_arch_tahoe, /* CCI/Harris Tahoe */ + bfd_arch_i860, /* Intel 860 */ + bfd_arch_i370, /* IBM 360/370 Mainframes */ + bfd_arch_romp, /* IBM ROMP PC/RT */ + bfd_arch_alliant, /* Alliant */ + bfd_arch_convex, /* Convex */ + bfd_arch_m88k, /* Motorola 88xxx */ + bfd_arch_m98k, /* Motorola 98xxx */ + bfd_arch_pyramid, /* Pyramid Technology */ + bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */ +#define bfd_mach_h8300 1 +#define bfd_mach_h8300h 2 +#define bfd_mach_h8300s 3 +#define bfd_mach_h8300hn 4 +#define bfd_mach_h8300sn 5 +#define bfd_mach_h8300sx 6 +#define bfd_mach_h8300sxn 7 + bfd_arch_pdp11, /* DEC PDP-11 */ + bfd_arch_powerpc, /* PowerPC */ +#define bfd_mach_ppc 32 +#define bfd_mach_ppc64 64 +#define bfd_mach_ppc_403 403 +#define bfd_mach_ppc_403gc 4030 +#define bfd_mach_ppc_505 505 +#define bfd_mach_ppc_601 601 +#define bfd_mach_ppc_602 602 +#define bfd_mach_ppc_603 603 +#define bfd_mach_ppc_ec603e 6031 +#define bfd_mach_ppc_604 604 +#define bfd_mach_ppc_620 620 +#define bfd_mach_ppc_630 630 +#define bfd_mach_ppc_750 750 +#define bfd_mach_ppc_860 860 +#define bfd_mach_ppc_a35 35 +#define bfd_mach_ppc_rs64ii 642 +#define bfd_mach_ppc_rs64iii 643 +#define bfd_mach_ppc_7400 7400 +#define bfd_mach_ppc_e500 500 + bfd_arch_rs6000, /* IBM RS/6000 */ +#define bfd_mach_rs6k 6000 +#define bfd_mach_rs6k_rs1 6001 +#define bfd_mach_rs6k_rsc 6003 +#define bfd_mach_rs6k_rs2 6002 + bfd_arch_hppa, /* HP PA RISC */ +#define bfd_mach_hppa10 10 +#define bfd_mach_hppa11 11 +#define bfd_mach_hppa20 20 +#define bfd_mach_hppa20w 25 + bfd_arch_d10v, /* Mitsubishi D10V */ +#define bfd_mach_d10v 1 +#define bfd_mach_d10v_ts2 2 +#define bfd_mach_d10v_ts3 3 + bfd_arch_d30v, /* Mitsubishi D30V */ + bfd_arch_dlx, /* DLX */ + bfd_arch_m68hc11, /* Motorola 68HC11 */ + bfd_arch_m68hc12, /* Motorola 68HC12 */ +#define bfd_mach_m6812_default 0 +#define bfd_mach_m6812 1 +#define bfd_mach_m6812s 2 + bfd_arch_z8k, /* Zilog Z8000 */ +#define bfd_mach_z8001 1 +#define bfd_mach_z8002 2 + bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */ + bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */ +#define bfd_mach_sh 1 +#define bfd_mach_sh2 0x20 +#define bfd_mach_sh_dsp 0x2d +#define bfd_mach_sh2a 0x2a +#define bfd_mach_sh2a_nofpu 0x2b +#define bfd_mach_sh2e 0x2e +#define bfd_mach_sh3 0x30 +#define bfd_mach_sh3_nommu 0x31 +#define bfd_mach_sh3_dsp 0x3d +#define bfd_mach_sh3e 0x3e +#define bfd_mach_sh4 0x40 +#define bfd_mach_sh4_nofpu 0x41 +#define bfd_mach_sh4_nommu_nofpu 0x42 +#define bfd_mach_sh4a 0x4a +#define bfd_mach_sh4a_nofpu 0x4b +#define bfd_mach_sh4al_dsp 0x4d +#define bfd_mach_sh5 0x50 + bfd_arch_alpha, /* Dec Alpha */ +#define bfd_mach_alpha_ev4 0x10 +#define bfd_mach_alpha_ev5 0x20 +#define bfd_mach_alpha_ev6 0x30 + bfd_arch_arm, /* Advanced Risc Machines ARM. */ +#define bfd_mach_arm_unknown 0 +#define bfd_mach_arm_2 1 +#define bfd_mach_arm_2a 2 +#define bfd_mach_arm_3 3 +#define bfd_mach_arm_3M 4 +#define bfd_mach_arm_4 5 +#define bfd_mach_arm_4T 6 +#define bfd_mach_arm_5 7 +#define bfd_mach_arm_5T 8 +#define bfd_mach_arm_5TE 9 +#define bfd_mach_arm_XScale 10 +#define bfd_mach_arm_ep9312 11 +#define bfd_mach_arm_iWMMXt 12 + bfd_arch_ns32k, /* National Semiconductors ns32000 */ + bfd_arch_w65, /* WDC 65816 */ + bfd_arch_tic30, /* Texas Instruments TMS320C30 */ + bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */ +#define bfd_mach_tic3x 30 +#define bfd_mach_tic4x 40 + bfd_arch_tic54x, /* Texas Instruments TMS320C54X */ + bfd_arch_tic80, /* TI TMS320c80 (MVP) */ + bfd_arch_v850, /* NEC V850 */ +#define bfd_mach_v850 1 +#define bfd_mach_v850e 'E' +#define bfd_mach_v850e1 '1' + bfd_arch_arc, /* ARC Cores */ +#define bfd_mach_arc_5 5 +#define bfd_mach_arc_6 6 +#define bfd_mach_arc_7 7 +#define bfd_mach_arc_8 8 + bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */ +#define bfd_mach_m32r 1 /* For backwards compatibility. */ +#define bfd_mach_m32rx 'x' +#define bfd_mach_m32r2 '2' + bfd_arch_mn10200, /* Matsushita MN10200 */ + bfd_arch_mn10300, /* Matsushita MN10300 */ +#define bfd_mach_mn10300 300 +#define bfd_mach_am33 330 +#define bfd_mach_am33_2 332 + bfd_arch_fr30, +#define bfd_mach_fr30 0x46523330 + bfd_arch_frv, +#define bfd_mach_frv 1 +#define bfd_mach_frvsimple 2 +#define bfd_mach_fr300 300 +#define bfd_mach_fr400 400 +#define bfd_mach_fr450 450 +#define bfd_mach_frvtomcat 499 /* fr500 prototype */ +#define bfd_mach_fr500 500 +#define bfd_mach_fr550 550 + bfd_arch_mcore, + bfd_arch_ia64, /* HP/Intel ia64 */ +#define bfd_mach_ia64_elf64 64 +#define bfd_mach_ia64_elf32 32 + bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */ +#define bfd_mach_ip2022 1 +#define bfd_mach_ip2022ext 2 + bfd_arch_iq2000, /* Vitesse IQ2000. */ +#define bfd_mach_iq2000 1 +#define bfd_mach_iq10 2 + bfd_arch_pj, + bfd_arch_avr, /* Atmel AVR microcontrollers. */ +#define bfd_mach_avr1 1 +#define bfd_mach_avr2 2 +#define bfd_mach_avr3 3 +#define bfd_mach_avr4 4 +#define bfd_mach_avr5 5 + bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ +#define bfd_mach_cr16c 1 + bfd_arch_crx, /* National Semiconductor CRX. */ +#define bfd_mach_crx 1 + bfd_arch_cris, /* Axis CRIS */ + bfd_arch_s390, /* IBM s390 */ +#define bfd_mach_s390_31 31 +#define bfd_mach_s390_64 64 + bfd_arch_openrisc, /* OpenRISC */ + bfd_arch_mmix, /* Donald Knuth's educational processor. */ + bfd_arch_xstormy16, +#define bfd_mach_xstormy16 1 + bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */ +#define bfd_mach_msp11 11 +#define bfd_mach_msp110 110 +#define bfd_mach_msp12 12 +#define bfd_mach_msp13 13 +#define bfd_mach_msp14 14 +#define bfd_mach_msp15 15 +#define bfd_mach_msp16 16 +#define bfd_mach_msp31 31 +#define bfd_mach_msp32 32 +#define bfd_mach_msp33 33 +#define bfd_mach_msp41 41 +#define bfd_mach_msp42 42 +#define bfd_mach_msp43 43 +#define bfd_mach_msp44 44 + bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ +#define bfd_mach_xtensa 1 + bfd_arch_last + }; + +typedef struct bfd_arch_info +{ + int bits_per_word; + int bits_per_address; + int bits_per_byte; + enum bfd_architecture arch; + unsigned long mach; + const char *arch_name; + const char *printable_name; + unsigned int section_align_power; + /* TRUE if this is the default machine for the architecture. + The default arch should be the first entry for an arch so that + all the entries for that arch can be accessed via <>. */ + bfd_boolean the_default; + const struct bfd_arch_info * (*compatible) + (const struct bfd_arch_info *a, const struct bfd_arch_info *b); + + bfd_boolean (*scan) (const struct bfd_arch_info *, const char *); + + const struct bfd_arch_info *next; +} +bfd_arch_info_type; + +const char *bfd_printable_name (bfd *abfd); + +const bfd_arch_info_type *bfd_scan_arch (const char *string); + +const char **bfd_arch_list (void); + +const bfd_arch_info_type *bfd_arch_get_compatible + (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns); + +void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg); + +enum bfd_architecture bfd_get_arch (bfd *abfd); + +unsigned long bfd_get_mach (bfd *abfd); + +unsigned int bfd_arch_bits_per_byte (bfd *abfd); + +unsigned int bfd_arch_bits_per_address (bfd *abfd); + +const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd); + +const bfd_arch_info_type *bfd_lookup_arch + (enum bfd_architecture arch, unsigned long machine); + +const char *bfd_printable_arch_mach + (enum bfd_architecture arch, unsigned long machine); + +unsigned int bfd_octets_per_byte (bfd *abfd); + +unsigned int bfd_arch_mach_octets_per_byte + (enum bfd_architecture arch, unsigned long machine); + +/* Extracted from reloc.c. */ +typedef enum bfd_reloc_status +{ + /* No errors detected. */ + bfd_reloc_ok, + + /* The relocation was performed, but there was an overflow. */ + bfd_reloc_overflow, + + /* The address to relocate was not within the section supplied. */ + bfd_reloc_outofrange, + + /* Used by special functions. */ + bfd_reloc_continue, + + /* Unsupported relocation size requested. */ + bfd_reloc_notsupported, + + /* Unused. */ + bfd_reloc_other, + + /* The symbol to relocate against was undefined. */ + bfd_reloc_undefined, + + /* The relocation was performed, but may not be ok - presently + generated only when linking i960 coff files with i960 b.out + symbols. If this type is returned, the error_message argument + to bfd_perform_relocation will be set. */ + bfd_reloc_dangerous + } + bfd_reloc_status_type; + + +typedef struct reloc_cache_entry +{ + /* A pointer into the canonical table of pointers. */ + struct bfd_symbol **sym_ptr_ptr; + + /* offset in section. */ + bfd_size_type address; + + /* addend for relocation value. */ + bfd_vma addend; + + /* Pointer to how to perform the required relocation. */ + reloc_howto_type *howto; + +} +arelent; + +enum complain_overflow +{ + /* Do not complain on overflow. */ + complain_overflow_dont, + + /* Complain if the bitfield overflows, whether it is considered + as signed or unsigned. */ + complain_overflow_bitfield, + + /* Complain if the value overflows when considered as signed + number. */ + complain_overflow_signed, + + /* Complain if the value overflows when considered as an + unsigned number. */ + complain_overflow_unsigned +}; + +struct reloc_howto_struct +{ + /* The type field has mainly a documentary use - the back end can + do what it wants with it, though normally the back end's + external idea of what a reloc number is stored + in this field. For example, a PC relative word relocation + in a coff environment has the type 023 - because that's + what the outside world calls a R_PCRWORD reloc. */ + unsigned int type; + + /* The value the final relocation is shifted right by. This drops + unwanted data from the relocation. */ + unsigned int rightshift; + + /* The size of the item to be relocated. This is *not* a + power-of-two measure. To get the number of bytes operated + on by a type of relocation, use bfd_get_reloc_size. */ + int size; + + /* The number of bits in the item to be relocated. This is used + when doing overflow checking. */ + unsigned int bitsize; + + /* Notes that the relocation is relative to the location in the + data section of the addend. The relocation function will + subtract from the relocation value the address of the location + being relocated. */ + bfd_boolean pc_relative; + + /* The bit position of the reloc value in the destination. + The relocated value is left shifted by this amount. */ + unsigned int bitpos; + + /* What type of overflow error should be checked for when + relocating. */ + enum complain_overflow complain_on_overflow; + + /* If this field is non null, then the supplied function is + called rather than the normal function. This allows really + strange relocation methods to be accommodated (e.g., i960 callj + instructions). */ + bfd_reloc_status_type (*special_function) + (bfd *, arelent *, struct bfd_symbol *, void *, asection *, + bfd *, char **); + + /* The textual name of the relocation type. */ + char *name; + + /* Some formats record a relocation addend in the section contents + rather than with the relocation. For ELF formats this is the + distinction between USE_REL and USE_RELA (though the code checks + for USE_REL == 1/0). The value of this field is TRUE if the + addend is recorded with the section contents; when performing a + partial link (ld -r) the section contents (the data) will be + modified. The value of this field is FALSE if addends are + recorded with the relocation (in arelent.addend); when performing + a partial link the relocation will be modified. + All relocations for all ELF USE_RELA targets should set this field + to FALSE (values of TRUE should be looked on with suspicion). + However, the converse is not true: not all relocations of all ELF + USE_REL targets set this field to TRUE. Why this is so is peculiar + to each particular target. For relocs that aren't used in partial + links (e.g. GOT stuff) it doesn't matter what this is set to. */ + bfd_boolean partial_inplace; + + /* src_mask selects the part of the instruction (or data) to be used + in the relocation sum. If the target relocations don't have an + addend in the reloc, eg. ELF USE_REL, src_mask will normally equal + dst_mask to extract the addend from the section contents. If + relocations do have an addend in the reloc, eg. ELF USE_RELA, this + field should be zero. Non-zero values for ELF USE_RELA targets are + bogus as in those cases the value in the dst_mask part of the + section contents should be treated as garbage. */ + bfd_vma src_mask; + + /* dst_mask selects which parts of the instruction (or data) are + replaced with a relocated value. */ + bfd_vma dst_mask; + + /* When some formats create PC relative instructions, they leave + the value of the pc of the place being relocated in the offset + slot of the instruction, so that a PC relative relocation can + be made just by adding in an ordinary offset (e.g., sun3 a.out). + Some formats leave the displacement part of an instruction + empty (e.g., m88k bcs); this flag signals the fact. */ + bfd_boolean pcrel_offset; +}; + +#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ + { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC } +#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ + HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ + NAME, FALSE, 0, 0, IN) + +#define EMPTY_HOWTO(C) \ + HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ + NULL, FALSE, 0, 0, FALSE) + +#define HOWTO_PREPARE(relocation, symbol) \ + { \ + if (symbol != NULL) \ + { \ + if (bfd_is_com_section (symbol->section)) \ + { \ + relocation = 0; \ + } \ + else \ + { \ + relocation = symbol->value; \ + } \ + } \ + } + +unsigned int bfd_get_reloc_size (reloc_howto_type *); + +typedef struct relent_chain +{ + arelent relent; + struct relent_chain *next; +} +arelent_chain; + +bfd_reloc_status_type bfd_check_overflow + (enum complain_overflow how, + unsigned int bitsize, + unsigned int rightshift, + unsigned int addrsize, + bfd_vma relocation); + +bfd_reloc_status_type bfd_perform_relocation + (bfd *abfd, + arelent *reloc_entry, + void *data, + asection *input_section, + bfd *output_bfd, + char **error_message); + +bfd_reloc_status_type bfd_install_relocation + (bfd *abfd, + arelent *reloc_entry, + void *data, bfd_vma data_start, + asection *input_section, + char **error_message); + +enum bfd_reloc_code_real { + _dummy_first_bfd_reloc_code_real, + + +/* Basic absolute relocations of N bits. */ + BFD_RELOC_64, + BFD_RELOC_32, + BFD_RELOC_26, + BFD_RELOC_24, + BFD_RELOC_16, + BFD_RELOC_14, + BFD_RELOC_8, + +/* PC-relative relocations. Sometimes these are relative to the address +of the relocation itself; sometimes they are relative to the start of +the section containing the relocation. It depends on the specific target. + +The 24-bit relocation is used in some Intel 960 configurations. */ + BFD_RELOC_64_PCREL, + BFD_RELOC_32_PCREL, + BFD_RELOC_24_PCREL, + BFD_RELOC_16_PCREL, + BFD_RELOC_12_PCREL, + BFD_RELOC_8_PCREL, + +/* Section relative relocations. Some targets need this for DWARF2. */ + BFD_RELOC_32_SECREL, + +/* For ELF. */ + BFD_RELOC_32_GOT_PCREL, + BFD_RELOC_16_GOT_PCREL, + BFD_RELOC_8_GOT_PCREL, + BFD_RELOC_32_GOTOFF, + BFD_RELOC_16_GOTOFF, + BFD_RELOC_LO16_GOTOFF, + BFD_RELOC_HI16_GOTOFF, + BFD_RELOC_HI16_S_GOTOFF, + BFD_RELOC_8_GOTOFF, + BFD_RELOC_64_PLT_PCREL, + BFD_RELOC_32_PLT_PCREL, + BFD_RELOC_24_PLT_PCREL, + BFD_RELOC_16_PLT_PCREL, + BFD_RELOC_8_PLT_PCREL, + BFD_RELOC_64_PLTOFF, + BFD_RELOC_32_PLTOFF, + BFD_RELOC_16_PLTOFF, + BFD_RELOC_LO16_PLTOFF, + BFD_RELOC_HI16_PLTOFF, + BFD_RELOC_HI16_S_PLTOFF, + BFD_RELOC_8_PLTOFF, + +/* Relocations used by 68K ELF. */ + BFD_RELOC_68K_GLOB_DAT, + BFD_RELOC_68K_JMP_SLOT, + BFD_RELOC_68K_RELATIVE, + +/* Linkage-table relative. */ + BFD_RELOC_32_BASEREL, + BFD_RELOC_16_BASEREL, + BFD_RELOC_LO16_BASEREL, + BFD_RELOC_HI16_BASEREL, + BFD_RELOC_HI16_S_BASEREL, + BFD_RELOC_8_BASEREL, + BFD_RELOC_RVA, + +/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */ + BFD_RELOC_8_FFnn, + +/* These PC-relative relocations are stored as word displacements -- +i.e., byte displacements shifted right two bits. The 30-bit word +displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the +SPARC. (SPARC tools generally refer to this as <>.) The +signed 16-bit displacement is used on the MIPS, and the 23-bit +displacement is used on the Alpha. */ + BFD_RELOC_32_PCREL_S2, + BFD_RELOC_16_PCREL_S2, + BFD_RELOC_23_PCREL_S2, + +/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of +the target word. These are used on the SPARC. */ + BFD_RELOC_HI22, + BFD_RELOC_LO10, + +/* For systems that allocate a Global Pointer register, these are +displacements off that register. These relocation types are +handled specially, because the value the register will have is +decided relatively late. */ + BFD_RELOC_GPREL16, + BFD_RELOC_GPREL32, + +/* Reloc types used for i960/b.out. */ + BFD_RELOC_I960_CALLJ, + +/* SPARC ELF relocations. There is probably some overlap with other +relocation types already defined. */ + BFD_RELOC_NONE, + BFD_RELOC_SPARC_WDISP22, + BFD_RELOC_SPARC22, + BFD_RELOC_SPARC13, + BFD_RELOC_SPARC_GOT10, + BFD_RELOC_SPARC_GOT13, + BFD_RELOC_SPARC_GOT22, + BFD_RELOC_SPARC_PC10, + BFD_RELOC_SPARC_PC22, + BFD_RELOC_SPARC_WPLT30, + BFD_RELOC_SPARC_COPY, + BFD_RELOC_SPARC_GLOB_DAT, + BFD_RELOC_SPARC_JMP_SLOT, + BFD_RELOC_SPARC_RELATIVE, + BFD_RELOC_SPARC_UA16, + BFD_RELOC_SPARC_UA32, + BFD_RELOC_SPARC_UA64, + +/* I think these are specific to SPARC a.out (e.g., Sun 4). */ + BFD_RELOC_SPARC_BASE13, + BFD_RELOC_SPARC_BASE22, + +/* SPARC64 relocations */ +#define BFD_RELOC_SPARC_64 BFD_RELOC_64 + BFD_RELOC_SPARC_10, + BFD_RELOC_SPARC_11, + BFD_RELOC_SPARC_OLO10, + BFD_RELOC_SPARC_HH22, + BFD_RELOC_SPARC_HM10, + BFD_RELOC_SPARC_LM22, + BFD_RELOC_SPARC_PC_HH22, + BFD_RELOC_SPARC_PC_HM10, + BFD_RELOC_SPARC_PC_LM22, + BFD_RELOC_SPARC_WDISP16, + BFD_RELOC_SPARC_WDISP19, + BFD_RELOC_SPARC_7, + BFD_RELOC_SPARC_6, + BFD_RELOC_SPARC_5, +#define BFD_RELOC_SPARC_DISP64 BFD_RELOC_64_PCREL + BFD_RELOC_SPARC_PLT32, + BFD_RELOC_SPARC_PLT64, + BFD_RELOC_SPARC_HIX22, + BFD_RELOC_SPARC_LOX10, + BFD_RELOC_SPARC_H44, + BFD_RELOC_SPARC_M44, + BFD_RELOC_SPARC_L44, + BFD_RELOC_SPARC_REGISTER, + +/* SPARC little endian relocation */ + BFD_RELOC_SPARC_REV32, + +/* SPARC TLS relocations */ + BFD_RELOC_SPARC_TLS_GD_HI22, + BFD_RELOC_SPARC_TLS_GD_LO10, + BFD_RELOC_SPARC_TLS_GD_ADD, + BFD_RELOC_SPARC_TLS_GD_CALL, + BFD_RELOC_SPARC_TLS_LDM_HI22, + BFD_RELOC_SPARC_TLS_LDM_LO10, + BFD_RELOC_SPARC_TLS_LDM_ADD, + BFD_RELOC_SPARC_TLS_LDM_CALL, + BFD_RELOC_SPARC_TLS_LDO_HIX22, + BFD_RELOC_SPARC_TLS_LDO_LOX10, + BFD_RELOC_SPARC_TLS_LDO_ADD, + BFD_RELOC_SPARC_TLS_IE_HI22, + BFD_RELOC_SPARC_TLS_IE_LO10, + BFD_RELOC_SPARC_TLS_IE_LD, + BFD_RELOC_SPARC_TLS_IE_LDX, + BFD_RELOC_SPARC_TLS_IE_ADD, + BFD_RELOC_SPARC_TLS_LE_HIX22, + BFD_RELOC_SPARC_TLS_LE_LOX10, + BFD_RELOC_SPARC_TLS_DTPMOD32, + BFD_RELOC_SPARC_TLS_DTPMOD64, + BFD_RELOC_SPARC_TLS_DTPOFF32, + BFD_RELOC_SPARC_TLS_DTPOFF64, + BFD_RELOC_SPARC_TLS_TPOFF32, + BFD_RELOC_SPARC_TLS_TPOFF64, + +/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or +"addend" in some special way. +For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when +writing; when reading, it will be the absolute section symbol. The +addend is the displacement in bytes of the "lda" instruction from +the "ldah" instruction (which is at the address of this reloc). */ + BFD_RELOC_ALPHA_GPDISP_HI16, + +/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as +with GPDISP_HI16 relocs. The addend is ignored when writing the +relocations out, and is filled in with the file's GP value on +reading, for convenience. */ + BFD_RELOC_ALPHA_GPDISP_LO16, + +/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 +relocation except that there is no accompanying GPDISP_LO16 +relocation. */ + BFD_RELOC_ALPHA_GPDISP, + +/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; +the assembler turns it into a LDQ instruction to load the address of +the symbol, and then fills in a register in the real instruction. + +The LITERAL reloc, at the LDQ instruction, refers to the .lita +section symbol. The addend is ignored when writing, but is filled +in with the file's GP value on reading, for convenience, as with the +GPDISP_LO16 reloc. + +The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16. +It should refer to the symbol to be referenced, as with 16_GOTOFF, +but it generates output not based on the position within the .got +section, but relative to the GP value chosen for the file during the +final link stage. + +The LITUSE reloc, on the instruction using the loaded address, gives +information to the linker that it might be able to use to optimize +away some literal section references. The symbol is ignored (read +as the absolute section symbol), and the "addend" indicates the type +of instruction using the register: +1 - "memory" fmt insn +2 - byte-manipulation (byte offset reg) +3 - jsr (target of branch) */ + BFD_RELOC_ALPHA_LITERAL, + BFD_RELOC_ALPHA_ELF_LITERAL, + BFD_RELOC_ALPHA_LITUSE, + +/* The HINT relocation indicates a value that should be filled into the +"hint" field of a jmp/jsr/ret instruction, for possible branch- +prediction logic which may be provided on some processors. */ + BFD_RELOC_ALPHA_HINT, + +/* The LINKAGE relocation outputs a linkage pair in the object file, +which is filled by the linker. */ + BFD_RELOC_ALPHA_LINKAGE, + +/* The CODEADDR relocation outputs a STO_CA in the object file, +which is filled by the linker. */ + BFD_RELOC_ALPHA_CODEADDR, + +/* The GPREL_HI/LO relocations together form a 32-bit offset from the +GP register. */ + BFD_RELOC_ALPHA_GPREL_HI16, + BFD_RELOC_ALPHA_GPREL_LO16, + +/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must +share a common GP, and the target address is adjusted for +STO_ALPHA_STD_GPLOAD. */ + BFD_RELOC_ALPHA_BRSGP, + +/* Alpha thread-local storage relocations. */ + BFD_RELOC_ALPHA_TLSGD, + BFD_RELOC_ALPHA_TLSLDM, + BFD_RELOC_ALPHA_DTPMOD64, + BFD_RELOC_ALPHA_GOTDTPREL16, + BFD_RELOC_ALPHA_DTPREL64, + BFD_RELOC_ALPHA_DTPREL_HI16, + BFD_RELOC_ALPHA_DTPREL_LO16, + BFD_RELOC_ALPHA_DTPREL16, + BFD_RELOC_ALPHA_GOTTPREL16, + BFD_RELOC_ALPHA_TPREL64, + BFD_RELOC_ALPHA_TPREL_HI16, + BFD_RELOC_ALPHA_TPREL_LO16, + BFD_RELOC_ALPHA_TPREL16, + +/* Bits 27..2 of the relocation address shifted right 2 bits; +simple reloc otherwise. */ + BFD_RELOC_MIPS_JMP, + +/* The MIPS16 jump instruction. */ + BFD_RELOC_MIPS16_JMP, + +/* MIPS16 GP relative reloc. */ + BFD_RELOC_MIPS16_GPREL, + +/* High 16 bits of 32-bit value; simple reloc. */ + BFD_RELOC_HI16, + +/* High 16 bits of 32-bit value but the low 16 bits will be sign +extended and added to form the final result. If the low 16 +bits form a negative number, we need to add one to the high value +to compensate for the borrow when the low bits are added. */ + BFD_RELOC_HI16_S, + +/* Low 16 bits. */ + BFD_RELOC_LO16, + +/* Relocation against a MIPS literal section. */ + BFD_RELOC_MIPS_LITERAL, + +/* MIPS ELF relocations. */ + BFD_RELOC_MIPS_GOT16, + BFD_RELOC_MIPS_CALL16, + BFD_RELOC_MIPS_GOT_HI16, + BFD_RELOC_MIPS_GOT_LO16, + BFD_RELOC_MIPS_CALL_HI16, + BFD_RELOC_MIPS_CALL_LO16, + BFD_RELOC_MIPS_SUB, + BFD_RELOC_MIPS_GOT_PAGE, + BFD_RELOC_MIPS_GOT_OFST, + BFD_RELOC_MIPS_GOT_DISP, + BFD_RELOC_MIPS_SHIFT5, + BFD_RELOC_MIPS_SHIFT6, + BFD_RELOC_MIPS_INSERT_A, + BFD_RELOC_MIPS_INSERT_B, + BFD_RELOC_MIPS_DELETE, + BFD_RELOC_MIPS_HIGHEST, + BFD_RELOC_MIPS_HIGHER, + BFD_RELOC_MIPS_SCN_DISP, + BFD_RELOC_MIPS_REL16, + BFD_RELOC_MIPS_RELGOT, + BFD_RELOC_MIPS_JALR, + + +/* Fujitsu Frv Relocations. */ + BFD_RELOC_FRV_LABEL16, + BFD_RELOC_FRV_LABEL24, + BFD_RELOC_FRV_LO16, + BFD_RELOC_FRV_HI16, + BFD_RELOC_FRV_GPREL12, + BFD_RELOC_FRV_GPRELU12, + BFD_RELOC_FRV_GPREL32, + BFD_RELOC_FRV_GPRELHI, + BFD_RELOC_FRV_GPRELLO, + BFD_RELOC_FRV_GOT12, + BFD_RELOC_FRV_GOTHI, + BFD_RELOC_FRV_GOTLO, + BFD_RELOC_FRV_FUNCDESC, + BFD_RELOC_FRV_FUNCDESC_GOT12, + BFD_RELOC_FRV_FUNCDESC_GOTHI, + BFD_RELOC_FRV_FUNCDESC_GOTLO, + BFD_RELOC_FRV_FUNCDESC_VALUE, + BFD_RELOC_FRV_FUNCDESC_GOTOFF12, + BFD_RELOC_FRV_FUNCDESC_GOTOFFHI, + BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, + BFD_RELOC_FRV_GOTOFF12, + BFD_RELOC_FRV_GOTOFFHI, + BFD_RELOC_FRV_GOTOFFLO, + + +/* This is a 24bit GOT-relative reloc for the mn10300. */ + BFD_RELOC_MN10300_GOTOFF24, + +/* This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes +in the instruction. */ + BFD_RELOC_MN10300_GOT32, + +/* This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes +in the instruction. */ + BFD_RELOC_MN10300_GOT24, + +/* This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes +in the instruction. */ + BFD_RELOC_MN10300_GOT16, + +/* Copy symbol at runtime. */ + BFD_RELOC_MN10300_COPY, + +/* Create GOT entry. */ + BFD_RELOC_MN10300_GLOB_DAT, + +/* Create PLT entry. */ + BFD_RELOC_MN10300_JMP_SLOT, + +/* Adjust by program base. */ + BFD_RELOC_MN10300_RELATIVE, + + +/* i386/elf relocations */ + BFD_RELOC_386_GOT32, + BFD_RELOC_386_PLT32, + BFD_RELOC_386_COPY, + BFD_RELOC_386_GLOB_DAT, + BFD_RELOC_386_JUMP_SLOT, + BFD_RELOC_386_RELATIVE, + BFD_RELOC_386_GOTOFF, + BFD_RELOC_386_GOTPC, + BFD_RELOC_386_TLS_TPOFF, + BFD_RELOC_386_TLS_IE, + BFD_RELOC_386_TLS_GOTIE, + BFD_RELOC_386_TLS_LE, + BFD_RELOC_386_TLS_GD, + BFD_RELOC_386_TLS_LDM, + BFD_RELOC_386_TLS_LDO_32, + BFD_RELOC_386_TLS_IE_32, + BFD_RELOC_386_TLS_LE_32, + BFD_RELOC_386_TLS_DTPMOD32, + BFD_RELOC_386_TLS_DTPOFF32, + BFD_RELOC_386_TLS_TPOFF32, + +/* x86-64/elf relocations */ + BFD_RELOC_X86_64_GOT32, + BFD_RELOC_X86_64_PLT32, + BFD_RELOC_X86_64_COPY, + BFD_RELOC_X86_64_GLOB_DAT, + BFD_RELOC_X86_64_JUMP_SLOT, + BFD_RELOC_X86_64_RELATIVE, + BFD_RELOC_X86_64_GOTPCREL, + BFD_RELOC_X86_64_32S, + BFD_RELOC_X86_64_DTPMOD64, + BFD_RELOC_X86_64_DTPOFF64, + BFD_RELOC_X86_64_TPOFF64, + BFD_RELOC_X86_64_TLSGD, + BFD_RELOC_X86_64_TLSLD, + BFD_RELOC_X86_64_DTPOFF32, + BFD_RELOC_X86_64_GOTTPOFF, + BFD_RELOC_X86_64_TPOFF32, + +/* ns32k relocations */ + BFD_RELOC_NS32K_IMM_8, + BFD_RELOC_NS32K_IMM_16, + BFD_RELOC_NS32K_IMM_32, + BFD_RELOC_NS32K_IMM_8_PCREL, + BFD_RELOC_NS32K_IMM_16_PCREL, + BFD_RELOC_NS32K_IMM_32_PCREL, + BFD_RELOC_NS32K_DISP_8, + BFD_RELOC_NS32K_DISP_16, + BFD_RELOC_NS32K_DISP_32, + BFD_RELOC_NS32K_DISP_8_PCREL, + BFD_RELOC_NS32K_DISP_16_PCREL, + BFD_RELOC_NS32K_DISP_32_PCREL, + +/* PDP11 relocations */ + BFD_RELOC_PDP11_DISP_8_PCREL, + BFD_RELOC_PDP11_DISP_6_PCREL, + +/* Picojava relocs. Not all of these appear in object files. */ + BFD_RELOC_PJ_CODE_HI16, + BFD_RELOC_PJ_CODE_LO16, + BFD_RELOC_PJ_CODE_DIR16, + BFD_RELOC_PJ_CODE_DIR32, + BFD_RELOC_PJ_CODE_REL16, + BFD_RELOC_PJ_CODE_REL32, + +/* Power(rs6000) and PowerPC relocations. */ + BFD_RELOC_PPC_B26, + BFD_RELOC_PPC_BA26, + BFD_RELOC_PPC_TOC16, + BFD_RELOC_PPC_B16, + BFD_RELOC_PPC_B16_BRTAKEN, + BFD_RELOC_PPC_B16_BRNTAKEN, + BFD_RELOC_PPC_BA16, + BFD_RELOC_PPC_BA16_BRTAKEN, + BFD_RELOC_PPC_BA16_BRNTAKEN, + BFD_RELOC_PPC_COPY, + BFD_RELOC_PPC_GLOB_DAT, + BFD_RELOC_PPC_JMP_SLOT, + BFD_RELOC_PPC_RELATIVE, + BFD_RELOC_PPC_LOCAL24PC, + BFD_RELOC_PPC_EMB_NADDR32, + BFD_RELOC_PPC_EMB_NADDR16, + BFD_RELOC_PPC_EMB_NADDR16_LO, + BFD_RELOC_PPC_EMB_NADDR16_HI, + BFD_RELOC_PPC_EMB_NADDR16_HA, + BFD_RELOC_PPC_EMB_SDAI16, + BFD_RELOC_PPC_EMB_SDA2I16, + BFD_RELOC_PPC_EMB_SDA2REL, + BFD_RELOC_PPC_EMB_SDA21, + BFD_RELOC_PPC_EMB_MRKREF, + BFD_RELOC_PPC_EMB_RELSEC16, + BFD_RELOC_PPC_EMB_RELST_LO, + BFD_RELOC_PPC_EMB_RELST_HI, + BFD_RELOC_PPC_EMB_RELST_HA, + BFD_RELOC_PPC_EMB_BIT_FLD, + BFD_RELOC_PPC_EMB_RELSDA, + BFD_RELOC_PPC64_HIGHER, + BFD_RELOC_PPC64_HIGHER_S, + BFD_RELOC_PPC64_HIGHEST, + BFD_RELOC_PPC64_HIGHEST_S, + BFD_RELOC_PPC64_TOC16_LO, + BFD_RELOC_PPC64_TOC16_HI, + BFD_RELOC_PPC64_TOC16_HA, + BFD_RELOC_PPC64_TOC, + BFD_RELOC_PPC64_PLTGOT16, + BFD_RELOC_PPC64_PLTGOT16_LO, + BFD_RELOC_PPC64_PLTGOT16_HI, + BFD_RELOC_PPC64_PLTGOT16_HA, + BFD_RELOC_PPC64_ADDR16_DS, + BFD_RELOC_PPC64_ADDR16_LO_DS, + BFD_RELOC_PPC64_GOT16_DS, + BFD_RELOC_PPC64_GOT16_LO_DS, + BFD_RELOC_PPC64_PLT16_LO_DS, + BFD_RELOC_PPC64_SECTOFF_DS, + BFD_RELOC_PPC64_SECTOFF_LO_DS, + BFD_RELOC_PPC64_TOC16_DS, + BFD_RELOC_PPC64_TOC16_LO_DS, + BFD_RELOC_PPC64_PLTGOT16_DS, + BFD_RELOC_PPC64_PLTGOT16_LO_DS, + +/* PowerPC and PowerPC64 thread-local storage relocations. */ + BFD_RELOC_PPC_TLS, + BFD_RELOC_PPC_DTPMOD, + BFD_RELOC_PPC_TPREL16, + BFD_RELOC_PPC_TPREL16_LO, + BFD_RELOC_PPC_TPREL16_HI, + BFD_RELOC_PPC_TPREL16_HA, + BFD_RELOC_PPC_TPREL, + BFD_RELOC_PPC_DTPREL16, + BFD_RELOC_PPC_DTPREL16_LO, + BFD_RELOC_PPC_DTPREL16_HI, + BFD_RELOC_PPC_DTPREL16_HA, + BFD_RELOC_PPC_DTPREL, + BFD_RELOC_PPC_GOT_TLSGD16, + BFD_RELOC_PPC_GOT_TLSGD16_LO, + BFD_RELOC_PPC_GOT_TLSGD16_HI, + BFD_RELOC_PPC_GOT_TLSGD16_HA, + BFD_RELOC_PPC_GOT_TLSLD16, + BFD_RELOC_PPC_GOT_TLSLD16_LO, + BFD_RELOC_PPC_GOT_TLSLD16_HI, + BFD_RELOC_PPC_GOT_TLSLD16_HA, + BFD_RELOC_PPC_GOT_TPREL16, + BFD_RELOC_PPC_GOT_TPREL16_LO, + BFD_RELOC_PPC_GOT_TPREL16_HI, + BFD_RELOC_PPC_GOT_TPREL16_HA, + BFD_RELOC_PPC_GOT_DTPREL16, + BFD_RELOC_PPC_GOT_DTPREL16_LO, + BFD_RELOC_PPC_GOT_DTPREL16_HI, + BFD_RELOC_PPC_GOT_DTPREL16_HA, + BFD_RELOC_PPC64_TPREL16_DS, + BFD_RELOC_PPC64_TPREL16_LO_DS, + BFD_RELOC_PPC64_TPREL16_HIGHER, + BFD_RELOC_PPC64_TPREL16_HIGHERA, + BFD_RELOC_PPC64_TPREL16_HIGHEST, + BFD_RELOC_PPC64_TPREL16_HIGHESTA, + BFD_RELOC_PPC64_DTPREL16_DS, + BFD_RELOC_PPC64_DTPREL16_LO_DS, + BFD_RELOC_PPC64_DTPREL16_HIGHER, + BFD_RELOC_PPC64_DTPREL16_HIGHERA, + BFD_RELOC_PPC64_DTPREL16_HIGHEST, + BFD_RELOC_PPC64_DTPREL16_HIGHESTA, + +/* IBM 370/390 relocations */ + BFD_RELOC_I370_D12, + +/* The type of reloc used to build a constructor table - at the moment +probably a 32 bit wide absolute relocation, but the target can choose. +It generally does map to one of the other relocation types. */ + BFD_RELOC_CTOR, + +/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are +not stored in the instruction. */ + BFD_RELOC_ARM_PCREL_BRANCH, + +/* ARM 26 bit pc-relative branch. The lowest bit must be zero and is +not stored in the instruction. The 2nd lowest bit comes from a 1 bit +field in the instruction. */ + BFD_RELOC_ARM_PCREL_BLX, + +/* Thumb 22 bit pc-relative branch. The lowest bit must be zero and is +not stored in the instruction. The 2nd lowest bit comes from a 1 bit +field in the instruction. */ + BFD_RELOC_THUMB_PCREL_BLX, + +/* These relocs are only used within the ARM assembler. They are not +(at present) written to any object files. */ + BFD_RELOC_ARM_IMMEDIATE, + BFD_RELOC_ARM_ADRL_IMMEDIATE, + BFD_RELOC_ARM_OFFSET_IMM, + BFD_RELOC_ARM_SHIFT_IMM, + BFD_RELOC_ARM_SMI, + BFD_RELOC_ARM_SWI, + BFD_RELOC_ARM_MULTI, + BFD_RELOC_ARM_CP_OFF_IMM, + BFD_RELOC_ARM_CP_OFF_IMM_S2, + BFD_RELOC_ARM_ADR_IMM, + BFD_RELOC_ARM_LDR_IMM, + BFD_RELOC_ARM_LITERAL, + BFD_RELOC_ARM_IN_POOL, + BFD_RELOC_ARM_OFFSET_IMM8, + BFD_RELOC_ARM_HWLITERAL, + BFD_RELOC_ARM_THUMB_ADD, + BFD_RELOC_ARM_THUMB_IMM, + BFD_RELOC_ARM_THUMB_SHIFT, + BFD_RELOC_ARM_THUMB_OFFSET, + BFD_RELOC_ARM_GOT12, + BFD_RELOC_ARM_GOT32, + BFD_RELOC_ARM_JUMP_SLOT, + BFD_RELOC_ARM_COPY, + BFD_RELOC_ARM_GLOB_DAT, + BFD_RELOC_ARM_PLT32, + BFD_RELOC_ARM_RELATIVE, + BFD_RELOC_ARM_GOTOFF, + BFD_RELOC_ARM_GOTPC, + +/* Pc-relative or absolute relocation depending on target. Used for +entries in .init_array sections. */ + BFD_RELOC_ARM_TARGET1, + +/* Read-only segment base relative address. */ + BFD_RELOC_ARM_ROSEGREL32, + +/* Data segment base relative address. */ + BFD_RELOC_ARM_SBREL32, + +/* This reloc is used for References to RTTI dta from exception handling +tables. The actual definition depends on the target. It may be a +pc-relative or some form of GOT-indirect relocation. */ + BFD_RELOC_ARM_TARGET2, + +/* 31-bit PC relative address. */ + BFD_RELOC_ARM_PREL31, + +/* Renesas / SuperH SH relocs. Not all of these appear in object files. */ + BFD_RELOC_SH_PCDISP8BY2, + BFD_RELOC_SH_PCDISP12BY2, + BFD_RELOC_SH_IMM3, + BFD_RELOC_SH_IMM3U, + BFD_RELOC_SH_DISP12, + BFD_RELOC_SH_DISP12BY2, + BFD_RELOC_SH_DISP12BY4, + BFD_RELOC_SH_DISP12BY8, + BFD_RELOC_SH_DISP20, + BFD_RELOC_SH_DISP20BY8, + BFD_RELOC_SH_IMM4, + BFD_RELOC_SH_IMM4BY2, + BFD_RELOC_SH_IMM4BY4, + BFD_RELOC_SH_IMM8, + BFD_RELOC_SH_IMM8BY2, + BFD_RELOC_SH_IMM8BY4, + BFD_RELOC_SH_PCRELIMM8BY2, + BFD_RELOC_SH_PCRELIMM8BY4, + BFD_RELOC_SH_SWITCH16, + BFD_RELOC_SH_SWITCH32, + BFD_RELOC_SH_USES, + BFD_RELOC_SH_COUNT, + BFD_RELOC_SH_ALIGN, + BFD_RELOC_SH_CODE, + BFD_RELOC_SH_DATA, + BFD_RELOC_SH_LABEL, + BFD_RELOC_SH_LOOP_START, + BFD_RELOC_SH_LOOP_END, + BFD_RELOC_SH_COPY, + BFD_RELOC_SH_GLOB_DAT, + BFD_RELOC_SH_JMP_SLOT, + BFD_RELOC_SH_RELATIVE, + BFD_RELOC_SH_GOTPC, + BFD_RELOC_SH_GOT_LOW16, + BFD_RELOC_SH_GOT_MEDLOW16, + BFD_RELOC_SH_GOT_MEDHI16, + BFD_RELOC_SH_GOT_HI16, + BFD_RELOC_SH_GOTPLT_LOW16, + BFD_RELOC_SH_GOTPLT_MEDLOW16, + BFD_RELOC_SH_GOTPLT_MEDHI16, + BFD_RELOC_SH_GOTPLT_HI16, + BFD_RELOC_SH_PLT_LOW16, + BFD_RELOC_SH_PLT_MEDLOW16, + BFD_RELOC_SH_PLT_MEDHI16, + BFD_RELOC_SH_PLT_HI16, + BFD_RELOC_SH_GOTOFF_LOW16, + BFD_RELOC_SH_GOTOFF_MEDLOW16, + BFD_RELOC_SH_GOTOFF_MEDHI16, + BFD_RELOC_SH_GOTOFF_HI16, + BFD_RELOC_SH_GOTPC_LOW16, + BFD_RELOC_SH_GOTPC_MEDLOW16, + BFD_RELOC_SH_GOTPC_MEDHI16, + BFD_RELOC_SH_GOTPC_HI16, + BFD_RELOC_SH_COPY64, + BFD_RELOC_SH_GLOB_DAT64, + BFD_RELOC_SH_JMP_SLOT64, + BFD_RELOC_SH_RELATIVE64, + BFD_RELOC_SH_GOT10BY4, + BFD_RELOC_SH_GOT10BY8, + BFD_RELOC_SH_GOTPLT10BY4, + BFD_RELOC_SH_GOTPLT10BY8, + BFD_RELOC_SH_GOTPLT32, + BFD_RELOC_SH_SHMEDIA_CODE, + BFD_RELOC_SH_IMMU5, + BFD_RELOC_SH_IMMS6, + BFD_RELOC_SH_IMMS6BY32, + BFD_RELOC_SH_IMMU6, + BFD_RELOC_SH_IMMS10, + BFD_RELOC_SH_IMMS10BY2, + BFD_RELOC_SH_IMMS10BY4, + BFD_RELOC_SH_IMMS10BY8, + BFD_RELOC_SH_IMMS16, + BFD_RELOC_SH_IMMU16, + BFD_RELOC_SH_IMM_LOW16, + BFD_RELOC_SH_IMM_LOW16_PCREL, + BFD_RELOC_SH_IMM_MEDLOW16, + BFD_RELOC_SH_IMM_MEDLOW16_PCREL, + BFD_RELOC_SH_IMM_MEDHI16, + BFD_RELOC_SH_IMM_MEDHI16_PCREL, + BFD_RELOC_SH_IMM_HI16, + BFD_RELOC_SH_IMM_HI16_PCREL, + BFD_RELOC_SH_PT_16, + BFD_RELOC_SH_TLS_GD_32, + BFD_RELOC_SH_TLS_LD_32, + BFD_RELOC_SH_TLS_LDO_32, + BFD_RELOC_SH_TLS_IE_32, + BFD_RELOC_SH_TLS_LE_32, + BFD_RELOC_SH_TLS_DTPMOD32, + BFD_RELOC_SH_TLS_DTPOFF32, + BFD_RELOC_SH_TLS_TPOFF32, + +/* Thumb 23-, 12- and 9-bit pc-relative branches. The lowest bit must +be zero and is not stored in the instruction. */ + BFD_RELOC_THUMB_PCREL_BRANCH9, + BFD_RELOC_THUMB_PCREL_BRANCH12, + BFD_RELOC_THUMB_PCREL_BRANCH23, + +/* ARC Cores relocs. +ARC 22 bit pc-relative branch. The lowest two bits must be zero and are +not stored in the instruction. The high 20 bits are installed in bits 26 +through 7 of the instruction. */ + BFD_RELOC_ARC_B22_PCREL, + +/* ARC 26 bit absolute branch. The lowest two bits must be zero and are not +stored in the instruction. The high 24 bits are installed in bits 23 +through 0. */ + BFD_RELOC_ARC_B26, + +/* Mitsubishi D10V relocs. +This is a 10-bit reloc with the right 2 bits +assumed to be 0. */ + BFD_RELOC_D10V_10_PCREL_R, + +/* Mitsubishi D10V relocs. +This is a 10-bit reloc with the right 2 bits +assumed to be 0. This is the same as the previous reloc +except it is in the left container, i.e., +shifted left 15 bits. */ + BFD_RELOC_D10V_10_PCREL_L, + +/* This is an 18-bit reloc with the right 2 bits +assumed to be 0. */ + BFD_RELOC_D10V_18, + +/* This is an 18-bit reloc with the right 2 bits +assumed to be 0. */ + BFD_RELOC_D10V_18_PCREL, + +/* Mitsubishi D30V relocs. +This is a 6-bit absolute reloc. */ + BFD_RELOC_D30V_6, + +/* This is a 6-bit pc-relative reloc with +the right 3 bits assumed to be 0. */ + BFD_RELOC_D30V_9_PCREL, + +/* This is a 6-bit pc-relative reloc with +the right 3 bits assumed to be 0. Same +as the previous reloc but on the right side +of the container. */ + BFD_RELOC_D30V_9_PCREL_R, + +/* This is a 12-bit absolute reloc with the +right 3 bitsassumed to be 0. */ + BFD_RELOC_D30V_15, + +/* This is a 12-bit pc-relative reloc with +the right 3 bits assumed to be 0. */ + BFD_RELOC_D30V_15_PCREL, + +/* This is a 12-bit pc-relative reloc with +the right 3 bits assumed to be 0. Same +as the previous reloc but on the right side +of the container. */ + BFD_RELOC_D30V_15_PCREL_R, + +/* This is an 18-bit absolute reloc with +the right 3 bits assumed to be 0. */ + BFD_RELOC_D30V_21, + +/* This is an 18-bit pc-relative reloc with +the right 3 bits assumed to be 0. */ + BFD_RELOC_D30V_21_PCREL, + +/* This is an 18-bit pc-relative reloc with +the right 3 bits assumed to be 0. Same +as the previous reloc but on the right side +of the container. */ + BFD_RELOC_D30V_21_PCREL_R, + +/* This is a 32-bit absolute reloc. */ + BFD_RELOC_D30V_32, + +/* This is a 32-bit pc-relative reloc. */ + BFD_RELOC_D30V_32_PCREL, + +/* DLX relocs */ + BFD_RELOC_DLX_HI16_S, + +/* DLX relocs */ + BFD_RELOC_DLX_LO16, + +/* DLX relocs */ + BFD_RELOC_DLX_JMP26, + +/* Renesas M32R (formerly Mitsubishi M32R) relocs. +This is a 24 bit absolute address. */ + BFD_RELOC_M32R_24, + +/* This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. */ + BFD_RELOC_M32R_10_PCREL, + +/* This is an 18-bit reloc with the right 2 bits assumed to be 0. */ + BFD_RELOC_M32R_18_PCREL, + +/* This is a 26-bit reloc with the right 2 bits assumed to be 0. */ + BFD_RELOC_M32R_26_PCREL, + +/* This is a 16-bit reloc containing the high 16 bits of an address +used when the lower 16 bits are treated as unsigned. */ + BFD_RELOC_M32R_HI16_ULO, + +/* This is a 16-bit reloc containing the high 16 bits of an address +used when the lower 16 bits are treated as signed. */ + BFD_RELOC_M32R_HI16_SLO, + +/* This is a 16-bit reloc containing the lower 16 bits of an address. */ + BFD_RELOC_M32R_LO16, + +/* This is a 16-bit reloc containing the small data area offset for use in +add3, load, and store instructions. */ + BFD_RELOC_M32R_SDA16, + +/* For PIC. */ + BFD_RELOC_M32R_GOT24, + BFD_RELOC_M32R_26_PLTREL, + BFD_RELOC_M32R_COPY, + BFD_RELOC_M32R_GLOB_DAT, + BFD_RELOC_M32R_JMP_SLOT, + BFD_RELOC_M32R_RELATIVE, + BFD_RELOC_M32R_GOTOFF, + BFD_RELOC_M32R_GOTOFF_HI_ULO, + BFD_RELOC_M32R_GOTOFF_HI_SLO, + BFD_RELOC_M32R_GOTOFF_LO, + BFD_RELOC_M32R_GOTPC24, + BFD_RELOC_M32R_GOT16_HI_ULO, + BFD_RELOC_M32R_GOT16_HI_SLO, + BFD_RELOC_M32R_GOT16_LO, + BFD_RELOC_M32R_GOTPC_HI_ULO, + BFD_RELOC_M32R_GOTPC_HI_SLO, + BFD_RELOC_M32R_GOTPC_LO, + +/* This is a 9-bit reloc */ + BFD_RELOC_V850_9_PCREL, + +/* This is a 22-bit reloc */ + BFD_RELOC_V850_22_PCREL, + +/* This is a 16 bit offset from the short data area pointer. */ + BFD_RELOC_V850_SDA_16_16_OFFSET, + +/* This is a 16 bit offset (of which only 15 bits are used) from the +short data area pointer. */ + BFD_RELOC_V850_SDA_15_16_OFFSET, + +/* This is a 16 bit offset from the zero data area pointer. */ + BFD_RELOC_V850_ZDA_16_16_OFFSET, + +/* This is a 16 bit offset (of which only 15 bits are used) from the +zero data area pointer. */ + BFD_RELOC_V850_ZDA_15_16_OFFSET, + +/* This is an 8 bit offset (of which only 6 bits are used) from the +tiny data area pointer. */ + BFD_RELOC_V850_TDA_6_8_OFFSET, + +/* This is an 8bit offset (of which only 7 bits are used) from the tiny +data area pointer. */ + BFD_RELOC_V850_TDA_7_8_OFFSET, + +/* This is a 7 bit offset from the tiny data area pointer. */ + BFD_RELOC_V850_TDA_7_7_OFFSET, + +/* This is a 16 bit offset from the tiny data area pointer. */ + BFD_RELOC_V850_TDA_16_16_OFFSET, + +/* This is a 5 bit offset (of which only 4 bits are used) from the tiny +data area pointer. */ + BFD_RELOC_V850_TDA_4_5_OFFSET, + +/* This is a 4 bit offset from the tiny data area pointer. */ + BFD_RELOC_V850_TDA_4_4_OFFSET, + +/* This is a 16 bit offset from the short data area pointer, with the +bits placed non-contiguously in the instruction. */ + BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, + +/* This is a 16 bit offset from the zero data area pointer, with the +bits placed non-contiguously in the instruction. */ + BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, + +/* This is a 6 bit offset from the call table base pointer. */ + BFD_RELOC_V850_CALLT_6_7_OFFSET, + +/* This is a 16 bit offset from the call table base pointer. */ + BFD_RELOC_V850_CALLT_16_16_OFFSET, + +/* Used for relaxing indirect function calls. */ + BFD_RELOC_V850_LONGCALL, + +/* Used for relaxing indirect jumps. */ + BFD_RELOC_V850_LONGJUMP, + +/* Used to maintain alignment whilst relaxing. */ + BFD_RELOC_V850_ALIGN, + +/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the +instruction. */ + BFD_RELOC_MN10300_32_PCREL, + +/* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the +instruction. */ + BFD_RELOC_MN10300_16_PCREL, + +/* This is a 8bit DP reloc for the tms320c30, where the most +significant 8 bits of a 24 bit word are placed into the least +significant 8 bits of the opcode. */ + BFD_RELOC_TIC30_LDP, + +/* This is a 7bit reloc for the tms320c54x, where the least +significant 7 bits of a 16 bit word are placed into the least +significant 7 bits of the opcode. */ + BFD_RELOC_TIC54X_PARTLS7, + +/* This is a 9bit DP reloc for the tms320c54x, where the most +significant 9 bits of a 16 bit word are placed into the least +significant 9 bits of the opcode. */ + BFD_RELOC_TIC54X_PARTMS9, + +/* This is an extended address 23-bit reloc for the tms320c54x. */ + BFD_RELOC_TIC54X_23, + +/* This is a 16-bit reloc for the tms320c54x, where the least +significant 16 bits of a 23-bit extended address are placed into +the opcode. */ + BFD_RELOC_TIC54X_16_OF_23, + +/* This is a reloc for the tms320c54x, where the most +significant 7 bits of a 23-bit extended address are placed into +the opcode. */ + BFD_RELOC_TIC54X_MS7_OF_23, + +/* This is a 48 bit reloc for the FR30 that stores 32 bits. */ + BFD_RELOC_FR30_48, + +/* This is a 32 bit reloc for the FR30 that stores 20 bits split up into +two sections. */ + BFD_RELOC_FR30_20, + +/* This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in +4 bits. */ + BFD_RELOC_FR30_6_IN_4, + +/* This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset +into 8 bits. */ + BFD_RELOC_FR30_8_IN_8, + +/* This is a 16 bit reloc for the FR30 that stores a 9 bit short offset +into 8 bits. */ + BFD_RELOC_FR30_9_IN_8, + +/* This is a 16 bit reloc for the FR30 that stores a 10 bit word offset +into 8 bits. */ + BFD_RELOC_FR30_10_IN_8, + +/* This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative +short offset into 8 bits. */ + BFD_RELOC_FR30_9_PCREL, + +/* This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative +short offset into 11 bits. */ + BFD_RELOC_FR30_12_PCREL, + +/* Motorola Mcore relocations. */ + BFD_RELOC_MCORE_PCREL_IMM8BY4, + BFD_RELOC_MCORE_PCREL_IMM11BY2, + BFD_RELOC_MCORE_PCREL_IMM4BY2, + BFD_RELOC_MCORE_PCREL_32, + BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, + BFD_RELOC_MCORE_RVA, + +/* These are relocations for the GETA instruction. */ + BFD_RELOC_MMIX_GETA, + BFD_RELOC_MMIX_GETA_1, + BFD_RELOC_MMIX_GETA_2, + BFD_RELOC_MMIX_GETA_3, + +/* These are relocations for a conditional branch instruction. */ + BFD_RELOC_MMIX_CBRANCH, + BFD_RELOC_MMIX_CBRANCH_J, + BFD_RELOC_MMIX_CBRANCH_1, + BFD_RELOC_MMIX_CBRANCH_2, + BFD_RELOC_MMIX_CBRANCH_3, + +/* These are relocations for the PUSHJ instruction. */ + BFD_RELOC_MMIX_PUSHJ, + BFD_RELOC_MMIX_PUSHJ_1, + BFD_RELOC_MMIX_PUSHJ_2, + BFD_RELOC_MMIX_PUSHJ_3, + BFD_RELOC_MMIX_PUSHJ_STUBBABLE, + +/* These are relocations for the JMP instruction. */ + BFD_RELOC_MMIX_JMP, + BFD_RELOC_MMIX_JMP_1, + BFD_RELOC_MMIX_JMP_2, + BFD_RELOC_MMIX_JMP_3, + +/* This is a relocation for a relative address as in a GETA instruction or +a branch. */ + BFD_RELOC_MMIX_ADDR19, + +/* This is a relocation for a relative address as in a JMP instruction. */ + BFD_RELOC_MMIX_ADDR27, + +/* This is a relocation for an instruction field that may be a general +register or a value 0..255. */ + BFD_RELOC_MMIX_REG_OR_BYTE, + +/* This is a relocation for an instruction field that may be a general +register. */ + BFD_RELOC_MMIX_REG, + +/* This is a relocation for two instruction fields holding a register and +an offset, the equivalent of the relocation. */ + BFD_RELOC_MMIX_BASE_PLUS_OFFSET, + +/* This relocation is an assertion that the expression is not allocated as +a global register. It does not modify contents. */ + BFD_RELOC_MMIX_LOCAL, + +/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative +short offset into 7 bits. */ + BFD_RELOC_AVR_7_PCREL, + +/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative +short offset into 12 bits. */ + BFD_RELOC_AVR_13_PCREL, + +/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually +program memory address) into 16 bits. */ + BFD_RELOC_AVR_16_PM, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually +data memory address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_LO8_LDI, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit +of data memory address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_HI8_LDI, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit +of program memory address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_HH8_LDI, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(usually data memory address) into 8 bit immediate value of SUBI insn. */ + BFD_RELOC_AVR_LO8_LDI_NEG, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(high 8 bit of data memory address) into 8 bit immediate value of +SUBI insn. */ + BFD_RELOC_AVR_HI8_LDI_NEG, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(most high 8 bit of program memory address) into 8 bit immediate value +of LDI or SUBI insn. */ + BFD_RELOC_AVR_HH8_LDI_NEG, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually +command address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_LO8_LDI_PM, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit +of command address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_HI8_LDI_PM, + +/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit +of command address) into 8 bit immediate value of LDI insn. */ + BFD_RELOC_AVR_HH8_LDI_PM, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(usually command address) into 8 bit immediate value of SUBI insn. */ + BFD_RELOC_AVR_LO8_LDI_PM_NEG, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(high 8 bit of 16 bit command address) into 8 bit immediate value +of SUBI insn. */ + BFD_RELOC_AVR_HI8_LDI_PM_NEG, + +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value +(high 6 bit of 22 bit command address) into 8 bit immediate +value of SUBI insn. */ + BFD_RELOC_AVR_HH8_LDI_PM_NEG, + +/* This is a 32 bit reloc for the AVR that stores 23 bit value +into 22 bits. */ + BFD_RELOC_AVR_CALL, + +/* Direct 12 bit. */ + BFD_RELOC_390_12, + +/* 12 bit GOT offset. */ + BFD_RELOC_390_GOT12, + +/* 32 bit PC relative PLT address. */ + BFD_RELOC_390_PLT32, + +/* Copy symbol at runtime. */ + BFD_RELOC_390_COPY, + +/* Create GOT entry. */ + BFD_RELOC_390_GLOB_DAT, + +/* Create PLT entry. */ + BFD_RELOC_390_JMP_SLOT, + +/* Adjust by program base. */ + BFD_RELOC_390_RELATIVE, + +/* 32 bit PC relative offset to GOT. */ + BFD_RELOC_390_GOTPC, + +/* 16 bit GOT offset. */ + BFD_RELOC_390_GOT16, + +/* PC relative 16 bit shifted by 1. */ + BFD_RELOC_390_PC16DBL, + +/* 16 bit PC rel. PLT shifted by 1. */ + BFD_RELOC_390_PLT16DBL, + +/* PC relative 32 bit shifted by 1. */ + BFD_RELOC_390_PC32DBL, + +/* 32 bit PC rel. PLT shifted by 1. */ + BFD_RELOC_390_PLT32DBL, + +/* 32 bit PC rel. GOT shifted by 1. */ + BFD_RELOC_390_GOTPCDBL, + +/* 64 bit GOT offset. */ + BFD_RELOC_390_GOT64, + +/* 64 bit PC relative PLT address. */ + BFD_RELOC_390_PLT64, + +/* 32 bit rel. offset to GOT entry. */ + BFD_RELOC_390_GOTENT, + +/* 64 bit offset to GOT. */ + BFD_RELOC_390_GOTOFF64, + +/* 12-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLT12, + +/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLT16, + +/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLT32, + +/* 64-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLT64, + +/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_390_GOTPLTENT, + +/* 16-bit rel. offset from the GOT to a PLT entry. */ + BFD_RELOC_390_PLTOFF16, + +/* 32-bit rel. offset from the GOT to a PLT entry. */ + BFD_RELOC_390_PLTOFF32, + +/* 64-bit rel. offset from the GOT to a PLT entry. */ + BFD_RELOC_390_PLTOFF64, + +/* s390 tls relocations. */ + BFD_RELOC_390_TLS_LOAD, + BFD_RELOC_390_TLS_GDCALL, + BFD_RELOC_390_TLS_LDCALL, + BFD_RELOC_390_TLS_GD32, + BFD_RELOC_390_TLS_GD64, + BFD_RELOC_390_TLS_GOTIE12, + BFD_RELOC_390_TLS_GOTIE32, + BFD_RELOC_390_TLS_GOTIE64, + BFD_RELOC_390_TLS_LDM32, + BFD_RELOC_390_TLS_LDM64, + BFD_RELOC_390_TLS_IE32, + BFD_RELOC_390_TLS_IE64, + BFD_RELOC_390_TLS_IEENT, + BFD_RELOC_390_TLS_LE32, + BFD_RELOC_390_TLS_LE64, + BFD_RELOC_390_TLS_LDO32, + BFD_RELOC_390_TLS_LDO64, + BFD_RELOC_390_TLS_DTPMOD, + BFD_RELOC_390_TLS_DTPOFF, + BFD_RELOC_390_TLS_TPOFF, + +/* Long displacement extension. */ + BFD_RELOC_390_20, + BFD_RELOC_390_GOT20, + BFD_RELOC_390_GOTPLT20, + BFD_RELOC_390_TLS_GOTIE20, + +/* Scenix IP2K - 9-bit register number / data address */ + BFD_RELOC_IP2K_FR9, + +/* Scenix IP2K - 4-bit register/data bank number */ + BFD_RELOC_IP2K_BANK, + +/* Scenix IP2K - low 13 bits of instruction word address */ + BFD_RELOC_IP2K_ADDR16CJP, + +/* Scenix IP2K - high 3 bits of instruction word address */ + BFD_RELOC_IP2K_PAGE3, + +/* Scenix IP2K - ext/low/high 8 bits of data address */ + BFD_RELOC_IP2K_LO8DATA, + BFD_RELOC_IP2K_HI8DATA, + BFD_RELOC_IP2K_EX8DATA, + +/* Scenix IP2K - low/high 8 bits of instruction word address */ + BFD_RELOC_IP2K_LO8INSN, + BFD_RELOC_IP2K_HI8INSN, + +/* Scenix IP2K - even/odd PC modifier to modify snb pcl.0 */ + BFD_RELOC_IP2K_PC_SKIP, + +/* Scenix IP2K - 16 bit word address in text section. */ + BFD_RELOC_IP2K_TEXT, + +/* Scenix IP2K - 7-bit sp or dp offset */ + BFD_RELOC_IP2K_FR_OFFSET, + +/* Scenix VPE4K coprocessor - data/insn-space addressing */ + BFD_RELOC_VPE4KMATH_DATA, + BFD_RELOC_VPE4KMATH_INSN, + +/* These two relocations are used by the linker to determine which of +the entries in a C++ virtual function table are actually used. When +the --gc-sections option is given, the linker will zero out the entries +that are not used, so that the code for those functions need not be +included in the output. + +VTABLE_INHERIT is a zero-space relocation used to describe to the +linker the inheritance tree of a C++ virtual function table. The +relocation's symbol should be the parent class' vtable, and the +relocation should be located at the child vtable. + +VTABLE_ENTRY is a zero-space relocation that describes the use of a +virtual function table entry. The reloc's symbol should refer to the +table of the class mentioned in the code. Off of that base, an offset +describes the entry that is being used. For Rela hosts, this offset +is stored in the reloc's addend. For Rel hosts, we are forced to put +this offset in the reloc's section offset. */ + BFD_RELOC_VTABLE_INHERIT, + BFD_RELOC_VTABLE_ENTRY, + +/* Intel IA64 Relocations. */ + BFD_RELOC_IA64_IMM14, + BFD_RELOC_IA64_IMM22, + BFD_RELOC_IA64_IMM64, + BFD_RELOC_IA64_DIR32MSB, + BFD_RELOC_IA64_DIR32LSB, + BFD_RELOC_IA64_DIR64MSB, + BFD_RELOC_IA64_DIR64LSB, + BFD_RELOC_IA64_GPREL22, + BFD_RELOC_IA64_GPREL64I, + BFD_RELOC_IA64_GPREL32MSB, + BFD_RELOC_IA64_GPREL32LSB, + BFD_RELOC_IA64_GPREL64MSB, + BFD_RELOC_IA64_GPREL64LSB, + BFD_RELOC_IA64_LTOFF22, + BFD_RELOC_IA64_LTOFF64I, + BFD_RELOC_IA64_PLTOFF22, + BFD_RELOC_IA64_PLTOFF64I, + BFD_RELOC_IA64_PLTOFF64MSB, + BFD_RELOC_IA64_PLTOFF64LSB, + BFD_RELOC_IA64_FPTR64I, + BFD_RELOC_IA64_FPTR32MSB, + BFD_RELOC_IA64_FPTR32LSB, + BFD_RELOC_IA64_FPTR64MSB, + BFD_RELOC_IA64_FPTR64LSB, + BFD_RELOC_IA64_PCREL21B, + BFD_RELOC_IA64_PCREL21BI, + BFD_RELOC_IA64_PCREL21M, + BFD_RELOC_IA64_PCREL21F, + BFD_RELOC_IA64_PCREL22, + BFD_RELOC_IA64_PCREL60B, + BFD_RELOC_IA64_PCREL64I, + BFD_RELOC_IA64_PCREL32MSB, + BFD_RELOC_IA64_PCREL32LSB, + BFD_RELOC_IA64_PCREL64MSB, + BFD_RELOC_IA64_PCREL64LSB, + BFD_RELOC_IA64_LTOFF_FPTR22, + BFD_RELOC_IA64_LTOFF_FPTR64I, + BFD_RELOC_IA64_LTOFF_FPTR32MSB, + BFD_RELOC_IA64_LTOFF_FPTR32LSB, + BFD_RELOC_IA64_LTOFF_FPTR64MSB, + BFD_RELOC_IA64_LTOFF_FPTR64LSB, + BFD_RELOC_IA64_SEGREL32MSB, + BFD_RELOC_IA64_SEGREL32LSB, + BFD_RELOC_IA64_SEGREL64MSB, + BFD_RELOC_IA64_SEGREL64LSB, + BFD_RELOC_IA64_SECREL32MSB, + BFD_RELOC_IA64_SECREL32LSB, + BFD_RELOC_IA64_SECREL64MSB, + BFD_RELOC_IA64_SECREL64LSB, + BFD_RELOC_IA64_REL32MSB, + BFD_RELOC_IA64_REL32LSB, + BFD_RELOC_IA64_REL64MSB, + BFD_RELOC_IA64_REL64LSB, + BFD_RELOC_IA64_LTV32MSB, + BFD_RELOC_IA64_LTV32LSB, + BFD_RELOC_IA64_LTV64MSB, + BFD_RELOC_IA64_LTV64LSB, + BFD_RELOC_IA64_IPLTMSB, + BFD_RELOC_IA64_IPLTLSB, + BFD_RELOC_IA64_COPY, + BFD_RELOC_IA64_LTOFF22X, + BFD_RELOC_IA64_LDXMOV, + BFD_RELOC_IA64_TPREL14, + BFD_RELOC_IA64_TPREL22, + BFD_RELOC_IA64_TPREL64I, + BFD_RELOC_IA64_TPREL64MSB, + BFD_RELOC_IA64_TPREL64LSB, + BFD_RELOC_IA64_LTOFF_TPREL22, + BFD_RELOC_IA64_DTPMOD64MSB, + BFD_RELOC_IA64_DTPMOD64LSB, + BFD_RELOC_IA64_LTOFF_DTPMOD22, + BFD_RELOC_IA64_DTPREL14, + BFD_RELOC_IA64_DTPREL22, + BFD_RELOC_IA64_DTPREL64I, + BFD_RELOC_IA64_DTPREL32MSB, + BFD_RELOC_IA64_DTPREL32LSB, + BFD_RELOC_IA64_DTPREL64MSB, + BFD_RELOC_IA64_DTPREL64LSB, + BFD_RELOC_IA64_LTOFF_DTPREL22, + +/* Motorola 68HC11 reloc. +This is the 8 bit high part of an absolute address. */ + BFD_RELOC_M68HC11_HI8, + +/* Motorola 68HC11 reloc. +This is the 8 bit low part of an absolute address. */ + BFD_RELOC_M68HC11_LO8, + +/* Motorola 68HC11 reloc. +This is the 3 bit of a value. */ + BFD_RELOC_M68HC11_3B, + +/* Motorola 68HC11 reloc. +This reloc marks the beginning of a jump/call instruction. +It is used for linker relaxation to correctly identify beginning +of instruction and change some branches to use PC-relative +addressing mode. */ + BFD_RELOC_M68HC11_RL_JUMP, + +/* Motorola 68HC11 reloc. +This reloc marks a group of several instructions that gcc generates +and for which the linker relaxation pass can modify and/or remove +some of them. */ + BFD_RELOC_M68HC11_RL_GROUP, + +/* Motorola 68HC11 reloc. +This is the 16-bit lower part of an address. It is used for 'call' +instruction to specify the symbol address without any special +transformation (due to memory bank window). */ + BFD_RELOC_M68HC11_LO16, + +/* Motorola 68HC11 reloc. +This is a 8-bit reloc that specifies the page number of an address. +It is used by 'call' instruction to specify the page number of +the symbol. */ + BFD_RELOC_M68HC11_PAGE, + +/* Motorola 68HC11 reloc. +This is a 24-bit reloc that represents the address with a 16-bit +value and a 8-bit page number. The symbol address is transformed +to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */ + BFD_RELOC_M68HC11_24, + +/* Motorola 68HC12 reloc. +This is the 5 bits of a value. */ + BFD_RELOC_M68HC12_5B, + +/* NS CR16C Relocations. */ + BFD_RELOC_16C_NUM08, + BFD_RELOC_16C_NUM08_C, + BFD_RELOC_16C_NUM16, + BFD_RELOC_16C_NUM16_C, + BFD_RELOC_16C_NUM32, + BFD_RELOC_16C_NUM32_C, + BFD_RELOC_16C_DISP04, + BFD_RELOC_16C_DISP04_C, + BFD_RELOC_16C_DISP08, + BFD_RELOC_16C_DISP08_C, + BFD_RELOC_16C_DISP16, + BFD_RELOC_16C_DISP16_C, + BFD_RELOC_16C_DISP24, + BFD_RELOC_16C_DISP24_C, + BFD_RELOC_16C_DISP24a, + BFD_RELOC_16C_DISP24a_C, + BFD_RELOC_16C_REG04, + BFD_RELOC_16C_REG04_C, + BFD_RELOC_16C_REG04a, + BFD_RELOC_16C_REG04a_C, + BFD_RELOC_16C_REG14, + BFD_RELOC_16C_REG14_C, + BFD_RELOC_16C_REG16, + BFD_RELOC_16C_REG16_C, + BFD_RELOC_16C_REG20, + BFD_RELOC_16C_REG20_C, + BFD_RELOC_16C_ABS20, + BFD_RELOC_16C_ABS20_C, + BFD_RELOC_16C_ABS24, + BFD_RELOC_16C_ABS24_C, + BFD_RELOC_16C_IMM04, + BFD_RELOC_16C_IMM04_C, + BFD_RELOC_16C_IMM16, + BFD_RELOC_16C_IMM16_C, + BFD_RELOC_16C_IMM20, + BFD_RELOC_16C_IMM20_C, + BFD_RELOC_16C_IMM24, + BFD_RELOC_16C_IMM24_C, + BFD_RELOC_16C_IMM32, + BFD_RELOC_16C_IMM32_C, + +/* NS CRX Relocations. */ + BFD_RELOC_CRX_REL4, + BFD_RELOC_CRX_REL8, + BFD_RELOC_CRX_REL8_CMP, + BFD_RELOC_CRX_REL16, + BFD_RELOC_CRX_REL24, + BFD_RELOC_CRX_REL32, + BFD_RELOC_CRX_REGREL12, + BFD_RELOC_CRX_REGREL22, + BFD_RELOC_CRX_REGREL28, + BFD_RELOC_CRX_REGREL32, + BFD_RELOC_CRX_ABS16, + BFD_RELOC_CRX_ABS32, + BFD_RELOC_CRX_NUM8, + BFD_RELOC_CRX_NUM16, + BFD_RELOC_CRX_NUM32, + BFD_RELOC_CRX_IMM16, + BFD_RELOC_CRX_IMM32, + BFD_RELOC_CRX_SWITCH8, + BFD_RELOC_CRX_SWITCH16, + BFD_RELOC_CRX_SWITCH32, + +/* These relocs are only used within the CRIS assembler. They are not +(at present) written to any object files. */ + BFD_RELOC_CRIS_BDISP8, + BFD_RELOC_CRIS_UNSIGNED_5, + BFD_RELOC_CRIS_SIGNED_6, + BFD_RELOC_CRIS_UNSIGNED_6, + BFD_RELOC_CRIS_UNSIGNED_4, + +/* Relocs used in ELF shared libraries for CRIS. */ + BFD_RELOC_CRIS_COPY, + BFD_RELOC_CRIS_GLOB_DAT, + BFD_RELOC_CRIS_JUMP_SLOT, + BFD_RELOC_CRIS_RELATIVE, + +/* 32-bit offset to symbol-entry within GOT. */ + BFD_RELOC_CRIS_32_GOT, + +/* 16-bit offset to symbol-entry within GOT. */ + BFD_RELOC_CRIS_16_GOT, + +/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_CRIS_32_GOTPLT, + +/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ + BFD_RELOC_CRIS_16_GOTPLT, + +/* 32-bit offset to symbol, relative to GOT. */ + BFD_RELOC_CRIS_32_GOTREL, + +/* 32-bit offset to symbol with PLT entry, relative to GOT. */ + BFD_RELOC_CRIS_32_PLT_GOTREL, + +/* 32-bit offset to symbol with PLT entry, relative to this relocation. */ + BFD_RELOC_CRIS_32_PLT_PCREL, + +/* Intel i860 Relocations. */ + BFD_RELOC_860_COPY, + BFD_RELOC_860_GLOB_DAT, + BFD_RELOC_860_JUMP_SLOT, + BFD_RELOC_860_RELATIVE, + BFD_RELOC_860_PC26, + BFD_RELOC_860_PLT26, + BFD_RELOC_860_PC16, + BFD_RELOC_860_LOW0, + BFD_RELOC_860_SPLIT0, + BFD_RELOC_860_LOW1, + BFD_RELOC_860_SPLIT1, + BFD_RELOC_860_LOW2, + BFD_RELOC_860_SPLIT2, + BFD_RELOC_860_LOW3, + BFD_RELOC_860_LOGOT0, + BFD_RELOC_860_SPGOT0, + BFD_RELOC_860_LOGOT1, + BFD_RELOC_860_SPGOT1, + BFD_RELOC_860_LOGOTOFF0, + BFD_RELOC_860_SPGOTOFF0, + BFD_RELOC_860_LOGOTOFF1, + BFD_RELOC_860_SPGOTOFF1, + BFD_RELOC_860_LOGOTOFF2, + BFD_RELOC_860_LOGOTOFF3, + BFD_RELOC_860_LOPC, + BFD_RELOC_860_HIGHADJ, + BFD_RELOC_860_HAGOT, + BFD_RELOC_860_HAGOTOFF, + BFD_RELOC_860_HAPC, + BFD_RELOC_860_HIGH, + BFD_RELOC_860_HIGOT, + BFD_RELOC_860_HIGOTOFF, + +/* OpenRISC Relocations. */ + BFD_RELOC_OPENRISC_ABS_26, + BFD_RELOC_OPENRISC_REL_26, + +/* H8 elf Relocations. */ + BFD_RELOC_H8_DIR16A8, + BFD_RELOC_H8_DIR16R8, + BFD_RELOC_H8_DIR24A8, + BFD_RELOC_H8_DIR24R8, + BFD_RELOC_H8_DIR32A16, + +/* Sony Xstormy16 Relocations. */ + BFD_RELOC_XSTORMY16_REL_12, + BFD_RELOC_XSTORMY16_12, + BFD_RELOC_XSTORMY16_24, + BFD_RELOC_XSTORMY16_FPTR16, + +/* Relocations used by VAX ELF. */ + BFD_RELOC_VAX_GLOB_DAT, + BFD_RELOC_VAX_JMP_SLOT, + BFD_RELOC_VAX_RELATIVE, + +/* msp430 specific relocation codes */ + BFD_RELOC_MSP430_10_PCREL, + BFD_RELOC_MSP430_16_PCREL, + BFD_RELOC_MSP430_16, + BFD_RELOC_MSP430_16_PCREL_BYTE, + BFD_RELOC_MSP430_16_BYTE, + BFD_RELOC_MSP430_2X_PCREL, + BFD_RELOC_MSP430_RL_PCREL, + +/* IQ2000 Relocations. */ + BFD_RELOC_IQ2000_OFFSET_16, + BFD_RELOC_IQ2000_OFFSET_21, + BFD_RELOC_IQ2000_UHI16, + +/* Special Xtensa relocation used only by PLT entries in ELF shared +objects to indicate that the runtime linker should set the value +to one of its own internal functions or data structures. */ + BFD_RELOC_XTENSA_RTLD, + +/* Xtensa relocations for ELF shared objects. */ + BFD_RELOC_XTENSA_GLOB_DAT, + BFD_RELOC_XTENSA_JMP_SLOT, + BFD_RELOC_XTENSA_RELATIVE, + +/* Xtensa relocation used in ELF object files for symbols that may require +PLT entries. Otherwise, this is just a generic 32-bit relocation. */ + BFD_RELOC_XTENSA_PLT, + +/* Xtensa relocations to mark the difference of two local symbols. +These are only needed to support linker relaxation and can be ignored +when not relaxing. The field is set to the value of the difference +assuming no relaxation. The relocation encodes the position of the +first symbol so the linker can determine whether to adjust the field +value. */ + BFD_RELOC_XTENSA_DIFF8, + BFD_RELOC_XTENSA_DIFF16, + BFD_RELOC_XTENSA_DIFF32, + +/* Generic Xtensa relocations for instruction operands. Only the slot +number is encoded in the relocation. The relocation applies to the +last PC-relative immediate operand, or if there are no PC-relative +immediates, to the last immediate operand. */ + BFD_RELOC_XTENSA_SLOT0_OP, + BFD_RELOC_XTENSA_SLOT1_OP, + BFD_RELOC_XTENSA_SLOT2_OP, + BFD_RELOC_XTENSA_SLOT3_OP, + BFD_RELOC_XTENSA_SLOT4_OP, + BFD_RELOC_XTENSA_SLOT5_OP, + BFD_RELOC_XTENSA_SLOT6_OP, + BFD_RELOC_XTENSA_SLOT7_OP, + BFD_RELOC_XTENSA_SLOT8_OP, + BFD_RELOC_XTENSA_SLOT9_OP, + BFD_RELOC_XTENSA_SLOT10_OP, + BFD_RELOC_XTENSA_SLOT11_OP, + BFD_RELOC_XTENSA_SLOT12_OP, + BFD_RELOC_XTENSA_SLOT13_OP, + BFD_RELOC_XTENSA_SLOT14_OP, + +/* Alternate Xtensa relocations. Only the slot is encoded in the +relocation. The meaning of these relocations is opcode-specific. */ + BFD_RELOC_XTENSA_SLOT0_ALT, + BFD_RELOC_XTENSA_SLOT1_ALT, + BFD_RELOC_XTENSA_SLOT2_ALT, + BFD_RELOC_XTENSA_SLOT3_ALT, + BFD_RELOC_XTENSA_SLOT4_ALT, + BFD_RELOC_XTENSA_SLOT5_ALT, + BFD_RELOC_XTENSA_SLOT6_ALT, + BFD_RELOC_XTENSA_SLOT7_ALT, + BFD_RELOC_XTENSA_SLOT8_ALT, + BFD_RELOC_XTENSA_SLOT9_ALT, + BFD_RELOC_XTENSA_SLOT10_ALT, + BFD_RELOC_XTENSA_SLOT11_ALT, + BFD_RELOC_XTENSA_SLOT12_ALT, + BFD_RELOC_XTENSA_SLOT13_ALT, + BFD_RELOC_XTENSA_SLOT14_ALT, + +/* Xtensa relocations for backward compatibility. These have all been +replaced by BFD_RELOC_XTENSA_SLOT0_OP. */ + BFD_RELOC_XTENSA_OP0, + BFD_RELOC_XTENSA_OP1, + BFD_RELOC_XTENSA_OP2, + +/* Xtensa relocation to mark that the assembler expanded the +instructions from an original target. The expansion size is +encoded in the reloc size. */ + BFD_RELOC_XTENSA_ASM_EXPAND, + +/* Xtensa relocation to mark that the linker should simplify +assembler-expanded instructions. This is commonly used +internally by the linker after analysis of a +BFD_RELOC_XTENSA_ASM_EXPAND. */ + BFD_RELOC_XTENSA_ASM_SIMPLIFY, + BFD_RELOC_UNUSED }; +typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; +reloc_howto_type *bfd_reloc_type_lookup + (bfd *abfd, bfd_reloc_code_real_type code); + +const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); + +/* Extracted from syms.c. */ + +typedef struct bfd_symbol +{ + /* A pointer to the BFD which owns the symbol. This information + is necessary so that a back end can work out what additional + information (invisible to the application writer) is carried + with the symbol. + + This field is *almost* redundant, since you can use section->owner + instead, except that some symbols point to the global sections + bfd_{abs,com,und}_section. This could be fixed by making + these globals be per-bfd (or per-target-flavor). FIXME. */ + struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ + + /* The text of the symbol. The name is left alone, and not copied; the + application may not alter it. */ + const char *name; + + /* The value of the symbol. This really should be a union of a + numeric value with a pointer, since some flags indicate that + a pointer to another symbol is stored here. */ + symvalue value; + + /* Attributes of a symbol. */ +#define BSF_NO_FLAGS 0x00 + + /* The symbol has local scope; <> in <>. The value + is the offset into the section of the data. */ +#define BSF_LOCAL 0x01 + + /* The symbol has global scope; initialized data in <>. The + value is the offset into the section of the data. */ +#define BSF_GLOBAL 0x02 + + /* The symbol has global scope and is exported. The value is + the offset into the section of the data. */ +#define BSF_EXPORT BSF_GLOBAL /* No real difference. */ + + /* A normal C symbol would be one of: + <>, <>, <> or + <>. */ + + /* The symbol is a debugging record. The value has an arbitrary + meaning, unless BSF_DEBUGGING_RELOC is also set. */ +#define BSF_DEBUGGING 0x08 + + /* The symbol denotes a function entry point. Used in ELF, + perhaps others someday. */ +#define BSF_FUNCTION 0x10 + + /* Used by the linker. */ +#define BSF_KEEP 0x20 +#define BSF_KEEP_G 0x40 + + /* A weak global symbol, overridable without warnings by + a regular global symbol of the same name. */ +#define BSF_WEAK 0x80 + + /* This symbol was created to point to a section, e.g. ELF's + STT_SECTION symbols. */ +#define BSF_SECTION_SYM 0x100 + + /* The symbol used to be a common symbol, but now it is + allocated. */ +#define BSF_OLD_COMMON 0x200 + + /* The default value for common data. */ +#define BFD_FORT_COMM_DEFAULT_VALUE 0 + + /* In some files the type of a symbol sometimes alters its + location in an output file - ie in coff a <> symbol + which is also <> symbol appears where it was + declared and not at the end of a section. This bit is set + by the target BFD part to convey this information. */ +#define BSF_NOT_AT_END 0x400 + + /* Signal that the symbol is the label of constructor section. */ +#define BSF_CONSTRUCTOR 0x800 + + /* Signal that the symbol is a warning symbol. The name is a + warning. The name of the next symbol is the one to warn about; + if a reference is made to a symbol with the same name as the next + symbol, a warning is issued by the linker. */ +#define BSF_WARNING 0x1000 + + /* Signal that the symbol is indirect. This symbol is an indirect + pointer to the symbol with the same name as the next symbol. */ +#define BSF_INDIRECT 0x2000 + + /* BSF_FILE marks symbols that contain a file name. This is used + for ELF STT_FILE symbols. */ +#define BSF_FILE 0x4000 + + /* Symbol is from dynamic linking information. */ +#define BSF_DYNAMIC 0x8000 + + /* The symbol denotes a data object. Used in ELF, and perhaps + others someday. */ +#define BSF_OBJECT 0x10000 + + /* This symbol is a debugging symbol. The value is the offset + into the section of the data. BSF_DEBUGGING should be set + as well. */ +#define BSF_DEBUGGING_RELOC 0x20000 + + /* This symbol is thread local. Used in ELF. */ +#define BSF_THREAD_LOCAL 0x40000 + + flagword flags; + + /* A pointer to the section to which this symbol is + relative. This will always be non NULL, there are special + sections for undefined and absolute symbols. */ + struct bfd_section *section; + + /* Back end special data. */ + union + { + void *p; + bfd_vma i; + } + udata; +} +asymbol; + +#define bfd_get_symtab_upper_bound(abfd) \ + BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) + +bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym); + +bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name); + +#define bfd_is_local_label_name(abfd, name) \ + BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) + +bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); + +#define bfd_is_target_special_symbol(abfd, sym) \ + BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) + +#define bfd_canonicalize_symtab(abfd, location) \ + BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) + +bfd_boolean bfd_set_symtab + (bfd *abfd, asymbol **location, unsigned int count); + +void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); + +#define bfd_make_empty_symbol(abfd) \ + BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) + +asymbol *_bfd_generic_make_empty_symbol (bfd *); + +#define bfd_make_debug_symbol(abfd,ptr,size) \ + BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) + +int bfd_decode_symclass (asymbol *symbol); + +bfd_boolean bfd_is_undefined_symclass (int symclass); + +void bfd_symbol_info (asymbol *symbol, symbol_info *ret); + +bfd_boolean bfd_copy_private_symbol_data + (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); + +#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ + BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ + (ibfd, isymbol, obfd, osymbol)) + +/* Extracted from bfd.c. */ +struct bfd +{ + /* A unique identifier of the BFD */ + unsigned int id; + + /* The filename the application opened the BFD with. */ + const char *filename; + + /* A pointer to the target jump table. */ + const struct bfd_target *xvec; + + /* The IOSTREAM, and corresponding IO vector that provide access + to the file backing the BFD. */ + void *iostream; + const struct bfd_iovec *iovec; + + /* Is the file descriptor being cached? That is, can it be closed as + needed, and re-opened when accessed later? */ + bfd_boolean cacheable; + + /* Marks whether there was a default target specified when the + BFD was opened. This is used to select which matching algorithm + to use to choose the back end. */ + bfd_boolean target_defaulted; + + /* The caching routines use these to maintain a + least-recently-used list of BFDs. */ + struct bfd *lru_prev, *lru_next; + + /* When a file is closed by the caching routines, BFD retains + state information on the file here... */ + ufile_ptr where; + + /* ... and here: (``once'' means at least once). */ + bfd_boolean opened_once; + + /* Set if we have a locally maintained mtime value, rather than + getting it from the file each time. */ + bfd_boolean mtime_set; + + /* File modified time, if mtime_set is TRUE. */ + long mtime; + + /* Reserved for an unimplemented file locking extension. */ + int ifd; + + /* The format which belongs to the BFD. (object, core, etc.) */ + bfd_format format; + + /* The direction with which the BFD was opened. */ + enum bfd_direction + { + no_direction = 0, + read_direction = 1, + write_direction = 2, + both_direction = 3 + } + direction; + + /* Format_specific flags. */ + flagword flags; + + /* Currently my_archive is tested before adding origin to + anything. I believe that this can become always an add of + origin, with origin set to 0 for non archive files. */ + ufile_ptr origin; + + /* Remember when output has begun, to stop strange things + from happening. */ + bfd_boolean output_has_begun; + + /* A hash table for section names. */ + struct bfd_hash_table section_htab; + + /* Pointer to linked list of sections. */ + struct bfd_section *sections; + + /* The place where we add to the section list. */ + struct bfd_section **section_tail; + + /* The number of sections. */ + unsigned int section_count; + + /* Stuff only useful for object files: + The start address. */ + bfd_vma start_address; + + /* Used for input and output. */ + unsigned int symcount; + + /* Symbol table for output BFD (with symcount entries). */ + struct bfd_symbol **outsymbols; + + /* Used for slurped dynamic symbol tables. */ + unsigned int dynsymcount; + + /* Pointer to structure which contains architecture information. */ + const struct bfd_arch_info *arch_info; + + /* Flag set if symbols from this BFD should not be exported. */ + bfd_boolean no_export; + + /* Stuff only useful for archives. */ + void *arelt_data; + struct bfd *my_archive; /* The containing archive BFD. */ + struct bfd *next; /* The next BFD in the archive. */ + struct bfd *archive_head; /* The first BFD in the archive. */ + bfd_boolean has_armap; + + /* A chain of BFD structures involved in a link. */ + struct bfd *link_next; + + /* A field used by _bfd_generic_link_add_archive_symbols. This will + be used only for archive elements. */ + int archive_pass; + + /* Used by the back end to hold private data. */ + union + { + struct aout_data_struct *aout_data; + struct artdata *aout_ar_data; + struct _oasys_data *oasys_obj_data; + struct _oasys_ar_data *oasys_ar_data; + struct coff_tdata *coff_obj_data; + struct pe_tdata *pe_obj_data; + struct xcoff_tdata *xcoff_obj_data; + struct ecoff_tdata *ecoff_obj_data; + struct ieee_data_struct *ieee_data; + struct ieee_ar_data_struct *ieee_ar_data; + struct srec_data_struct *srec_data; + struct ihex_data_struct *ihex_data; + struct tekhex_data_struct *tekhex_data; + struct elf_obj_tdata *elf_obj_data; + struct nlm_obj_tdata *nlm_obj_data; + struct bout_data_struct *bout_data; + struct mmo_data_struct *mmo_data; + struct sun_core_struct *sun_core_data; + struct sco5_core_struct *sco5_core_data; + struct trad_core_struct *trad_core_data; + struct som_data_struct *som_data; + struct hpux_core_struct *hpux_core_data; + struct hppabsd_core_struct *hppabsd_core_data; + struct sgi_core_struct *sgi_core_data; + struct lynx_core_struct *lynx_core_data; + struct osf_core_struct *osf_core_data; + struct cisco_core_struct *cisco_core_data; + struct versados_data_struct *versados_data; + struct netbsd_core_struct *netbsd_core_data; + struct mach_o_data_struct *mach_o_data; + struct mach_o_fat_data_struct *mach_o_fat_data; + struct bfd_pef_data_struct *pef_data; + struct bfd_pef_xlib_data_struct *pef_xlib_data; + struct bfd_sym_data_struct *sym_data; + void *any; + } + tdata; + + /* Used by the application to hold private data. */ + void *usrdata; + + /* Where all the allocated stuff under this BFD goes. This is a + struct objalloc *, but we use void * to avoid requiring the inclusion + of objalloc.h. */ + void *memory; +}; + +typedef enum bfd_error +{ + bfd_error_no_error = 0, + bfd_error_system_call, + bfd_error_invalid_target, + bfd_error_wrong_format, + bfd_error_wrong_object_format, + bfd_error_invalid_operation, + bfd_error_no_memory, + bfd_error_no_symbols, + bfd_error_no_armap, + bfd_error_no_more_archived_files, + bfd_error_malformed_archive, + bfd_error_file_not_recognized, + bfd_error_file_ambiguously_recognized, + bfd_error_no_contents, + bfd_error_nonrepresentable_section, + bfd_error_no_debug_section, + bfd_error_bad_value, + bfd_error_file_truncated, + bfd_error_file_too_big, + bfd_error_invalid_error_code +} +bfd_error_type; + +bfd_error_type bfd_get_error (void); + +void bfd_set_error (bfd_error_type error_tag); + +const char *bfd_errmsg (bfd_error_type error_tag); + +void bfd_perror (const char *message); + +typedef void (*bfd_error_handler_type) (const char *, ...); + +bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); + +void bfd_set_error_program_name (const char *); + +bfd_error_handler_type bfd_get_error_handler (void); + +long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect); + +long bfd_canonicalize_reloc + (bfd *abfd, asection *sec, arelent **loc, asymbol **syms); + +void bfd_set_reloc + (bfd *abfd, asection *sec, arelent **rel, unsigned int count); + +bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags); + +int bfd_get_arch_size (bfd *abfd); + +int bfd_get_sign_extend_vma (bfd *abfd); + +bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma); + +unsigned int bfd_get_gp_size (bfd *abfd); + +void bfd_set_gp_size (bfd *abfd, unsigned int i); + +bfd_vma bfd_scan_vma (const char *string, const char **end, int base); + +bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd); + +#define bfd_copy_private_header_data(ibfd, obfd) \ + BFD_SEND (obfd, _bfd_copy_private_header_data, \ + (ibfd, obfd)) +bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd); + +#define bfd_copy_private_bfd_data(ibfd, obfd) \ + BFD_SEND (obfd, _bfd_copy_private_bfd_data, \ + (ibfd, obfd)) +bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd); + +#define bfd_merge_private_bfd_data(ibfd, obfd) \ + BFD_SEND (obfd, _bfd_merge_private_bfd_data, \ + (ibfd, obfd)) +bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); + +#define bfd_set_private_flags(abfd, flags) \ + BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags)) +#define bfd_sizeof_headers(abfd, reloc) \ + BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) + +#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ + BFD_SEND (abfd, _bfd_find_nearest_line, \ + (abfd, sec, syms, off, file, func, line)) + +#define bfd_debug_info_start(abfd) \ + BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) + +#define bfd_debug_info_end(abfd) \ + BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) + +#define bfd_debug_info_accumulate(abfd, section) \ + BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) + +#define bfd_stat_arch_elt(abfd, stat) \ + BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) + +#define bfd_update_armap_timestamp(abfd) \ + BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) + +#define bfd_set_arch_mach(abfd, arch, mach)\ + BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) + +#define bfd_relax_section(abfd, section, link_info, again) \ + BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) + +#define bfd_gc_sections(abfd, link_info) \ + BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) + +#define bfd_merge_sections(abfd, link_info) \ + BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) + +#define bfd_is_group_section(abfd, sec) \ + BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec)) + +#define bfd_discard_group(abfd, sec) \ + BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) + +#define bfd_link_hash_table_create(abfd) \ + BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) + +#define bfd_link_hash_table_free(abfd, hash) \ + BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) + +#define bfd_link_add_symbols(abfd, info) \ + BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) + +#define bfd_link_just_syms(sec, info) \ + BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) + +#define bfd_final_link(abfd, info) \ + BFD_SEND (abfd, _bfd_final_link, (abfd, info)) + +#define bfd_free_cached_info(abfd) \ + BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) + +#define bfd_get_dynamic_symtab_upper_bound(abfd) \ + BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) + +#define bfd_print_private_bfd_data(abfd, file)\ + BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) + +#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ + BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) + +#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ + BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ + dyncount, dynsyms, ret)) + +#define bfd_get_dynamic_reloc_upper_bound(abfd) \ + BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) + +#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ + BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) + +extern bfd_byte *bfd_get_relocated_section_contents + (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, + bfd_boolean, asymbol **); + +bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative); + +struct bfd_preserve +{ + void *marker; + void *tdata; + flagword flags; + const struct bfd_arch_info *arch_info; + struct bfd_section *sections; + struct bfd_section **section_tail; + unsigned int section_count; + struct bfd_hash_table section_htab; +}; + +bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *); + +void bfd_preserve_restore (bfd *, struct bfd_preserve *); + +void bfd_preserve_finish (bfd *, struct bfd_preserve *); + +/* Extracted from archive.c. */ +symindex bfd_get_next_mapent + (bfd *abfd, symindex previous, carsym **sym); + +bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); + +bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); + +/* Extracted from corefile.c. */ +const char *bfd_core_file_failing_command (bfd *abfd); + +int bfd_core_file_failing_signal (bfd *abfd); + +bfd_boolean core_file_matches_executable_p + (bfd *core_bfd, bfd *exec_bfd); + +/* Extracted from targets.c. */ +#define BFD_SEND(bfd, message, arglist) \ + ((*((bfd)->xvec->message)) arglist) + +#ifdef DEBUG_BFD_SEND +#undef BFD_SEND +#define BFD_SEND(bfd, message, arglist) \ + (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ + ((*((bfd)->xvec->message)) arglist) : \ + (bfd_assert (__FILE__,__LINE__), NULL)) +#endif +#define BFD_SEND_FMT(bfd, message, arglist) \ + (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) + +#ifdef DEBUG_BFD_SEND +#undef BFD_SEND_FMT +#define BFD_SEND_FMT(bfd, message, arglist) \ + (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ + (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \ + (bfd_assert (__FILE__,__LINE__), NULL)) +#endif + +enum bfd_flavour +{ + bfd_target_unknown_flavour, + bfd_target_aout_flavour, + bfd_target_coff_flavour, + bfd_target_ecoff_flavour, + bfd_target_xcoff_flavour, + bfd_target_elf_flavour, + bfd_target_ieee_flavour, + bfd_target_nlm_flavour, + bfd_target_oasys_flavour, + bfd_target_tekhex_flavour, + bfd_target_srec_flavour, + bfd_target_ihex_flavour, + bfd_target_som_flavour, + bfd_target_os9k_flavour, + bfd_target_versados_flavour, + bfd_target_msdos_flavour, + bfd_target_ovax_flavour, + bfd_target_evax_flavour, + bfd_target_mmo_flavour, + bfd_target_mach_o_flavour, + bfd_target_pef_flavour, + bfd_target_pef_xlib_flavour, + bfd_target_sym_flavour +}; + +enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; + +/* Forward declaration. */ +typedef struct bfd_link_info _bfd_link_info; + +typedef struct bfd_target +{ + /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */ + char *name; + + /* The "flavour" of a back end is a general indication about + the contents of a file. */ + enum bfd_flavour flavour; + + /* The order of bytes within the data area of a file. */ + enum bfd_endian byteorder; + + /* The order of bytes within the header parts of a file. */ + enum bfd_endian header_byteorder; + + /* A mask of all the flags which an executable may have set - + from the set <>, <>, ...<>. */ + flagword object_flags; + + /* A mask of all the flags which a section may have set - from + the set <>, <>, ...<>. */ + flagword section_flags; + + /* The character normally found at the front of a symbol. + (if any), perhaps `_'. */ + char symbol_leading_char; + + /* The pad character for file names within an archive header. */ + char ar_pad_char; + + /* The maximum number of characters in an archive header. */ + unsigned short ar_max_namelen; + + /* Entries for byte swapping for data. These are different from the + other entry points, since they don't take a BFD asthe first argument. + Certain other handlers could do the same. */ + bfd_uint64_t (*bfd_getx64) (const void *); + bfd_int64_t (*bfd_getx_signed_64) (const void *); + void (*bfd_putx64) (bfd_uint64_t, void *); + bfd_vma (*bfd_getx32) (const void *); + bfd_signed_vma (*bfd_getx_signed_32) (const void *); + void (*bfd_putx32) (bfd_vma, void *); + bfd_vma (*bfd_getx16) (const void *); + bfd_signed_vma (*bfd_getx_signed_16) (const void *); + void (*bfd_putx16) (bfd_vma, void *); + + /* Byte swapping for the headers. */ + bfd_uint64_t (*bfd_h_getx64) (const void *); + bfd_int64_t (*bfd_h_getx_signed_64) (const void *); + void (*bfd_h_putx64) (bfd_uint64_t, void *); + bfd_vma (*bfd_h_getx32) (const void *); + bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); + void (*bfd_h_putx32) (bfd_vma, void *); + bfd_vma (*bfd_h_getx16) (const void *); + bfd_signed_vma (*bfd_h_getx_signed_16) (const void *); + void (*bfd_h_putx16) (bfd_vma, void *); + + /* Format dependent routines: these are vectors of entry points + within the target vector structure, one for each format to check. */ + + /* Check the format of a file being read. Return a <> or zero. */ + const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *); + + /* Set the format of a file being written. */ + bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *); + + /* Write cached information into a file being written, at <>. */ + bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *); + + + /* Generic entry points. */ +#define BFD_JUMP_TABLE_GENERIC(NAME) \ + NAME##_close_and_cleanup, \ + NAME##_bfd_free_cached_info, \ + NAME##_new_section_hook, \ + NAME##_get_section_contents, \ + NAME##_get_section_contents_in_window + + /* Called when the BFD is being closed to do any necessary cleanup. */ + bfd_boolean (*_close_and_cleanup) (bfd *); + /* Ask the BFD to free all cached information. */ + bfd_boolean (*_bfd_free_cached_info) (bfd *); + /* Called when a new section is created. */ + bfd_boolean (*_new_section_hook) (bfd *, sec_ptr); + /* Read the contents of a section. */ + bfd_boolean (*_bfd_get_section_contents) + (bfd *, sec_ptr, void *, file_ptr, bfd_size_type); + bfd_boolean (*_bfd_get_section_contents_in_window) + (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type); + + /* Entry points to copy private data. */ +#define BFD_JUMP_TABLE_COPY(NAME) \ + NAME##_bfd_copy_private_bfd_data, \ + NAME##_bfd_merge_private_bfd_data, \ + NAME##_bfd_copy_private_section_data, \ + NAME##_bfd_copy_private_symbol_data, \ + NAME##_bfd_copy_private_header_data, \ + NAME##_bfd_set_private_flags, \ + NAME##_bfd_print_private_bfd_data + + /* Called to copy BFD general private data from one object file + to another. */ + bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *); + /* Called to merge BFD general private data from one object file + to a common output file when linking. */ + bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); + /* Called to copy BFD private section data from one object file + to another. */ + bfd_boolean (*_bfd_copy_private_section_data) + (bfd *, sec_ptr, bfd *, sec_ptr); + /* Called to copy BFD private symbol data from one symbol + to another. */ + bfd_boolean (*_bfd_copy_private_symbol_data) + (bfd *, asymbol *, bfd *, asymbol *); + /* Called to copy BFD private header data from one object file + to another. */ + bfd_boolean (*_bfd_copy_private_header_data) + (bfd *, bfd *); + /* Called to set private backend flags. */ + bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword); + + /* Called to print private BFD data. */ + bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *); + + /* Core file entry points. */ +#define BFD_JUMP_TABLE_CORE(NAME) \ + NAME##_core_file_failing_command, \ + NAME##_core_file_failing_signal, \ + NAME##_core_file_matches_executable_p + + char * (*_core_file_failing_command) (bfd *); + int (*_core_file_failing_signal) (bfd *); + bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *); + + /* Archive entry points. */ +#define BFD_JUMP_TABLE_ARCHIVE(NAME) \ + NAME##_slurp_armap, \ + NAME##_slurp_extended_name_table, \ + NAME##_construct_extended_name_table, \ + NAME##_truncate_arname, \ + NAME##_write_armap, \ + NAME##_read_ar_hdr, \ + NAME##_openr_next_archived_file, \ + NAME##_get_elt_at_index, \ + NAME##_generic_stat_arch_elt, \ + NAME##_update_armap_timestamp + + bfd_boolean (*_bfd_slurp_armap) (bfd *); + bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *); + bfd_boolean (*_bfd_construct_extended_name_table) + (bfd *, char **, bfd_size_type *, const char **); + void (*_bfd_truncate_arname) (bfd *, const char *, char *); + bfd_boolean (*write_armap) + (bfd *, unsigned int, struct orl *, unsigned int, int); + void * (*_bfd_read_ar_hdr_fn) (bfd *); + bfd * (*openr_next_archived_file) (bfd *, bfd *); +#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i)) + bfd * (*_bfd_get_elt_at_index) (bfd *, symindex); + int (*_bfd_stat_arch_elt) (bfd *, struct stat *); + bfd_boolean (*_bfd_update_armap_timestamp) (bfd *); + + /* Entry points used for symbols. */ +#define BFD_JUMP_TABLE_SYMBOLS(NAME) \ + NAME##_get_symtab_upper_bound, \ + NAME##_canonicalize_symtab, \ + NAME##_make_empty_symbol, \ + NAME##_print_symbol, \ + NAME##_get_symbol_info, \ + NAME##_bfd_is_local_label_name, \ + NAME##_bfd_is_target_special_symbol, \ + NAME##_get_lineno, \ + NAME##_find_nearest_line, \ + NAME##_bfd_make_debug_symbol, \ + NAME##_read_minisymbols, \ + NAME##_minisymbol_to_symbol + + long (*_bfd_get_symtab_upper_bound) (bfd *); + long (*_bfd_canonicalize_symtab) + (bfd *, struct bfd_symbol **); + struct bfd_symbol * + (*_bfd_make_empty_symbol) (bfd *); + void (*_bfd_print_symbol) + (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type); +#define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e)) + void (*_bfd_get_symbol_info) + (bfd *, struct bfd_symbol *, symbol_info *); +#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e)) + bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *); + bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *); + alent * (*_get_lineno) (bfd *, struct bfd_symbol *); + bfd_boolean (*_bfd_find_nearest_line) + (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, + const char **, const char **, unsigned int *); + /* Back-door to allow format-aware applications to create debug symbols + while using BFD for everything else. Currently used by the assembler + when creating COFF files. */ + asymbol * (*_bfd_make_debug_symbol) + (bfd *, void *, unsigned long size); +#define bfd_read_minisymbols(b, d, m, s) \ + BFD_SEND (b, _read_minisymbols, (b, d, m, s)) + long (*_read_minisymbols) + (bfd *, bfd_boolean, void **, unsigned int *); +#define bfd_minisymbol_to_symbol(b, d, m, f) \ + BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) + asymbol * (*_minisymbol_to_symbol) + (bfd *, bfd_boolean, const void *, asymbol *); + + /* Routines for relocs. */ +#define BFD_JUMP_TABLE_RELOCS(NAME) \ + NAME##_get_reloc_upper_bound, \ + NAME##_canonicalize_reloc, \ + NAME##_bfd_reloc_type_lookup + + long (*_get_reloc_upper_bound) (bfd *, sec_ptr); + long (*_bfd_canonicalize_reloc) + (bfd *, sec_ptr, arelent **, struct bfd_symbol **); + /* See documentation on reloc types. */ + reloc_howto_type * + (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type); + + /* Routines used when writing an object file. */ +#define BFD_JUMP_TABLE_WRITE(NAME) \ + NAME##_set_arch_mach, \ + NAME##_set_section_contents + + bfd_boolean (*_bfd_set_arch_mach) + (bfd *, enum bfd_architecture, unsigned long); + bfd_boolean (*_bfd_set_section_contents) + (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); + + /* Routines used by the linker. */ +#define BFD_JUMP_TABLE_LINK(NAME) \ + NAME##_sizeof_headers, \ + NAME##_bfd_get_relocated_section_contents, \ + NAME##_bfd_relax_section, \ + NAME##_bfd_link_hash_table_create, \ + NAME##_bfd_link_hash_table_free, \ + NAME##_bfd_link_add_symbols, \ + NAME##_bfd_link_just_syms, \ + NAME##_bfd_final_link, \ + NAME##_bfd_link_split_section, \ + NAME##_bfd_gc_sections, \ + NAME##_bfd_merge_sections, \ + NAME##_bfd_is_group_section, \ + NAME##_bfd_discard_group, \ + NAME##_section_already_linked \ + + int (*_bfd_sizeof_headers) (bfd *, bfd_boolean); + bfd_byte * (*_bfd_get_relocated_section_contents) + (bfd *, struct bfd_link_info *, struct bfd_link_order *, + bfd_byte *, bfd_boolean, struct bfd_symbol **); + + bfd_boolean (*_bfd_relax_section) + (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *); + + /* Create a hash table for the linker. Different backends store + different information in this table. */ + struct bfd_link_hash_table * + (*_bfd_link_hash_table_create) (bfd *); + + /* Release the memory associated with the linker hash table. */ + void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *); + + /* Add symbols from this object file into the hash table. */ + bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *); + + /* Indicate that we are only retrieving symbol values from this section. */ + void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); + + /* Do a link based on the link_order structures attached to each + section of the BFD. */ + bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *); + + /* Should this section be split up into smaller pieces during linking. */ + bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *); + + /* Remove sections that are not referenced from the output. */ + bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); + + /* Attempt to merge SEC_MERGE sections. */ + bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); + + /* Is this section a member of a group? */ + bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *); + + /* Discard members of a group. */ + bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); + + /* Check if SEC has been already linked during a reloceatable or + final link. */ + void (*_section_already_linked) (bfd *, struct bfd_section *); + + /* Routines to handle dynamic symbols and relocs. */ +#define BFD_JUMP_TABLE_DYNAMIC(NAME) \ + NAME##_get_dynamic_symtab_upper_bound, \ + NAME##_canonicalize_dynamic_symtab, \ + NAME##_get_synthetic_symtab, \ + NAME##_get_dynamic_reloc_upper_bound, \ + NAME##_canonicalize_dynamic_reloc + + /* Get the amount of memory required to hold the dynamic symbols. */ + long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *); + /* Read in the dynamic symbols. */ + long (*_bfd_canonicalize_dynamic_symtab) + (bfd *, struct bfd_symbol **); + /* Create synthetized symbols. */ + long (*_bfd_get_synthetic_symtab) + (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, + struct bfd_symbol **); + /* Get the amount of memory required to hold the dynamic relocs. */ + long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); + /* Read in the dynamic relocs. */ + long (*_bfd_canonicalize_dynamic_reloc) + (bfd *, arelent **, struct bfd_symbol **); + + /* Opposite endian version of this target. */ + const struct bfd_target * alternative_target; + + /* Data for use by back-end routines, which isn't + generic enough to belong in this structure. */ + const void *backend_data; + +} bfd_target; + +bfd_boolean bfd_set_default_target (const char *name); + +const bfd_target *bfd_find_target (const char *target_name, bfd *abfd); + +const char ** bfd_target_list (void); + +const bfd_target *bfd_search_for_target + (int (*search_func) (const bfd_target *, void *), + void *); + +/* Extracted from format.c. */ +bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); + +bfd_boolean bfd_check_format_matches + (bfd *abfd, bfd_format format, char ***matching); + +bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); + +const char *bfd_format_string (bfd_format format); + +/* Extracted from linker.c. */ +bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); + +#define bfd_link_split_section(abfd, sec) \ + BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) + +void bfd_section_already_linked (bfd *abfd, asection *sec); + +#define bfd_section_already_linked(abfd, sec) \ + BFD_SEND (abfd, _section_already_linked, (abfd, sec)) + +/* Extracted from simple.c. */ +bfd_byte *bfd_simple_get_relocated_section_contents + (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/bin/gdb/bfd/config-x86_64/bfdver.h b/src/bin/gdb/bfd/config-x86_64/bfdver.h new file mode 100644 index 0000000000..f900613cd2 --- /dev/null +++ b/src/bin/gdb/bfd/config-x86_64/bfdver.h @@ -0,0 +1,3 @@ +#define BFD_VERSION_DATE 20041018 +#define BFD_VERSION 215930000 +#define BFD_VERSION_STRING "2.15.93 20041018" diff --git a/src/bin/gdb/bfd/config-x86_64/config.h b/src/bin/gdb/bfd/config-x86_64/config.h new file mode 100644 index 0000000000..50f4e83f34 --- /dev/null +++ b/src/bin/gdb/bfd/config-x86_64/config.h @@ -0,0 +1,322 @@ +/* config.h. Generated by configure. */ +/* config.in. Generated from configure.in by autoheader. */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* Define to 1 if NLS is requested */ +#define ENABLE_NLS 1 + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ARGZ_H */ + +/* Define to 1 if you have the `dcgettext' function. */ +/* #undef HAVE_DCGETTEXT */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the `fcntl' function. */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `fdopen' function. */ +#define HAVE_FDOPEN 1 + +/* Define to 1 if you have the `fseeko' function. */ +#define HAVE_FSEEKO 1 + +/* Define to 1 if you have the `fseeko64' function. */ +/* #undef HAVE_FSEEKO64 */ + +/* Define to 1 if you have the `ftello' function. */ +#define HAVE_FTELLO 1 + +/* Define to 1 if you have the `ftello64' function. */ +/* #undef HAVE_FTELLO64 */ + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the `getgid' function. */ +#define HAVE_GETGID 1 + +/* Define to 1 if you have the `getpagesize' function. */ +/* #undef HAVE_GETPAGESIZE */ + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +/* #undef HAVE_GETTEXT */ + +/* Define to 1 if you have the `getuid' function. */ +#define HAVE_GETUID 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if your locale.h file contains LC_MESSAGES. */ +#define HAVE_LC_MESSAGES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if has lwpstatus_t. */ +/* #undef HAVE_LWPSTATUS_T */ + +/* Define if has lwpstatus_t.pr_context. */ +/* #undef HAVE_LWPSTATUS_T_PR_CONTEXT */ + +/* Define if has lwpstatus_t.pr_reg. */ +/* #undef HAVE_LWPSTATUS_T_PR_REG */ + +/* Define if has lwpxstatus_t. */ +/* #undef HAVE_LWPXSTATUS_T */ + +/* Define to 1 if you have the `madvise' function. */ +/* #undef HAVE_MADVISE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MEMORY_H */ + +/* Define to 1 if you have a working `mmap' system call. */ +/* #undef HAVE_MMAP */ + +/* Define to 1 if you have the `mprotect' function. */ +/* #undef HAVE_MPROTECT */ + +/* Define to 1 if you have the `munmap' function. */ +/* #undef HAVE_MUNMAP */ + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NL_TYPES_H 1 + +/* Define if has prpsinfo32_t. */ +/* #undef HAVE_PRPSINFO32_T */ + +/* Define if has prpsinfo_t. */ +/* #undef HAVE_PRPSINFO_T */ + +/* Define if has prstatus32_t. */ +/* #undef HAVE_PRSTATUS32_T */ + +/* Define if has prstatus32_t.pr_who. */ +/* #undef HAVE_PRSTATUS32_T_PR_WHO */ + +/* Define if has prstatus_t. */ +/* #undef HAVE_PRSTATUS_T */ + +/* Define if has prstatus_t.pr_who. */ +/* #undef HAVE_PRSTATUS_T_PR_WHO */ + +/* Define if has psinfo32_t. */ +/* #undef HAVE_PSINFO32_T */ + +/* Define if has psinfo_t. */ +/* #undef HAVE_PSINFO_T */ + +/* Define if has pstatus32_t. */ +/* #undef HAVE_PSTATUS32_T */ + +/* Define if has pstatus_t. */ +/* #undef HAVE_PSTATUS_T */ + +/* Define to 1 if you have the `putenv' function. */ +#define HAVE_PUTENV 1 + +/* Define if has pxstatus_t. */ +/* #undef HAVE_PXSTATUS_T */ + +/* Define to 1 if you have the `setenv' function. */ +#define HAVE_SETENV 1 + +/* Define to 1 if you have the `setitimer' function. */ +#define HAVE_SETITIMER 1 + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the stpcpy function */ +#define HAVE_STPCPY 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtoull' function. */ +#define HAVE_STRTOULL 1 + +/* Define if struct core_dumpx has member c_impl */ +/* #undef HAVE_ST_C_IMPL */ + +/* Define to 1 if you have the `sysconf' function. */ +#define HAVE_SYSCONF 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_FILE_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PROCFS_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VALUES_H */ + +/* Define if has win32_pstatus_t. */ +/* #undef HAVE_WIN32_PSTATUS_T */ + +/* Define to 1 if you have the `__argz_count' function. */ +/* #undef HAVE___ARGZ_COUNT */ + +/* Define to 1 if you have the `__argz_next' function. */ +/* #undef HAVE___ARGZ_NEXT */ + +/* Define to 1 if you have the `__argz_stringify' function. */ +/* #undef HAVE___ARGZ_STRINGIFY */ + +/* Define if free is not declared in system header files. */ +/* #undef NEED_DECLARATION_FREE */ + +/* Define if getenv is not declared in system header files. */ +/* #undef NEED_DECLARATION_GETENV */ + +/* Define if malloc is not declared in system header files. */ +/* #undef NEED_DECLARATION_MALLOC */ + +/* Define if realloc is not declared in system header files. */ +/* #undef NEED_DECLARATION_REALLOC */ + +/* Define if strstr is not declared in system header files. */ +/* #undef NEED_DECLARATION_STRSTR */ + +/* Name of package */ +#define PACKAGE "bfd" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* The number of bytes in type long */ +#define SIZEOF_LONG 8 + +/* The number of bytes in type long long */ +#define SIZEOF_LONG_LONG 8 + +/* The number of bytes in type off_t */ +#define SIZEOF_OFF_T 8 + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Name of host specific header file to include in trad-core.c. */ +/* #undef TRAD_HEADER */ + +/* Use b modifier when opening binary files? */ +/* #undef USE_BINARY_FOPEN */ + +/* Use mmap if it's available? */ +/* #undef USE_MMAP */ + +/* Version number of package */ +#define VERSION "2.15.93" + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `long' if does not define. */ +/* #undef off_t */ + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ diff --git a/src/bin/gdb/gdb/Jamfile b/src/bin/gdb/gdb/Jamfile index 93d8826520..9860845224 100644 --- a/src/bin/gdb/gdb/Jamfile +++ b/src/bin/gdb/gdb/Jamfile @@ -33,6 +33,11 @@ if $(TARGET_ARCH) = x86 { gdbHaikuArchTargetSources = i386-tdep.c i386-haiku-tdep.c i387-tdep.c ; gdbHaikuArchNativeSources = i386-haiku-nat.c ; gdbProcessorName = i386 ; +} else if $(TARGET_ARCH) = x86_64 { + gdbHaikuArchTargetSources = amd64-tdep.c amd64-haiku-tdep.c i386-tdep.c + i387-tdep.c ; + gdbHaikuArchNativeSources = amd64-haiku-nat.c ; + gdbProcessorName = i386 ; } else if $(TARGET_ARCH) = ppc { # TODO: Not yet implemented! gdbProcessorName = ppc ; diff --git a/src/bin/gdb/gdb/amd64-haiku-nat.c b/src/bin/gdb/gdb/amd64-haiku-nat.c new file mode 100644 index 0000000000..7a4ae5117d --- /dev/null +++ b/src/bin/gdb/gdb/amd64-haiku-nat.c @@ -0,0 +1,96 @@ +/* Native-dependent code for Haiku x86_64. + + Copyright 2012 Alex Smith . + Copyright 2005 Ingo Weinhold . + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "haiku-nat.h" +#include "amd64-tdep.h" +#include "i387-tdep.h" +#include "inferior.h" +#include "regcache.h" +#include "target.h" + +/* Offset in `struct debug_cpu_state' where MEMBER is stored. */ +#define REG_OFFSET(member) offsetof (struct x86_64_debug_cpu_state, member) + +/* At kHaikuAMD64RegOffset[REGNUM] you'll find the offset in `struct + debug_cpu_state' where the GDB register REGNUM is stored. */ +static int kHaikuAMD64RegOffset[] = { + REG_OFFSET (rax), + REG_OFFSET (rbx), + REG_OFFSET (rcx), + REG_OFFSET (rdx), + REG_OFFSET (rsi), + REG_OFFSET (rdi), + REG_OFFSET (rbp), + REG_OFFSET (rsp), + REG_OFFSET (r8), + REG_OFFSET (r9), + REG_OFFSET (r10), + REG_OFFSET (r11), + REG_OFFSET (r12), + REG_OFFSET (r13), + REG_OFFSET (r14), + REG_OFFSET (r15), + REG_OFFSET (rip), + REG_OFFSET (rflags), + REG_OFFSET (cs), + REG_OFFSET (ss), + REG_OFFSET (ds), + REG_OFFSET (es), + REG_OFFSET (fs), + REG_OFFSET (gs) +}; + + +void +haiku_supply_registers(int reg, const debug_cpu_state *cpuState) +{ + if (reg == -1) { + int i; + for (i = 0; i < NUM_REGS; i++) + haiku_supply_registers(i, cpuState); + } else if (reg < AMD64_ST0_REGNUM) { + int offset = kHaikuAMD64RegOffset[reg]; + regcache_raw_supply (current_regcache, reg, (char*)cpuState + offset); + } else { + amd64_supply_fxsave (current_regcache, -1, + &cpuState->extended_registers); + } +} + + +void +haiku_collect_registers(int reg, debug_cpu_state *cpuState) +{ + if (reg == -1) { + int i; + for (i = 0; i < NUM_REGS; i++) + haiku_collect_registers(i, cpuState); + } else if (reg < AMD64_ST0_REGNUM) { + int offset = kHaikuAMD64RegOffset[reg]; + regcache_raw_collect (current_regcache, reg, (char*)cpuState + offset); + } else { + amd64_collect_fxsave (current_regcache, -1, + &cpuState->extended_registers); + } +} + diff --git a/src/bin/gdb/gdb/amd64-haiku-tdep.c b/src/bin/gdb/gdb/amd64-haiku-tdep.c new file mode 100644 index 0000000000..5923e58c12 --- /dev/null +++ b/src/bin/gdb/gdb/amd64-haiku-tdep.c @@ -0,0 +1,61 @@ +/* Target-dependent code for Haiku x86_64. + + Copyright 2012 Alex Smith . + Copyright 2005 Ingo Weinhold . + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdbarch.h" +#include "amd64-tdep.h" +#include "osabi.h" + + +static void +amd64_haiku_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + amd64_init_abi (info, gdbarch); + + // the offset of the PC in the jmp_buf structure (cf. setjmp(), longjmp()) + tdep->jb_pc_offset = 0; +} + + +static enum gdb_osabi +amd64_haiku_osabi_sniffer (bfd * abfd) +{ + char *targetName = bfd_get_target (abfd); + + if (strcmp (targetName, "elf64-x86-64") == 0) + return GDB_OSABI_HAIKU; + + return GDB_OSABI_UNKNOWN; +} + + +void +_initialize_amd64_haiku_tdep (void) +{ + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour, + amd64_haiku_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_HAIKU, + amd64_haiku_init_abi); +} diff --git a/src/bin/gdb/gdb/config-x86_64/config.h b/src/bin/gdb/gdb/config-x86_64/config.h new file mode 100644 index 0000000000..7802fae410 --- /dev/null +++ b/src/bin/gdb/gdb/config-x86_64/config.h @@ -0,0 +1,593 @@ +/* config.h. Generated automatically by configure. */ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define if the `long double' type works. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define if you have a working `mmap' system call. */ +/* #undef HAVE_MMAP */ + +/* Define if you have . */ +/* #undef HAVE_VFORK_H */ + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if the `setpgrp' function takes no argument. */ +#define SETPGRP_VOID 1 + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define vfork as fork if vfork does not work. */ +#define vfork fork + +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +/* Define if your struct reg has r_fs. */ +/* #undef HAVE_STRUCT_REG_R_FS */ + +/* Define if your struct stat has st_blocks. */ +/* #undef HAVE_STRUCT_STAT_ST_BLOCKS */ + +/* Define if your struct reg has r_gs. */ +/* #undef HAVE_STRUCT_REG_R_GS */ + +/* Define if exists and defines struct link_map which has + members with an ``l_'' prefix. (For Solaris, SVR4, and + SVR4-like systems.) */ +/* #undef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS */ + +/* Define if exists and defines struct link_map which has + members with an ``lm_'' prefix. (For SunOS.) */ +/* #undef HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS */ + +/* Define if exists and defines a struct so_map which has + members with an ``som_'' prefix. (Found on older *BSD systems.) */ +/* #undef HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS */ + +/* Define if has struct link_map32 */ +/* #undef HAVE_STRUCT_LINK_MAP32 */ + +/* Define if has link_map32 (solaris sparc-64 target) */ +/* #undef _SYSCALL32 */ + +/* Define if the prfpregset_t type is broken. */ +/* #undef PRFPREGSET_T_BROKEN */ + +/* Define if you want to use new multi-fd /proc interface + (replaces HAVE_MULTIPLE_PROC_FDS as well as other macros). */ +/* #undef NEW_PROC_API */ + +/* Define if ioctl argument PIOCSET is available. */ +/* #undef HAVE_PROCFS_PIOCSET */ + +/* Define if the `long long' type works. */ +#define CC_HAS_LONG_LONG 1 + +/* Define if the "ll" format works to print long long ints. */ +#define PRINTF_HAS_LONG_LONG 1 + +/* Define if the "%Lg" format works to print long doubles. */ +/* #undef PRINTF_HAS_LONG_DOUBLE */ + +/* Define if the "%Lg" format works to scan long doubles. */ +/* #undef SCANF_HAS_LONG_DOUBLE */ + +/* Define if using Solaris thread debugging. */ +/* #undef HAVE_THREAD_DB_LIB */ + +/* Define on a GNU/Linux system to work around problems in sys/procfs.h. */ +/* #undef START_INFERIOR_TRAPS_EXPECTED */ +/* #undef sys_quotactl */ + +/* Define if you have HPUX threads */ +/* #undef HAVE_HPUX_THREAD_SUPPORT */ + +/* Define if on solaris uses int instead of + size_t, and assorted other type changes. */ +/* #undef PROC_SERVICE_IS_OLD */ + +/* Define if the simulator is being linked in. */ +#define WITH_SIM 1 + +/* Set to true if the save_state_t structure is present */ +/* #undef HAVE_STRUCT_SAVE_STATE_T */ + +/* Set to true if the save_state_t structure has the ss_wide member */ +/* #undef HAVE_STRUCT_MEMBER_SS_WIDE */ + +/* Define if defines the PTRACE_GETREGS request. */ +/* #undef HAVE_PTRACE_GETREGS */ + +/* Define if defines the PTRACE_GETFPXREGS request. */ +/* #undef HAVE_PTRACE_GETFPXREGS */ + +/* Define if defines the PT_GETDBREGS request. */ +/* #undef HAVE_PT_GETDBREGS */ + +/* Define if defines the PT_GETXMMREGS request. */ +/* #undef HAVE_PT_GETXMMREGS */ + +/* Define if libunwind library is being used. */ +/* #undef HAVE_LIBUNWIND */ + +/* hostfile */ +/* #undef GDB_XM_FILE */ + +/* targetfile */ +#define GDB_TM_FILE "config/i386/tm-haiku.h" + +/* nativefile */ +#define GDB_NM_FILE "config/i386/nm-haiku.h" + +/* Define to 1 so gets a definition of anon_hdl. Works + around a problem on IRIX 5. */ +#ifndef _KMEMUSER +/* #undef _KMEMUSER */ +#endif + +/* Define if you have the __argz_count function. */ +/* #undef HAVE___ARGZ_COUNT */ + +/* Define if you have the __argz_next function. */ +/* #undef HAVE___ARGZ_NEXT */ + +/* Define if you have the __argz_stringify function. */ +/* #undef HAVE___ARGZ_STRINGIFY */ + +/* Define if you have the _mcleanup function. */ +/* #undef HAVE__MCLEANUP */ + +/* Define if you have the canonicalize_file_name function. */ +/* #undef HAVE_CANONICALIZE_FILE_NAME */ + +/* Define if you have the dcgettext function. */ +/* #undef HAVE_DCGETTEXT */ + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getpagesize function. */ +/* #undef HAVE_GETPAGESIZE */ + +/* Define if you have the monstartup function. */ +/* #undef HAVE_MONSTARTUP */ + +/* Define if you have the munmap function. */ +/* #undef HAVE_MUNMAP */ + +/* Define if you have the poll function. */ +/* #undef HAVE_POLL */ + +/* Define if you have the pread64 function. */ +/* #undef HAVE_PREAD64 */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the realpath function. */ +/* #undef HAVE_REALPATH */ + +/* Define if you have the sbrk function. */ +#define HAVE_SBRK 1 + +/* Define if you have the setenv function. */ +/* #undef HAVE_SETENV */ + +/* Define if you have the setlocale function. */ +#define HAVE_SETLOCALE 1 + +/* Define if you have the setpgid function. */ +#define HAVE_SETPGID 1 + +/* Define if you have the setpgrp function. */ +#define HAVE_SETPGRP 1 + +/* Define if you have the sigaction function. */ +#define HAVE_SIGACTION 1 + +/* Define if you have the sigprocmask function. */ +#define HAVE_SIGPROCMASK 1 + +/* Define if you have the sigsetmask function. */ +/* #undef HAVE_SIGSETMASK */ + +/* Define if you have the socketpair function. */ +/* #undef HAVE_SOCKETPAIR */ + +/* Define if you have the stpcpy function. */ +#define HAVE_STPCPY 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the syscall function. */ +/* #undef HAVE_SYSCALL */ + +/* Define if you have the ttrace function. */ +/* #undef HAVE_TTRACE */ + +/* Define if you have the wborder function. */ +/* #undef HAVE_WBORDER */ + +/* Define if you have the header file. */ +/* #undef HAVE_ARGZ_H */ + +/* Define if you have the header file. */ +#define HAVE_CTYPE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_CURSES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_CURSESX_H */ + +/* Define if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_GNU_LIBC_VERSION_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LIBUNWIND_IA64_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LIBUNWIND_H */ + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINK_H */ + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_MACHINE_REG_H */ + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +#define HAVE_NCURSES_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NCURSES_NCURSES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NL_TYPES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NLIST_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_POLL_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_PROC_SERVICE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_PTRACE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SGTTY_H */ + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DEBUGREG_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_FAULT_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_FILIO_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_POLL_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PROC_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PROCFS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PTRACE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_REG_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_SELECT_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_SYSCALL_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_USER_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_TERM_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_TERMIO_H */ + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_THREAD_DB_H */ + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_VALUES_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_WAIT_H */ + +/* Define if you have the dl library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define if you have the m library (-lm). */ +/* #undef HAVE_LIBM */ + +/* Define if you have the w library (-lw). */ +/* #undef HAVE_LIBW */ + +/* Define if you have the stpcpy function */ +#define HAVE_STPCPY 1 + +/* Define if your locale.h file contains LC_MESSAGES. */ +#define HAVE_LC_MESSAGES 1 + +/* Define to 1 if NLS is requested */ +#define ENABLE_NLS 1 + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +/* #undef HAVE_GETTEXT */ + +/* Name of this package. */ +#define PACKAGE "gdb" + +/* Global directory for separate debug files. */ +#define DEBUGDIR "/usr/local/lib/debug" + +/* Define to BFD's default architecture. */ +#define DEFAULT_BFD_ARCH bfd_i386_arch + +/* Define to BFD's default target vector. */ +#define DEFAULT_BFD_VEC bfd_elf64_x86_64_vec + +/* Define to 1 if your system has the _etext variable. */ +#define HAVE__ETEXT 1 + +/* Define to 1 to avoid a clash between and on + Solaris 2.[789] when using GCC. */ +/* #undef _MSE_INT_H */ + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_GETOPT 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_PTRACE 0 + +/* Define as the return type of ptrace. */ +#define PTRACE_TYPE_RET int + +/* Define to the type of arg 3 for ptrace. */ +#define PTRACE_TYPE_ARG3 long + +/* Define to the type of arg 5 for ptrace. */ +/* #undef PTRACE_TYPE_ARG5 */ + +/* Define if sigsetjmp is available. */ +#define HAVE_SIGSETJMP 1 + +/* Define to 1 if the regex included in libiberty should be used. */ +#define USE_INCLUDED_REGEX 1 + +/* Define to 1 if your system has td_pcb in struct thread. */ +/* #undef HAVE_STRUCT_THREAD_TD_PCB */ + +/* Define to 1 if your system has struct lwp. */ +/* #undef HAVE_STRUCT_LWP */ + +/* Define to 1 if your system has struct reg in . */ +/* #undef HAVE_STRUCT_REG */ + +/* Define if provides the uintptr_t type. */ +#define HAVE_UINTPTR_T 1 + +/* Define if malloc is not declared in system header files. */ +/* #undef NEED_DECLARATION_MALLOC */ + +/* Define if realloc is not declared in system header files. */ +/* #undef NEED_DECLARATION_REALLOC */ + +/* Define if free is not declared in system header files. */ +/* #undef NEED_DECLARATION_FREE */ + +/* Define if strerror is not declared in system header files. */ +/* #undef NEED_DECLARATION_STRERROR */ + +/* Define if strdup is not declared in system header files. */ +/* #undef NEED_DECLARATION_STRDUP */ + +/* Define if strstr is not declared in system header files. */ +/* #undef NEED_DECLARATION_STRSTR */ + +/* Define if canonicalize_file_name is not declared in system header files. */ +#define NEED_DECLARATION_CANONICALIZE_FILE_NAME 1 + +/* Define if has pstatus_t. */ +/* #undef HAVE_PSTATUS_T */ + +/* Define if has prrun_t. */ +/* #undef HAVE_PRRUN_T */ + +/* Define if has gregset_t. */ +/* #undef HAVE_GREGSET_T */ + +/* Define if has fpregset_t. */ +/* #undef HAVE_FPREGSET_T */ + +/* Define if has prgregset_t. */ +/* #undef HAVE_PRGREGSET_T */ + +/* Define if has prfpregset_t. */ +/* #undef HAVE_PRFPREGSET_T */ + +/* Define if has prgregset32_t. */ +/* #undef HAVE_PRGREGSET32_T */ + +/* Define if has prfpregset32_t. */ +/* #undef HAVE_PRFPREGSET32_T */ + +/* Define if has lwpid_t. */ +/* #undef HAVE_LWPID_T */ + +/* Define if has psaddr_t. */ +/* #undef HAVE_PSADDR_T */ + +/* Define if has prsysent_t. */ +/* #undef HAVE_PRSYSENT_T */ + +/* Define if has pr_sigset_t. */ +/* #undef HAVE_PR_SIGSET_T */ + +/* Define if has pr_sigaction64_t. */ +/* #undef HAVE_PR_SIGACTION64_T */ + +/* Define if has pr_siginfo64_t. */ +/* #undef HAVE_PR_SIGINFO64_T */ + +/* Define if has the TD_NOTALLOC error code. */ +/* #undef THREAD_DB_HAS_TD_NOTALLOC */ + +/* Define if we can use the tkill syscall. */ +/* #undef HAVE_TKILL_SYSCALL */ + +/* Host float floatformat */ +#define GDB_HOST_FLOAT_FORMAT 0 + +/* Host double floatformat */ +#define GDB_HOST_DOUBLE_FORMAT 0 + +/* Host long double floatformat */ +#define GDB_HOST_LONG_DOUBLE_FORMAT 0 + +/* Define to the default OS ABI for this configuration. */ +/* #undef GDB_OSABI_DEFAULT */ + +/* Define to be a string naming the default host character set. */ +#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1" + +/* Define if you have the iconv() function. */ +/* #undef HAVE_ICONV */ + +/* Define as const if the declaration of iconv() needs const. */ +/* #undef ICONV_CONST */ diff --git a/src/bin/gdb/gdb/config-x86_64/init.c b/src/bin/gdb/gdb/config-x86_64/init.c new file mode 100644 index 0000000000..8fbdafcf3e --- /dev/null +++ b/src/bin/gdb/gdb/config-x86_64/init.c @@ -0,0 +1,224 @@ +/* Do not modify this file. */ +/* It is created automatically by the Makefile. */ +#include "defs.h" /* For initialize_file_ftype. */ +#include "call-cmds.h" /* For initialize_all_files. */ +extern initialize_file_ftype _initialize_gdbtypes; +extern initialize_file_ftype _initialize_amd64_haiku_tdep; +extern initialize_file_ftype _initialize_i386_tdep; +extern initialize_file_ftype _initialize_solib; +extern initialize_file_ftype _initialize_haiku_solib; +extern initialize_file_ftype _initialize_symfile_mem; +extern initialize_file_ftype _initialize_ser_hardwire; +extern initialize_file_ftype _initialize_ser_pipe; +extern initialize_file_ftype _initialize_ser_tcp; +extern initialize_file_ftype _initialize_haiku_nat; +extern initialize_file_ftype _initialize_remote; +extern initialize_file_ftype _initialize_dcache; +extern initialize_file_ftype _initialize_sr_support; +extern initialize_file_ftype _initialize_tracepoint; +extern initialize_file_ftype _initialize_ax_gdb; +extern initialize_file_ftype _initialize_ada_exp; +extern initialize_file_ftype _initialize_annotate; +extern initialize_file_ftype _initialize_auxv; +extern initialize_file_ftype _initialize_breakpoint; +extern initialize_file_ftype _initialize_regcache; +extern initialize_file_ftype _initialize_charset; +extern initialize_file_ftype _initialize_dummy_frame; +extern initialize_file_ftype _initialize_source; +extern initialize_file_ftype _initialize_values; +extern initialize_file_ftype _initialize_valops; +extern initialize_file_ftype _initialize_valarith; +extern initialize_file_ftype _initialize_valprint; +extern initialize_file_ftype _initialize_printcmd; +extern initialize_file_ftype _initialize_symtab; +extern initialize_file_ftype _initialize_symfile; +extern initialize_file_ftype _initialize_symmisc; +extern initialize_file_ftype _initialize_infcall; +extern initialize_file_ftype _initialize_infcmd; +extern initialize_file_ftype _initialize_infrun; +extern initialize_file_ftype _initialize_stack; +extern initialize_file_ftype _initialize_thread; +extern initialize_file_ftype _initialize_interpreter; +extern initialize_file_ftype _initialize_macrocmd; +extern initialize_file_ftype _initialize_gdbarch; +extern initialize_file_ftype _initialize_gdbarch_utils; +extern initialize_file_ftype _initialize_gdb_osabi; +extern initialize_file_ftype _initialize_copying; +extern initialize_file_ftype _initialize_mem; +extern initialize_file_ftype _initialize_parse; +extern initialize_file_ftype _initialize_language; +extern initialize_file_ftype _initialize_frame_reg; +extern initialize_file_ftype _initialize_signals; +extern initialize_file_ftype _initialize_kod; +extern initialize_file_ftype _initialize_gdb_events; +extern initialize_file_ftype _initialize_exec; +extern initialize_file_ftype _initialize_observer; +extern initialize_file_ftype _initialize_maint_cmds; +extern initialize_file_ftype _initialize_demangler; +extern initialize_file_ftype _initialize_dbxread; +extern initialize_file_ftype _initialize_coffread; +extern initialize_file_ftype _initialize_elfread; +extern initialize_file_ftype _initialize_dwarf2_read; +extern initialize_file_ftype _initialize_mipsread; +extern initialize_file_ftype _initialize_stabsread; +extern initialize_file_ftype _initialize_core; +extern initialize_file_ftype _initialize_dwarf2_frame; +extern initialize_file_ftype _initialize_ada_language; +extern initialize_file_ftype _initialize_c_language; +extern initialize_file_ftype _initialize_f_language; +extern initialize_file_ftype _initialize_objc_language; +extern initialize_file_ftype _initialize_ui_out; +extern initialize_file_ftype _initialize_cli_out; +extern initialize_file_ftype _initialize_varobj; +extern initialize_file_ftype _initialize_java_language; +extern initialize_file_ftype _initialize_m2_language; +extern initialize_file_ftype _initialize_pascal_language; +extern initialize_file_ftype _initialize_pascal_valprint; +extern initialize_file_ftype _initialize_scheme_language; +extern initialize_file_ftype _initialize_complaints; +extern initialize_file_ftype _initialize_typeprint; +extern initialize_file_ftype _initialize_cp_valprint; +extern initialize_file_ftype _initialize_f_valprint; +extern initialize_file_ftype _initialize_nlmread; +extern initialize_file_ftype _initialize_serial; +extern initialize_file_ftype _initialize_mdebugread; +extern initialize_file_ftype _initialize_user_regs; +extern initialize_file_ftype _initialize_frame; +extern initialize_file_ftype _initialize_frame_unwind; +extern initialize_file_ftype _initialize_doublest; +extern initialize_file_ftype _initialize_frame_base; +extern initialize_file_ftype _initialize_gnu_v2_abi; +extern initialize_file_ftype _initialize_gnu_v3_abi; +extern initialize_file_ftype _initialize_hpacc_abi; +extern initialize_file_ftype _initialize_cp_abi; +extern initialize_file_ftype _initialize_cp_support; +extern initialize_file_ftype _initialize_cp_namespace; +extern initialize_file_ftype _initialize_reggroup; +extern initialize_file_ftype _initialize_inflow; +extern initialize_file_ftype _initialize_cli_dump; +extern initialize_file_ftype _initialize_cli_logging; +extern initialize_file_ftype _initialize_cli_interp; +extern initialize_file_ftype _initialize_mi_out; +extern initialize_file_ftype _initialize_mi_cmds; +extern initialize_file_ftype _initialize_mi_cmd_env; +extern initialize_file_ftype _initialize_mi_interp; +extern initialize_file_ftype _initialize_mi_main; +extern initialize_file_ftype _initialize_tui_hooks; +extern initialize_file_ftype _initialize_tui_interp; +extern initialize_file_ftype _initialize_tui_layout; +extern initialize_file_ftype _initialize_tui_out; +extern initialize_file_ftype _initialize_tui_regs; +extern initialize_file_ftype _initialize_tui_stack; +extern initialize_file_ftype _initialize_tui_win; +void +initialize_all_files (void) +{ + _initialize_gdbtypes (); + _initialize_amd64_haiku_tdep(); + _initialize_i386_tdep (); + _initialize_solib (); + _initialize_haiku_solib (); + _initialize_symfile_mem (); + _initialize_ser_hardwire (); + _initialize_ser_pipe (); + _initialize_ser_tcp (); + _initialize_haiku_nat (); + _initialize_remote (); + _initialize_dcache (); + _initialize_sr_support (); + _initialize_tracepoint (); + _initialize_ax_gdb (); + _initialize_ada_exp (); + _initialize_annotate (); + _initialize_auxv (); + _initialize_breakpoint (); + _initialize_regcache (); + _initialize_charset (); + _initialize_dummy_frame (); + _initialize_source (); + _initialize_values (); + _initialize_valops (); + _initialize_valarith (); + _initialize_valprint (); + _initialize_printcmd (); + _initialize_symtab (); + _initialize_symfile (); + _initialize_symmisc (); + _initialize_infcall (); + _initialize_infcmd (); + _initialize_infrun (); + _initialize_stack (); + _initialize_thread (); + _initialize_interpreter (); + _initialize_macrocmd (); + _initialize_gdbarch (); + _initialize_gdbarch_utils (); + _initialize_gdb_osabi (); + _initialize_copying (); + _initialize_mem (); + _initialize_parse (); + _initialize_language (); + _initialize_frame_reg (); + _initialize_signals (); + _initialize_kod (); + _initialize_gdb_events (); + _initialize_exec (); + _initialize_observer (); + _initialize_maint_cmds (); + _initialize_demangler (); + _initialize_dbxread (); + _initialize_coffread (); + _initialize_elfread (); + _initialize_dwarf2_read (); + _initialize_mipsread (); + _initialize_stabsread (); + _initialize_core (); + _initialize_dwarf2_frame (); + _initialize_ada_language (); + _initialize_c_language (); + _initialize_f_language (); + _initialize_objc_language (); + _initialize_ui_out (); + _initialize_cli_out (); + _initialize_varobj (); + _initialize_java_language (); + _initialize_m2_language (); + _initialize_pascal_language (); + _initialize_pascal_valprint (); + _initialize_scheme_language (); + _initialize_complaints (); + _initialize_typeprint (); + _initialize_cp_valprint (); + _initialize_f_valprint (); + _initialize_nlmread (); + _initialize_serial (); + _initialize_mdebugread (); + _initialize_user_regs (); + _initialize_frame (); + _initialize_frame_unwind (); + _initialize_doublest (); + _initialize_frame_base (); + _initialize_gnu_v2_abi (); + _initialize_gnu_v3_abi (); + _initialize_hpacc_abi (); + _initialize_cp_abi (); + _initialize_cp_support (); + _initialize_cp_namespace (); + _initialize_reggroup (); + _initialize_inflow (); + _initialize_cli_dump (); + _initialize_cli_logging (); + _initialize_cli_interp (); + _initialize_mi_out (); + _initialize_mi_cmds (); + _initialize_mi_cmd_env (); + _initialize_mi_interp (); + _initialize_mi_main (); + _initialize_tui_hooks (); + _initialize_tui_interp (); + _initialize_tui_layout (); + _initialize_tui_out (); + _initialize_tui_regs (); + _initialize_tui_stack (); + _initialize_tui_win (); +} diff --git a/src/bin/gdb/gdb/config-x86_64/observer.h b/src/bin/gdb/gdb/config-x86_64/observer.h new file mode 100644 index 0000000000..75f795b8dd --- /dev/null +++ b/src/bin/gdb/gdb/config-x86_64/observer.h @@ -0,0 +1,65 @@ +/* GDB Notifications to Observers. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + -- + + This file was generated using observer.sh and observer.texi. */ + +#ifndef OBSERVER_H +#define OBSERVER_H + +struct observer; +struct bpstats; +struct so_list; + +/* normal_stop notifications. */ + +typedef void (observer_normal_stop_ftype) (struct bpstats *bs); + +extern struct observer *observer_attach_normal_stop (observer_normal_stop_ftype *f); +extern void observer_detach_normal_stop (struct observer *observer); +extern void observer_notify_normal_stop (struct bpstats *bs); + +/* target_changed notifications. */ + +typedef void (observer_target_changed_ftype) (struct target_ops *target); + +extern struct observer *observer_attach_target_changed (observer_target_changed_ftype *f); +extern void observer_detach_target_changed (struct observer *observer); +extern void observer_notify_target_changed (struct target_ops *target); + +/* inferior_created notifications. */ + +typedef void (observer_inferior_created_ftype) (struct target_ops *objfile, int from_tty); + +extern struct observer *observer_attach_inferior_created (observer_inferior_created_ftype *f); +extern void observer_detach_inferior_created (struct observer *observer); +extern void observer_notify_inferior_created (struct target_ops *objfile, int from_tty); + +/* solib_unloaded notifications. */ + +typedef void (observer_solib_unloaded_ftype) (struct so_list *solib); + +extern struct observer *observer_attach_solib_unloaded (observer_solib_unloaded_ftype *f); +extern void observer_detach_solib_unloaded (struct observer *observer); +extern void observer_notify_solib_unloaded (struct so_list *solib); + +#endif /* OBSERVER_H */ diff --git a/src/bin/gdb/gdb/config-x86_64/observer.inc b/src/bin/gdb/gdb/config-x86_64/observer.inc new file mode 100644 index 0000000000..fe779e3b38 --- /dev/null +++ b/src/bin/gdb/gdb/config-x86_64/observer.inc @@ -0,0 +1,177 @@ +/* GDB Notifications to Observers. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + -- + + This file was generated using observer.sh and observer.texi. */ + + +/* normal_stop notifications. */ + +static struct observer_list *normal_stop_subject = NULL; + +struct normal_stop_args { struct bpstats *bs; }; + +static void +observer_normal_stop_notification_stub (const void *data, const void *args_data) +{ + observer_normal_stop_ftype *notify = (observer_normal_stop_ftype *) data; + const struct normal_stop_args *args = args_data; + notify (args->bs); +} + +struct observer * +observer_attach_normal_stop (observer_normal_stop_ftype *f) +{ + return generic_observer_attach (&normal_stop_subject, + &observer_normal_stop_notification_stub, + (void *) f); +} + +void +observer_detach_normal_stop (struct observer *observer) +{ + generic_observer_detach (&normal_stop_subject, observer); +} + +void +observer_notify_normal_stop (struct bpstats *bs) +{ + struct normal_stop_args args; + args.bs = bs; + if (observer_debug) + fprintf_unfiltered (gdb_stdlog, "observer_notify_normal_stop() called\n"); + generic_observer_notify (normal_stop_subject, &args); +} + +/* target_changed notifications. */ + +static struct observer_list *target_changed_subject = NULL; + +struct target_changed_args { struct target_ops *target; }; + +static void +observer_target_changed_notification_stub (const void *data, const void *args_data) +{ + observer_target_changed_ftype *notify = (observer_target_changed_ftype *) data; + const struct target_changed_args *args = args_data; + notify (args->target); +} + +struct observer * +observer_attach_target_changed (observer_target_changed_ftype *f) +{ + return generic_observer_attach (&target_changed_subject, + &observer_target_changed_notification_stub, + (void *) f); +} + +void +observer_detach_target_changed (struct observer *observer) +{ + generic_observer_detach (&target_changed_subject, observer); +} + +void +observer_notify_target_changed (struct target_ops *target) +{ + struct target_changed_args args; + args.target = target; + if (observer_debug) + fprintf_unfiltered (gdb_stdlog, "observer_notify_target_changed() called\n"); + generic_observer_notify (target_changed_subject, &args); +} + +/* inferior_created notifications. */ + +static struct observer_list *inferior_created_subject = NULL; + +struct inferior_created_args { struct target_ops *objfile; int from_tty; }; + +static void +observer_inferior_created_notification_stub (const void *data, const void *args_data) +{ + observer_inferior_created_ftype *notify = (observer_inferior_created_ftype *) data; + const struct inferior_created_args *args = args_data; + notify (args->objfile, args->from_tty); +} + +struct observer * +observer_attach_inferior_created (observer_inferior_created_ftype *f) +{ + return generic_observer_attach (&inferior_created_subject, + &observer_inferior_created_notification_stub, + (void *) f); +} + +void +observer_detach_inferior_created (struct observer *observer) +{ + generic_observer_detach (&inferior_created_subject, observer); +} + +void +observer_notify_inferior_created (struct target_ops *objfile, int from_tty) +{ + struct inferior_created_args args; + args.objfile = objfile, args.from_tty = from_tty; + if (observer_debug) + fprintf_unfiltered (gdb_stdlog, "observer_notify_inferior_created() called\n"); + generic_observer_notify (inferior_created_subject, &args); +} + +/* solib_unloaded notifications. */ + +static struct observer_list *solib_unloaded_subject = NULL; + +struct solib_unloaded_args { struct so_list *solib; }; + +static void +observer_solib_unloaded_notification_stub (const void *data, const void *args_data) +{ + observer_solib_unloaded_ftype *notify = (observer_solib_unloaded_ftype *) data; + const struct solib_unloaded_args *args = args_data; + notify (args->solib); +} + +struct observer * +observer_attach_solib_unloaded (observer_solib_unloaded_ftype *f) +{ + return generic_observer_attach (&solib_unloaded_subject, + &observer_solib_unloaded_notification_stub, + (void *) f); +} + +void +observer_detach_solib_unloaded (struct observer *observer) +{ + generic_observer_detach (&solib_unloaded_subject, observer); +} + +void +observer_notify_solib_unloaded (struct so_list *solib) +{ + struct solib_unloaded_args args; + args.solib = solib; + if (observer_debug) + fprintf_unfiltered (gdb_stdlog, "observer_notify_solib_unloaded() called\n"); + generic_observer_notify (solib_unloaded_subject, &args); +} diff --git a/src/bin/gdb/gdb/config-x86_64/version.c b/src/bin/gdb/gdb/config-x86_64/version.c new file mode 100644 index 0000000000..10f078e936 --- /dev/null +++ b/src/bin/gdb/gdb/config-x86_64/version.c @@ -0,0 +1,4 @@ +#include "version.h" +const char version[] = "6.3"; +const char host_name[] = "x86_64-unknown-haiku"; +const char target_name[] = "x86_64-unknown-haiku"; diff --git a/src/bin/gdb/libiberty/clock.c b/src/bin/gdb/libiberty/clock.c index 3ea70c31c6..02f51cc417 100644 --- a/src/bin/gdb/libiberty/clock.c +++ b/src/bin/gdb/libiberty/clock.c @@ -66,7 +66,7 @@ number of seconds used. /* FIXME: should be able to declare as clock_t. */ -long +clock_t clock () { #ifdef HAVE_GETRUSAGE diff --git a/src/bin/gdb/opcodes/Jamfile b/src/bin/gdb/opcodes/Jamfile index e86641a2c3..175fab3439 100644 --- a/src/bin/gdb/opcodes/Jamfile +++ b/src/bin/gdb/opcodes/Jamfile @@ -13,7 +13,7 @@ SubDirCcFlags -DHAVE_CONFIG_H -D_GNU_SOURCE ; # architecture specific sources local opcodesArchSources ; -if $(TARGET_ARCH) = x86 { +if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 { opcodesArchSources = i386-dis.c ; } else if $(TARGET_ARCH) = ppc { opcodesArchSources = ppc-dis.c ; diff --git a/src/bin/isvolume.cpp b/src/bin/isvolume.cpp index 0d4c0b9455..a7a8b89103 100644 --- a/src/bin/isvolume.cpp +++ b/src/bin/isvolume.cpp @@ -93,8 +93,8 @@ main(int argc, char** argv) BVolume volume(volumeDevice); status_t ret = volume.InitCheck(); if (ret != B_OK) { - fprintf(stderr, "%s: failed to get BVolume for device %ld: %s\n", - argv[0], volumeDevice, strerror(ret)); + fprintf(stderr, "%s: failed to get BVolume for device %" B_PRIdDEV + ": %s\n", argv[0], volumeDevice, strerror(ret)); return 1; } @@ -103,8 +103,8 @@ main(int argc, char** argv) BPartition* partition; ret = roster.FindPartitionByVolume(volume, &diskDevice, &partition); if (ret != B_OK) { - fprintf(stderr, "%s: failed to get partition for device %ld: %s\n", - argv[0], volumeDevice, strerror(ret)); + fprintf(stderr, "%s: failed to get partition for device %" B_PRIdDEV + ": %s\n", argv[0], volumeDevice, strerror(ret)); return 1; } // check this option directly and not via fs_stat_dev() @@ -122,8 +122,8 @@ main(int argc, char** argv) return 0; } else { - fprintf(stderr, "%s: can't get information about dev_t: %ld\n", - argv[0], volumeDevice); + fprintf(stderr, "%s: can't get information about dev_t: %" B_PRIdDEV + "\n", argv[0], volumeDevice); return 1; } } diff --git a/src/bin/keymap/Keymap.cpp b/src/bin/keymap/Keymap.cpp index 29cc48ce5d..0bf6cf81d5 100644 --- a/src/bin/keymap/Keymap.cpp +++ b/src/bin/keymap/Keymap.cpp @@ -569,7 +569,7 @@ Keymap::SaveAsSource(const char* name) _SaveSourceText(file, &textRuns); if (textRuns != NULL) { - ssize_t dataSize; + int32 dataSize; void* data = BTextView::FlattenRunArray(textRuns, &dataSize); if (data != NULL) { BNode node(name); diff --git a/src/bin/listarea.c b/src/bin/listarea.c index 00ab99bfd5..f381bb16ee 100644 --- a/src/bin/listarea.c +++ b/src/bin/listarea.c @@ -41,7 +41,7 @@ show_memory_totals(void) static void list_areas_for_id(team_id id) { - int32 cookie = 0; + ssize_t cookie = 0; team_info teamInfo; area_info areaInfo; diff --git a/src/bin/listattr.cpp b/src/bin/listattr.cpp index 77ea615dd8..13e4010828 100644 --- a/src/bin/listattr.cpp +++ b/src/bin/listattr.cpp @@ -29,7 +29,7 @@ dump_raw_data(const char *buffer, size_t size) while (dumpPosition < size) { // Position for this line - printf("\t%04lx: ", dumpPosition); + printf("\t%04" B_PRIx32 ": ", dumpPosition); // Print the bytes in form of hexadecimal numbers for (uint32 i = 0; i < kChunkSize; i++) { @@ -72,35 +72,35 @@ show_attr_contents(BNode& node, const char* attribute, const attr_info& info) char buffer[kLimit]; ssize_t bytesRead = node.ReadAttr(attribute, info.type, 0, buffer, size); if (bytesRead != size) { - fprintf(stderr, "Could only read %lld bytes from attribute!\n", + fprintf(stderr, "Could only read %" B_PRIdOFF " bytes from attribute!\n", size); return; } switch (info.type) { case B_INT8_TYPE: - printf("%d\n", *((int8 *)buffer)); + printf("%" B_PRId8 "\n", *((int8 *)buffer)); break; case B_UINT8_TYPE: - printf("%u\n", *((uint8 *)buffer)); + printf("%" B_PRIu8 "\n", *((uint8 *)buffer)); break; case B_INT16_TYPE: - printf("%d\n", *((int16 *)buffer)); + printf("%" B_PRId16 "\n", *((int16 *)buffer)); break; case B_UINT16_TYPE: - printf("%u\n", *((uint16 *)buffer)); + printf("%" B_PRIu16 "\n", *((uint16 *)buffer)); break; case B_INT32_TYPE: - printf("%ld\n", *((int32 *)buffer)); + printf("%" B_PRId32 "\n", *((int32 *)buffer)); break; case B_UINT32_TYPE: - printf("%lu\n", *((uint32 *)buffer)); + printf("%" B_PRIu32 "\n", *((uint32 *)buffer)); break; case B_INT64_TYPE: - printf("%lld\n", *((int64 *)buffer)); + printf("%" B_PRId64 "\n", *((int64 *)buffer)); break; case B_UINT64_TYPE: - printf("%llu\n", *((uint64 *)buffer)); + printf("%" B_PRIu64 "\n", *((uint64 *)buffer)); break; case B_FLOAT_TYPE: printf("%f\n", *((float *)buffer)); @@ -198,7 +198,7 @@ get_type(type_code type) sprintf(buffer, "'%c%c%c%c'", value[0], value[1], value[2], value[3]); } else - sprintf(buffer, "0x%08lx", type); + sprintf(buffer, "0x%08" B_PRIx32, type); return buffer; } @@ -262,7 +262,7 @@ main(int argc, char *argv[]) status = node.GetAttrInfo(name, &attrInfo); if (status >= B_OK) { printf("%*s", kTypeWidth, get_type(attrInfo.type)); - printf("% *Li ", kSizeWidth, attrInfo.size); + printf("% *" B_PRId64 " ", kSizeWidth, attrInfo.size); printf("\"%s\"", name); if (printContents) { @@ -283,6 +283,6 @@ main(int argc, char *argv[]) } } - printf("\n%Ld bytes total in attributes.\n", total); + printf("\n%" B_PRId64 " bytes total in attributes.\n", total); return 0; } diff --git a/src/bin/listdev/listdev.c b/src/bin/listdev/listdev.c index f582d0fa5d..77cc02a532 100644 --- a/src/bin/listdev/listdev.c +++ b/src/bin/listdev/listdev.c @@ -87,16 +87,20 @@ dump_attribute(struct device_attr_info *attr, int32 level) printf("string : \"%s\"", attr->value.string); break; case B_UINT8_TYPE: - printf("uint8 : %u (%#x)", attr->value.ui8, attr->value.ui8); + printf("uint8 : %" B_PRIu8 " (%#" B_PRIx8 ")", attr->value.ui8, + attr->value.ui8); break; case B_UINT16_TYPE: - printf("uint16 : %u (%#x)", attr->value.ui16, attr->value.ui16); + printf("uint16 : %" B_PRIu16 " (%#" B_PRIx16 ")", attr->value.ui16, + attr->value.ui16); break; case B_UINT32_TYPE: - printf("uint32 : %lu (%#lx)", attr->value.ui32, attr->value.ui32); + printf("uint32 : %" B_PRIu32 " (%#" B_PRIx32 ")", attr->value.ui32, + attr->value.ui32); break; case B_UINT64_TYPE: - printf("uint64 : %Lu (%#Lx)", attr->value.ui64, attr->value.ui64); + printf("uint64 : %" B_PRIu64 " (%#" B_PRIx64 ")", attr->value.ui64, + attr->value.ui64); break; default: printf("raw data"); diff --git a/src/bin/locale/collectcatkeys.cpp b/src/bin/locale/collectcatkeys.cpp index 06156c8d6c..e8ded99946 100644 --- a/src/bin/locale/collectcatkeys.cpp +++ b/src/bin/locale/collectcatkeys.cpp @@ -184,11 +184,11 @@ collectAllCatalogKeys(BString& inputStr) if (fetchKey(in)) { if (haveID) { if (showKeys) - printf("CatKey(%ld)\n", id); + printf("CatKey(%" B_PRId32 ")\n", id); res = catalog->SetString(id, ""); if (res != B_OK) { - fprintf(stderr, "couldn't add key %ld - error: %s\n", - id, strerror(res)); + fprintf(stderr, "couldn't add key %" B_PRId32 " - error: " + "%s\n", id, strerror(res)); exit(-1); } } else { @@ -285,8 +285,8 @@ main(int argc, char **argv) char *buf = inputStr.LockBuffer(sz); off_t rsz = inFile.Read(buf, sz); if (rsz < sz) { - fprintf(stderr, "couldn't read %Ld bytes from %s (got only %Ld)\n", - sz, inputFile, rsz); + fprintf(stderr, "couldn't read %" B_PRId64 " bytes from %s (got " + "only %" B_PRId64 ")\n", sz, inputFile, rsz); exit(-1); } inputStr.UnlockBuffer(rsz); @@ -301,7 +301,7 @@ main(int argc, char **argv) if (showSummary) { int32 count = catalog->CountItems(); if (count) - fprintf(stderr, "%ld key%s found and written to %s\n", + fprintf(stderr, "%" B_PRId32 " key%s found and written to %s\n", count, (count==1 ? "": "s"), outputFile.String()); else fprintf(stderr, "no keys found\n"); diff --git a/src/bin/locale/dumpcatalog.cpp b/src/bin/locale/dumpcatalog.cpp index b1f58b6054..d90f790bdc 100644 --- a/src/bin/locale/dumpcatalog.cpp +++ b/src/bin/locale/dumpcatalog.cpp @@ -64,15 +64,16 @@ main(int argc, char **argv) while (!walker.AtEnd()) { const CatKey &key(walker.GetKey()); key.GetStringParts(&str, &ctx, &cmt); - printf("Hash:\t\t%lu\nKey:\t\t<%s:%s:%s>\nTranslation:\t%s\n-----\n", - key.fHashVal, str.String(), ctx.String(), cmt.String(), + printf("Hash:\t\t%" B_PRIu32 "\nKey:\t\t<%s:%s:%s>\nTranslation:\t%s\n" + "-----\n", key.fHashVal, str.String(), ctx.String(), cmt.String(), walker.GetValue()); walker.Next(); } int32 count = inputCatalog.CountItems(); - if (count) - fprintf(stderr, "%ld entr%s dumped\n", count, (count==1 ? "y": "ies")); - else + if (count) { + fprintf(stderr, "%" B_PRId32 " entr%s dumped\n", count, + (count==1 ? "y": "ies")); + } else fprintf(stderr, "no entries found\n"); return res; } diff --git a/src/bin/locale/linkcatkeys.cpp b/src/bin/locale/linkcatkeys.cpp index 0fe8ac9b2f..be81f5a948 100644 --- a/src/bin/locale/linkcatkeys.cpp +++ b/src/bin/locale/linkcatkeys.cpp @@ -180,7 +180,7 @@ main(int argc, char **argv) if (showSummary) { int32 count = targetCatalog.CountItems(); if (count) { - fprintf(stderr, "%ld key%s found and written to %s\n", + fprintf(stderr, "%" B_PRId32 " key%s found and written to %s\n", count, (count==1 ? "": "s"), outputFile.String()); } else fprintf(stderr, "no keys found\n"); diff --git a/src/bin/mountvolume.cpp b/src/bin/mountvolume.cpp index d3c2be3378..b9bd217749 100644 --- a/src/bin/mountvolume.cpp +++ b/src/bin/mountvolume.cpp @@ -99,7 +99,7 @@ size_string(int64 size) static char string[64]; if (size < 1024) - sprintf(string, "%Ld", size); + sprintf(string, "%" B_PRId64, size); else { const char* units[] = {"K", "M", "G", NULL}; int32 i = -1; diff --git a/src/bin/ps.c b/src/bin/ps.c index bc5fb0788b..a650f965ed 100644 --- a/src/bin/ps.c +++ b/src/bin/ps.c @@ -28,8 +28,8 @@ printTeamInfo(team_info *teamInfo, bool printHeader) printf("%-50s %5s %8s %4s %4s\n", "Team", "Id", "#Threads", "Gid", \ "Uid"); - printf("%-50s %5ld %8ld %4d %4d\n", teamInfo->args, teamInfo->team, - teamInfo->thread_count, teamInfo->gid, teamInfo->uid); + printf("%-50s %5" B_PRId32 " %8" B_PRId32 " %4d %4d\n", teamInfo->args, + teamInfo->team, teamInfo->thread_count, teamInfo->gid, teamInfo->uid); } @@ -37,7 +37,7 @@ static void printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo) { char *threadState; - uint32 threadCookie = 0; + int32 threadCookie = 0; sem_info semaphoreInfo; thread_info threadInfo; @@ -51,18 +51,21 @@ printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo) else threadState = sStates[threadInfo.state - 1]; - printf("%-37s %5ld %8s %4ld %8llu %8llu ", - threadInfo.name, threadInfo.thread, threadState, + printf("%-37s %5" B_PRId32 " %8s %4" B_PRId32 " %8" B_PRIu64 " %8" + B_PRId64 " ", threadInfo.name, threadInfo.thread, threadState, threadInfo.priority, (threadInfo.user_time / 1000), (threadInfo.kernel_time / 1000)); if (printSemaphoreInfo) { if (threadInfo.state == B_THREAD_WAITING && threadInfo.sem != -1) { status_t status = get_sem_info(threadInfo.sem, &semaphoreInfo); - if (status == B_OK) - printf("%s(%ld)\n", semaphoreInfo.name, semaphoreInfo.sem); - else - printf("%s(%ld)\n", strerror(status), threadInfo.sem); + if (status == B_OK) { + printf("%s(%" B_PRId32 ")\n", semaphoreInfo.name, + semaphoreInfo.sem); + } else { + printf("%s(%" B_PRId32 ")\n", strerror(status), + threadInfo.sem); + } } else puts(""); } else @@ -74,7 +77,7 @@ int main(int argc, char **argv) { team_info teamInfo; - uint32 teamCookie = 0; + int32 teamCookie = 0; system_info systemInfo; bool printSystemInfo = false; bool printThreads = false; @@ -153,13 +156,13 @@ main(int argc, char **argv) // system stats get_system_info(&systemInfo); printf("\nSystem Info\n"); - printf("%luk (%lu bytes) total memory\n", + printf("%" B_PRIu32 "k (%" B_PRIu32 " bytes) total memory\n", (systemInfo.max_pages * B_PAGE_SIZE / 1024), (systemInfo.max_pages * B_PAGE_SIZE)); - printf("%luk (%lu bytes) currently committed\n", + printf("%" B_PRIu32 "k (%" B_PRIu32 " bytes) currently committed\n", (systemInfo.used_pages * B_PAGE_SIZE / 1024), (systemInfo.used_pages * B_PAGE_SIZE)); - printf("%luk (%lu bytes) currently available\n", + printf("%" B_PRIu32 "k (%" B_PRIu32 " bytes) currently available\n", (systemInfo.max_pages - systemInfo.used_pages) * B_PAGE_SIZE / 1024, (systemInfo.max_pages - systemInfo.used_pages) * B_PAGE_SIZE); printf("%2.1f%% memory utilisation\n", diff --git a/src/bin/sysinfo.cpp b/src/bin/sysinfo.cpp index 931d057f99..0723ff8ab5 100644 --- a/src/bin/sysinfo.cpp +++ b/src/bin/sysinfo.cpp @@ -17,7 +17,7 @@ // TODO: -disable_cpu_sn option is not yet implemented // TODO: most of this file should go into an architecture dependent source file -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) struct cache_description { uint8 code; @@ -210,7 +210,7 @@ print_intel_cache_descriptors(enum cpu_types type, cpuid_info *info) } } -#endif // __INTEL__ +#endif // __INTEL__ || __x86_64__ static void @@ -246,14 +246,15 @@ print_level2_cache(uint32 reg, const char *name) // intel does not define this uint32 lineSize = reg & 0xff; - printf("\t%s: %lu KB, ", name, size); + printf("\t%s: %" B_PRIu32 " KB, ", name, size); if (ways == 0xf) printf("fully associative, "); else if (ways == 0x1) printf("direct-mapped, "); else printf("%lu-way set associative, ", 1UL << (ways / 2)); - printf("%lu lines/tag, %lu bytes/line\n", linesPerTag, lineSize); + printf("%" B_PRIu32 " lines/tag, %" B_PRIu32 " bytes/line\n", linesPerTag, + lineSize); } @@ -265,16 +266,17 @@ print_level1_cache(uint32 reg, const char *name) uint32 linesPerTag = (reg >> 8) & 0xff; uint32 lineSize = reg & 0xff; - printf("\t%s: %lu KB, ", name, size); + printf("\t%s: %" B_PRIu32 " KB, ", name, size); if (ways == 0xff) printf("fully associative, "); else - printf("%lu-way set associative, ", ways); - printf("%lu lines/tag, %lu bytes/line\n", linesPerTag, lineSize); + printf("%" B_PRIu32 "-way set associative, ", ways); + printf("%" B_PRIu32 " lines/tag, %" B_PRIu32 " bytes/line\n", linesPerTag, + lineSize); } -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) static void print_cache_desc(int32 cpu) @@ -318,7 +320,7 @@ print_intel_cache_desc(int32 cpu) uint32 sets = info.regs.ecx; - printf("\tL%ld ",level); + printf("\tL%" B_PRId32 " ",level); switch (type) { case 1: printf("Data cache "); break; @@ -330,8 +332,9 @@ print_intel_cache_desc(int32 cpu) if (isFullyAssoc) printf("fully associative, "); else - printf("%lu-way set associative, ", ways); - printf("%lu lines/tag, %lu bytes/line\n", linesPerTag, lineSize); + printf("%" B_PRIu32 "-way set associative, ", ways); + printf("%" B_PRIu32 " lines/tag, %" B_PRIu32 " bytes/line\n", linesPerTag, + lineSize); get_cpuid(&info, 0x80000006, cpu); print_level2_cache(sets, "L2 cache"); @@ -345,7 +348,7 @@ print_transmeta_features(uint32 features) printf("\t\tFCMOV\n"); } -#endif // __INTEL__ +#endif // __INTEL__ || __x86_64__ static void @@ -459,7 +462,7 @@ print_features(uint32 features) } -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) static void print_processor_signature(system_info *sys_info, cpuid_info *info, @@ -467,8 +470,10 @@ print_processor_signature(system_info *sys_info, cpuid_info *info, { if ((sys_info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_AMD_x86) { - printf("\t%s%sype %lu, family %lu, model %lu, stepping %lu, features " - "0x%08lx\n", prefix ? prefix : "", prefix && prefix[0] ? "t" : "T", + + printf("\t%s%sype %" B_PRIu32 ", family %" B_PRIu32 ", model %" B_PRIu32 + ", stepping %" B_PRIu32 ", features 0x%08" B_PRIx32 "\n", + prefix ? prefix : "", prefix && prefix[0] ? "t" : "T", info->eax_1.type, info->eax_1.family + (info->eax_1.family == 0xf ? info->eax_1.extended_family : 0), @@ -479,8 +484,9 @@ print_processor_signature(system_info *sys_info, cpuid_info *info, } else if ((sys_info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86) { // model calculation is different for INTEL - printf("\t%s%sype %lu, family %lu, model %lu, stepping %lu, features " - "0x%08lx\n", prefix ? prefix : "", prefix && prefix[0] ? "t" : "T", + printf("\t%s%sype %" B_PRIu32 ", family %" B_PRIu32 ", model %" B_PRIu32 + ", stepping %" B_PRIu32 ", features 0x%08" B_PRIx32 "\n", + prefix ? prefix : "", prefix && prefix[0] ? "t" : "T", info->eax_1.type, info->eax_1.family + (info->eax_1.family == 0xf ? info->eax_1.extended_family : 0), @@ -492,7 +498,7 @@ print_processor_signature(system_info *sys_info, cpuid_info *info, } } -#endif // __INTEL__ +#endif // __INTEL__ || __x86_64__ static void @@ -505,7 +511,7 @@ dump_platform(system_info *info) } -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) static void dump_cpu(system_info *info, int32 cpu) @@ -562,15 +568,15 @@ dump_cpu(system_info *info, int32 cpu) // the BIOS may not have set the processor name if (name[0]) - printf("CPU #%ld: \"%s\"\n", cpu, name); + printf("CPU #%" B_PRId32 ": \"%s\"\n", cpu, name); else { // Intel CPUs don't seem to have the genuine vendor field - printf("CPU #%ld: %.12s\n", cpu, + printf("CPU #%" B_PRId32 ": %.12s\n", cpu, (info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86 ? baseInfo.eax_0.vendor_id : cpuInfo.eax_0.vendor_id); } } else { - printf("CPU #%ld: %.12s\n", cpu, baseInfo.eax_0.vendor_id); + printf("CPU #%" B_PRId32 ": %.12s\n", cpu, baseInfo.eax_0.vendor_id); if (maxStandardFunction == 0) return; } @@ -581,7 +587,7 @@ dump_cpu(system_info *info, int32 cpu) if (maxStandardFunction >= 1) { /* Extended features */ - printf("\tExtended Intel: 0x%08lx\n", cpuInfo.eax_1.extended_features); + printf("\tExtended Intel: 0x%08" B_PRIx32 "\n", cpuInfo.eax_1.extended_features); print_extended_features(cpuInfo.eax_1.extended_features); } @@ -632,7 +638,8 @@ dump_cpu(system_info *info, int32 cpu) if (flagsInfo.eax_1.features & (1UL << 18)) { get_cpuid(&cpuInfo, 3, cpu); - printf("Serial number: %04lx-%04lx-%04lx-%04lx-%04lx-%04lx\n", + printf("Serial number: %04" B_PRIx32 "-%04" B_PRIx32 "-%04" B_PRIx32 + "-%04" B_PRIx32 "-%04" B_PRIx32 "-%04" B_PRIx32 "\n", flagsInfo.eax_1.features >> 16, flagsInfo.eax_1.features & 0xffff, cpuInfo.regs.edx >> 16, cpuInfo.regs.edx & 0xffff, @@ -643,7 +650,7 @@ dump_cpu(system_info *info, int32 cpu) putchar('\n'); } -#endif // __INTEL__ +#endif // __INTEL__ || __x86_64__ static void @@ -660,28 +667,30 @@ dump_cpus(system_info *info) snprintf(modelString, 32, "(Unknown %x)", info->cpu_type); } - printf("%ld %s%s%s, revision %04lx running at %LdMHz (ID: 0x%08lx " - "0x%08lx)\n\n", info->cpu_count, + printf("%" B_PRId32 " %s%s%s, revision %04" B_PRIx32 " running at %" + B_PRId64 "MHz (ID: 0x%08" B_PRIx32 " 0x%08" B_PRIx32 ")\n\n", + info->cpu_count, vendor ? vendor : "", vendor ? " " : "", model, info->cpu_revision, info->cpu_clock_speed / 1000000, info->id[0], info->id[1]); -#ifdef __INTEL__ +#if defined(__INTEL__) || defined(__x86_64__) for (int32 cpu = 0; cpu < info->cpu_count; cpu++) dump_cpu(info, cpu); -#endif // __INTEL__ +#endif // __INTEL__ || __x86_64__ } static void dump_mem(system_info *info) { - printf("%10lu bytes free (used/max %10lu / %10lu)\n", + printf("%10" B_PRIu32 " bytes free (used/max %10" B_PRIu32 " / %10" + B_PRIu32 ")\n", B_PAGE_SIZE * (uint32)(info->max_pages - info->used_pages), B_PAGE_SIZE * (uint32)info->used_pages, B_PAGE_SIZE * (uint32)info->max_pages); - printf(" (cached %10lu)\n", + printf(" (cached %10" B_PRIu32 ")\n", B_PAGE_SIZE * (uint32)info->cached_pages); } @@ -689,7 +698,8 @@ dump_mem(system_info *info) static void dump_sem(system_info *info) { - printf("%10ld semaphores free (used/max %10ld / %10ld)\n", + printf("%10" B_PRId32 " semaphores free (used/max %10" B_PRId32 " / %10" + B_PRId32 ")\n", info->max_sems - info->used_sems, info->used_sems, info->max_sems); } @@ -698,7 +708,8 @@ dump_sem(system_info *info) static void dump_ports(system_info *info) { - printf("%10ld ports free (used/max %10ld / %10ld)\n", + printf("%10" B_PRId32 " ports free (used/max %10" B_PRId32 " / %10" + B_PRId32 ")\n", info->max_ports - info->used_ports, info->used_ports, info->max_ports); } @@ -707,7 +718,8 @@ dump_ports(system_info *info) static void dump_thread(system_info *info) { - printf("%10ld threads free (used/max %10ld / %10ld)\n", + printf("%10" B_PRId32 " threads free (used/max %10" B_PRId32 " / %10" + B_PRId32 ")\n", info->max_threads - info->used_threads, info->used_threads, info->max_threads); } @@ -716,7 +728,8 @@ dump_thread(system_info *info) static void dump_team(system_info *info) { - printf("%10ld teams free (used/max %10ld / %10ld)\n", + printf("%10" B_PRId32 " teams free (used/max %10" B_PRId32 " / %10" + B_PRId32 ")\n", info->max_teams - info->used_teams, info->used_teams, info->max_teams); } @@ -725,7 +738,7 @@ dump_team(system_info *info) static void dump_kinfo(system_info *info) { - printf("Kernel name: %s built on: %s %s version 0x%Lx\n", + printf("Kernel name: %s built on: %s %s version 0x%" B_PRIx64 "\n", info->kernel_name, info->kernel_build_date, info->kernel_build_time, info->kernel_version ); @@ -766,7 +779,8 @@ main(int argc, char *argv[]) const char *opt = argv[i]; if (strncmp(opt, "-id", strlen(opt)) == 0) { /* note: the original also assumes this option on "sysinfo -" */ - printf("0x%.8lx 0x%.8lx\n", info.id[0], info.id[1]); + printf("0x%.8" B_PRIx32 " 0x%.8" B_PRIx32 "\n", info.id[0], + info.id[1]); } else if (strncmp(opt, "-cpu", strlen(opt)) == 0) { dump_cpus(&info); } else if (strncmp(opt, "-mem", strlen(opt)) == 0) { diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index 386e7e50c8..b8d9c6eb0d 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -522,7 +522,7 @@ BApplication::Quit() if (!name) name = "no-name"; printf("ERROR - you must Lock the application object before calling " - "Quit(), team=%ld, looper=%s\n", Team(), name); + "Quit(), team=%" B_PRId32 ", looper=%s\n", Team(), name); unlock = true; if (!Lock()) return; diff --git a/src/kits/app/Looper.cpp b/src/kits/app/Looper.cpp index 2d1879dbcb..1713e99cb9 100644 --- a/src/kits/app/Looper.cpp +++ b/src/kits/app/Looper.cpp @@ -443,7 +443,8 @@ BLooper::Quit() if (!IsLocked()) { printf("ERROR - you must Lock a looper before calling Quit(), " - "team=%ld, looper=%s\n", Team(), Name() ? Name() : "unnamed"); + "team=%" B_PRId32 ", looper=%s\n", Team(), + Name() ? Name() : "unnamed"); } // Try to lock @@ -547,7 +548,7 @@ BLooper::IsLocked() const } uint32 stack; - return ((uint32)&stack & ~(B_PAGE_SIZE - 1)) == fCachedStack + return ((addr_t)&stack & ~(B_PAGE_SIZE - 1)) == fCachedStack || find_thread(NULL) == fOwner; } @@ -1338,7 +1339,7 @@ BLooper::check_lock() // It is used in situations where it's clear that the looper is valid, // ie. from handlers uint32 stack; - if (((uint32)&stack & ~(B_PAGE_SIZE - 1)) == fCachedStack + if (((addr_t)&stack & ~(B_PAGE_SIZE - 1)) == fCachedStack || fOwner == find_thread(NULL)) return; diff --git a/src/kits/app/PropertyInfo.cpp b/src/kits/app/PropertyInfo.cpp index 10f45b3e09..e09c4863b3 100644 --- a/src/kits/app/PropertyInfo.cpp +++ b/src/kits/app/PropertyInfo.cpp @@ -426,7 +426,7 @@ BPropertyInfo::PrintToStream() const // specifiers for (int32 i = 0; i < 10 && fPropInfo[pi].specifiers[i] != 0; i++) { uint32 spec = fPropInfo[pi].specifiers[i]; - printf("%lu", spec); + printf("%" B_PRIu32, spec); } printf("\n"); } diff --git a/src/kits/app/Roster.cpp b/src/kits/app/Roster.cpp index a500c70dd7..051d200270 100644 --- a/src/kits/app/Roster.cpp +++ b/src/kits/app/Roster.cpp @@ -657,7 +657,7 @@ BRoster::GetAppList(BList* teamIDList) const if (reply.what == B_REG_SUCCESS) { team_id team; for (int32 i = 0; reply.FindInt32("teams", i, &team) == B_OK; i++) - teamIDList->AddItem((void*)team); + teamIDList->AddItem((void*)(addr_t)team); } else { if (reply.FindInt32("error", &error) != B_OK) error = B_ERROR; @@ -700,7 +700,7 @@ BRoster::GetAppList(const char* sig, BList* teamIDList) const if (reply.what == B_REG_SUCCESS) { team_id team; for (int32 i = 0; reply.FindInt32("teams", i, &team) == B_OK; i++) - teamIDList->AddItem((void*)team); + teamIDList->AddItem((void*)(addr_t)team); } else if (reply.FindInt32("error", &error) != B_OK) error = B_ERROR; } diff --git a/src/kits/app/ServerLink.cpp b/src/kits/app/ServerLink.cpp index 2c1b2af9f2..ea7664abce 100644 --- a/src/kits/app/ServerLink.cpp +++ b/src/kits/app/ServerLink.cpp @@ -62,7 +62,7 @@ ServerLink::SetTo(port_id sender, port_id receiver) status_t ServerLink::ReadRegion(BRegion* region) { - fReceiver->Read(®ion->fCount, sizeof(long)); + fReceiver->Read(®ion->fCount, sizeof(int32)); if (region->fCount > 0) { fReceiver->Read(®ion->fBounds, sizeof(clipping_rect)); if (!region->_SetSize(region->fCount)) @@ -78,7 +78,7 @@ ServerLink::ReadRegion(BRegion* region) status_t ServerLink::AttachRegion(const BRegion& region) { - fSender->Attach(®ion.fCount, sizeof(long)); + fSender->Attach(®ion.fCount, sizeof(int32)); if (region.fCount > 0) { fSender->Attach(®ion.fBounds, sizeof(clipping_rect)); return fSender->Attach(region.fData, diff --git a/src/kits/debug/DebugEventStream.cpp b/src/kits/debug/DebugEventStream.cpp index 422efe3645..ec2711e386 100644 --- a/src/kits/debug/DebugEventStream.cpp +++ b/src/kits/debug/DebugEventStream.cpp @@ -123,7 +123,7 @@ BDebugEventInputStream::Seek(off_t streamOffset) if (fStream != NULL) return B_UNSUPPORTED; - if (streamOffset < 0 || streamOffset > fBufferCapacity) + if (streamOffset < 0 || streamOffset > (off_t)fBufferCapacity) return B_BUFFER_OVERFLOW; fStreamPosition = 0; diff --git a/src/kits/debug/Image.cpp b/src/kits/debug/Image.cpp index 4075b482cc..1022792350 100644 --- a/src/kits/debug/Image.cpp +++ b/src/kits/debug/Image.cpp @@ -82,17 +82,17 @@ SymbolTableBasedImage::~SymbolTableBasedImage() } -const Elf32_Sym* +const elf_sym* SymbolTableBasedImage::LookupSymbol(addr_t address, addr_t* _baseAddress, const char** _symbolName, size_t *_symbolNameLen, bool *_exactMatch) const { - const Elf32_Sym* symbolFound = NULL; + const elf_sym* symbolFound = NULL; const char* symbolName = NULL; bool exactMatch = false; addr_t deltaFound = ~(addr_t)0; for (int32 i = 0; i < fSymbolCount; i++) { - const Elf32_Sym* symbol = &fSymbolTable[i]; + const elf_sym* symbol = &fSymbolTable[i]; if (symbol->st_value == 0 || symbol->st_size >= (size_t)fInfo.text_size + fInfo.data_size) { @@ -141,10 +141,9 @@ SymbolTableBasedImage::NextSymbol(int32& iterator, const char** _symbolName, if (++iterator >= fSymbolCount) return B_ENTRY_NOT_FOUND; - const Elf32_Sym* symbol = &fSymbolTable[iterator]; + const elf_sym* symbol = &fSymbolTable[iterator]; - if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC - && ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT) + if ((symbol->Type() != STT_FUNC && symbol->Type() != STT_OBJECT) || symbol->st_value == 0) { continue; } @@ -153,8 +152,8 @@ SymbolTableBasedImage::NextSymbol(int32& iterator, const char** _symbolName, *_symbolNameLen = _SymbolNameLen(*_symbolName); *_symbolAddress = symbol->st_value + fLoadDelta; *_symbolSize = symbol->st_size; - *_symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC - ? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA; + *_symbolType = symbol->Type() == STT_FUNC ? B_SYMBOL_TYPE_TEXT + : B_SYMBOL_TYPE_DATA; return B_OK; } @@ -268,7 +267,7 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize, return errno; fFileSize = st.st_size; - if (fFileSize < sizeof(Elf32_Ehdr)) + if (fFileSize < (off_t)sizeof(elf_ehdr)) return B_NOT_AN_EXECUTABLE; // map it @@ -277,36 +276,37 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize, return errno; // examine the elf header - Elf32_Ehdr* elfHeader = (Elf32_Ehdr*)fMappedFile; + elf_ehdr* elfHeader = (elf_ehdr*)fMappedFile; if (memcmp(elfHeader->e_ident, ELF_MAGIC, 4) != 0) return B_NOT_AN_EXECUTABLE; - if (elfHeader->e_ident[4] != ELFCLASS32) + if (elfHeader->e_ident[4] != ELF_CLASS) return B_NOT_AN_EXECUTABLE; // verify the location of the program headers int32 programHeaderCount = elfHeader->e_phnum; - if (elfHeader->e_phoff < sizeof(Elf32_Ehdr) - || elfHeader->e_phentsize < sizeof(Elf32_Phdr) - || elfHeader->e_phoff + programHeaderCount * elfHeader->e_phentsize + if (elfHeader->e_phoff < sizeof(elf_ehdr) + || elfHeader->e_phentsize < sizeof(elf_phdr) + || (off_t)(elfHeader->e_phoff + programHeaderCount + * elfHeader->e_phentsize) > fFileSize) { return B_NOT_AN_EXECUTABLE; } - Elf32_Phdr* programHeaders - = (Elf32_Phdr*)(fMappedFile + elfHeader->e_phoff); + elf_phdr* programHeaders + = (elf_phdr*)(fMappedFile + elfHeader->e_phoff); // verify the location of the section headers int32 sectionCount = elfHeader->e_shnum; - if (elfHeader->e_shoff < sizeof(Elf32_Ehdr) - || elfHeader->e_shentsize < sizeof(Elf32_Shdr) - || elfHeader->e_shoff + sectionCount * elfHeader->e_shentsize + if (elfHeader->e_shoff < sizeof(elf_ehdr) + || elfHeader->e_shentsize < sizeof(elf_shdr) + || (off_t)(elfHeader->e_shoff + sectionCount * elfHeader->e_shentsize) > fFileSize) { return B_NOT_AN_EXECUTABLE; } - Elf32_Shdr* sectionHeaders - = (Elf32_Shdr*)(fMappedFile + elfHeader->e_shoff); + elf_shdr* sectionHeaders + = (elf_shdr*)(fMappedFile + elfHeader->e_shoff); // find the text and data segment -- we need load address and size *_textAddress = 0; @@ -314,7 +314,7 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize, *_dataAddress = 0; *_dataSize = 0; for (int32 i = 0; i < programHeaderCount; i++) { - Elf32_Phdr* header = (Elf32_Phdr*) + elf_phdr* header = (elf_phdr*) ((uint8*)programHeaders + i * elfHeader->e_phentsize); if (header->p_type == PT_LOAD) { if ((header->p_flags & PF_WRITE) == 0) { @@ -330,25 +330,27 @@ ImageFile::_LoadFile(const char* path, addr_t* _textAddress, size_t* _textSize, // find the symbol table for (int32 i = 0; i < elfHeader->e_shnum; i++) { - Elf32_Shdr* sectionHeader = (Elf32_Shdr*) + elf_shdr* sectionHeader = (elf_shdr*) ((uint8*)sectionHeaders + i * elfHeader->e_shentsize); if (sectionHeader->sh_type == SHT_SYMTAB) { - Elf32_Shdr& stringHeader = *(Elf32_Shdr*) + elf_shdr& stringHeader = *(elf_shdr*) ((uint8*)sectionHeaders + sectionHeader->sh_link * elfHeader->e_shentsize); if (stringHeader.sh_type != SHT_STRTAB) return B_BAD_DATA; - if (sectionHeader->sh_offset + sectionHeader->sh_size > fFileSize - || stringHeader.sh_offset + stringHeader.sh_size > fFileSize) { + if ((off_t)(sectionHeader->sh_offset + sectionHeader->sh_size) + > fFileSize + || (off_t)(stringHeader.sh_offset + stringHeader.sh_size) + > fFileSize) { return B_BAD_DATA; } - fSymbolTable = (Elf32_Sym*)(fMappedFile + sectionHeader->sh_offset); + fSymbolTable = (elf_sym*)(fMappedFile + sectionHeader->sh_offset); fStringTable = (char*)(fMappedFile + stringHeader.sh_offset); - fSymbolCount = sectionHeader->sh_size / sizeof(Elf32_Sym); + fSymbolCount = sectionHeader->sh_size / sizeof(elf_sym); fStringTableSize = stringHeader.sh_size; return B_OK; @@ -388,7 +390,7 @@ KernelImage::Init(const image_info& info) return error; // allocate the tables - fSymbolTable = new(std::nothrow) Elf32_Sym[fSymbolCount]; + fSymbolTable = new(std::nothrow) elf_sym[fSymbolCount]; fStringTable = new(std::nothrow) char[fStringTableSize]; if (fSymbolTable == NULL || fStringTable == NULL) return B_NO_MEMORY; diff --git a/src/kits/debug/Image.h b/src/kits/debug/Image.h index 5a691defd6..aa4e76db89 100644 --- a/src/kits/debug/Image.h +++ b/src/kits/debug/Image.h @@ -8,6 +8,7 @@ #include +#include #include #include @@ -16,7 +17,6 @@ struct image_t; struct runtime_loader_debug_area; -struct Elf32_Sym; namespace BPrivate { @@ -35,7 +35,7 @@ public: { return (addr_t)fInfo.text; } size_t TextSize() const { return fInfo.text_size; } - virtual const Elf32_Sym* LookupSymbol(addr_t address, + virtual const elf_sym* LookupSymbol(addr_t address, addr_t* _baseAddress, const char** _symbolName, size_t *_symbolNameLen, @@ -60,7 +60,7 @@ public: SymbolTableBasedImage(); virtual ~SymbolTableBasedImage(); - virtual const Elf32_Sym* LookupSymbol(addr_t address, + virtual const elf_sym* LookupSymbol(addr_t address, addr_t* _baseAddress, const char** _symbolName, size_t *_symbolNameLen, @@ -76,7 +76,7 @@ protected: protected: addr_t fLoadDelta; - Elf32_Sym* fSymbolTable; + elf_sym* fSymbolTable; char* fStringTable; int32 fSymbolCount; size_t fStringTableSize; diff --git a/src/kits/debug/SymbolLookup.cpp b/src/kits/debug/SymbolLookup.cpp index 930ac95a9f..cb061064e6 100644 --- a/src/kits/debug/SymbolLookup.cpp +++ b/src/kits/debug/SymbolLookup.cpp @@ -33,15 +33,15 @@ using namespace BPrivate::Debug; const void * Area::PrepareAddress(const void *address) { - TRACE(("Area::PrepareAddress(%p): area: %ld\n", address, fRemoteID)); + TRACE(("Area::PrepareAddress(%p): area: %" B_PRId32 "\n", address, fRemoteID)); // clone the area, if not done already if (fLocalID < 0) { fLocalID = clone_area("cloned area", &fLocalAddress, B_ANY_ADDRESS, B_READ_AREA, fRemoteID); if (fLocalID < 0) { - TRACE(("Area::PrepareAddress(): Failed to clone area %ld: %s\n", - fRemoteID, strerror(fLocalID))); + TRACE(("Area::PrepareAddress(): Failed to clone area %" B_PRId32 + ": %s\n", fRemoteID, strerror(fLocalID))); throw Exception(fLocalID); } } @@ -86,11 +86,11 @@ RemoteMemoryAccessor::Init() // get a list of the team's areas area_info areaInfo; - int32 cookie = 0; + ssize_t cookie = 0; status_t error; while ((error = get_next_area_info(fTeam, &cookie, &areaInfo)) == B_OK) { - TRACE(("area %ld: address: %p, size: %ld, name: %s\n", areaInfo.area, - areaInfo.address, areaInfo.size, areaInfo.name)); + TRACE(("area %" B_PRId32 ": address: %p, size: %ld, name: %s\n", + areaInfo.area, areaInfo.address, areaInfo.size, areaInfo.name)); Area *area = new(std::nothrow) Area(areaInfo.area, areaInfo.address, areaInfo.size); @@ -111,8 +111,8 @@ const void * RemoteMemoryAccessor::PrepareAddress(const void *remoteAddress, int32 size) const { - TRACE(("RemoteMemoryAccessor::PrepareAddress(%p, %ld)\n", remoteAddress, - size)); + TRACE(("RemoteMemoryAccessor::PrepareAddress(%p, %" B_PRId32 ")\n", + remoteAddress, size)); if (!remoteAddress) { TRACE(("RemoteMemoryAccessor::PrepareAddress(): Got null address!\n")); @@ -159,7 +159,8 @@ RemoteMemoryAccessor::AreaForLocalAddress(const void* address) const Area & RemoteMemoryAccessor::_FindArea(const void *address, int32 size) const { - TRACE(("RemoteMemoryAccessor::_FindArea(%p, %ld)\n", address, size)); + TRACE(("RemoteMemoryAccessor::_FindArea(%p, %" B_PRId32 ")\n", address, + size)); for (AreaList::ConstIterator it = fAreas.GetIterator(); it.HasNext();) { Area *area = it.Next(); @@ -196,7 +197,7 @@ public: const image_t* image, int32 symbolCount); virtual ~LoadedImage(); - virtual const Elf32_Sym* LookupSymbol(addr_t address, + virtual const elf_sym* LookupSymbol(addr_t address, addr_t* _baseAddress, const char** _symbolName, size_t *_symbolNameLen, @@ -251,7 +252,7 @@ SymbolLookup::Init() // find the runtime loader debug area runtime_loader_debug_area *remoteDebugArea = NULL; - int32 cookie = 0; + ssize_t cookie = 0; area_info areaInfo; while (get_next_area_info(fTeam, &cookie, &areaInfo) == B_OK) { if (strcmp(areaInfo.name, RUNTIME_LOADER_DEBUG_AREA_NAME) == 0) { @@ -340,7 +341,7 @@ SymbolLookup::LookupSymbolAddress(addr_t address, addr_t *_baseAddress, if (_imageName != NULL) *_imageName = image->Name(); - const Elf32_Sym* symbolFound = image->LookupSymbol(address, _baseAddress, + const elf_sym* symbolFound = image->LookupSymbol(address, _baseAddress, _symbolName, _symbolNameLen, _exactMatch); TRACE(("SymbolLookup::LookupSymbolAddress(): done: symbol: %p, image name: " @@ -375,7 +376,8 @@ status_t SymbolLookup::InitSymbolIterator(image_id imageID, SymbolIterator& iterator) const { - TRACE(("SymbolLookup::InitSymbolIterator(): image ID: %ld\n", imageID)); + TRACE(("SymbolLookup::InitSymbolIterator(): image ID: %" B_PRId32 "\n", + imageID)); // find the image iterator.image = _FindImageByID(imageID); @@ -557,16 +559,16 @@ SymbolLookup::LoadedImage::~LoadedImage() } -const Elf32_Sym* +const elf_sym* SymbolLookup::LoadedImage::LookupSymbol(addr_t address, addr_t* _baseAddress, const char** _symbolName, size_t *_symbolNameLen, bool *_exactMatch) const { - TRACE(("LoadedImage::LookupSymbol(): found image: ID: %ld, text: " + TRACE(("LoadedImage::LookupSymbol(): found image: ID: %" B_PRId32 ", text: " "address: %p, size: %ld\n", fImage->id, (void*)fImage->regions[0].vmstart, fImage->regions[0].size)); // search the image for the symbol - const struct Elf32_Sym *symbolFound = NULL; + const elf_sym *symbolFound = NULL; addr_t deltaFound = INT_MAX; bool exactMatch = false; const char *symbolName = NULL; @@ -575,7 +577,7 @@ SymbolLookup::LoadedImage::LookupSymbol(addr_t address, addr_t* _baseAddress, const elf_region_t *textRegion = fImage->regions; // local for (int32 i = 0; i < symbolCount; i++) { - const struct Elf32_Sym *symbol = &fSymbolLookup->Read(fImage->syms[i]); + const elf_sym *symbol = &fSymbolLookup->Read(fImage->syms[i]); // The symbol table contains not only symbols referring to functions // and data symbols within the shared object, but also referenced @@ -584,8 +586,7 @@ SymbolLookup::LoadedImage::LookupSymbol(addr_t address, addr_t* _baseAddress, // that have an st_value != 0 (0 seems to be an indication for a // symbol defined elsewhere -- couldn't verify that in the specs // though). - if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC - && ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT) + if ((symbol->Type() != STT_FUNC && symbol->Type() != STT_OBJECT) || symbol->st_value == 0 || symbol->st_value + symbol->st_size + textRegion->delta > textRegion->vmstart + textRegion->size) { @@ -643,10 +644,9 @@ SymbolLookup::LoadedImage::NextSymbol(int32& iterator, const char** _symbolName, if (++iterator >= fSymbolCount) return B_ENTRY_NOT_FOUND; - const struct Elf32_Sym* symbol + const elf_sym* symbol = &fSymbolLookup->Read(fImage->syms[iterator]); - if ((ELF32_ST_TYPE(symbol->st_info) != STT_FUNC - && ELF32_ST_TYPE(symbol->st_info) != STT_OBJECT) + if ((symbol->Type() != STT_FUNC && symbol->Type() != STT_OBJECT) || symbol->st_value == 0) { continue; } @@ -656,8 +656,8 @@ SymbolLookup::LoadedImage::NextSymbol(int32& iterator, const char** _symbolName, *_symbolNameLen = fSymbolLookup->_SymbolNameLen(*_symbolName); *_symbolAddress = symbol->st_value + fTextDelta; *_symbolSize = symbol->st_size; - *_symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC - ? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA; + *_symbolType = symbol->Type() == STT_FUNC ? B_SYMBOL_TYPE_TEXT + : B_SYMBOL_TYPE_DATA; return B_OK; } diff --git a/src/kits/debug/SymbolLookup.h b/src/kits/debug/SymbolLookup.h index b2c78bb7f3..c7890c3b68 100644 --- a/src/kits/debug/SymbolLookup.h +++ b/src/kits/debug/SymbolLookup.h @@ -16,7 +16,6 @@ struct image_t; struct runtime_loader_debug_area; -struct Elf32_Sym; namespace BPrivate { diff --git a/src/kits/debug/arch/x86_64/arch_debug_support.cpp b/src/kits/debug/arch/x86_64/arch_debug_support.cpp new file mode 100644 index 0000000000..83f6b35cdf --- /dev/null +++ b/src/kits/debug/arch/x86_64/arch_debug_support.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include "arch_debug_support.h" + + +struct stack_frame { + struct stack_frame *previous; + void *return_address; +}; + + +status_t +arch_debug_get_instruction_pointer(debug_context *context, thread_id thread, + void **ip, void **stackFrameAddress) +{ + // get the CPU state + debug_cpu_state cpuState; + status_t error = debug_get_cpu_state(context, thread, NULL, &cpuState); + if (error != B_OK) + return error; + + *ip = (void*)cpuState.rip; + *stackFrameAddress = (void*)cpuState.rbp; + + return B_OK; +} + + +status_t +arch_debug_get_stack_frame(debug_context *context, void *stackFrameAddress, + debug_stack_frame_info *stackFrameInfo) +{ + stack_frame stackFrame; + ssize_t bytesRead = debug_read_memory(context, stackFrameAddress, + &stackFrame, sizeof(stackFrame)); + if (bytesRead < B_OK) + return bytesRead; + if (bytesRead != sizeof(stackFrame)) + return B_ERROR; + + stackFrameInfo->frame = stackFrameAddress; + stackFrameInfo->parent_frame = stackFrame.previous; + stackFrameInfo->return_address = stackFrame.return_address; + return B_OK; +} diff --git a/src/kits/game/DirectWindow.cpp b/src/kits/game/DirectWindow.cpp index 5e30f64e4e..ed850a1f51 100644 --- a/src/kits/game/DirectWindow.cpp +++ b/src/kits/game/DirectWindow.cpp @@ -365,7 +365,7 @@ BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const if (IsLocked() || !_LockDirect()) return B_ERROR; - if (fInDirectConnect) { + if (!fInDirectConnect) { _UnlockDirect(); return B_ERROR; } diff --git a/src/kits/interface/AbstractLayout.cpp b/src/kits/interface/AbstractLayout.cpp index 1788b4bec9..e61cd09964 100644 --- a/src/kits/interface/AbstractLayout.cpp +++ b/src/kits/interface/AbstractLayout.cpp @@ -30,6 +30,10 @@ struct BAbstractLayout::Proxy { { } + virtual ~Proxy() + { + } + virtual BSize MinSize() const = 0; virtual void SetMinSize(const BSize&) = 0; diff --git a/src/kits/interface/Alert.cpp b/src/kits/interface/Alert.cpp index b6ec85cfa4..ed53bb17d9 100644 --- a/src/kits/interface/Alert.cpp +++ b/src/kits/interface/Alert.cpp @@ -697,7 +697,7 @@ BAlert::_CreateButton(int32 which, const char* label) rect.bottom = rect.top; char name[32]; - snprintf(name, sizeof(name), "_b%ld_", which); + snprintf(name, sizeof(name), "_b%" B_PRId32 "_", which); BButton* button = new(std::nothrow) BButton(rect, name, label, message, B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); diff --git a/src/kits/interface/ChannelSlider.cpp b/src/kits/interface/ChannelSlider.cpp index c2d6040a3d..02e90a9470 100644 --- a/src/kits/interface/ChannelSlider.cpp +++ b/src/kits/interface/ChannelSlider.cpp @@ -839,7 +839,8 @@ BChannelSlider::_DrawThumbs() // draw some kind of current value tool tip if (fCurrentChannel != -1 && fMinPoint != 0) { char valueString[32]; - snprintf(valueString, 32, "%ld", ValueFor(fCurrentChannel)); + snprintf(valueString, 32, "%" B_PRId32, + ValueFor(fCurrentChannel)); float stringWidth = fBackingView->StringWidth(valueString); float width = max_c(10.0, stringWidth); BRect valueRect(0.0, 0.0, width, 10.0); diff --git a/src/kits/interface/Layout.cpp b/src/kits/interface/Layout.cpp index ded10e2023..98cffc5b1a 100644 --- a/src/kits/interface/Layout.cpp +++ b/src/kits/interface/Layout.cpp @@ -222,7 +222,7 @@ bool BLayout::RemoveItem(BLayoutItem* item) { int32 index = IndexOfItem(item); - return (index >= 0 ? RemoveItem(index) : false); + return (index >= 0 ? RemoveItem(index) != NULL : false); } diff --git a/src/kits/interface/ListView.cpp b/src/kits/interface/ListView.cpp index d6093c5a6c..54a1259513 100644 --- a/src/kits/interface/ListView.cpp +++ b/src/kits/interface/ListView.cpp @@ -498,7 +498,7 @@ BListView::MouseDown(BPoint point) doubleClick = true; if (doubleClick && index >= fFirstSelected && index <= fLastSelected) { - fTrack->drag_start.Set(LONG_MAX, LONG_MAX); + fTrack->drag_start.Set(INT32_MAX, INT32_MAX); Invoke(); return; } diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 6905c15605..8491d2fcce 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -68,9 +68,9 @@ public: // TODO: make this work with Unicode characters! bool HasTrigger(uint32 c) - { return fList.HasItem((void*)tolower(c)); } + { return fList.HasItem((void*)(addr_t)tolower(c)); } bool AddTrigger(uint32 c) - { return fList.AddItem((void*)tolower(c)); } + { return fList.AddItem((void*)(addr_t)tolower(c)); } private: BList fList; @@ -2883,7 +2883,7 @@ bool BMenu::_OkToProceed(BMenuItem* item, bool keyDown) { BPoint where; - ulong buttons; + uint32 buttons; GetMouse(&where, &buttons, false); bool stickyMode = _IsStickyMode(); // Quit if user clicks the mouse button in sticky mode diff --git a/src/kits/interface/PictureDataWriter.cpp b/src/kits/interface/PictureDataWriter.cpp index 93668a0873..32154151b9 100644 --- a/src/kits/interface/PictureDataWriter.cpp +++ b/src/kits/interface/PictureDataWriter.cpp @@ -607,7 +607,7 @@ PictureDataWriter::BeginOp(const int16 &op) fData->Write(&op, sizeof(op)); // Init the size of the opcode block to 0 - size_t size = 0; + int32 size = 0; fData->Write(&size, sizeof(size)); } @@ -625,8 +625,8 @@ PictureDataWriter::EndOp() // The size of the op is calculated like this: // current position on the stream minus the position on the stack, // minus the space occupied by the op code itself (int16) - // and the space occupied by the size field (size_t) - size_t size = curPos - stackPos - sizeof(size_t) - sizeof(int16); + // and the space occupied by the size field (int32) + int32 size = curPos - stackPos - sizeof(int32) - sizeof(int16); // Size was set to 0 in BeginOp() // Now we overwrite it with the correct value diff --git a/src/kits/interface/Polygon.cpp b/src/kits/interface/Polygon.cpp index 07c27ba55c..0728b785ad 100644 --- a/src/kits/interface/Polygon.cpp +++ b/src/kits/interface/Polygon.cpp @@ -157,15 +157,16 @@ BPolygon::_AddPoints(const BPoint* points, int32 count, bool computeBounds) if (points == NULL || count <= 0) return false; if (count > MAX_POINT_COUNT || (fCount + count) > MAX_POINT_COUNT) { - fprintf(stderr, "BPolygon::_AddPoints(%ld) - too many points\n", - count); + fprintf(stderr, "BPolygon::_AddPoints(%" B_PRId32 ") - too many points" + "\n", count); return false; } BPoint* newPoints = (BPoint*)realloc(fPoints, (fCount + count) * sizeof(BPoint)); if (newPoints == NULL) { - fprintf(stderr, "BPolygon::_AddPoints(%ld) out of memory\n", count); + fprintf(stderr, "BPolygon::_AddPoints(%" B_PRId32 ") out of memory\n", + count); return false; } diff --git a/src/kits/interface/PrintJob.cpp b/src/kits/interface/PrintJob.cpp index e037fc9862..18a58da6ba 100644 --- a/src/kits/interface/PrintJob.cpp +++ b/src/kits/interface/PrintJob.cpp @@ -576,7 +576,7 @@ BPrintJob::_RecurseView(BView* view, BPoint origin, BPicture* picture, void BPrintJob::_GetMangledName(char* buffer, size_t bufferSize) const { - snprintf(buffer, bufferSize, "%s@%lld", fPrintJobName, + snprintf(buffer, bufferSize, "%s@%" B_PRId64, fPrintJobName, system_time() / 1000); } diff --git a/src/kits/interface/Region.cpp b/src/kits/interface/Region.cpp index d44529ec86..d2d06043bb 100644 --- a/src/kits/interface/Region.cpp +++ b/src/kits/interface/Region.cpp @@ -330,9 +330,9 @@ BRegion::PrintToStream() const { Frame().PrintToStream(); - for (long i = 0; i < fCount; i++) { + for (int32 i = 0; i < fCount; i++) { clipping_rect *rect = &fData[i]; - printf("data[%ld] = BRect(l:%" B_PRId32 ".0, t:%" B_PRId32 + printf("data[%" B_PRId32 "] = BRect(l:%" B_PRId32 ".0, t:%" B_PRId32 ".0, r:%" B_PRId32 ".0, b:%" B_PRId32 ".0)\n", i, rect->left, rect->top, rect->right - 1, rect->bottom - 1); } @@ -361,7 +361,7 @@ BRegion::OffsetBy(int32 x, int32 y) if (fCount > 0) { if (fData != &fBounds) { - for (long i = 0; i < fCount; i++) + for (int32 i = 0; i < fCount; i++) offset_rect(fData[i], x, y); } @@ -545,7 +545,7 @@ BRegion::_AdoptRegionData(BRegion& region) able to hold. */ bool -BRegion::_SetSize(long newSize) +BRegion::_SetSize(int32 newSize) { // we never shrink the size newSize = max_c(fDataSize, newSize); diff --git a/src/kits/interface/Shelf.cpp b/src/kits/interface/Shelf.cpp index bcd75b979c..0ffdf5671d 100644 --- a/src/kits/interface/Shelf.cpp +++ b/src/kits/interface/Shelf.cpp @@ -557,7 +557,7 @@ BShelf::~BShelf() while (fReplicants.CountItems() > 0) { replicant_data *data = (replicant_data *)fReplicants.ItemAt(0); - fReplicants.RemoveItem(0L); + fReplicants.RemoveItem((int32)0); delete data; } } @@ -1003,7 +1003,7 @@ BShelf::ReplicantAt(int32 index, BView **_view, uint32 *_uniqueID, if (_view) *_view = NULL; if (_uniqueID) - *_uniqueID = ~0UL; + *_uniqueID = ~(uint32)0; if (_error) *_error = B_BAD_INDEX; diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp index 7caca729d3..cb08c8d8a9 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -739,7 +739,7 @@ BTextView::WindowActivated(bool state) } BPoint where; - ulong buttons; + uint32 buttons; GetMouse(&where, &buttons, false); if (Bounds().Contains(where)) @@ -3266,7 +3266,7 @@ BTextView::_InitObject(BRect textRect, const BFont *initialFont, fSelectable = true; fEditable = true; fWrap = true; - fMaxBytes = LONG_MAX; + fMaxBytes = INT32_MAX; fDisallowedChars = NULL; fAlignment = B_ALIGN_LEFT; fAutoindent = false; @@ -5063,7 +5063,7 @@ BTextView::_Activate() _ShowCaret(); BPoint where; - ulong buttons; + uint32 buttons; GetMouse(&where, &buttons, false); if (Bounds().Contains(where)) _TrackMouse(where, NULL); @@ -5659,7 +5659,7 @@ BTextView::_ShowContextMenu(BPoint where) void -BTextView::_FilterDisallowedChars(char* text, int32& length, +BTextView::_FilterDisallowedChars(char* text, ssize_t& length, text_run_array* runArray) { if (!fDisallowedChars) @@ -5668,9 +5668,9 @@ BTextView::_FilterDisallowedChars(char* text, int32& length, if (fDisallowedChars->IsEmpty() || !text) return; - int32 stringIndex = 0; + ssize_t stringIndex = 0; if (runArray) { - int32 remNext = 0; + ssize_t remNext = 0; for (int i = 0; i < runArray->count; i++) { runArray->runs[i].offset -= remNext; @@ -5728,7 +5728,7 @@ void BTextView::TextTrackState::SimulateMouseMovement(BTextView *textView) { BPoint where; - ulong buttons; + uint32 buttons; // When the mouse cursor is still and outside the textview, // no B_MOUSE_MOVED message are sent, obviously. But scrolling // has to work neverthless, so we "fake" a MouseMoved() call here. diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index 7adf00e468..d1bc743b35 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -5892,8 +5892,8 @@ BView::_PrintToStream() "\tNextSibling: %s\n" "\tPrevSibling: %s\n" "\tOwner(Window): %s\n" - "\tToken: %ld\n" - "\tFlags: %ld\n" + "\tToken: %" B_PRId32 "\n" + "\tFlags: %" B_PRId32 "\n" "\tView origin: (%f,%f)\n" "\tView Bounds rectangle: (%f,%f,%f,%f)\n" "\tShow level: %d\n" @@ -5903,8 +5903,8 @@ BView::_PrintToStream() "\tHorizontal Scrollbar %s\n" "\tIs Printing?: %s\n" "\tShelf?: %s\n" - "\tEventMask: %ld\n" - "\tEventOptions: %ld\n", + "\tEventMask: %" B_PRId32 "\n" + "\tEventOptions: %" B_PRId32 "\n", Name(), fParent ? fParent->Name() : "NULL", fFirstChild ? fFirstChild->Name() : "NULL", @@ -5932,7 +5932,7 @@ BView::_PrintToStream() "\t\tHighColor: [%d,%d,%d,%d]\n" "\t\tLowColor: [%d,%d,%d,%d]\n" "\t\tViewColor: [%d,%d,%d,%d]\n" - "\t\tPattern: %llx\n" + "\t\tPattern: %" B_PRIx64 "\n" "\t\tDrawingMode: %d\n" "\t\tLineJoinMode: %d\n" "\t\tLineCapMode: %d\n" diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index 276d672127..78089889e2 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -515,7 +515,7 @@ BWindow::Quit() name = "no-name"; printf("ERROR - you must Lock a looper before calling Quit(), " - "team=%ld, looper=%s\n", Team(), name); + "team=%" B_PRId32 ", looper=%s\n", Team(), name); } // Try to lock @@ -1029,7 +1029,8 @@ BWindow::DispatchMessage(BMessage* msg, BHandler* target) be_roster->GetAppList(info.signature, &list); for (int32 i = 0; i < list.CountItems(); i++) { - do_minimize_team(BRect(), (team_id)list.ItemAt(i), false); + do_minimize_team(BRect(), (team_id)(addr_t)list.ItemAt(i), + false); } break; } @@ -1430,8 +1431,8 @@ FrameMoved(origin); if (BView* view = _FindView(info->token)) view->_Draw(info->updateRect); else { - printf("_UPDATE_ - didn't find view by token: %ld\n", - info->token); + printf("_UPDATE_ - didn't find view by token: %" + B_PRId32 "\n", info->token); } //drawTime += system_time() - drawStart; } diff --git a/src/kits/interface/layouter/ComplexLayouter.cpp b/src/kits/interface/layouter/ComplexLayouter.cpp index 00f559a7a1..c694bda059 100644 --- a/src/kits/interface/layouter/ComplexLayouter.cpp +++ b/src/kits/interface/layouter/ComplexLayouter.cpp @@ -85,9 +85,12 @@ public: void Dump() { - printf("ComplexLayouter::MyLayoutInfo(): %ld elements:\n", fCount); - for (int32 i = 0; i < fCount + 1; i++) - printf(" %2ld: location: %4ld\n", i, fLocations[i]); + printf("ComplexLayouter::MyLayoutInfo(): %" B_PRId32 " elements:\n", + fCount); + for (int32 i = 0; i < fCount + 1; i++) { + printf(" %2" B_PRId32 ": location: %4" B_PRId32 "\n", i, + fLocations[i]); + } } public: diff --git a/src/kits/interface/textview_support/LineBuffer.cpp b/src/kits/interface/textview_support/LineBuffer.cpp index 82c38e55a6..35c0c0772c 100644 --- a/src/kits/interface/textview_support/LineBuffer.cpp +++ b/src/kits/interface/textview_support/LineBuffer.cpp @@ -94,7 +94,7 @@ BTextView::LineBuffer::PixelToLine(float pixel) const void -BTextView::LineBuffer::BumpOrigin(float delta, long index) +BTextView::LineBuffer::BumpOrigin(float delta, int32 index) { for (long i = index; i < fItemCount; i++) fBuffer[i].origin += delta; diff --git a/src/kits/interface/textview_support/LineBuffer.h b/src/kits/interface/textview_support/LineBuffer.h index a32758bbde..81e124eb78 100644 --- a/src/kits/interface/textview_support/LineBuffer.h +++ b/src/kits/interface/textview_support/LineBuffer.h @@ -39,7 +39,7 @@ public: void BumpOrigin(float delta, int32 index); void BumpOffset(int32 delta, int32 index); - long NumLines() const; + int32 NumLines() const; float MaxWidth() const; STELine* operator[](int32 index) const; }; diff --git a/src/kits/interface/textview_support/StyleBuffer.h b/src/kits/interface/textview_support/StyleBuffer.h index 227fc91e9e..9b289a24b2 100644 --- a/src/kits/interface/textview_support/StyleBuffer.h +++ b/src/kits/interface/textview_support/StyleBuffer.h @@ -56,7 +56,7 @@ class _BStyleRunDescBuffer_ : public _BTextViewSupportBuffer_ { void InsertDesc(STEStyleRunDesc* inDesc, int32 index); void RemoveDescs(int32 index, int32 count = 1); - long OffsetToRun(int32 offset) const; + int32 OffsetToRun(int32 offset) const; void BumpOffset(int32 delta, int32 index); STEStyleRunDesc* operator[](int32 index) const; diff --git a/src/kits/interface/textview_support/TextGapBuffer.cpp b/src/kits/interface/textview_support/TextGapBuffer.cpp index af122f0c6c..bc4de30dc2 100644 --- a/src/kits/interface/textview_support/TextGapBuffer.cpp +++ b/src/kits/interface/textview_support/TextGapBuffer.cpp @@ -188,7 +188,7 @@ TextGapBuffer::GetString(int32 fromOffset, int32* _numBytes) bool -TextGapBuffer::FindChar(char inChar, long fromIndex, long* ioDelta) +TextGapBuffer::FindChar(char inChar, int32 fromIndex, int32* ioDelta) { long numChars = *ioDelta; for (long i = 0; i < numChars; i++) { @@ -333,7 +333,7 @@ TextGapBuffer::_MoveGapTo(int32 toIndex) void -TextGapBuffer::_EnlargeGapTo(long inCount) +TextGapBuffer::_EnlargeGapTo(int32 inCount) { if (inCount == fGapCount) return; @@ -348,7 +348,7 @@ TextGapBuffer::_EnlargeGapTo(long inCount) void -TextGapBuffer::_ShrinkGapTo(long inCount) +TextGapBuffer::_ShrinkGapTo(int32 inCount) { if (inCount == fGapCount) return; diff --git a/src/kits/locale/DefaultCatalog.cpp b/src/kits/locale/DefaultCatalog.cpp index dbb913d952..43a39d06b2 100644 --- a/src/kits/locale/DefaultCatalog.cpp +++ b/src/kits/locale/DefaultCatalog.cpp @@ -359,7 +359,7 @@ DefaultCatalog::WriteToFile(const char *path) return res; BMallocIO mallocIO; - mallocIO.SetBlockSize(max(fCatMap.Size() * 20, 256L)); + mallocIO.SetBlockSize(max(fCatMap.Size() * 20, (int32)256)); // set a largish block-size in order to avoid reallocs res = Flatten(&mallocIO); if (res == B_OK) { @@ -390,7 +390,7 @@ DefaultCatalog::WriteToAttribute(const entry_ref &appOrAddOnRef) return res; BMallocIO mallocIO; - mallocIO.SetBlockSize(max(fCatMap.Size() * 20, 256L)); + mallocIO.SetBlockSize(max(fCatMap.Size() * 20, (int32)256)); // set a largish block-size in order to avoid reallocs res = Flatten(&mallocIO); @@ -421,7 +421,7 @@ DefaultCatalog::WriteToResource(const entry_ref &appOrAddOnRef) return res; BMallocIO mallocIO; - mallocIO.SetBlockSize(max(fCatMap.Size() * 20, 256L)); + mallocIO.SetBlockSize(max(fCatMap.Size() * 20, (int32)256)); // set a largish block-size in order to avoid reallocs res = Flatten(&mallocIO); diff --git a/src/kits/network/libbind/inet/inet_addr.c b/src/kits/network/libbind/inet/inet_addr.c index 73a4c5c9b8..7366db981b 100644 --- a/src/kits/network/libbind/inet/inet_addr.c +++ b/src/kits/network/libbind/inet/inet_addr.c @@ -107,7 +107,7 @@ inet_addr(const char *cp) { */ int inet_aton(const char *cp, struct in_addr *addr) { - u_long val; + u_int32_t val; int base, n; char c; u_int8_t parts[4]; diff --git a/src/kits/network/libbind/irs/lcl_sv.cpp b/src/kits/network/libbind/irs/lcl_sv.cpp index 0d1f2e423c..c0e7218156 100644 --- a/src/kits/network/libbind/irs/lcl_sv.cpp +++ b/src/kits/network/libbind/irs/lcl_sv.cpp @@ -107,9 +107,9 @@ find_own_image(image_info* _info) int32 cookie = 0; image_info info; while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { - if (((uint32)info.text <= (uint32)find_own_image - && (uint32)info.text + (uint32)info.text_size - > (uint32)find_own_image)) { + if (((addr_t)info.text <= (addr_t)find_own_image + && (addr_t)info.text + (size_t)info.text_size + > (addr_t)find_own_image)) { // found us *_info = info; return B_OK; diff --git a/src/kits/network/libnetapi/NetAddress.cpp b/src/kits/network/libnetapi/NetAddress.cpp index 6c4fdd3cea..734363cbee 100644 --- a/src/kits/network/libnetapi/NetAddress.cpp +++ b/src/kits/network/libnetapi/NetAddress.cpp @@ -346,7 +346,7 @@ BNetAddress::SetTo(const char* hostname, unsigned short port) // See if the string is an ASCII-fied IP address. addr = inet_addr(hostname); - if (addr == INADDR_ANY || addr == (unsigned long)-1) { + if (addr == INADDR_ANY || addr == (in_addr_t)-1) { // See if we can resolve the hostname to an IP address. struct hostent* host = gethostbyname(hostname); if (host != NULL) diff --git a/src/kits/network/libnetapi/init.cpp b/src/kits/network/libnetapi/init.cpp index bffee43a83..c311573fdd 100644 --- a/src/kits/network/libnetapi/init.cpp +++ b/src/kits/network/libnetapi/init.cpp @@ -20,8 +20,8 @@ find_own_image() int32 cookie = 0; image_info info; while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { - if (((uint32)info.text <= (uint32)find_own_image - && (uint32)info.text + (uint32)info.text_size > (uint32)find_own_image)) { + if (((addr_t)info.text <= (addr_t)find_own_image + && (addr_t)info.text + (size_t)info.text_size > (addr_t)find_own_image)) { // found us __gNetAPIStart = (addr_t)min_c(info.text, info.data); __gNetAPIEnd = min_c((addr_t)info.text + info.text_size, diff --git a/src/kits/opengl/Jamfile b/src/kits/opengl/Jamfile index 009ff9fe10..2b96f1f0e2 100644 --- a/src/kits/opengl/Jamfile +++ b/src/kits/opengl/Jamfile @@ -46,9 +46,6 @@ SharedLibrary libGL.so : $(sources) : # GLU $(HAIKU_GLU_LIBS) - # Glut - glut.o - # Mesa libraries (from Mesa optional package): $(HAIKU_MESA_LIBS) diff --git a/src/kits/shared/IconButton.cpp b/src/kits/shared/IconButton.cpp index 5881fd5bd5..fb55ff030e 100644 --- a/src/kits/shared/IconButton.cpp +++ b/src/kits/shared/IconButton.cpp @@ -520,7 +520,7 @@ BIconButton::TrimIcon(bool keepAspect) uint32 bpr = fNormalBitmap->BytesPerRow(); uint32 width = fNormalBitmap->Bounds().IntegerWidth() + 1; uint32 height = fNormalBitmap->Bounds().IntegerHeight() + 1; - BRect trimmed(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN); + BRect trimmed(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN); for (uint32 y = 0; y < height; y++) { uint8* b = bits + 3; bool rowHasAlpha = false; diff --git a/src/kits/shared/QueryFile.cpp b/src/kits/shared/QueryFile.cpp index 05314be9bb..159c4101c6 100644 --- a/src/kits/shared/QueryFile.cpp +++ b/src/kits/shared/QueryFile.cpp @@ -180,14 +180,14 @@ BQueryFile::SetPredicate(const char* predicate) status_t BQueryFile::AddVolume(const BVolume& volume) { - return fVolumes.AddItem((void*)volume.Device()) ? B_OK : B_NO_MEMORY; + return fVolumes.AddItem((void*)(addr_t)volume.Device()) ? B_OK : B_NO_MEMORY; } status_t BQueryFile::AddVolume(dev_t device) { - return fVolumes.AddItem((void*)device) ? B_OK : B_NO_MEMORY; + return fVolumes.AddItem((void*)(addr_t)device) ? B_OK : B_NO_MEMORY; } @@ -211,7 +211,7 @@ BQueryFile::VolumeAt(int32 index) const if (index < 0 || index >= fVolumes.CountItems()) return -1; - return (dev_t)fVolumes.ItemAt(index); + return (dev_t)(addr_t)fVolumes.ItemAt(index); } diff --git a/src/kits/storage/AppFileInfo.cpp b/src/kits/storage/AppFileInfo.cpp index fb9581e52e..ad81175416 100644 --- a/src/kits/storage/AppFileInfo.cpp +++ b/src/kits/storage/AppFileInfo.cpp @@ -1430,7 +1430,7 @@ BAppFileInfo::_ReadData(const char* name, int32 id, type_code type, error = B_NO_MEMORY; bufferSize = info.size; } - if (error == B_OK && bufferSize < info.size) + if (error == B_OK && (off_t)bufferSize < info.size) error = B_BAD_VALUE; // read the data diff --git a/src/kits/storage/Entry.cpp b/src/kits/storage/Entry.cpp index d04038fd38..c078bee141 100644 --- a/src/kits/storage/Entry.cpp +++ b/src/kits/storage/Entry.cpp @@ -689,14 +689,14 @@ BEntry::_Dump(const char* name) printf("------------------------------------------------------------\n"); } - printf("fCStatus == %ld\n", fCStatus); + printf("fCStatus == %" B_PRId32 "\n", fCStatus); struct stat st; if (fDirFd != -1 && _kern_read_stat(fDirFd, NULL, false, &st, sizeof(struct stat)) == B_OK) { - printf("dir.device == %ld\n", st.st_dev); - printf("dir.inode == %lld\n", st.st_ino); + printf("dir.device == %" B_PRIdDEV "\n", st.st_dev); + printf("dir.inode == %" B_PRIdINO "\n", st.st_ino); } else { printf("dir == NullFd\n"); } diff --git a/src/kits/storage/QueryPredicate.cpp b/src/kits/storage/QueryPredicate.cpp index 997c5dda13..bb48f961cc 100644 --- a/src/kits/storage/QueryPredicate.cpp +++ b/src/kits/storage/QueryPredicate.cpp @@ -272,7 +272,7 @@ ValueNode::GetString(BString &predicate) } value; value.asFloat = fValue; // int32 value = *reinterpret_cast(&fValue); - sprintf(buffer, "0x%08lx", value.asInteger); + sprintf(buffer, "0x%08" B_PRIx32, value.asInteger); predicate.SetTo(buffer); return B_OK; } @@ -289,7 +289,7 @@ ValueNode::GetString(BString &predicate) } value; // int64 value = *reinterpret_cast(&fValue); value.asFloat = fValue; - sprintf(buffer, "0x%016Lx", value.asInteger); + sprintf(buffer, "0x%016" B_PRIx64, value.asInteger); predicate.SetTo(buffer); return B_OK; } diff --git a/src/kits/storage/disk_device/Partition.cpp b/src/kits/storage/disk_device/Partition.cpp index 8bd5fea703..3dbcadd60b 100644 --- a/src/kits/storage/disk_device/Partition.cpp +++ b/src/kits/storage/disk_device/Partition.cpp @@ -354,10 +354,11 @@ BPartition::GetPath(BPath* path) const if (!leaf || strcmp(leaf, "raw") != B_OK) return B_ERROR; - snprintf(indexBuffer, sizeof(indexBuffer), "%ld", Index()); + snprintf(indexBuffer, sizeof(indexBuffer), "%" B_PRId32, Index()); } else { // Our parent is a normal partition, no device: Append our index. - snprintf(indexBuffer, sizeof(indexBuffer), "%s_%ld", path->Leaf(), Index()); + snprintf(indexBuffer, sizeof(indexBuffer), "%s_%" B_PRId32, + path->Leaf(), Index()); } error = path->GetParent(path); diff --git a/src/kits/storage/disk_device/PartitioningInfo.cpp b/src/kits/storage/disk_device/PartitioningInfo.cpp index 19abfe8296..0e0cba3c90 100644 --- a/src/kits/storage/disk_device/PartitioningInfo.cpp +++ b/src/kits/storage/disk_device/PartitioningInfo.cpp @@ -220,10 +220,10 @@ BPartitioningInfo::PrintToStream() const printf("BPartitioningInfo is not initialized\n"); return; } - printf("BPartitioningInfo has %ld spaces:\n", fCount); + printf("BPartitioningInfo has %" B_PRId32 " spaces:\n", fCount); for (int32 i = 0; i < fCount; i++) { - printf(" space at %ld: offset = %lld, size = %lld\n", - i, fSpaces[i].offset, fSpaces[i].size); + printf(" space at %" B_PRId32 ": offset = %" B_PRId64 ", size = %" + B_PRId64 "\n", i, fSpaces[i].offset, fSpaces[i].size); } } diff --git a/src/kits/storage/mime/database_support.cpp b/src/kits/storage/mime/database_support.cpp index 24add0c804..750a5c041e 100644 --- a/src/kits/storage/mime/database_support.cpp +++ b/src/kits/storage/mime/database_support.cpp @@ -191,7 +191,7 @@ open_or_create_type(const char *type, BNode *result, bool *didCreate) // Figure out what type of node we need to create // + Supertype == directory // + Non-supertype == file - uint32 pos = typeLower.find_first_of('/'); + size_t pos = typeLower.find_first_of('/'); if (pos == std::string::npos) { // Supertype == directory BDirectory parent(get_database_directory().c_str()); diff --git a/src/kits/storage/sniffer/Range.cpp b/src/kits/storage/sniffer/Range.cpp index 2f994f7970..ebf64711a5 100644 --- a/src/kits/storage/sniffer/Range.cpp +++ b/src/kits/storage/sniffer/Range.cpp @@ -34,8 +34,8 @@ Range::GetErr() const { else { char start_str[32]; char end_str[32]; - sprintf(start_str, "%ld", fStart); - sprintf(end_str, "%ld", fEnd); + sprintf(start_str, "%" B_PRId32, fStart); + sprintf(end_str, "%" B_PRId32, fEnd); return new Err(std::string("Sniffer Parser Error -- Invalid range: [") + start_str + ":" + end_str + "]", -1); } } diff --git a/src/kits/support/BufferIO.cpp b/src/kits/support/BufferIO.cpp index f6d1cc9afd..a64d611c4e 100644 --- a/src/kits/support/BufferIO.cpp +++ b/src/kits/support/BufferIO.cpp @@ -71,7 +71,7 @@ BBufferIO::ReadAt(off_t pos, void* buffer, size_t size) // If the data we are looking for is not in the buffer... if (size > fBufferUsed || pos < fBufferStart - || pos > fBufferStart + fBufferUsed + || pos > fBufferStart + (off_t)fBufferUsed || pos + size > fBufferStart + fBufferUsed) { if (fBufferIsDirty) { // If there are pending writes, do them. @@ -119,7 +119,7 @@ BBufferIO::WriteAt(off_t pos, const void* buffer, size_t size) } // If we want to write beyond the cached data... - if (pos > fBufferStart + fBufferUsed + if (pos > fBufferStart + (off_t)fBufferUsed || pos < fBufferStart) { ssize_t read; off_t where = pos; @@ -245,7 +245,7 @@ BBufferIO::PrintToStream() const { printf("stream %p\n", fStream); printf("buffer %p\n", fBuffer); - printf("start %lld\n", fBufferStart); + printf("start %" B_PRId64 "\n", fBufferStart); printf("used %ld\n", fBufferUsed); printf("phys %ld\n", fBufferSize); printf("dirty %s\n", (fBufferIsDirty) ? "true" : "false"); diff --git a/src/kits/support/ByteOrder.cpp b/src/kits/support/ByteOrder.cpp index 649448741b..c009a5fe07 100644 --- a/src/kits/support/ByteOrder.cpp +++ b/src/kits/support/ByteOrder.cpp @@ -49,14 +49,15 @@ swap_data(type_code type, void *_data, size_t length, swap_action action) case B_FLOAT_TYPE: case B_INT32_TYPE: case B_UINT32_TYPE: - case B_SIZE_T_TYPE: - case B_SSIZE_T_TYPE: case B_TIME_TYPE: - case B_POINTER_TYPE: case B_RECT_TYPE: case B_POINT_TYPE: +#if B_HAIKU_32_BIT + case B_SIZE_T_TYPE: + case B_SSIZE_T_TYPE: + case B_POINTER_TYPE: +#endif { - // ToDo: some of these types may not be 32-bit on 64-bit platforms! uint32 *data = (uint32 *)_data; uint32 *end = (uint32 *)((addr_t)_data + length); @@ -72,6 +73,11 @@ swap_data(type_code type, void *_data, size_t length, swap_action action) case B_INT64_TYPE: case B_UINT64_TYPE: case B_OFF_T_TYPE: +#if B_HAIKU_64_BIT + case B_SIZE_T_TYPE: + case B_SSIZE_T_TYPE: + case B_POINTER_TYPE: +#endif { uint64 *data = (uint64 *)_data; uint64 *end = (uint64 *)((addr_t)_data + length); diff --git a/src/kits/tracker/ContainerWindow.cpp b/src/kits/tracker/ContainerWindow.cpp index 574cc2349a..2a85b8720e 100644 --- a/src/kits/tracker/ContainerWindow.cpp +++ b/src/kits/tracker/ContainerWindow.cpp @@ -1310,7 +1310,7 @@ BContainerWindow::SetLayoutState(BNode* node, const BMessage* message) for (int32 index = 0; index < count; index++) { const void* buffer; - int32 size; + ssize_t size; result = message->FindData(name, type, index, &buffer, &size); if (result != B_OK) { PRINT(("error reading %s \n", name)); @@ -3072,7 +3072,7 @@ BContainerWindow::BuildAddOnMenu(BMenu* menu) // found the addons menu, empty it first for (;;) { - item = menu->RemoveItem(0L); + item = menu->RemoveItem((int32)0); if (!item) break; delete item; diff --git a/src/kits/tracker/CountView.cpp b/src/kits/tracker/CountView.cpp index 5ac1cba1ad..f2dbf2b184 100644 --- a/src/kits/tracker/CountView.cpp +++ b/src/kits/tracker/CountView.cpp @@ -229,7 +229,7 @@ BCountView::Draw(BRect updateRect) else { itemString.SetTo(B_TRANSLATE("%num items")); char numString[256]; - snprintf(numString, sizeof(numString), "%ld", fLastCount); + snprintf(numString, sizeof(numString), "%" B_PRId32, fLastCount); itemString.ReplaceFirst("%num", numString); } } diff --git a/src/kits/tracker/DeskWindow.cpp b/src/kits/tracker/DeskWindow.cpp index 84090b6b57..b8ea334441 100644 --- a/src/kits/tracker/DeskWindow.cpp +++ b/src/kits/tracker/DeskWindow.cpp @@ -470,7 +470,7 @@ BDeskWindow::MessageReceived(BMessage* message) { if (message->WasDropped()) { const rgb_color* color; - int32 size; + ssize_t size; // handle "roColour"-style color drops if (message->FindData("RGBColor", 'RGBC', (const void**)&color, &size) == B_OK) { diff --git a/src/kits/tracker/FSClipboard.cpp b/src/kits/tracker/FSClipboard.cpp index 00958c4e0d..ce90756fc5 100644 --- a/src/kits/tracker/FSClipboard.cpp +++ b/src/kits/tracker/FSClipboard.cpp @@ -73,14 +73,14 @@ MakeNodeFromName(node_ref* node, char* name) static inline void MakeRefName(char* refName, const node_ref* node) { - sprintf(refName, "r%ld_%Ld", node->device, node->node); + sprintf(refName, "r%" B_PRIdDEV "_%" B_PRIdINO, node->device, node->node); } static inline void MakeModeName(char* modeName, const node_ref* node) { - sprintf(modeName, "m%ld_%Ld", node->device, node->node); + sprintf(modeName, "m%" B_PRIdDEV "_%" B_PRIdINO, node->device, node->node); } @@ -702,7 +702,7 @@ BClipboardRefsWatcher::RemoveNodesByDevice(dev_t device) BMessage* clip = be_clipboard->Data(); if (clip != NULL) { char deviceName[6]; - sprintf(deviceName, "r%ld_", device); + sprintf(deviceName, "r%" B_PRIdDEV "_", device); int32 index = 0; char* refName; diff --git a/src/kits/tracker/FSUtils.cpp b/src/kits/tracker/FSUtils.cpp index 021825dd24..040b2a4063 100644 --- a/src/kits/tracker/FSUtils.cpp +++ b/src/kits/tracker/FSUtils.cpp @@ -1264,7 +1264,7 @@ LowLevelCopy(BEntry* srcEntry, StatStruct* srcStat, BDirectory* destDir, const size_t kMaxBufferSize = 1024* 1024; size_t bufsize = kMinBufferSize; - if (bufsize < srcStat->st_size) { + if ((off_t)bufsize < srcStat->st_size) { // File bigger than the buffer size: determine an optimal buffer size system_info sinfo; get_system_info(&sinfo); @@ -2356,7 +2356,7 @@ FSMakeOriginalName(char* name, BDirectory* destDir, const char* suffix) fnum = 1; strcpy(temp_name, name); while (destDir->Contains(temp_name)) { - sprintf(temp_name, "%s %ld", copybase, ++fnum); + sprintf(temp_name, "%s %" B_PRId32, copybase, ++fnum); if (strlen(temp_name) > (B_FILE_NAME_LENGTH - 1)) { // The name has grown too long. Maybe we just went from @@ -2365,7 +2365,7 @@ FSMakeOriginalName(char* name, BDirectory* destDir, const char* suffix) // truncate the 'root' name and continue. // ??? should we reset fnum or not ??? root[strlen(root) - 1] = '\0'; - sprintf(temp_name, "%s%s %ld", root, suffix, fnum); + sprintf(temp_name, "%s%s %" B_PRId32, root, suffix, fnum); } } @@ -3249,7 +3249,7 @@ _TrackerLaunchAppWithDocuments(const entry_ref* appRef, const BMessage* refs, if (error == B_OK) { // close possible parent window, if specified const node_ref* nodeToClose = 0; - int32 numBytes; + ssize_t numBytes; refs->FindData("nodeRefsToClose", B_RAW_TYPE, (const void**)&nodeToClose, &numBytes); if (nodeToClose) diff --git a/src/kits/tracker/FindPanel.cpp b/src/kits/tracker/FindPanel.cpp index 36e795701f..939fb192f8 100644 --- a/src/kits/tracker/FindPanel.cpp +++ b/src/kits/tracker/FindPanel.cpp @@ -2303,7 +2303,7 @@ FindPanel::RestoreWindowState(const BNode* node) BTextControl* textControl = dynamic_cast(view); if (textControl != NULL && Mode() == kByFormulaItem) { int32 selStart = 0; - int32 selEnd = LONG_MAX; + int32 selEnd = INT32_MAX; node->ReadAttr("_trk/focusedSelStart", B_INT32_TYPE, 0, &selStart, sizeof(selStart)); node->ReadAttr("_trk/focusedSelEnd", B_INT32_TYPE, 0, @@ -3162,7 +3162,7 @@ MostUsedNames::~MostUsedNames() if (entry->count < -10 && i > 0) continue; - sprintf(line, "%ld %s\n", entry->count, entry->name); + sprintf(line, "%" B_PRId32 " %s\n", entry->count, entry->name); if (file.Write(line, strlen(line)) < B_OK) break; } diff --git a/src/kits/tracker/GroupedMenu.cpp b/src/kits/tracker/GroupedMenu.cpp index d781ee7338..7d73de2a25 100644 --- a/src/kits/tracker/GroupedMenu.cpp +++ b/src/kits/tracker/GroupedMenu.cpp @@ -27,7 +27,7 @@ TMenuItemGroup::~TMenuItemGroup() if (fMenu == NULL) { BMenuItem* item; - while ((item = RemoveItem(0L)) != NULL) + while ((item = RemoveItem((int32)0)) != NULL) delete item; } } @@ -176,7 +176,7 @@ TGroupedMenu::TGroupedMenu(const char* name) TGroupedMenu::~TGroupedMenu() { TMenuItemGroup* group; - while ((group = static_cast(fGroups.RemoveItem(0L))) + while ((group = static_cast(fGroups.RemoveItem((int32)0))) != NULL) { delete group; } diff --git a/src/kits/tracker/InfoWindow.cpp b/src/kits/tracker/InfoWindow.cpp index 11cc5d64de..b5c9840ad3 100644 --- a/src/kits/tracker/InfoWindow.cpp +++ b/src/kits/tracker/InfoWindow.cpp @@ -675,7 +675,7 @@ BInfoWindow::GetSizeString(BString &result, off_t size, int32 fileCount) // TODO: use BCountry::FormatNumber if (size >= kKBSize) { char numStr[128]; - snprintf(numStr, sizeof(numStr), "%Ld", size); + snprintf(numStr, sizeof(numStr), "%" B_PRIdOFF, size); BString bytes; uint32 length = strlen(numStr); diff --git a/src/kits/tracker/Model.cpp b/src/kits/tracker/Model.cpp index 7c5e617569..a64d6aceb7 100644 --- a/src/kits/tracker/Model.cpp +++ b/src/kits/tracker/Model.cpp @@ -1089,7 +1089,7 @@ Model::SupportsMimeType(const char* type, const BObjectList* list, // check if this model lists the type of dropped document as supported const char* mimeSignature; - int32 bufferLength; + ssize_t bufferLength; if (message.FindData("types", 'CSTR', index, (const void**)&mimeSignature, &bufferLength)) { @@ -1163,7 +1163,7 @@ Model::IsSuperHandler() const for (int32 index = 0; ; index++) { const char* mimeSignature; - int32 bufferLength; + ssize_t bufferLength; if (message.FindData("types", 'CSTR', index, (const void**)&mimeSignature, &bufferLength)) { @@ -1278,8 +1278,8 @@ Model::GetVersionString(BString &result, version_kind kind) return error; char vstr[32]; - sprintf(vstr, "%ld.%ld.%ld", version.major, version.middle, - version.minor); + sprintf(vstr, "%" B_PRId32 ".%" B_PRId32 ".%" B_PRId32, version.major, + version.middle, version.minor); result = vstr; return B_OK; } diff --git a/src/kits/tracker/MountMenu.cpp b/src/kits/tracker/MountMenu.cpp index 6c0a84a4ee..e00810be6b 100644 --- a/src/kits/tracker/MountMenu.cpp +++ b/src/kits/tracker/MountMenu.cpp @@ -171,7 +171,7 @@ MountMenu::AddDynamicItem(add_state) { // remove old items for (;;) { - BMenuItem* item = RemoveItem(0L); + BMenuItem* item = RemoveItem((int32)0); if (item == NULL) break; delete item; diff --git a/src/kits/tracker/PoseView.cpp b/src/kits/tracker/PoseView.cpp index 5e228fc4da..390e12fa0d 100644 --- a/src/kits/tracker/PoseView.cpp +++ b/src/kits/tracker/PoseView.cpp @@ -212,7 +212,7 @@ BPoseView::BPoseView(Model* model, BRect bounds, uint32 viewMode, fVScrollBar(NULL), fModel(model), fActivePose(NULL), - fExtent(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN), + fExtent(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN), fPoseList(new PoseList(40, true)), fFilteredPoseList(new PoseList()), fVSPoseList(new PoseList()), @@ -229,9 +229,9 @@ BPoseView::BPoseView(Model* model, BRect bounds, uint32 viewMode, fDropTarget(NULL), fAlreadySelectedDropTarget(NULL), fSelectionHandler(be_app), - fLastClickPt(LONG_MAX, LONG_MAX), + fLastClickPt(INT32_MAX, INT32_MAX), fLastClickedPose(NULL), - fLastExtent(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN), + fLastExtent(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN), fTitleView(NULL), fRefFilter(NULL), fAutoScrollInc(20), @@ -4549,7 +4549,7 @@ BPoseView::HandleDropCommon(BMessage* message, Model* targetModel, BPose* target return false; // find the text - int32 textLength; + ssize_t textLength; const char* text; if (message->FindData(kPlainTextMimeType, B_MIME_TYPE, (const void**)&text, &textLength) != B_OK) @@ -4576,12 +4576,13 @@ BPoseView::HandleDropCommon(BMessage* message, Model* targetModel, BPose* target // pick up TextView styles if available and save them with the file const text_run_array* textRuns = NULL; - int32 dataSize = 0; + ssize_t dataSize = 0; if (message->FindData("application/x-vnd.Be-text_run_array", B_MIME_TYPE, (const void**)&textRuns, &dataSize) == B_OK && textRuns && dataSize) { // save styles the same way StyledEdit does - void* data = BTextView::FlattenRunArray(textRuns, &dataSize); - file.WriteAttr("styles", B_RAW_TYPE, 0, data, (size_t)dataSize); + int32 tmpSize = dataSize; + void* data = BTextView::FlattenRunArray(textRuns, &tmpSize); + file.WriteAttr("styles", B_RAW_TYPE, 0, data, (size_t)tmpSize); free(data); } @@ -7227,7 +7228,7 @@ BPoseView::WasDoubleClick(const BPose* pose, BPoint point) && fabs(delta.x) < kDoubleClickTresh && fabs(delta.y) < kDoubleClickTresh && pose == fLastClickedPose) { - fLastClickPt.Set(LONG_MAX, LONG_MAX); + fLastClickPt.Set(INT32_MAX, INT32_MAX); fLastClickedPose = NULL; if (fTextWidgetToCheck != NULL) fTextWidgetToCheck->CancelWait(); @@ -7526,7 +7527,7 @@ BPoseView::SelectPosesListMode(BRect selectionRect, BList** oldList) if (selectionRect.Intersects(poseRect)) { bool selected = pose->IsSelected(); pose->Select(!fSelectionList->HasItem(pose)); - newList->AddItem((void*)index); + newList->AddItem((void*)(addr_t)index); // this sucks, need to clean up using a vector class instead // of BList @@ -7548,9 +7549,9 @@ BPoseView::SelectPosesListMode(BRect selectionRect, BList** oldList) // on those which are no longer enclosed count = (*oldList)->CountItems(); for (int32 index = 0; index < count; index++) { - int32 oldIndex = (int32)(*oldList)->ItemAt(index); + int32 oldIndex = (addr_t)(*oldList)->ItemAt(index); - if (!newList->HasItem((void*)oldIndex)) { + if (!newList->HasItem((void*)(addr_t)oldIndex)) { BPose* pose = poseList->ItemAt(oldIndex); pose->Select(!pose->IsSelected()); loc.Set(0, oldIndex * fListElemHeight); @@ -7590,7 +7591,7 @@ BPoseView::SelectPosesIconMode(BRect selectionRect, BList** oldList) if (selectionRect.Intersects(poseRect)) { bool selected = pose->IsSelected(); pose->Select(!fSelectionList->HasItem(pose)); - newList->AddItem((void*)index); + newList->AddItem((void*)(addr_t)index); if ((selected != pose->IsSelected()) && poseRect.Intersects(bounds)) { @@ -7611,9 +7612,9 @@ BPoseView::SelectPosesIconMode(BRect selectionRect, BList** oldList) // on those which are no longer enclosed count = (*oldList)->CountItems(); for (int32 index = 0; index < count; index++) { - int32 oldIndex = (int32)(*oldList)->ItemAt(index); + int32 oldIndex = (addr_t)(*oldList)->ItemAt(index); - if (!newList->HasItem((void*)oldIndex)) { + if (!newList->HasItem((void*)(addr_t)oldIndex)) { BPose* pose = fVSPoseList->ItemAt(oldIndex); pose->Select(!pose->IsSelected()); BRect poseRect(pose->CalcRect(this)); diff --git a/src/kits/tracker/PoseView.h b/src/kits/tracker/PoseView.h index efdda4d552..6179f07d17 100644 --- a/src/kits/tracker/PoseView.h +++ b/src/kits/tracker/PoseView.h @@ -1021,7 +1021,7 @@ BPoseView::AddToExtent(const BRect&rect) inline void BPoseView::ClearExtent() { - fExtent.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN); + fExtent.Set(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN); } diff --git a/src/kits/tracker/Settings.cpp b/src/kits/tracker/Settings.cpp index 31261dba17..99df1bbeb7 100644 --- a/src/kits/tracker/Settings.cpp +++ b/src/kits/tracker/Settings.cpp @@ -200,7 +200,7 @@ ScalarValueSetting::Value() const void ScalarValueSetting::GetValueAsString(char* buffer) const { - sprintf(buffer, "%ld", fValue); + sprintf(buffer, "%" B_PRId32, fValue); } @@ -212,7 +212,7 @@ ScalarValueSetting::Handle(const char* const* argv) int32 newValue; if ((*argv)[0] == '0' && (*argv)[1] == 'x') - sscanf(*argv,"%lx",&newValue); + sscanf(*argv, "%" B_PRIx32, &newValue); else newValue = atoi(*argv); @@ -253,14 +253,14 @@ HexScalarValueSetting::HexScalarValueSetting(const char* name, void HexScalarValueSetting::GetValueAsString(char* buffer) const { - sprintf(buffer, "0x%08lx", fValue); + sprintf(buffer, "0x%08" B_PRIx32, fValue); } void HexScalarValueSetting::SaveSettingValue(Settings* settings) { - settings->Write("0x%08lx", fValue); + settings->Write("0x%08" B_PRIx32, fValue); } diff --git a/src/kits/tracker/Settings.h b/src/kits/tracker/Settings.h index 47ae4b3c64..5c104c7b42 100644 --- a/src/kits/tracker/Settings.h +++ b/src/kits/tracker/Settings.h @@ -86,8 +86,8 @@ class ScalarValueSetting : public SettingsArgvDispatcher { public: ScalarValueSetting(const char* name, int32 defaultValue, const char* valueExpectedErrorString, - const char* wrongValueErrorString, int32 min = LONG_MIN, - int32 max = LONG_MAX); + const char* wrongValueErrorString, int32 min = INT32_MIN, + int32 max = INT32_MAX); void ValueChanged(int32 newValue); int32 Value() const; @@ -112,8 +112,8 @@ class HexScalarValueSetting : public ScalarValueSetting { public: HexScalarValueSetting(const char* name, int32 defaultValue, const char* valueExpectedErrorString, - const char* wrongValueErrorString, int32 min = LONG_MIN, - int32 max = LONG_MAX); + const char* wrongValueErrorString, int32 min = INT32_MIN, + int32 max = INT32_MAX); void GetValueAsString(char* buffer) const; diff --git a/src/kits/tracker/SettingsHandler.cpp b/src/kits/tracker/SettingsHandler.cpp index 0fe7285fef..32f4fb84b1 100644 --- a/src/kits/tracker/SettingsHandler.cpp +++ b/src/kits/tracker/SettingsHandler.cpp @@ -103,8 +103,10 @@ ArgvParser::SendArgv(ArgvHandler argvHandlerFunc, void* passThru) NextArgv(); fCurrentArgv[fArgc] = 0; const char* result = (argvHandlerFunc)(fArgc, fCurrentArgv, passThru); - if (result) - printf("File %s; Line %ld # %s", fFileName, fLineNo, result); + if (result) { + printf("File %s; Line %" B_PRId32 " # %s", fFileName, fLineNo, + result); + } MakeArgvEmpty(); if (result) return B_ERROR; @@ -188,8 +190,8 @@ ArgvParser::EachArgvPrivate(const char* name, ArgvHandler argvHandlerFunc, // handle new line fEatComment = false; if (!fSawBackslash && (fInDoubleQuote || fInSingleQuote)) { - printf("File %s ; Line %ld # unterminated quote\n", name, - fLineNo); + printf("File %s ; Line %" B_PRId32 " # unterminated quote\n", + name, fLineNo); result = B_ERROR; break; } diff --git a/src/kits/tracker/StatusWindow.cpp b/src/kits/tracker/StatusWindow.cpp index 5a1e7ed7f8..b8ee82ad38 100644 --- a/src/kits/tracker/StatusWindow.cpp +++ b/src/kits/tracker/StatusWindow.cpp @@ -580,7 +580,7 @@ BStatusView::InitStatus(int32 totalItems, off_t totalSize, if (totalItems > 0) { char totalStr[32]; buffer.SetTo(B_TRANSLATE("of %items")); - snprintf(totalStr, sizeof(totalStr), "%ld", totalItems); + snprintf(totalStr, sizeof(totalStr), "%" B_PRId32, totalItems); buffer.ReplaceFirst("%items", totalStr); } diff --git a/src/kits/tracker/TemplatesMenu.cpp b/src/kits/tracker/TemplatesMenu.cpp index aa3468b073..20dfc36cbf 100644 --- a/src/kits/tracker/TemplatesMenu.cpp +++ b/src/kits/tracker/TemplatesMenu.cpp @@ -122,7 +122,7 @@ TemplatesMenu::BuildMenu(bool addItems) fOpenItem = NULL; int32 count = CountItems(); while (count--) - delete RemoveItem(0L); + delete RemoveItem((int32)0); // Add the Folder IconMenuItem* menuItem = new IconMenuItem(B_TRANSLATE("New folder"), diff --git a/src/kits/tracker/Tracker.cpp b/src/kits/tracker/Tracker.cpp index 38e96e03d7..0ad8f6aa0a 100644 --- a/src/kits/tracker/Tracker.cpp +++ b/src/kits/tracker/Tracker.cpp @@ -415,7 +415,7 @@ TTracker::MessageReceived(BMessage* message) case kCloseWindowAndChildren: { const node_ref* itemNode; - int32 bytes; + ssize_t bytes; message->FindData("node_ref", B_RAW_TYPE, (const void**)&itemNode, &bytes); CloseWindowAndChildren(itemNode); diff --git a/src/kits/tracker/WidgetAttributeText.cpp b/src/kits/tracker/WidgetAttributeText.cpp index deaa71be06..1fb5cd873d 100644 --- a/src/kits/tracker/WidgetAttributeText.cpp +++ b/src/kits/tracker/WidgetAttributeText.cpp @@ -1300,7 +1300,7 @@ GenericAttributeText::ReadValue(BString* result) GenericValueStruct tmp; if (fModel->Node()->GetAttrInfo(fColumn->AttrName(), &info) == B_OK) { - if (info.size && info.size <= sizeof(int64)) { + if (info.size && info.size <= (off_t)sizeof(int64)) { length = fModel->Node()->ReadAttr(fColumn->AttrName(), fColumn->AttrType(), 0, &tmp, (size_t)info.size); } @@ -1460,22 +1460,22 @@ GenericAttributeText::FitValue(BString* result, const BPoseView* view) break; case B_INT32_TYPE: - sprintf(buffer, "%ld", fValue.int32t); + sprintf(buffer, "%" B_PRId32, fValue.int32t); fFullValueText = buffer; break; case B_UINT32_TYPE: - sprintf(buffer, "%ld", fValue.uint32t); + sprintf(buffer, "%" B_PRId32, fValue.uint32t); fFullValueText = buffer; break; case B_INT64_TYPE: - sprintf(buffer, "%Ld", fValue.int64t); + sprintf(buffer, "%" B_PRId64, fValue.int64t); fFullValueText = buffer; break; case B_UINT64_TYPE: - sprintf(buffer, "%Ld", fValue.uint64t); + sprintf(buffer, "%" B_PRId64, fValue.uint64t); fFullValueText = buffer; break; @@ -1886,10 +1886,10 @@ DurationAttributeText::FitValue(BString* result, const BPoseView* view) char buffer[256]; if (hours > 0) { - snprintf(buffer, sizeof(buffer), "%s%ld:%02ld:%02ld", - negative ? "-" : "", hours, minutes, seconds); + snprintf(buffer, sizeof(buffer), "%s%" B_PRId32 ":%02" B_PRId32 ":%02" + B_PRId32, negative ? "-" : "", hours, minutes, seconds); } else { - snprintf(buffer, sizeof(buffer), "%s%ld:%02ld", + snprintf(buffer, sizeof(buffer), "%s%" B_PRId32 ":%02" B_PRId32, negative ? "-" : "", minutes, seconds); } diff --git a/src/kits/translation/BitmapStream.cpp b/src/kits/translation/BitmapStream.cpp index 5faf1c360b..db2572f62f 100644 --- a/src/kits/translation/BitmapStream.cpp +++ b/src/kits/translation/BitmapStream.cpp @@ -82,13 +82,13 @@ BBitmapStream::ReadAt(off_t pos, void* buffer, size_t size) return B_NO_INIT; if (size == 0) return B_OK; - if (pos >= fSize || pos < 0 || buffer == NULL) + if (pos >= (off_t)fSize || pos < 0 || buffer == NULL) return B_BAD_VALUE; ssize_t toRead; void *source; - if (pos < sizeof(TranslatorBitmap)) { + if (pos < (off_t)sizeof(TranslatorBitmap)) { toRead = sizeof(TranslatorBitmap) - pos; source = (reinterpret_cast(fBigEndianHeader)) + pos; } else { @@ -122,7 +122,7 @@ BBitmapStream::WriteAt(off_t pos, const void* data, size_t size) { if (size == 0) return B_OK; - if (!data || pos < 0 || pos > fSize) + if (!data || pos < 0 || pos > (off_t)fSize) return B_BAD_VALUE; ssize_t written = 0; @@ -131,7 +131,7 @@ BBitmapStream::WriteAt(off_t pos, const void* data, size_t size) void *dest; // We depend on writing the header separately in detecting // changes to it - if (pos < sizeof(TranslatorBitmap)) { + if (pos < (off_t)sizeof(TranslatorBitmap)) { toWrite = sizeof(TranslatorBitmap) - pos; dest = (reinterpret_cast (&fHeader)) + pos; } else { @@ -153,7 +153,7 @@ BBitmapStream::WriteAt(off_t pos, const void* data, size_t size) written += toWrite; data = (reinterpret_cast (data)) + toWrite; size -= toWrite; - if (pos > fSize) + if (pos > (off_t)fSize) fSize = pos; // If we change the header, the rest needs to be reset if (pos == sizeof(TranslatorBitmap)) { @@ -185,7 +185,7 @@ BBitmapStream::WriteAt(off_t pos, const void* data, size_t size) return error; } if ((uint32)fBitmap->BytesPerRow() != fHeader.rowBytes) { - fprintf(stderr, "BitmapStream %ld %ld\n", + fprintf(stderr, "BitmapStream %" B_PRId32 " %" B_PRId32 "\n", fBitmap->BytesPerRow(), fHeader.rowBytes); return B_MISMATCHED_VALUES; } @@ -218,7 +218,7 @@ BBitmapStream::Seek(off_t position, uint32 seekMode) else if (seekMode == SEEK_END) position += fSize; - if (position < 0 || position > fSize) + if (position < 0 || position > (off_t)fSize) return B_BAD_VALUE; fPosition = position; @@ -257,7 +257,7 @@ BBitmapStream::SetSize(off_t size) { if (size < 0) return B_BAD_VALUE; - if (fBitmap && (size > fHeader.dataSize + sizeof(TranslatorBitmap))) + if (fBitmap && (size > (off_t)(fHeader.dataSize + sizeof(TranslatorBitmap)))) return B_BAD_VALUE; // Problem: // What if someone calls SetSize() before writing the header, diff --git a/src/libs/compat/freebsd_network/Jamfile b/src/libs/compat/freebsd_network/Jamfile index 28e747bd85..fff177a61b 100644 --- a/src/libs/compat/freebsd_network/Jamfile +++ b/src/libs/compat/freebsd_network/Jamfile @@ -13,7 +13,7 @@ Includes [ FGristFiles kernel_c++_structs.h ] SubDirCcFlags [ FDefines _KERNEL=1 ] ; KernelStaticLibrary libfreebsd_network.a : - bus.c + bus.cpp callout.cpp clock.c compat.c diff --git a/src/libs/compat/freebsd_network/bus.c b/src/libs/compat/freebsd_network/bus.cpp similarity index 97% rename from src/libs/compat/freebsd_network/bus.c rename to src/libs/compat/freebsd_network/bus.cpp index fddbd17637..bc89fe8900 100644 --- a/src/libs/compat/freebsd_network/bus.c +++ b/src/libs/compat/freebsd_network/bus.cpp @@ -5,12 +5,17 @@ */ +extern "C" { #include "device.h" +} #include +#include + #include +extern "C" { #include #include #include @@ -18,6 +23,7 @@ #include #include #include +} // private kernel header to get B_NO_HANDLED_INFO #include @@ -146,10 +152,10 @@ bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start, return NULL; device_printf(dev, "bus_alloc_resource(%i, [%i], 0x%lx, 0x%lx, 0x%lx," - "0x%lx)\n", type, *rid, start, end, count, flags); + "0x%" B_PRIx32 ")\n", type, *rid, start, end, count, flags); // maybe a local array of resources is enough - res = malloc(sizeof(struct resource)); + res = (struct resource *)malloc(sizeof(struct resource)); if (res == NULL) return NULL; @@ -256,7 +262,7 @@ rman_get_bustag(struct resource *res) static int32 intr_wrapper(void *data) { - struct internal_intr *intr = data; + struct internal_intr *intr = (struct internal_intr *)data; //device_printf(intr->dev, "in interrupt handler.\n"); @@ -271,7 +277,7 @@ intr_wrapper(void *data) static int32 intr_fast_wrapper(void *data) { - struct internal_intr *intr = data; + struct internal_intr *intr = (struct internal_intr *)data; intr->handler(intr->arg); @@ -283,7 +289,7 @@ intr_fast_wrapper(void *data) static int32 intr_handler(void *data) { - struct internal_intr *intr = data; + struct internal_intr *intr = (struct internal_intr *)data; status_t status; while (1) { @@ -398,7 +404,7 @@ bus_setup_intr(device_t dev, struct resource *res, int flags, int bus_teardown_intr(device_t dev, struct resource *res, void *arg) { - struct internal_intr *intr = arg; + struct internal_intr *intr = (struct internal_intr *)arg; if (intr->is_msi && gPCIx86 != NULL) { // disable msi generation @@ -892,7 +898,7 @@ pci_set_powerstate(device_t dev, int newPowerState) if (oldPowerState == newPowerState) return EOK; - switch (max(oldPowerState, newPowerState)) { + switch (std::max(oldPowerState, newPowerState)) { case PCI_POWERSTATE_D2: stateTransitionDelayInUs = 200; break; diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c index caa8c0ecf1..f17eb59319 100644 --- a/src/libs/compat/freebsd_network/compat.c +++ b/src/libs/compat/freebsd_network/compat.c @@ -74,9 +74,9 @@ find_own_image() int32 cookie = 0; image_info info; while (get_next_image_info(B_SYSTEM_TEAM, &cookie, &info) == B_OK) { - if (((uint32)info.text <= (uint32)find_own_image - && (uint32)info.text + (uint32)info.text_size - > (uint32)find_own_image)) { + if (((addr_t)info.text <= (addr_t)find_own_image + && (addr_t)info.text + (addr_t)info.text_size + > (addr_t)find_own_image)) { // found our own image return info.id; } @@ -635,8 +635,8 @@ pmap_kextract(vm_offset_t virtualAddress) physical_entry entry; status_t status = get_memory_map((void *)virtualAddress, 1, &entry, 1); if (status < B_OK) { - panic("fbsd compat: get_memory_map failed for %p, error %08lx\n", - (void *)virtualAddress, status); + panic("fbsd compat: get_memory_map failed for %p, error %08" B_PRIx32 + "\n", (void *)virtualAddress, status); } return (vm_paddr_t)entry.address; diff --git a/src/libs/compat/freebsd_network/compat/machine/_bus.h b/src/libs/compat/freebsd_network/compat/machine/_bus.h index acdd148c58..a4b9025408 100644 --- a/src/libs/compat/freebsd_network/compat/machine/_bus.h +++ b/src/libs/compat/freebsd_network/compat/machine/_bus.h @@ -7,10 +7,26 @@ #define _FBSD_COMPAT_MACHINE__BUS_H_ +#ifdef B_HAIKU_64_BIT + + +typedef uint64_t bus_addr_t; +typedef uint64_t bus_size_t; + +typedef uint64_t bus_space_tag_t; +typedef uint64_t bus_space_handle_t; + + +#else + + typedef uint32_t bus_addr_t; typedef uint32_t bus_size_t; typedef int bus_space_tag_t; typedef unsigned int bus_space_handle_t; + +#endif + #endif /* _FBSD_COMPAT_MACHINE__BUS_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/machine/bus.h b/src/libs/compat/freebsd_network/compat/machine/bus.h index 10f549f3c3..717f895fed 100644 --- a/src/libs/compat/freebsd_network/compat/machine/bus.h +++ b/src/libs/compat/freebsd_network/compat/machine/bus.h @@ -120,7 +120,11 @@ #define I386_BUS_SPACE_MEM 1 #define BUS_SPACE_MAXADDR_32BIT 0xffffffff -#define BUS_SPACE_MAXADDR 0xffffffff +#ifdef __x86_64__ +# define BUS_SPACE_MAXADDR 0xffffffffffffffffull +#else +# define BUS_SPACE_MAXADDR 0xffffffff +#endif #define BUS_SPACE_MAXSIZE_32BIT 0xffffffff #define BUS_SPACE_MAXSIZE 0xffffffff diff --git a/src/libs/compat/freebsd_network/compat/vm/vm.h b/src/libs/compat/freebsd_network/compat/vm/vm.h index 982426560c..56eef91da4 100644 --- a/src/libs/compat/freebsd_network/compat/vm/vm.h +++ b/src/libs/compat/freebsd_network/compat/vm/vm.h @@ -10,11 +10,18 @@ #include -// TODO at the moment for 32 bit machines only +#ifdef B_HAIKU_64_BIT + +typedef uint64_t vm_offset_t; +typedef uint64_t vm_paddr_t; + +#else typedef uint32_t vm_offset_t; typedef uint32_t vm_paddr_t; +#endif + typedef void *pmap_t; diff --git a/src/libs/compat/freebsd_network/device.c b/src/libs/compat/freebsd_network/device.c index c9a435c22f..2e7fb3113e 100644 --- a/src/libs/compat/freebsd_network/device.c +++ b/src/libs/compat/freebsd_network/device.c @@ -41,7 +41,7 @@ compat_open(const char *name, uint32 flags, void **cookie) return B_ERROR; ifp = gDevices[i]; - if_printf(ifp, "compat_open(0x%lx)\n", flags); + if_printf(ifp, "compat_open(0x%" B_PRIx32 ")\n", flags); if (atomic_or(&ifp->open_count, 1)) { put_module(NET_STACK_MODULE_NAME); diff --git a/src/libs/compat/freebsd_network/fbsd_busdma_x86.c b/src/libs/compat/freebsd_network/fbsd_busdma_x86.c index 7c26791d77..67f3a4981c 100644 --- a/src/libs/compat/freebsd_network/fbsd_busdma_x86.c +++ b/src/libs/compat/freebsd_network/fbsd_busdma_x86.c @@ -43,7 +43,11 @@ __FBSDID("$FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.74.2.4 2006/10/21 16: #include #include -#define MAX_BPAGES 512 +#ifdef __x86_64__ +# define MAX_BPAGES 8192 +#else +# define MAX_BPAGES 512 +#endif /* -hugo */ #define malloc(a, b, c) kernel_malloc(a, b, c) @@ -60,7 +64,7 @@ struct bounce_zone; struct bus_dma_tag { bus_dma_tag_t parent; bus_size_t alignment; - bus_size_t boundary; + bus_addr_t boundary; bus_addr_t lowaddr; bus_addr_t highaddr; bus_dma_filter_t *filter; @@ -97,7 +101,7 @@ struct bounce_zone { int total_bounced; int total_deferred; bus_size_t alignment; - bus_size_t boundary; + bus_addr_t boundary; bus_addr_t lowaddr; char zoneid[8]; char lowaddrid[20]; diff --git a/src/libs/glut/Jamfile b/src/libs/glut/Jamfile index cb380e8fb1..54750c26bc 100644 --- a/src/libs/glut/Jamfile +++ b/src/libs/glut/Jamfile @@ -1,4 +1,5 @@ SubDir HAIKU_TOP src libs glut ; +SubDirSysHdrs $(HAIKU_GLU_HEADERS) ; SubDirSysHdrs $(HAIKU_MESA_HEADERS) ; SetSubDirSupportedPlatformsBeOSCompatible ; @@ -55,16 +56,13 @@ if $(HAIKU_GCC_VERSION[1]) < 3 { } -# Ensure GLU dependency is met -Includes [ FGristFiles $(sourcesCc) $(sourcesCpp) ] - : $(HAIKU_GLU_HEADERS_DEPENDENCY) ; # Ensure Mesa dependency is met Includes [ FGristFiles $(sourcesCc) $(sourcesCpp) ] : $(HAIKU_MESA_HEADERS_DEPENDENCY) ; -MergeObject glut.o : - # C++ sources +SharedLibrary libglut.so : $(sourcesCpp) - # C sources $(sourcesCc) + : + GL game be $(TARGET_LIBSTDC++) ; diff --git a/src/libs/glut/LICENSE.txt b/src/libs/glut/LICENSE.txt new file mode 100644 index 0000000000..4fc3611641 --- /dev/null +++ b/src/libs/glut/LICENSE.txt @@ -0,0 +1,42 @@ +On 2012-11-15 4:04 pm, Mark Kilgard wrote: +Alex, + +> Ideally, if you gave permission to license the GLUT code MIT it would make my life easier... but that of course is your decision. :) + +Please feel free to use the GLUT code any way you please for +commercial or non-commercial use. Put whatever license you want other +than a GPL. There's no warrantee for the code of course. + +Good luck with your project. + +- Mark + +> -----Original Message----- +> From: Alexander von Gluck IV [mailto:kallisti5@unixzen.com] +> Sent: Thursday, November 15, 2012 1:45 PM +> To: Mark Kilgard +> Subject: BeOS GLUT +> +> Good afternoon! +> +> I'm one of the developers of the Haiku project. (Open Source MIT +> licensed re-implementation of BeOS) +> +> At the moment, we have the unmodified GLUT source code in our tree to +> ensure binary compatibility with BeOS (GLUT was present in libGL.so on +> BeOS R5). However, our developers feel anxious distributing any +> modified sources or binaries of GLUT given the licensing terms present +> when the last public version was released. +> +> I would like to know if you would be willing to give Haiku permission +> to modify GLUT and distribute it to ensure the best GL compatibility. +> The license notated in the code was a little unclear and I wanted to +> make 100% sure we were following your wishes. +> +> Ideally, if you gave permission to license the GLUT code MIT it would +> make my life easier... but that of course is your decision. :) +> +> http://cgit.haiku-os.org/haiku/tree/src/libs/glut +> +> Thanks for your time. +> -- Alexander von Gluck IV diff --git a/src/libs/glut/glut_bitmap.c b/src/libs/glut/glut_bitmap.c index f1afdd7a04..a17e8d07f3 100644 --- a/src/libs/glut/glut_bitmap.c +++ b/src/libs/glut/glut_bitmap.c @@ -1,13 +1,16 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ -/* Copyright (c) Mark J. Kilgard, 1994. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #include "glutint.h" #include "glutbitmap.h" + void APIENTRY glutBitmapCharacter(GLUTbitmapFont font, int c) { diff --git a/src/libs/glut/glut_bwidth.c b/src/libs/glut/glut_bwidth.c index bee5e8827e..a72c33eab8 100644 --- a/src/libs/glut/glut_bwidth.c +++ b/src/libs/glut/glut_bwidth.c @@ -1,13 +1,16 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ -/* Copyright (c) Mark J. Kilgard, 1994. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #include "glutint.h" #include "glutbitmap.h" + /* CENTRY */ int APIENTRY glutBitmapWidth(GLUTbitmapFont font, int c) diff --git a/src/libs/glut/glut_ext.c b/src/libs/glut/glut_ext.c index 147b5b4803..83704ca0ae 100644 --- a/src/libs/glut/glut_ext.c +++ b/src/libs/glut/glut_ext.c @@ -1,15 +1,18 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ -/* Copyright (c) Mark J. Kilgard, 1994, 1997. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #include #include #include "glutint.h" + /* CENTRY */ int GLUTAPIENTRY glutExtensionSupported(const char *extension) diff --git a/src/libs/glut/glut_shapes.c b/src/libs/glut/glut_shapes.c index ce5bebb2be..1f9d84991e 100644 --- a/src/libs/glut/glut_shapes.c +++ b/src/libs/glut/glut_shapes.c @@ -1,5 +1,10 @@ - -/* Copyright (c) Mark J. Kilgard, 1994, 1997. */ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ /** (c) Copyright 1993, Silicon Graphics, Inc. diff --git a/src/libs/glut/glut_stroke.c b/src/libs/glut/glut_stroke.c index 2fe408be1a..689ccd2e2b 100644 --- a/src/libs/glut/glut_stroke.c +++ b/src/libs/glut/glut_stroke.c @@ -1,13 +1,16 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ -/* Copyright (c) Mark J. Kilgard, 1994. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #include "glutint.h" #include "glutstroke.h" + void APIENTRY glutStrokeCharacter(GLUTstrokeFont font, int c) { diff --git a/src/libs/glut/glut_swidth.c b/src/libs/glut/glut_swidth.c index e1b7374575..547aae0710 100644 --- a/src/libs/glut/glut_swidth.c +++ b/src/libs/glut/glut_swidth.c @@ -1,13 +1,16 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ -/* Copyright (c) Mark J. Kilgard, 1995. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #include "glutint.h" #include "glutstroke.h" + /* CENTRY */ int APIENTRY glutStrokeWidth(GLUTstrokeFont font, int c) diff --git a/src/libs/glut/glut_teapot.c b/src/libs/glut/glut_teapot.c index 3c9bdc1ab7..366bef7be1 100644 --- a/src/libs/glut/glut_teapot.c +++ b/src/libs/glut/glut_teapot.c @@ -1,5 +1,10 @@ - -/* Copyright (c) Mark J. Kilgard, 1994. */ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ /** (c) Copyright 1993, Silicon Graphics, Inc. @@ -44,8 +49,10 @@ Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA OpenGL(TM) is a trademark of Silicon Graphics, Inc. */ + #include "glutint.h" + /* Rim, body, lid, and bottom data must be reflected in x and y; handle and spout data across the y axis only. */ diff --git a/src/libs/glut/glut_util.c b/src/libs/glut/glut_util.c index 6acd938d20..1461fa845b 100644 --- a/src/libs/glut/glut_util.c +++ b/src/libs/glut/glut_util.c @@ -1,9 +1,11 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ -/* Copyright (c) Mark J. Kilgard, 1994. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #include #include @@ -12,6 +14,7 @@ #include "glutint.h" + /* strdup is actually not a standard ANSI C or POSIX routine so implement a private one for GLUT. OpenVMS does not have a strdup; Linux's standard libc doesn't declare strdup by default diff --git a/src/libs/glut/glut_vidresize.c b/src/libs/glut/glut_vidresize.c index f2617c3b99..afda7bfa23 100644 --- a/src/libs/glut/glut_vidresize.c +++ b/src/libs/glut/glut_vidresize.c @@ -1,12 +1,15 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ -/* Copyright (c) Mark J. Kilgard, 1996. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #include + #if !defined(_WIN32) && !(defined(__BEOS__) || defined(__HAIKU__)) #include #endif diff --git a/src/libs/glut/glutbitmap.h b/src/libs/glut/glutbitmap.h index 32bf53c097..830046f40b 100644 --- a/src/libs/glut/glutbitmap.h +++ b/src/libs/glut/glutbitmap.h @@ -1,14 +1,17 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ #ifndef __glutbitmap_h__ #define __glutbitmap_h__ -/* Copyright (c) Mark J. Kilgard, 1994. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #include + typedef struct { const GLsizei width; const GLsizei height; @@ -27,4 +30,5 @@ typedef struct { typedef void *GLUTbitmapFont; + #endif /* __glutbitmap_h__ */ diff --git a/src/libs/glut/glutint.h b/src/libs/glut/glutint.h index c618ccd328..6f3d7241ef 100644 --- a/src/libs/glut/glutint.h +++ b/src/libs/glut/glutint.h @@ -1,11 +1,13 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ #ifndef __glutint_h__ #define __glutint_h__ -/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #if defined(__CYGWIN32__) #include diff --git a/src/libs/glut/glutstroke.h b/src/libs/glut/glutstroke.h index cbc9e156fe..12d3235f5a 100644 --- a/src/libs/glut/glutstroke.h +++ b/src/libs/glut/glutstroke.h @@ -1,11 +1,13 @@ +/* + * Copyright 1994-1997 Mark Kilgard, All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Mark Kilgard + */ #ifndef __glutstroke_h__ #define __glutstroke_h__ -/* Copyright (c) Mark J. Kilgard, 1994. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ #if defined(_WIN32) #pragma warning (disable:4244) /* disable bogus conversion warnings */ diff --git a/src/libs/linprog/Constraint.cpp b/src/libs/linprog/Constraint.cpp index 6dbfe451e9..9d0596b5df 100644 --- a/src/libs/linprog/Constraint.cpp +++ b/src/libs/linprog/Constraint.cpp @@ -335,7 +335,7 @@ Constraint::ToString() const BString string; string << "Constraint "; string << fLabel; - string << "(" << (int32)this << "): "; + string << "(" << (addr_t)this << "): "; for (int i = 0; i < fLeftSide->CountItems(); i++) { Summand* s = static_cast(fLeftSide->ItemAt(i)); diff --git a/src/libs/linprog/LinearSpec.cpp b/src/libs/linprog/LinearSpec.cpp index ac50ef6474..bdb5d39884 100644 --- a/src/libs/linprog/LinearSpec.cpp +++ b/src/libs/linprog/LinearSpec.cpp @@ -675,7 +675,7 @@ BString LinearSpec::ToString() const { BString string; - string << "LinearSpec " << (int32)this << ":\n"; + string << "LinearSpec " << (addr_t)this << ":\n"; for (int i = 0; i < fVariables.CountItems(); i++) { Variable* variable = fVariables.ItemAt(i); string += variable->ToString(); diff --git a/src/libs/linprog/Variable.cpp b/src/libs/linprog/Variable.cpp index 880b38882d..88fbb32e9d 100644 --- a/src/libs/linprog/Variable.cpp +++ b/src/libs/linprog/Variable.cpp @@ -173,7 +173,7 @@ Variable::ToString() const string << "(invalid)"; } else { if (!fIsValid) - string << "(invalid," << (int32)this << ")"; + string << "(invalid," << (addr_t)this << ")"; else string << Index() << ": "; } diff --git a/src/libs/x86emu/debug.c b/src/libs/x86emu/debug.c new file mode 100644 index 0000000000..cee36f595d --- /dev/null +++ b/src/libs/x86emu/debug.c @@ -0,0 +1,496 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: This file contains the code to handle debugging of the +* emulator. +* +****************************************************************************/ + +#include "x86emu/x86emui.h" +#include +#include +#ifndef NO_SYS_HEADERS +#include +#include +#endif + +/*----------------------------- Implementation ----------------------------*/ + +#ifdef DEBUG + +static void print_encoded_bytes(u16 s, u16 o); +static void print_decoded_instruction(void); +static int parse_line(char *s, int *ps, int *n); + +/* should look something like debug's output. */ +void +X86EMU_trace_regs(void) +{ + if (DEBUG_TRACE()) { + x86emu_dump_regs(); + } + if (DEBUG_DECODE() && !DEBUG_DECODE_NOPRINT()) { + printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip); + print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip); + print_decoded_instruction(); + } +} + +void +X86EMU_trace_xregs(void) +{ + if (DEBUG_TRACE()) { + x86emu_dump_xregs(); + } +} + +void +x86emu_just_disassemble(void) +{ + /* + * This routine called if the flag DEBUG_DISASSEMBLE is set kind + * of a hack! + */ + printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip); + print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip); + print_decoded_instruction(); +} + +static void +disassemble_forward(u16 seg, u16 off, int n) +{ + X86EMU_sysEnv tregs; + int i; + u8 op1; + + /* + * hack, hack, hack. What we do is use the exact machinery set up + * for execution, except that now there is an additional state + * flag associated with the "execution", and we are using a copy + * of the register struct. All the major opcodes, once fully + * decoded, have the following two steps: TRACE_REGS(r,m); + * SINGLE_STEP(r,m); which disappear if DEBUG is not defined to + * the preprocessor. The TRACE_REGS macro expands to: + * + * if (debug&DEBUG_DISASSEMBLE) + * {just_disassemble(); goto EndOfInstruction;} + * if (debug&DEBUG_TRACE) trace_regs(r,m); + * + * ...... and at the last line of the routine. + * + * EndOfInstruction: end_instr(); + * + * Up to the point where TRACE_REG is expanded, NO modifications + * are done to any register EXCEPT the IP register, for fetch and + * decoding purposes. + * + * This was done for an entirely different reason, but makes a + * nice way to get the system to help debug codes. + */ + tregs = M; + tregs.x86.R_IP = off; + tregs.x86.R_CS = seg; + + /* reset the decoding buffers */ + tregs.x86.enc_str_pos = 0; + tregs.x86.enc_pos = 0; + + /* turn on the "disassemble only, no execute" flag */ + tregs.x86.debug |= DEBUG_DISASSEMBLE_F; + + /* DUMP NEXT n instructions to screen in straight_line fashion */ + /* + * This looks like the regular instruction fetch stream, except + * that when this occurs, each fetched opcode, upon seeing the + * DEBUG_DISASSEMBLE flag set, exits immediately after decoding + * the instruction. XXX --- CHECK THAT MEM IS NOT AFFECTED!!! + * Note the use of a copy of the register structure... + */ + for (i = 0; i < n; i++) { + op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++)); + (x86emu_optab[op1]) (op1); + } + /* end major hack mode. */ +} + +void +x86emu_check_ip_access(void) +{ + /* NULL as of now */ +} + +void +x86emu_check_sp_access(void) +{ +} + +void +x86emu_check_mem_access(u32 dummy) +{ + /* check bounds, etc */ +} + +void +x86emu_check_data_access(uint dummy1, uint dummy2) +{ + /* check bounds, etc */ +} + +void +x86emu_inc_decoded_inst_len(int x) +{ + M.x86.enc_pos += x; +} + +void +x86emu_decode_printf(const char *x) +{ + sprintf(M.x86.decoded_buf + M.x86.enc_str_pos, "%s", x); + M.x86.enc_str_pos += strlen(x); +} + +void +x86emu_decode_printf2(const char *x, int y) +{ + char temp[100]; + + snprintf(temp, sizeof(temp), x, y); + sprintf(M.x86.decoded_buf + M.x86.enc_str_pos, "%s", temp); + M.x86.enc_str_pos += strlen(temp); +} + +void +x86emu_end_instr(void) +{ + M.x86.enc_str_pos = 0; + M.x86.enc_pos = 0; +} + +static void +print_encoded_bytes(u16 s, u16 o) +{ + int i; + char buf1[64]; + + for (i = 0; i < M.x86.enc_pos; i++) { + sprintf(buf1 + 2 * i, "%02x", fetch_data_byte_abs(s, o + i)); + } + printk("%-20s", buf1); +} + +static void +print_decoded_instruction(void) +{ + printk("%s", M.x86.decoded_buf); +} + +void +x86emu_print_int_vect(u16 iv) +{ + u16 seg, off; + + if (iv > 256) + return; + seg = fetch_data_word_abs(0, iv * 4); + off = fetch_data_word_abs(0, iv * 4 + 2); + printk("%04x:%04x ", seg, off); +} + +void +X86EMU_dump_memory(u16 seg, u16 off, u32 amt) +{ + u32 start = off & 0xfffffff0; + u32 end = (off + 16) & 0xfffffff0; + u32 i; + u32 current; + + current = start; + while (end <= off + amt) { + printk("%04x:%04x ", seg, start); + for (i = start; i < off; i++) + printk(" "); + for (; i < end; i++) + printk("%02x ", fetch_data_byte_abs(seg, i)); + printk("\n"); + start = end; + end = start + 16; + } +} + +void +x86emu_single_step(void) +{ + return; + char s[1024]; + int ps[10]; + int ntok; + int cmd; + int done; + int segment; + int offset; + static int breakpoint; + static int noDecode = 1; + + //char *p; + + if (DEBUG_BREAK()) { + if (M.x86.saved_ip != breakpoint) { + return; + } + else { + M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; + M.x86.debug |= DEBUG_TRACE_F; + M.x86.debug &= ~DEBUG_BREAK_F; + print_decoded_instruction(); + X86EMU_trace_regs(); + } + } + done = 0; + offset = M.x86.saved_ip; + while (!done) { + printk("-"); + //p = fgets(s, 1023, stdin); + cmd = parse_line(s, ps, &ntok); + switch (cmd) { + case 'u': + disassemble_forward(M.x86.saved_cs, (u16) offset, 10); + break; + case 'd': + if (ntok == 2) { + segment = M.x86.saved_cs; + offset = ps[1]; + X86EMU_dump_memory(segment, (u16) offset, 16); + offset += 16; + } + else if (ntok == 3) { + segment = ps[1]; + offset = ps[2]; + X86EMU_dump_memory(segment, (u16) offset, 16); + offset += 16; + } + else { + segment = M.x86.saved_cs; + X86EMU_dump_memory(segment, (u16) offset, 16); + offset += 16; + } + break; + case 'c': + M.x86.debug ^= DEBUG_TRACECALL_F; + break; + case 's': + M.x86.debug ^= DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F; + break; + case 'r': + X86EMU_trace_regs(); + break; + case 'x': + X86EMU_trace_xregs(); + break; + case 'g': + if (ntok == 2) { + breakpoint = ps[1]; + if (noDecode) { + M.x86.debug |= DEBUG_DECODE_NOPRINT_F; + } + else { + M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; + } + M.x86.debug &= ~DEBUG_TRACE_F; + M.x86.debug |= DEBUG_BREAK_F; + done = 1; + } + break; + case 'q': + M.x86.debug |= DEBUG_EXIT; + return; + case 'P': + noDecode = (noDecode) ? 0 : 1; + printk("Toggled decoding to %s\n", (noDecode) ? "FALSE" : "TRUE"); + break; + case 't': + case 0: + done = 1; + break; + } + } +} + +int +X86EMU_trace_on(void) +{ + return M.x86.debug |= DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F; +} + +int +X86EMU_trace_off(void) +{ + return M.x86.debug &= ~(DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F); +} + +static int +parse_line(char *s, int *ps, int *n) +{ + int cmd; + + *n = 0; + while (*s == ' ' || *s == '\t') + s++; + ps[*n] = *s; + switch (*s) { + case '\n': + *n += 1; + return 0; + default: + cmd = *s; + *n += 1; + } + + while (1) { + while (*s != ' ' && *s != '\t' && *s != '\n') + s++; + + if (*s == '\n') + return cmd; + + while (*s == ' ' || *s == '\t') + s++; + + //sscanf(s, "%x", &ps[*n]); + *n += 1; + } +} + +#endif /* DEBUG */ + +void +x86emu_dump_regs(void) +{ + printk("\tAX=%04x ", M.x86.R_AX); + printk("BX=%04x ", M.x86.R_BX); + printk("CX=%04x ", M.x86.R_CX); + printk("DX=%04x ", M.x86.R_DX); + printk("SP=%04x ", M.x86.R_SP); + printk("BP=%04x ", M.x86.R_BP); + printk("SI=%04x ", M.x86.R_SI); + printk("DI=%04x\n", M.x86.R_DI); + printk("\tDS=%04x ", M.x86.R_DS); + printk("ES=%04x ", M.x86.R_ES); + printk("SS=%04x ", M.x86.R_SS); + printk("CS=%04x ", M.x86.R_CS); + printk("IP=%04x ", M.x86.R_IP); + if (ACCESS_FLAG(F_OF)) + printk("OV "); /* CHECKED... */ + else + printk("NV "); + if (ACCESS_FLAG(F_DF)) + printk("DN "); + else + printk("UP "); + if (ACCESS_FLAG(F_IF)) + printk("EI "); + else + printk("DI "); + if (ACCESS_FLAG(F_SF)) + printk("NG "); + else + printk("PL "); + if (ACCESS_FLAG(F_ZF)) + printk("ZR "); + else + printk("NZ "); + if (ACCESS_FLAG(F_AF)) + printk("AC "); + else + printk("NA "); + if (ACCESS_FLAG(F_PF)) + printk("PE "); + else + printk("PO "); + if (ACCESS_FLAG(F_CF)) + printk("CY "); + else + printk("NC "); + printk("\n"); +} + +void +x86emu_dump_xregs(void) +{ + printk("\tEAX=%08x ", M.x86.R_EAX); + printk("EBX=%08x ", M.x86.R_EBX); + printk("ECX=%08x ", M.x86.R_ECX); + printk("EDX=%08x \n", M.x86.R_EDX); + printk("\tESP=%08x ", M.x86.R_ESP); + printk("EBP=%08x ", M.x86.R_EBP); + printk("ESI=%08x ", M.x86.R_ESI); + printk("EDI=%08x\n", M.x86.R_EDI); + printk("\tDS=%04x ", M.x86.R_DS); + printk("ES=%04x ", M.x86.R_ES); + printk("SS=%04x ", M.x86.R_SS); + printk("CS=%04x ", M.x86.R_CS); + printk("EIP=%08x\n\t", M.x86.R_EIP); + if (ACCESS_FLAG(F_OF)) + printk("OV "); /* CHECKED... */ + else + printk("NV "); + if (ACCESS_FLAG(F_DF)) + printk("DN "); + else + printk("UP "); + if (ACCESS_FLAG(F_IF)) + printk("EI "); + else + printk("DI "); + if (ACCESS_FLAG(F_SF)) + printk("NG "); + else + printk("PL "); + if (ACCESS_FLAG(F_ZF)) + printk("ZR "); + else + printk("NZ "); + if (ACCESS_FLAG(F_AF)) + printk("AC "); + else + printk("NA "); + if (ACCESS_FLAG(F_PF)) + printk("PE "); + else + printk("PO "); + if (ACCESS_FLAG(F_CF)) + printk("CY "); + else + printk("NC "); + printk("\n"); +} diff --git a/src/libs/x86emu/decode.c b/src/libs/x86emu/decode.c new file mode 100644 index 0000000000..12f8fb84b3 --- /dev/null +++ b/src/libs/x86emu/decode.c @@ -0,0 +1,1092 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: This file includes subroutines which are related to +* instruction decoding and accessess of immediate data via IP. etc. +* +****************************************************************************/ + +#include +#include "x86emu/x86emui.h" + +/*----------------------------- Implementation ----------------------------*/ + +/**************************************************************************** +REMARKS: +Handles any pending asychronous interrupts. +****************************************************************************/ +static void +x86emu_intr_handle(void) +{ + u8 intno; + + if (M.x86.intr & INTR_SYNCH) { + intno = M.x86.intno; + if (_X86EMU_intrTab[intno]) { + (*_X86EMU_intrTab[intno]) (intno); + } + else { + push_word((u16) M.x86.R_FLG); + CLEAR_FLAG(F_IF); + CLEAR_FLAG(F_TF); + push_word(M.x86.R_CS); + M.x86.R_CS = mem_access_word(intno * 4 + 2); + push_word(M.x86.R_IP); + M.x86.R_IP = mem_access_word(intno * 4); + M.x86.intr = 0; + } + } +} + +/**************************************************************************** +PARAMETERS: +intrnum - Interrupt number to raise + +REMARKS: +Raise the specified interrupt to be handled before the execution of the +next instruction. +****************************************************************************/ +void +x86emu_intr_raise(u8 intrnum) +{ + M.x86.intno = intrnum; + M.x86.intr |= INTR_SYNCH; +} + +/**************************************************************************** +REMARKS: +Main execution loop for the emulator. We return from here when the system +halts, which is normally caused by a stack fault when we return from the +original real mode call. +****************************************************************************/ +void +X86EMU_exec(void) +{ + u8 op1; + + M.x86.intr = 0; + DB(x86emu_end_instr(); + ) + + for (;;) { + DB(if (CHECK_IP_FETCH()) + x86emu_check_ip_access();) + /* If debugging, save the IP and CS values. */ + SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP); + INC_DECODED_INST_LEN(1); + if (M.x86.intr) { + if (M.x86.intr & INTR_HALTED) { + DB(if (M.x86.R_SP != 0) { + printk("halted\n"); X86EMU_trace_regs();} + else { + if (M.x86.debug) + printk("Service completed successfully\n");} + ) + return; + } + if (((M.x86.intr & INTR_SYNCH) && + (M.x86.intno == 0 || M.x86.intno == 2)) || + !ACCESS_FLAG(F_IF)) { + x86emu_intr_handle(); + } + } + op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++)); + (*x86emu_optab[op1]) (op1); + if (M.x86.debug & DEBUG_EXIT) { + M.x86.debug &= ~DEBUG_EXIT; + return; + } + } +} + +/**************************************************************************** +REMARKS: +Halts the system by setting the halted system flag. +****************************************************************************/ +void +X86EMU_halt_sys(void) +{ + M.x86.intr |= INTR_HALTED; +} + +/**************************************************************************** +PARAMETERS: +mod - Mod value from decoded byte +regh - Reg h value from decoded byte +regl - Reg l value from decoded byte + +REMARKS: +Raise the specified interrupt to be handled before the execution of the +next instruction. + +NOTE: Do not inline this function, as (*sys_rdb) is already inline! +****************************************************************************/ +void +fetch_decode_modrm(int *mod, int *regh, int *regl) +{ + int fetched; + + DB(if (CHECK_IP_FETCH()) + x86emu_check_ip_access();) + fetched = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++)); + INC_DECODED_INST_LEN(1); + *mod = (fetched >> 6) & 0x03; + *regh = (fetched >> 3) & 0x07; + *regl = (fetched >> 0) & 0x07; +} + +/**************************************************************************** +RETURNS: +Immediate byte value read from instruction queue + +REMARKS: +This function returns the immediate byte from the instruction queue, and +moves the instruction pointer to the next value. + +NOTE: Do not inline this function, as (*sys_rdb) is already inline! +****************************************************************************/ +u8 +fetch_byte_imm(void) +{ + u8 fetched; + + DB(if (CHECK_IP_FETCH()) + x86emu_check_ip_access();) + fetched = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++)); + INC_DECODED_INST_LEN(1); + return fetched; +} + +/**************************************************************************** +RETURNS: +Immediate word value read from instruction queue + +REMARKS: +This function returns the immediate byte from the instruction queue, and +moves the instruction pointer to the next value. + +NOTE: Do not inline this function, as (*sys_rdw) is already inline! +****************************************************************************/ +u16 +fetch_word_imm(void) +{ + u16 fetched; + + DB(if (CHECK_IP_FETCH()) + x86emu_check_ip_access();) + fetched = (*sys_rdw) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP)); + M.x86.R_IP += 2; + INC_DECODED_INST_LEN(2); + return fetched; +} + +/**************************************************************************** +RETURNS: +Immediate lone value read from instruction queue + +REMARKS: +This function returns the immediate byte from the instruction queue, and +moves the instruction pointer to the next value. + +NOTE: Do not inline this function, as (*sys_rdw) is already inline! +****************************************************************************/ +u32 +fetch_long_imm(void) +{ + u32 fetched; + + DB(if (CHECK_IP_FETCH()) + x86emu_check_ip_access();) + fetched = (*sys_rdl) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP)); + M.x86.R_IP += 4; + INC_DECODED_INST_LEN(4); + return fetched; +} + +/**************************************************************************** +RETURNS: +Value of the default data segment + +REMARKS: +Inline function that returns the default data segment for the current +instruction. + +On the x86 processor, the default segment is not always DS if there is +no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to +addresses relative to SS (ie: on the stack). So, at the minimum, all +decodings of addressing modes would have to set/clear a bit describing +whether the access is relative to DS or SS. That is the function of the +cpu-state-varible M.x86.mode. There are several potential states: + + repe prefix seen (handled elsewhere) + repne prefix seen (ditto) + + cs segment override + ds segment override + es segment override + fs segment override + gs segment override + ss segment override + + ds/ss select (in absense of override) + +Each of the above 7 items are handled with a bit in the mode field. +****************************************************************************/ +_INLINE u32 +get_data_segment(void) +{ +#define GET_SEGMENT(segment) + switch (M.x86.mode & SYSMODE_SEGMASK) { + case 0: /* default case: use ds register */ + case SYSMODE_SEGOVR_DS: + case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS: + return M.x86.R_DS; + case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */ + return M.x86.R_SS; + case SYSMODE_SEGOVR_CS: + case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS: + return M.x86.R_CS; + case SYSMODE_SEGOVR_ES: + case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS: + return M.x86.R_ES; + case SYSMODE_SEGOVR_FS: + case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS: + return M.x86.R_FS; + case SYSMODE_SEGOVR_GS: + case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS: + return M.x86.R_GS; + case SYSMODE_SEGOVR_SS: + case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS: + return M.x86.R_SS; + default: +#ifdef DEBUG + printk("error: should not happen: multiple overrides.\n"); +#endif + HALT_SYS(); + return 0; + } +} + +/**************************************************************************** +PARAMETERS: +offset - Offset to load data from + +RETURNS: +Byte value read from the absolute memory location. + +NOTE: Do not inline this function as (*sys_rdX) is already inline! +****************************************************************************/ +u8 +fetch_data_byte(uint offset) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((u16) get_data_segment(), offset); +#endif + return (*sys_rdb) ((get_data_segment() << 4) + offset); +} + +/**************************************************************************** +PARAMETERS: +offset - Offset to load data from + +RETURNS: +Word value read from the absolute memory location. + +NOTE: Do not inline this function as (*sys_rdX) is already inline! +****************************************************************************/ +u16 +fetch_data_word(uint offset) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((u16) get_data_segment(), offset); +#endif + return (*sys_rdw) ((get_data_segment() << 4) + offset); +} + +/**************************************************************************** +PARAMETERS: +offset - Offset to load data from + +RETURNS: +Long value read from the absolute memory location. + +NOTE: Do not inline this function as (*sys_rdX) is already inline! +****************************************************************************/ +u32 +fetch_data_long(uint offset) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((u16) get_data_segment(), offset); +#endif + return (*sys_rdl) ((get_data_segment() << 4) + offset); +} + +/**************************************************************************** +PARAMETERS: +segment - Segment to load data from +offset - Offset to load data from + +RETURNS: +Byte value read from the absolute memory location. + +NOTE: Do not inline this function as (*sys_rdX) is already inline! +****************************************************************************/ +u8 +fetch_data_byte_abs(uint segment, uint offset) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); +#endif + return (*sys_rdb) (((u32) segment << 4) + offset); +} + +/**************************************************************************** +PARAMETERS: +segment - Segment to load data from +offset - Offset to load data from + +RETURNS: +Word value read from the absolute memory location. + +NOTE: Do not inline this function as (*sys_rdX) is already inline! +****************************************************************************/ +u16 +fetch_data_word_abs(uint segment, uint offset) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); +#endif + return (*sys_rdw) (((u32) segment << 4) + offset); +} + +/**************************************************************************** +PARAMETERS: +segment - Segment to load data from +offset - Offset to load data from + +RETURNS: +Long value read from the absolute memory location. + +NOTE: Do not inline this function as (*sys_rdX) is already inline! +****************************************************************************/ +u32 +fetch_data_long_abs(uint segment, uint offset) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); +#endif + return (*sys_rdl) (((u32) segment << 4) + offset); +} + +/**************************************************************************** +PARAMETERS: +offset - Offset to store data at +val - Value to store + +REMARKS: +Writes a word value to an segmented memory location. The segment used is +the current 'default' segment, which may have been overridden. + +NOTE: Do not inline this function as (*sys_wrX) is already inline! +****************************************************************************/ +void +store_data_byte(uint offset, u8 val) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((u16) get_data_segment(), offset); +#endif + (*sys_wrb) ((get_data_segment() << 4) + offset, val); +} + +/**************************************************************************** +PARAMETERS: +offset - Offset to store data at +val - Value to store + +REMARKS: +Writes a word value to an segmented memory location. The segment used is +the current 'default' segment, which may have been overridden. + +NOTE: Do not inline this function as (*sys_wrX) is already inline! +****************************************************************************/ +void +store_data_word(uint offset, u16 val) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((u16) get_data_segment(), offset); +#endif + (*sys_wrw) ((get_data_segment() << 4) + offset, val); +} + +/**************************************************************************** +PARAMETERS: +offset - Offset to store data at +val - Value to store + +REMARKS: +Writes a long value to an segmented memory location. The segment used is +the current 'default' segment, which may have been overridden. + +NOTE: Do not inline this function as (*sys_wrX) is already inline! +****************************************************************************/ +void +store_data_long(uint offset, u32 val) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((u16) get_data_segment(), offset); +#endif + (*sys_wrl) ((get_data_segment() << 4) + offset, val); +} + +/**************************************************************************** +PARAMETERS: +segment - Segment to store data at +offset - Offset to store data at +val - Value to store + +REMARKS: +Writes a byte value to an absolute memory location. + +NOTE: Do not inline this function as (*sys_wrX) is already inline! +****************************************************************************/ +void +store_data_byte_abs(uint segment, uint offset, u8 val) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); +#endif + (*sys_wrb) (((u32) segment << 4) + offset, val); +} + +/**************************************************************************** +PARAMETERS: +segment - Segment to store data at +offset - Offset to store data at +val - Value to store + +REMARKS: +Writes a word value to an absolute memory location. + +NOTE: Do not inline this function as (*sys_wrX) is already inline! +****************************************************************************/ +void +store_data_word_abs(uint segment, uint offset, u16 val) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); +#endif + (*sys_wrw) (((u32) segment << 4) + offset, val); +} + +/**************************************************************************** +PARAMETERS: +segment - Segment to store data at +offset - Offset to store data at +val - Value to store + +REMARKS: +Writes a long value to an absolute memory location. + +NOTE: Do not inline this function as (*sys_wrX) is already inline! +****************************************************************************/ +void +store_data_long_abs(uint segment, uint offset, u32 val) +{ +#ifdef DEBUG + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); +#endif + (*sys_wrl) (((u32) segment << 4) + offset, val); +} + +/**************************************************************************** +PARAMETERS: +reg - Register to decode + +RETURNS: +Pointer to the appropriate register + +REMARKS: +Return a pointer to the register given by the R/RM field of the +modrm byte, for byte operands. Also enables the decoding of instructions. +****************************************************************************/ +u8 * +decode_rm_byte_register(int reg) +{ + switch (reg) { + case 0: + DECODE_PRINTF("AL"); + return &M.x86.R_AL; + case 1: + DECODE_PRINTF("CL"); + return &M.x86.R_CL; + case 2: + DECODE_PRINTF("DL"); + return &M.x86.R_DL; + case 3: + DECODE_PRINTF("BL"); + return &M.x86.R_BL; + case 4: + DECODE_PRINTF("AH"); + return &M.x86.R_AH; + case 5: + DECODE_PRINTF("CH"); + return &M.x86.R_CH; + case 6: + DECODE_PRINTF("DH"); + return &M.x86.R_DH; + case 7: + DECODE_PRINTF("BH"); + return &M.x86.R_BH; + } + HALT_SYS(); + return NULL; /* NOT REACHED OR REACHED ON ERROR */ +} + +/**************************************************************************** +PARAMETERS: +reg - Register to decode + +RETURNS: +Pointer to the appropriate register + +REMARKS: +Return a pointer to the register given by the R/RM field of the +modrm byte, for word operands. Also enables the decoding of instructions. +****************************************************************************/ +u16 * +decode_rm_word_register(int reg) +{ + switch (reg) { + case 0: + DECODE_PRINTF("AX"); + return &M.x86.R_AX; + case 1: + DECODE_PRINTF("CX"); + return &M.x86.R_CX; + case 2: + DECODE_PRINTF("DX"); + return &M.x86.R_DX; + case 3: + DECODE_PRINTF("BX"); + return &M.x86.R_BX; + case 4: + DECODE_PRINTF("SP"); + return &M.x86.R_SP; + case 5: + DECODE_PRINTF("BP"); + return &M.x86.R_BP; + case 6: + DECODE_PRINTF("SI"); + return &M.x86.R_SI; + case 7: + DECODE_PRINTF("DI"); + return &M.x86.R_DI; + } + HALT_SYS(); + return NULL; /* NOTREACHED OR REACHED ON ERROR */ +} + +/**************************************************************************** +PARAMETERS: +reg - Register to decode + +RETURNS: +Pointer to the appropriate register + +REMARKS: +Return a pointer to the register given by the R/RM field of the +modrm byte, for dword operands. Also enables the decoding of instructions. +****************************************************************************/ +u32 * +decode_rm_long_register(int reg) +{ + switch (reg) { + case 0: + DECODE_PRINTF("EAX"); + return &M.x86.R_EAX; + case 1: + DECODE_PRINTF("ECX"); + return &M.x86.R_ECX; + case 2: + DECODE_PRINTF("EDX"); + return &M.x86.R_EDX; + case 3: + DECODE_PRINTF("EBX"); + return &M.x86.R_EBX; + case 4: + DECODE_PRINTF("ESP"); + return &M.x86.R_ESP; + case 5: + DECODE_PRINTF("EBP"); + return &M.x86.R_EBP; + case 6: + DECODE_PRINTF("ESI"); + return &M.x86.R_ESI; + case 7: + DECODE_PRINTF("EDI"); + return &M.x86.R_EDI; + } + HALT_SYS(); + return NULL; /* NOTREACHED OR REACHED ON ERROR */ +} + +/**************************************************************************** +PARAMETERS: +reg - Register to decode + +RETURNS: +Pointer to the appropriate register + +REMARKS: +Return a pointer to the register given by the R/RM field of the +modrm byte, for word operands, modified from above for the weirdo +special case of segreg operands. Also enables the decoding of instructions. +****************************************************************************/ +u16 * +decode_rm_seg_register(int reg) +{ + switch (reg) { + case 0: + DECODE_PRINTF("ES"); + return &M.x86.R_ES; + case 1: + DECODE_PRINTF("CS"); + return &M.x86.R_CS; + case 2: + DECODE_PRINTF("SS"); + return &M.x86.R_SS; + case 3: + DECODE_PRINTF("DS"); + return &M.x86.R_DS; + case 4: + DECODE_PRINTF("FS"); + return &M.x86.R_FS; + case 5: + DECODE_PRINTF("GS"); + return &M.x86.R_GS; + case 6: + case 7: + DECODE_PRINTF("ILLEGAL SEGREG"); + break; + } + HALT_SYS(); + return NULL; /* NOT REACHED OR REACHED ON ERROR */ +} + +/* + * + * return offset from the SIB Byte + */ +u32 +decode_sib_address(int sib, int mod) +{ + u32 base = 0, i = 0, scale = 1; + + switch (sib & 0x07) { + case 0: + DECODE_PRINTF("[EAX]"); + base = M.x86.R_EAX; + break; + case 1: + DECODE_PRINTF("[ECX]"); + base = M.x86.R_ECX; + break; + case 2: + DECODE_PRINTF("[EDX]"); + base = M.x86.R_EDX; + break; + case 3: + DECODE_PRINTF("[EBX]"); + base = M.x86.R_EBX; + break; + case 4: + DECODE_PRINTF("[ESP]"); + base = M.x86.R_ESP; + M.x86.mode |= SYSMODE_SEG_DS_SS; + break; + case 5: + if (mod == 0) { + base = fetch_long_imm(); + DECODE_PRINTF2("%08x", base); + } + else { + DECODE_PRINTF("[EBP]"); + base = M.x86.R_ESP; + M.x86.mode |= SYSMODE_SEG_DS_SS; + } + break; + case 6: + DECODE_PRINTF("[ESI]"); + base = M.x86.R_ESI; + break; + case 7: + DECODE_PRINTF("[EDI]"); + base = M.x86.R_EDI; + break; + } + switch ((sib >> 3) & 0x07) { + case 0: + DECODE_PRINTF("[EAX"); + i = M.x86.R_EAX; + break; + case 1: + DECODE_PRINTF("[ECX"); + i = M.x86.R_ECX; + break; + case 2: + DECODE_PRINTF("[EDX"); + i = M.x86.R_EDX; + break; + case 3: + DECODE_PRINTF("[EBX"); + i = M.x86.R_EBX; + break; + case 4: + i = 0; + break; + case 5: + DECODE_PRINTF("[EBP"); + i = M.x86.R_EBP; + break; + case 6: + DECODE_PRINTF("[ESI"); + i = M.x86.R_ESI; + break; + case 7: + DECODE_PRINTF("[EDI"); + i = M.x86.R_EDI; + break; + } + scale = 1 << ((sib >> 6) & 0x03); + if (((sib >> 3) & 0x07) != 4) { + if (scale == 1) { + DECODE_PRINTF("]"); + } + else { + DECODE_PRINTF2("*%d]", scale); + } + } + return base + (i * scale); +} + +/**************************************************************************** +PARAMETERS: +rm - RM value to decode + +RETURNS: +Offset in memory for the address decoding + +REMARKS: +Return the offset given by mod=00 addressing. Also enables the +decoding of instructions. + +NOTE: The code which specifies the corresponding segment (ds vs ss) + below in the case of [BP+..]. The assumption here is that at the + point that this subroutine is called, the bit corresponding to + SYSMODE_SEG_DS_SS will be zero. After every instruction + except the segment override instructions, this bit (as well + as any bits indicating segment overrides) will be clear. So + if a SS access is needed, set this bit. Otherwise, DS access + occurs (unless any of the segment override bits are set). +****************************************************************************/ +u32 +decode_rm00_address(int rm) +{ + u32 offset; + int sib; + + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + /* 32-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF("[EAX]"); + return M.x86.R_EAX; + case 1: + DECODE_PRINTF("[ECX]"); + return M.x86.R_ECX; + case 2: + DECODE_PRINTF("[EDX]"); + return M.x86.R_EDX; + case 3: + DECODE_PRINTF("[EBX]"); + return M.x86.R_EBX; + case 4: + sib = fetch_byte_imm(); + return decode_sib_address(sib, 0); + case 5: + offset = fetch_long_imm(); + DECODE_PRINTF2("[%08x]", offset); + return offset; + case 6: + DECODE_PRINTF("[ESI]"); + return M.x86.R_ESI; + case 7: + DECODE_PRINTF("[EDI]"); + return M.x86.R_EDI; + } + HALT_SYS(); + } + else { + /* 16-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF("[BX+SI]"); + return (M.x86.R_BX + M.x86.R_SI) & 0xffff; + case 1: + DECODE_PRINTF("[BX+DI]"); + return (M.x86.R_BX + M.x86.R_DI) & 0xffff; + case 2: + DECODE_PRINTF("[BP+SI]"); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_SI) & 0xffff; + case 3: + DECODE_PRINTF("[BP+DI]"); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_DI) & 0xffff; + case 4: + DECODE_PRINTF("[SI]"); + return M.x86.R_SI; + case 5: + DECODE_PRINTF("[DI]"); + return M.x86.R_DI; + case 6: + offset = fetch_word_imm(); + DECODE_PRINTF2("[%04x]", offset); + return offset; + case 7: + DECODE_PRINTF("[BX]"); + return M.x86.R_BX; + } + HALT_SYS(); + } + return 0; +} + +/**************************************************************************** +PARAMETERS: +rm - RM value to decode + +RETURNS: +Offset in memory for the address decoding + +REMARKS: +Return the offset given by mod=01 addressing. Also enables the +decoding of instructions. +****************************************************************************/ +u32 +decode_rm01_address(int rm) +{ + int displacement = 0; + int sib; + + /* Fetch disp8 if no SIB byte */ + if (!((M.x86.mode & SYSMODE_PREFIX_ADDR) && (rm == 4))) + displacement = (s8) fetch_byte_imm(); + + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + /* 32-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF2("%d[EAX]", displacement); + return M.x86.R_EAX + displacement; + case 1: + DECODE_PRINTF2("%d[ECX]", displacement); + return M.x86.R_ECX + displacement; + case 2: + DECODE_PRINTF2("%d[EDX]", displacement); + return M.x86.R_EDX + displacement; + case 3: + DECODE_PRINTF2("%d[EBX]", displacement); + return M.x86.R_EBX + displacement; + case 4: + sib = fetch_byte_imm(); + displacement = (s8) fetch_byte_imm(); + DECODE_PRINTF2("%d", displacement); + return decode_sib_address(sib, 1) + displacement; + case 5: + DECODE_PRINTF2("%d[EBP]", displacement); + return M.x86.R_EBP + displacement; + case 6: + DECODE_PRINTF2("%d[ESI]", displacement); + return M.x86.R_ESI + displacement; + case 7: + DECODE_PRINTF2("%d[EDI]", displacement); + return M.x86.R_EDI + displacement; + } + HALT_SYS(); + } + else { + /* 16-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF2("%d[BX+SI]", displacement); + return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; + case 1: + DECODE_PRINTF2("%d[BX+DI]", displacement); + return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; + case 2: + DECODE_PRINTF2("%d[BP+SI]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; + case 3: + DECODE_PRINTF2("%d[BP+DI]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; + case 4: + DECODE_PRINTF2("%d[SI]", displacement); + return (M.x86.R_SI + displacement) & 0xffff; + case 5: + DECODE_PRINTF2("%d[DI]", displacement); + return (M.x86.R_DI + displacement) & 0xffff; + case 6: + DECODE_PRINTF2("%d[BP]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + displacement) & 0xffff; + case 7: + DECODE_PRINTF2("%d[BX]", displacement); + return (M.x86.R_BX + displacement) & 0xffff; + } + HALT_SYS(); + } + return 0; /* SHOULD NOT HAPPEN */ +} + +/**************************************************************************** +PARAMETERS: +rm - RM value to decode + +RETURNS: +Offset in memory for the address decoding + +REMARKS: +Return the offset given by mod=10 addressing. Also enables the +decoding of instructions. +****************************************************************************/ +u32 +decode_rm10_address(int rm) +{ + u32 displacement = 0; + int sib; + + /* Fetch disp16 if 16-bit addr mode */ + if (!(M.x86.mode & SYSMODE_PREFIX_ADDR)) + displacement = (u16) fetch_word_imm(); + else { + /* Fetch disp32 if no SIB byte */ + if (rm != 4) + displacement = (u32) fetch_long_imm(); + } + + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + /* 32-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF2("%08x[EAX]", displacement); + return M.x86.R_EAX + displacement; + case 1: + DECODE_PRINTF2("%08x[ECX]", displacement); + return M.x86.R_ECX + displacement; + case 2: + DECODE_PRINTF2("%08x[EDX]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return M.x86.R_EDX + displacement; + case 3: + DECODE_PRINTF2("%08x[EBX]", displacement); + return M.x86.R_EBX + displacement; + case 4: + sib = fetch_byte_imm(); + displacement = (u32) fetch_long_imm(); + DECODE_PRINTF2("%08x", displacement); + return decode_sib_address(sib, 2) + displacement; + break; + case 5: + DECODE_PRINTF2("%08x[EBP]", displacement); + return M.x86.R_EBP + displacement; + case 6: + DECODE_PRINTF2("%08x[ESI]", displacement); + return M.x86.R_ESI + displacement; + case 7: + DECODE_PRINTF2("%08x[EDI]", displacement); + return M.x86.R_EDI + displacement; + } + HALT_SYS(); + } + else { + /* 16-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF2("%04x[BX+SI]", displacement); + return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; + case 1: + DECODE_PRINTF2("%04x[BX+DI]", displacement); + return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; + case 2: + DECODE_PRINTF2("%04x[BP+SI]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; + case 3: + DECODE_PRINTF2("%04x[BP+DI]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; + case 4: + DECODE_PRINTF2("%04x[SI]", displacement); + return (M.x86.R_SI + displacement) & 0xffff; + case 5: + DECODE_PRINTF2("%04x[DI]", displacement); + return (M.x86.R_DI + displacement) & 0xffff; + case 6: + DECODE_PRINTF2("%04x[BP]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + displacement) & 0xffff; + case 7: + DECODE_PRINTF2("%04x[BX]", displacement); + return (M.x86.R_BX + displacement) & 0xffff; + } + HALT_SYS(); + } + return 0; + /*NOTREACHED */ +} diff --git a/src/libs/x86emu/fpu.c b/src/libs/x86emu/fpu.c new file mode 100644 index 0000000000..0dab05ce38 --- /dev/null +++ b/src/libs/x86emu/fpu.c @@ -0,0 +1,976 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: This file contains the code to implement the decoding and +* emulation of the FPU instructions. +* +****************************************************************************/ + +#include "x86emu/x86emui.h" + +/*----------------------------- Implementation ----------------------------*/ + +/* opcode=0xd8 */ +void +x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("ESC D8\n"); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR_NO_TRACE(); +} + +#ifdef DEBUG + +static const char *x86emu_fpu_op_d9_tab[] = { + "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ", + "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t", + + "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ", + "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t", + + "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ", + "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t", +}; + +static const char *x86emu_fpu_op_d9_tab1[] = { + "FLD\t", "FLD\t", "FLD\t", "FLD\t", + "FLD\t", "FLD\t", "FLD\t", "FLD\t", + + "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t", + "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t", + + "FNOP", "ESC_D9", "ESC_D9", "ESC_D9", + "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9", + + "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t", + "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t", + + "FCHS", "FABS", "ESC_D9", "ESC_D9", + "FTST", "FXAM", "ESC_D9", "ESC_D9", + + "FLD1", "FLDL2T", "FLDL2E", "FLDPI", + "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9", + + "F2XM1", "FYL2X", "FPTAN", "FPATAN", + "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP", + + "FPREM", "FYL2XP1", "FSQRT", "ESC_D9", + "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9", +}; + +#endif /* DEBUG */ + +/* opcode=0xd9 */ +void +x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset = 0; + u8 stkelem = 0; + + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (mod != 3) { + DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl); + } + else { + DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]); + } +#endif + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + break; + case 3: /* register to register */ + stkelem = (u8) rl; + if (rh < 4) { + DECODE_PRINTF2("ST(%d)\n", stkelem); + } + else { + DECODE_PRINTF("\n"); + } + break; + } +#ifdef X86EMU_FPU_PRESENT + /* execute */ + switch (mod) { + case 3: + switch (rh) { + case 0: + x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem); + break; + case 1: + x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem); + break; + case 2: + switch (rl) { + case 0: + x86emu_fpu_R_nop(); + break; + default: + x86emu_fpu_illegal(); + break; + } + case 3: + x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem); + break; + case 4: + switch (rl) { + case 0: + x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP); + break; + case 1: + x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP); + break; + case 4: + x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP); + break; + case 5: + x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP); + break; + default: + /* 2,3,6,7 */ + x86emu_fpu_illegal(); + break; + } + break; + + case 5: + switch (rl) { + case 0: + x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP); + break; + case 1: + x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP); + break; + case 2: + x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP); + break; + case 3: + x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP); + break; + case 4: + x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP); + break; + case 5: + x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP); + break; + case 6: + x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP); + break; + default: + /* 7 */ + x86emu_fpu_illegal(); + break; + } + break; + + case 6: + switch (rl) { + case 0: + x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP); + break; + case 1: + x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP); + break; + case 2: + x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP); + break; + case 3: + x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP); + break; + case 4: + x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP); + break; + case 5: + x86emu_fpu_illegal(); + break; + case 6: + x86emu_fpu_R_decstp(); + break; + case 7: + x86emu_fpu_R_incstp(); + break; + } + break; + + case 7: + switch (rl) { + case 0: + x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP); + break; + case 1: + x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP); + break; + case 2: + x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP); + break; + case 3: + x86emu_fpu_illegal(); + break; + case 4: + x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP); + break; + case 5: + x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP); + break; + case 6: + case 7: + default: + x86emu_fpu_illegal(); + break; + } + break; + + default: + switch (rh) { + case 0: + x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset); + break; + case 1: + x86emu_fpu_illegal(); + break; + case 2: + x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset); + break; + case 3: + x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset); + break; + case 4: + x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset); + break; + case 5: + x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset); + break; + case 6: + x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset); + break; + case 7: + x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset); + break; + } + } + } +#else + (void) destoffset; + (void) stkelem; +#endif /* X86EMU_FPU_PRESENT */ + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR_NO_TRACE(); +} + +#ifdef DEBUG + +static const char *x86emu_fpu_op_da_tab[] = { + "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ", + "FICOMP\tDWORD PTR ", + "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ", + "FIDIVR\tDWORD PTR ", + + "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ", + "FICOMP\tDWORD PTR ", + "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ", + "FIDIVR\tDWORD PTR ", + + "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ", + "FICOMP\tDWORD PTR ", + "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ", + "FIDIVR\tDWORD PTR ", + + "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ", + "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ", +}; + +#endif /* DEBUG */ + +/* opcode=0xda */ +void +x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset = 0; + u8 stkelem = 0; + + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); + DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + break; + case 3: /* register to register */ + stkelem = (u8) rl; + DECODE_PRINTF2("\tST(%d),ST\n", stkelem); + break; + } +#ifdef X86EMU_FPU_PRESENT + switch (mod) { + case 3: + x86emu_fpu_illegal(); + break; + default: + switch (rh) { + case 0: + x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset); + break; + case 1: + x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset); + break; + case 2: + x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset); + break; + case 3: + x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset); + break; + case 4: + x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset); + break; + case 5: + x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset); + break; + case 6: + x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset); + break; + case 7: + x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset); + break; + } + } +#else + (void) destoffset; + (void) stkelem; +#endif + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR_NO_TRACE(); +} + +#ifdef DEBUG + +static const char *x86emu_fpu_op_db_tab[] = { + "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ", + "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ", + + "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ", + "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ", + + "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ", + "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ", +}; + +#endif /* DEBUG */ + +/* opcode=0xdb */ +void +x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset = 0; + + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (mod != 3) { + DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl); + } + else if (rh == 4) { /* === 11 10 0 nnn */ + switch (rl) { + case 0: + DECODE_PRINTF("FENI\n"); + break; + case 1: + DECODE_PRINTF("FDISI\n"); + break; + case 2: + DECODE_PRINTF("FCLEX\n"); + break; + case 3: + DECODE_PRINTF("FINIT\n"); + break; + } + } + else { + DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl)); + } +#endif /* DEBUG */ + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + break; + case 1: + destoffset = decode_rm01_address(rl); + break; + case 2: + destoffset = decode_rm10_address(rl); + break; + case 3: /* register to register */ + break; + } +#ifdef X86EMU_FPU_PRESENT + /* execute */ + switch (mod) { + case 3: + switch (rh) { + case 4: + switch (rl) { + case 0: + x86emu_fpu_R_feni(); + break; + case 1: + x86emu_fpu_R_fdisi(); + break; + case 2: + x86emu_fpu_R_fclex(); + break; + case 3: + x86emu_fpu_R_finit(); + break; + default: + x86emu_fpu_illegal(); + break; + } + break; + default: + x86emu_fpu_illegal(); + break; + } + break; + default: + switch (rh) { + case 0: + x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset); + break; + case 1: + x86emu_fpu_illegal(); + break; + case 2: + x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset); + break; + case 3: + x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset); + break; + case 4: + x86emu_fpu_illegal(); + break; + case 5: + x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset); + break; + case 6: + x86emu_fpu_illegal(); + break; + case 7: + x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset); + break; + } + } +#else + (void) destoffset; +#endif + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR_NO_TRACE(); +} + +#ifdef DEBUG +static const char *x86emu_fpu_op_dc_tab[] = { + "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ", + "FCOMP\tQWORD PTR ", + "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ", + "FDIVR\tQWORD PTR ", + + "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ", + "FCOMP\tQWORD PTR ", + "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ", + "FDIVR\tQWORD PTR ", + + "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ", + "FCOMP\tQWORD PTR ", + "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ", + "FDIVR\tQWORD PTR ", + + "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t", + "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t", +}; +#endif /* DEBUG */ + +/* opcode=0xdc */ +void +x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset = 0; + u8 stkelem = 0; + + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); + DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + break; + case 3: /* register to register */ + stkelem = (u8) rl; + DECODE_PRINTF2("\tST(%d),ST\n", stkelem); + break; + } +#ifdef X86EMU_FPU_PRESENT + /* execute */ + switch (mod) { + case 3: + switch (rh) { + case 0: + x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP); + break; + case 1: + x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP); + break; + case 2: + x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP); + break; + case 3: + x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP); + break; + case 4: + x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP); + break; + case 5: + x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP); + break; + case 6: + x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP); + break; + case 7: + x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP); + break; + } + break; + default: + switch (rh) { + case 0: + x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset); + break; + case 1: + x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset); + break; + case 2: + x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset); + break; + case 3: + x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset); + break; + case 4: + x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset); + break; + case 5: + x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset); + break; + case 6: + x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset); + break; + case 7: + x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset); + break; + } + } +#else + (void) destoffset; + (void) stkelem; +#endif + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR_NO_TRACE(); +} + +#ifdef DEBUG + +static const char *x86emu_fpu_op_dd_tab[] = { + "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ", + "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t", + + "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ", + "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t", + + "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ", + "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t", + + "FFREE\t", "FXCH\t", "FST\t", "FSTP\t", + "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,", +}; + +#endif /* DEBUG */ + +/* opcode=0xdd */ +void +x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset = 0; + u8 stkelem = 0; + + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); + DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + break; + case 3: /* register to register */ + stkelem = (u8) rl; + DECODE_PRINTF2("\tST(%d),ST\n", stkelem); + break; + } +#ifdef X86EMU_FPU_PRESENT + switch (mod) { + case 3: + switch (rh) { + case 0: + x86emu_fpu_R_ffree(stkelem); + break; + case 1: + x86emu_fpu_R_fxch(stkelem); + break; + case 2: + x86emu_fpu_R_fst(stkelem); /* register version */ + break; + case 3: + x86emu_fpu_R_fstp(stkelem); /* register version */ + break; + default: + x86emu_fpu_illegal(); + break; + } + break; + default: + switch (rh) { + case 0: + x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset); + break; + case 1: + x86emu_fpu_illegal(); + break; + case 2: + x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset); + break; + case 3: + x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset); + break; + case 4: + x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset); + break; + case 5: + x86emu_fpu_illegal(); + break; + case 6: + x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset); + break; + case 7: + x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset); + break; + } + } +#else + (void) destoffset; + (void) stkelem; +#endif + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR_NO_TRACE(); +} + +#ifdef DEBUG + +static const char *x86emu_fpu_op_de_tab[] = { + "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ", + "FICOMP\tWORD PTR ", + "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ", + "FIDIVR\tWORD PTR ", + + "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ", + "FICOMP\tWORD PTR ", + "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ", + "FIDIVR\tWORD PTR ", + + "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ", + "FICOMP\tWORD PTR ", + "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ", + "FIDIVR\tWORD PTR ", + + "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t", + "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t", +}; + +#endif /* DEBUG */ + +/* opcode=0xde */ +void +x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset = 0; + u8 stkelem = 0; + + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); + DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + break; + case 3: /* register to register */ + stkelem = (u8) rl; + DECODE_PRINTF2("\tST(%d),ST\n", stkelem); + break; + } +#ifdef X86EMU_FPU_PRESENT + switch (mod) { + case 3: + switch (rh) { + case 0: + x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP); + break; + case 1: + x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP); + break; + case 2: + x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP); + break; + case 3: + if (stkelem == 1) + x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP); + else + x86emu_fpu_illegal(); + break; + case 4: + x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP); + break; + case 5: + x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP); + break; + case 6: + x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP); + break; + case 7: + x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP); + break; + } + break; + default: + switch (rh) { + case 0: + x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset); + break; + case 1: + x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset); + break; + case 2: + x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset); + break; + case 3: + x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset); + break; + case 4: + x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset); + break; + case 5: + x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset); + break; + case 6: + x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset); + break; + case 7: + x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset); + break; + } + } +#else + (void) destoffset; + (void) stkelem; +#endif + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR_NO_TRACE(); +} + +#ifdef DEBUG + +static const char *x86emu_fpu_op_df_tab[] = { + /* mod == 00 */ + "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ", + "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ", + "FISTP\tQWORD PTR ", + + /* mod == 01 */ + "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ", + "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ", + "FISTP\tQWORD PTR ", + + /* mod == 10 */ + "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ", + "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ", + "FISTP\tQWORD PTR ", + + /* mod == 11 */ + "FFREE\t", "FXCH\t", "FST\t", "FSTP\t", + "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F," +}; + +#endif /* DEBUG */ + +/* opcode=0xdf */ +void +x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset = 0; + u8 stkelem = 0; + + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); + DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + break; + case 3: /* register to register */ + stkelem = (u8) rl; + DECODE_PRINTF2("\tST(%d)\n", stkelem); + break; + } +#ifdef X86EMU_FPU_PRESENT + switch (mod) { + case 3: + switch (rh) { + case 0: + x86emu_fpu_R_ffree(stkelem); + break; + case 1: + x86emu_fpu_R_fxch(stkelem); + break; + case 2: + x86emu_fpu_R_fst(stkelem); /* register version */ + break; + case 3: + x86emu_fpu_R_fstp(stkelem); /* register version */ + break; + default: + x86emu_fpu_illegal(); + break; + } + break; + default: + switch (rh) { + case 0: + x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset); + break; + case 1: + x86emu_fpu_illegal(); + break; + case 2: + x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset); + break; + case 3: + x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset); + break; + case 4: + x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset); + break; + case 5: + x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset); + break; + case 6: + x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset); + break; + case 7: + x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset); + break; + } + } +#else + (void) destoffset; + (void) stkelem; +#endif + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR_NO_TRACE(); +} diff --git a/src/libs/x86emu/ops.c b/src/libs/x86emu/ops.c new file mode 100644 index 0000000000..8af1df47a8 --- /dev/null +++ b/src/libs/x86emu/ops.c @@ -0,0 +1,12307 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: This file includes subroutines to implement the decoding +* and emulation of all the x86 processor instructions. +* +* There are approximately 250 subroutines in here, which correspond +* to the 256 byte-"opcodes" found on the 8086. The table which +* dispatches this is found in the files optab.[ch]. +* +* Each opcode proc has a comment preceeding it which gives it's table +* address. Several opcodes are missing (undefined) in the table. +* +* Each proc includes information for decoding (DECODE_PRINTF and +* DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc +* functions (START_OF_INSTR, END_OF_INSTR). +* +* Many of the procedures are *VERY* similar in coding. This has +* allowed for a very large amount of code to be generated in a fairly +* short amount of time (i.e. cut, paste, and modify). The result is +* that much of the code below could have been folded into subroutines +* for a large reduction in size of this file. The downside would be +* that there would be a penalty in execution speed. The file could +* also have been *MUCH* larger by inlining certain functions which +* were called. This could have resulted even faster execution. The +* prime directive I used to decide whether to inline the code or to +* modularize it, was basically: 1) no unnecessary subroutine calls, +* 2) no routines more than about 200 lines in size, and 3) modularize +* any code that I might not get right the first time. The fetch_* +* subroutines fall into the latter category. The The decode_* fall +* into the second category. The coding of the "switch(mod){ .... }" +* in many of the subroutines below falls into the first category. +* Especially, the coding of {add,and,or,sub,...}_{byte,word} +* subroutines are an especially glaring case of the third guideline. +* Since so much of the code is cloned from other modules (compare +* opcode #00 to opcode #01), making the basic operations subroutine +* calls is especially important; otherwise mistakes in coding an +* "add" would represent a nightmare in maintenance. +* +****************************************************************************/ + +#include "x86emu/x86emui.h" + +/*----------------------------- Implementation ----------------------------*/ + +/**************************************************************************** +PARAMETERS: +op1 - Instruction op code + +REMARKS: +Handles illegal opcodes. +****************************************************************************/ +static void +x86emuOp_illegal_op(u8 op1) +{ + START_OF_INSTR(); + if (M.x86.R_SP != 0) { + DECODE_PRINTF("ILLEGAL X86 OPCODE\n"); + TRACE_REGS(); + DB(printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", + M.x86.R_CS, M.x86.R_IP - 1, op1)); + HALT_SYS(); + } + else { + /* If we get here, it means the stack pointer is back to zero + * so we are just returning from an emulator service call + * so therte is no need to display an error message. We trap + * the emulator with an 0xF1 opcode to finish the service + * call. + */ + X86EMU_halt_sys(); + } + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x00 +****************************************************************************/ +static void +x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + u8 *destreg, *srcreg; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("ADD\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x01 +****************************************************************************/ +static void +x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("ADD\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = add_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x02 +****************************************************************************/ +static void +x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("ADD\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_byte(*destreg, srcval); + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_byte(*destreg, srcval); + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_byte(*destreg, srcval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x03 +****************************************************************************/ +static void +x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("ADD\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_word(*destreg, srcval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_word(*destreg, srcval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_word(*destreg, srcval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = add_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x04 +****************************************************************************/ +static void +x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("ADD\tAL,"); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + M.x86.R_AL = add_byte(M.x86.R_AL, srcval); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x05 +****************************************************************************/ +static void +x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("ADD\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("ADD\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = add_long(M.x86.R_EAX, srcval); + } + else { + M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x06 +****************************************************************************/ +static void +x86emuOp_push_ES(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("PUSH\tES\n"); + TRACE_AND_STEP(); + push_word(M.x86.R_ES); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x07 +****************************************************************************/ +static void +x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("POP\tES\n"); + TRACE_AND_STEP(); + M.x86.R_ES = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x08 +****************************************************************************/ +static void +x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("OR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x09 +****************************************************************************/ +static void +x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("OR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = or_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0a +****************************************************************************/ +static void +x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("OR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_byte(*destreg, srcval); + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_byte(*destreg, srcval); + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_byte(*destreg, srcval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0b +****************************************************************************/ +static void +x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("OR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_word(*destreg, srcval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_word(*destreg, srcval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_word(*destreg, srcval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = or_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0c +****************************************************************************/ +static void +x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("OR\tAL,"); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + M.x86.R_AL = or_byte(M.x86.R_AL, srcval); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0d +****************************************************************************/ +static void +x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("OR\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("OR\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = or_long(M.x86.R_EAX, srcval); + } + else { + M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0e +****************************************************************************/ +static void +x86emuOp_push_CS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("PUSH\tCS\n"); + TRACE_AND_STEP(); + push_word(M.x86.R_CS); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f. Escape for two-byte opcode (286 or better) +****************************************************************************/ +static void +x86emuOp_two_byte(u8 X86EMU_UNUSED(op1)) +{ + u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++)); + + INC_DECODED_INST_LEN(1); + (*x86emu_optab2[op2]) (op2); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x10 +****************************************************************************/ +static void +x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("ADC\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x11 +****************************************************************************/ +static void +x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("ADC\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = adc_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x12 +****************************************************************************/ +static void +x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("ADC\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_byte(*destreg, srcval); + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_byte(*destreg, srcval); + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_byte(*destreg, srcval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x13 +****************************************************************************/ +static void +x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("ADC\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_word(*destreg, srcval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_word(*destreg, srcval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_word(*destreg, srcval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = adc_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x14 +****************************************************************************/ +static void +x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("ADC\tAL,"); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + M.x86.R_AL = adc_byte(M.x86.R_AL, srcval); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x15 +****************************************************************************/ +static void +x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("ADC\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("ADC\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval); + } + else { + M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x16 +****************************************************************************/ +static void +x86emuOp_push_SS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("PUSH\tSS\n"); + TRACE_AND_STEP(); + push_word(M.x86.R_SS); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x17 +****************************************************************************/ +static void +x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("POP\tSS\n"); + TRACE_AND_STEP(); + M.x86.R_SS = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x18 +****************************************************************************/ +static void +x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("SBB\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x19 +****************************************************************************/ +static void +x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("SBB\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sbb_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x1a +****************************************************************************/ +static void +x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("SBB\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_byte(*destreg, srcval); + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_byte(*destreg, srcval); + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_byte(*destreg, srcval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x1b +****************************************************************************/ +static void +x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("SBB\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_word(*destreg, srcval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_word(*destreg, srcval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_word(*destreg, srcval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sbb_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x1c +****************************************************************************/ +static void +x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("SBB\tAL,"); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x1d +****************************************************************************/ +static void +x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("SBB\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("SBB\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval); + } + else { + M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x1e +****************************************************************************/ +static void +x86emuOp_push_DS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("PUSH\tDS\n"); + TRACE_AND_STEP(); + push_word(M.x86.R_DS); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x1f +****************************************************************************/ +static void +x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("POP\tDS\n"); + TRACE_AND_STEP(); + M.x86.R_DS = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x20 +****************************************************************************/ +static void +x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("AND\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x21 +****************************************************************************/ +static void +x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("AND\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = and_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x22 +****************************************************************************/ +static void +x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("AND\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_byte(*destreg, srcval); + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_byte(*destreg, srcval); + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_byte(*destreg, srcval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x23 +****************************************************************************/ +static void +x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("AND\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_word(*destreg, srcval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_long(*destreg, srcval); + break; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_word(*destreg, srcval); + break; + } + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_word(*destreg, srcval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = and_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x24 +****************************************************************************/ +static void +x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("AND\tAL,"); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + M.x86.R_AL = and_byte(M.x86.R_AL, srcval); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x25 +****************************************************************************/ +static void +x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("AND\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("AND\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = and_long(M.x86.R_EAX, srcval); + } + else { + M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x26 +****************************************************************************/ +static void +x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("ES:\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_SEGOVR_ES; + /* + * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 + * opcode subroutines we do not want to do this. + */ + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x27 +****************************************************************************/ +static void +x86emuOp_daa(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("DAA\n"); + TRACE_AND_STEP(); + M.x86.R_AL = daa_byte(M.x86.R_AL); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x28 +****************************************************************************/ +static void +x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("SUB\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x29 +****************************************************************************/ +static void +x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("SUB\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = sub_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x2a +****************************************************************************/ +static void +x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("SUB\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_byte(*destreg, srcval); + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_byte(*destreg, srcval); + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_byte(*destreg, srcval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x2b +****************************************************************************/ +static void +x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("SUB\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_word(*destreg, srcval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_word(*destreg, srcval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_word(*destreg, srcval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = sub_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x2c +****************************************************************************/ +static void +x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("SUB\tAL,"); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + M.x86.R_AL = sub_byte(M.x86.R_AL, srcval); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x2d +****************************************************************************/ +static void +x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("SUB\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("SUB\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval); + } + else { + M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x2e +****************************************************************************/ +static void +x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("CS:\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_SEGOVR_CS; + /* note no DECODE_CLEAR_SEGOVR here. */ + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x2f +****************************************************************************/ +static void +x86emuOp_das(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("DAS\n"); + TRACE_AND_STEP(); + M.x86.R_AL = das_byte(M.x86.R_AL); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x30 +****************************************************************************/ +static void +x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("XOR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_byte(destval, *srcreg); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x31 +****************************************************************************/ +static void +x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("XOR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_long(destval, *srcreg); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = xor_word(destval, *srcreg); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x32 +****************************************************************************/ +static void +x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("XOR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_byte(*destreg, srcval); + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_byte(*destreg, srcval); + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_byte(*destreg, srcval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x33 +****************************************************************************/ +static void +x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("XOR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_word(*destreg, srcval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_word(*destreg, srcval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_word(*destreg, srcval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = xor_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x34 +****************************************************************************/ +static void +x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("XOR\tAL,"); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + M.x86.R_AL = xor_byte(M.x86.R_AL, srcval); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x35 +****************************************************************************/ +static void +x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("XOR\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("XOR\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval); + } + else { + M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x36 +****************************************************************************/ +static void +x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("SS:\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_SEGOVR_SS; + /* no DECODE_CLEAR_SEGOVR ! */ + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x37 +****************************************************************************/ +static void +x86emuOp_aaa(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("AAA\n"); + TRACE_AND_STEP(); + M.x86.R_AX = aaa_word(M.x86.R_AX); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x38 +****************************************************************************/ +static void +x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + u8 *destreg, *srcreg; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("CMP\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_byte(destval, *srcreg); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_byte(destval, *srcreg); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_byte(destval, *srcreg); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x39 +****************************************************************************/ +static void +x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("CMP\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_long(destval, *srcreg); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_word(destval, *srcreg); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_long(destval, *srcreg); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_word(destval, *srcreg); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_long(destval, *srcreg); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_word(destval, *srcreg); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x3a +****************************************************************************/ +static void +x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("CMP\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_byte(*destreg, srcval); + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_byte(*destreg, srcval); + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_byte(*destreg, srcval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x3b +****************************************************************************/ +static void +x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("CMP\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_word(*destreg, srcval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_word(*destreg, srcval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_word(*destreg, srcval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + cmp_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x3c +****************************************************************************/ +static void +x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("CMP\tAL,"); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + cmp_byte(M.x86.R_AL, srcval); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x3d +****************************************************************************/ +static void +x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("CMP\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("CMP\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + cmp_long(M.x86.R_EAX, srcval); + } + else { + cmp_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x3e +****************************************************************************/ +static void +x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("DS:\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_SEGOVR_DS; + /* NO DECODE_CLEAR_SEGOVR! */ + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x3f +****************************************************************************/ +static void +x86emuOp_aas(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("AAS\n"); + TRACE_AND_STEP(); + M.x86.R_AX = aas_word(M.x86.R_AX); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x40 +****************************************************************************/ +static void +x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tEAX\n"); + } + else { + DECODE_PRINTF("INC\tAX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = inc_long(M.x86.R_EAX); + } + else { + M.x86.R_AX = inc_word(M.x86.R_AX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x41 +****************************************************************************/ +static void +x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tECX\n"); + } + else { + DECODE_PRINTF("INC\tCX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ECX = inc_long(M.x86.R_ECX); + } + else { + M.x86.R_CX = inc_word(M.x86.R_CX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x42 +****************************************************************************/ +static void +x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tEDX\n"); + } + else { + DECODE_PRINTF("INC\tDX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDX = inc_long(M.x86.R_EDX); + } + else { + M.x86.R_DX = inc_word(M.x86.R_DX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x43 +****************************************************************************/ +static void +x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tEBX\n"); + } + else { + DECODE_PRINTF("INC\tBX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EBX = inc_long(M.x86.R_EBX); + } + else { + M.x86.R_BX = inc_word(M.x86.R_BX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x44 +****************************************************************************/ +static void +x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tESP\n"); + } + else { + DECODE_PRINTF("INC\tSP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ESP = inc_long(M.x86.R_ESP); + } + else { + M.x86.R_SP = inc_word(M.x86.R_SP); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x45 +****************************************************************************/ +static void +x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tEBP\n"); + } + else { + DECODE_PRINTF("INC\tBP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EBP = inc_long(M.x86.R_EBP); + } + else { + M.x86.R_BP = inc_word(M.x86.R_BP); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x46 +****************************************************************************/ +static void +x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tESI\n"); + } + else { + DECODE_PRINTF("INC\tSI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ESI = inc_long(M.x86.R_ESI); + } + else { + M.x86.R_SI = inc_word(M.x86.R_SI); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x47 +****************************************************************************/ +static void +x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tEDI\n"); + } + else { + DECODE_PRINTF("INC\tDI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDI = inc_long(M.x86.R_EDI); + } + else { + M.x86.R_DI = inc_word(M.x86.R_DI); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x48 +****************************************************************************/ +static void +x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tEAX\n"); + } + else { + DECODE_PRINTF("DEC\tAX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = dec_long(M.x86.R_EAX); + } + else { + M.x86.R_AX = dec_word(M.x86.R_AX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x49 +****************************************************************************/ +static void +x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tECX\n"); + } + else { + DECODE_PRINTF("DEC\tCX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ECX = dec_long(M.x86.R_ECX); + } + else { + M.x86.R_CX = dec_word(M.x86.R_CX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x4a +****************************************************************************/ +static void +x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tEDX\n"); + } + else { + DECODE_PRINTF("DEC\tDX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDX = dec_long(M.x86.R_EDX); + } + else { + M.x86.R_DX = dec_word(M.x86.R_DX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x4b +****************************************************************************/ +static void +x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tEBX\n"); + } + else { + DECODE_PRINTF("DEC\tBX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EBX = dec_long(M.x86.R_EBX); + } + else { + M.x86.R_BX = dec_word(M.x86.R_BX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x4c +****************************************************************************/ +static void +x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tESP\n"); + } + else { + DECODE_PRINTF("DEC\tSP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ESP = dec_long(M.x86.R_ESP); + } + else { + M.x86.R_SP = dec_word(M.x86.R_SP); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x4d +****************************************************************************/ +static void +x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tEBP\n"); + } + else { + DECODE_PRINTF("DEC\tBP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EBP = dec_long(M.x86.R_EBP); + } + else { + M.x86.R_BP = dec_word(M.x86.R_BP); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x4e +****************************************************************************/ +static void +x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tESI\n"); + } + else { + DECODE_PRINTF("DEC\tSI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ESI = dec_long(M.x86.R_ESI); + } + else { + M.x86.R_SI = dec_word(M.x86.R_SI); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x4f +****************************************************************************/ +static void +x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tEDI\n"); + } + else { + DECODE_PRINTF("DEC\tDI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDI = dec_long(M.x86.R_EDI); + } + else { + M.x86.R_DI = dec_word(M.x86.R_DI); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x50 +****************************************************************************/ +static void +x86emuOp_push_AX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSH\tEAX\n"); + } + else { + DECODE_PRINTF("PUSH\tAX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_EAX); + } + else { + push_word(M.x86.R_AX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x51 +****************************************************************************/ +static void +x86emuOp_push_CX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSH\tECX\n"); + } + else { + DECODE_PRINTF("PUSH\tCX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_ECX); + } + else { + push_word(M.x86.R_CX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x52 +****************************************************************************/ +static void +x86emuOp_push_DX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSH\tEDX\n"); + } + else { + DECODE_PRINTF("PUSH\tDX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_EDX); + } + else { + push_word(M.x86.R_DX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x53 +****************************************************************************/ +static void +x86emuOp_push_BX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSH\tEBX\n"); + } + else { + DECODE_PRINTF("PUSH\tBX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_EBX); + } + else { + push_word(M.x86.R_BX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x54 +****************************************************************************/ +static void +x86emuOp_push_SP(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSH\tESP\n"); + } + else { + DECODE_PRINTF("PUSH\tSP\n"); + } + TRACE_AND_STEP(); + /* Always push (E)SP, since we are emulating an i386 and above + * processor. This is necessary as some BIOS'es use this to check + * what type of processor is in the system. + */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_ESP); + } + else { + push_word((u16) (M.x86.R_SP)); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x55 +****************************************************************************/ +static void +x86emuOp_push_BP(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSH\tEBP\n"); + } + else { + DECODE_PRINTF("PUSH\tBP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_EBP); + } + else { + push_word(M.x86.R_BP); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x56 +****************************************************************************/ +static void +x86emuOp_push_SI(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSH\tESI\n"); + } + else { + DECODE_PRINTF("PUSH\tSI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_ESI); + } + else { + push_word(M.x86.R_SI); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x57 +****************************************************************************/ +static void +x86emuOp_push_DI(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSH\tEDI\n"); + } + else { + DECODE_PRINTF("PUSH\tDI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_EDI); + } + else { + push_word(M.x86.R_DI); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x58 +****************************************************************************/ +static void +x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POP\tEAX\n"); + } + else { + DECODE_PRINTF("POP\tAX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = pop_long(); + } + else { + M.x86.R_AX = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x59 +****************************************************************************/ +static void +x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POP\tECX\n"); + } + else { + DECODE_PRINTF("POP\tCX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ECX = pop_long(); + } + else { + M.x86.R_CX = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x5a +****************************************************************************/ +static void +x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POP\tEDX\n"); + } + else { + DECODE_PRINTF("POP\tDX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDX = pop_long(); + } + else { + M.x86.R_DX = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x5b +****************************************************************************/ +static void +x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POP\tEBX\n"); + } + else { + DECODE_PRINTF("POP\tBX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EBX = pop_long(); + } + else { + M.x86.R_BX = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x5c +****************************************************************************/ +static void +x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POP\tESP\n"); + } + else { + DECODE_PRINTF("POP\tSP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ESP = pop_long(); + } + else { + M.x86.R_SP = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x5d +****************************************************************************/ +static void +x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POP\tEBP\n"); + } + else { + DECODE_PRINTF("POP\tBP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EBP = pop_long(); + } + else { + M.x86.R_BP = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x5e +****************************************************************************/ +static void +x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POP\tESI\n"); + } + else { + DECODE_PRINTF("POP\tSI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ESI = pop_long(); + } + else { + M.x86.R_SI = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x5f +****************************************************************************/ +static void +x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POP\tEDI\n"); + } + else { + DECODE_PRINTF("POP\tDI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDI = pop_long(); + } + else { + M.x86.R_DI = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x60 +****************************************************************************/ +static void +x86emuOp_push_all(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSHAD\n"); + } + else { + DECODE_PRINTF("PUSHA\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 old_sp = M.x86.R_ESP; + + push_long(M.x86.R_EAX); + push_long(M.x86.R_ECX); + push_long(M.x86.R_EDX); + push_long(M.x86.R_EBX); + push_long(old_sp); + push_long(M.x86.R_EBP); + push_long(M.x86.R_ESI); + push_long(M.x86.R_EDI); + } + else { + u16 old_sp = M.x86.R_SP; + + push_word(M.x86.R_AX); + push_word(M.x86.R_CX); + push_word(M.x86.R_DX); + push_word(M.x86.R_BX); + push_word(old_sp); + push_word(M.x86.R_BP); + push_word(M.x86.R_SI); + push_word(M.x86.R_DI); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x61 +****************************************************************************/ +static void +x86emuOp_pop_all(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POPAD\n"); + } + else { + DECODE_PRINTF("POPA\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDI = pop_long(); + M.x86.R_ESI = pop_long(); + M.x86.R_EBP = pop_long(); + M.x86.R_ESP += 4; /* skip ESP */ + M.x86.R_EBX = pop_long(); + M.x86.R_EDX = pop_long(); + M.x86.R_ECX = pop_long(); + M.x86.R_EAX = pop_long(); + } + else { + M.x86.R_DI = pop_word(); + M.x86.R_SI = pop_word(); + M.x86.R_BP = pop_word(); + M.x86.R_SP += 2; /* skip SP */ + M.x86.R_BX = pop_word(); + M.x86.R_DX = pop_word(); + M.x86.R_CX = pop_word(); + M.x86.R_AX = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */ +/*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */ + +/**************************************************************************** +REMARKS: +Handles opcode 0x64 +****************************************************************************/ +static void +x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("FS:\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_SEGOVR_FS; + /* + * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 + * opcode subroutines we do not want to do this. + */ + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x65 +****************************************************************************/ +static void +x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("GS:\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_SEGOVR_GS; + /* + * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 + * opcode subroutines we do not want to do this. + */ + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x66 - prefix for 32-bit register +****************************************************************************/ +static void +x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("DATA:\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_PREFIX_DATA; + /* note no DECODE_CLEAR_SEGOVR here. */ + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x67 - prefix for 32-bit address +****************************************************************************/ +static void +x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("ADDR:\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_PREFIX_ADDR; + /* note no DECODE_CLEAR_SEGOVR here. */ + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x68 +****************************************************************************/ +static void +x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 imm; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + imm = fetch_long_imm(); + } + else { + imm = fetch_word_imm(); + } + DECODE_PRINTF2("PUSH\t%x\n", imm); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(imm); + } + else { + push_word((u16) imm); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x69 +****************************************************************************/ +static void +x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("IMUL\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + s32 imm; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + imm = fetch_long_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + s16 imm; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + imm = fetch_word_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + res = (s16) srcval *(s16) imm; + + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + s32 imm; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + imm = fetch_long_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + s16 imm; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + imm = fetch_word_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + res = (s16) srcval *(s16) imm; + + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + s32 imm; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + imm = fetch_long_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + s16 imm; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + imm = fetch_word_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + res = (s16) srcval *(s16) imm; + + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + u32 res_lo, res_hi; + s32 imm; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + imm = fetch_long_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg, *srcreg; + u32 res; + s16 imm; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + imm = fetch_word_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + res = (s16) * srcreg * (s16) imm; + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x6a +****************************************************************************/ +static void +x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1)) +{ + s16 imm; + + START_OF_INSTR(); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2("PUSH\t%d\n", imm); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long((s32) imm); + } + else { + push_word(imm); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x6b +****************************************************************************/ +static void +x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + s8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("IMUL\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + res = (s16) srcval *(s16) imm; + + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + res = (s16) srcval *(s16) imm; + + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + res = (s16) srcval *(s16) imm; + + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + u32 res_lo, res_hi; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg, *srcreg; + u32 res; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%d\n", (s32) imm); + res = (s16) * srcreg * (s16) imm; + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x6c +****************************************************************************/ +static void +x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("INSB\n"); + ins(1); + TRACE_AND_STEP(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x6d +****************************************************************************/ +static void +x86emuOp_ins_word(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INSD\n"); + ins(4); + } + else { + DECODE_PRINTF("INSW\n"); + ins(2); + } + TRACE_AND_STEP(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x6e +****************************************************************************/ +static void +x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("OUTSB\n"); + outs(1); + TRACE_AND_STEP(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x6f +****************************************************************************/ +static void +x86emuOp_outs_word(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("OUTSD\n"); + outs(4); + } + else { + DECODE_PRINTF("OUTSW\n"); + outs(2); + } + TRACE_AND_STEP(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x70 +****************************************************************************/ +static void +x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if overflow flag is set */ + START_OF_INSTR(); + DECODE_PRINTF("JO\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_OF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x71 +****************************************************************************/ +static void +x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if overflow is not set */ + START_OF_INSTR(); + DECODE_PRINTF("JNO\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (!ACCESS_FLAG(F_OF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x72 +****************************************************************************/ +static void +x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if carry flag is set. */ + START_OF_INSTR(); + DECODE_PRINTF("JB\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_CF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x73 +****************************************************************************/ +static void +x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if carry flag is clear. */ + START_OF_INSTR(); + DECODE_PRINTF("JNB\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (!ACCESS_FLAG(F_CF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x74 +****************************************************************************/ +static void +x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if zero flag is set. */ + START_OF_INSTR(); + DECODE_PRINTF("JZ\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_ZF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x75 +****************************************************************************/ +static void +x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if zero flag is clear. */ + START_OF_INSTR(); + DECODE_PRINTF("JNZ\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (!ACCESS_FLAG(F_ZF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x76 +****************************************************************************/ +static void +x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if carry flag is set or if the zero + flag is set. */ + START_OF_INSTR(); + DECODE_PRINTF("JBE\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x77 +****************************************************************************/ +static void +x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if carry flag is clear and if the zero + flag is clear */ + START_OF_INSTR(); + DECODE_PRINTF("JNBE\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x78 +****************************************************************************/ +static void +x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if sign flag is set */ + START_OF_INSTR(); + DECODE_PRINTF("JS\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_SF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x79 +****************************************************************************/ +static void +x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if sign flag is clear */ + START_OF_INSTR(); + DECODE_PRINTF("JNS\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (!ACCESS_FLAG(F_SF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x7a +****************************************************************************/ +static void +x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if parity flag is set (even parity) */ + START_OF_INSTR(); + DECODE_PRINTF("JP\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_PF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x7b +****************************************************************************/ +static void +x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + + /* jump to byte offset if parity flag is clear (odd parity) */ + START_OF_INSTR(); + DECODE_PRINTF("JNP\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (!ACCESS_FLAG(F_PF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x7c +****************************************************************************/ +static void +x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + int sf, of; + + /* jump to byte offset if sign flag not equal to overflow flag. */ + START_OF_INSTR(); + DECODE_PRINTF("JL\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + sf = ACCESS_FLAG(F_SF) != 0; + of = ACCESS_FLAG(F_OF) != 0; + if (sf ^ of) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x7d +****************************************************************************/ +static void +x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + int sf, of; + + /* jump to byte offset if sign flag not equal to overflow flag. */ + START_OF_INSTR(); + DECODE_PRINTF("JNL\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + sf = ACCESS_FLAG(F_SF) != 0; + of = ACCESS_FLAG(F_OF) != 0; + /* note: inverse of above, but using == instead of xor. */ + if (sf == of) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x7e +****************************************************************************/ +static void +x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + int sf, of; + + /* jump to byte offset if sign flag not equal to overflow flag + or the zero flag is set */ + START_OF_INSTR(); + DECODE_PRINTF("JLE\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + sf = ACCESS_FLAG(F_SF) != 0; + of = ACCESS_FLAG(F_OF) != 0; + if ((sf ^ of) || ACCESS_FLAG(F_ZF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x7f +****************************************************************************/ +static void +x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1)) +{ + s8 offset; + u16 target; + int sf, of; + + /* jump to byte offset if sign flag equal to overflow flag. + and the zero flag is clear */ + START_OF_INSTR(); + DECODE_PRINTF("JNLE\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + (s16) offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + sf = ACCESS_FLAG(F_SF) != 0; + of = ACCESS_FLAG(F_OF) != 0; + if ((sf == of) && !ACCESS_FLAG(F_ZF)) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +static u8(*opc80_byte_operation[]) (u8 d, u8 s) = { + add_byte, /* 00 */ + or_byte, /* 01 */ + adc_byte, /* 02 */ + sbb_byte, /* 03 */ + and_byte, /* 04 */ + sub_byte, /* 05 */ + xor_byte, /* 06 */ + cmp_byte, /* 07 */ +}; + +/**************************************************************************** +REMARKS: +Handles opcode 0x80 +****************************************************************************/ +static void +x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg; + uint destoffset; + u8 imm; + u8 destval; + + /* + * Weirdo special case instruction format. Part of the opcode + * held below in "RH". Doubly nested case would result, except + * that the decoded instruction + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + + switch (rh) { + case 0: + DECODE_PRINTF("ADD\t"); + break; + case 1: + DECODE_PRINTF("OR\t"); + break; + case 2: + DECODE_PRINTF("ADC\t"); + break; + case 3: + DECODE_PRINTF("SBB\t"); + break; + case 4: + DECODE_PRINTF("AND\t"); + break; + case 5: + DECODE_PRINTF("SUB\t"); + break; + case 6: + DECODE_PRINTF("XOR\t"); + break; + case 7: + DECODE_PRINTF("CMP\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + switch (mod) { + case 0: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc80_byte_operation[rh]) (destval, imm); + if (rh != 7) + store_data_byte(destoffset, destval); + break; + case 1: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc80_byte_operation[rh]) (destval, imm); + if (rh != 7) + store_data_byte(destoffset, destval); + break; + case 2: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc80_byte_operation[rh]) (destval, imm); + if (rh != 7) + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc80_byte_operation[rh]) (*destreg, imm); + if (rh != 7) + *destreg = destval; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +static u16(*opc81_word_operation[]) (u16 d, u16 s) = { + add_word, /*00 */ + or_word, /*01 */ + adc_word, /*02 */ + sbb_word, /*03 */ + and_word, /*04 */ + sub_word, /*05 */ + xor_word, /*06 */ + cmp_word, /*07 */ +}; + +static u32(*opc81_long_operation[]) (u32 d, u32 s) = { + add_long, /*00 */ + or_long, /*01 */ + adc_long, /*02 */ + sbb_long, /*03 */ + and_long, /*04 */ + sub_long, /*05 */ + xor_long, /*06 */ + cmp_long, /*07 */ +}; + +/**************************************************************************** +REMARKS: +Handles opcode 0x81 +****************************************************************************/ +static void +x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + /* + * Weirdo special case instruction format. Part of the opcode + * held below in "RH". Doubly nested case would result, except + * that the decoded instruction + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + + switch (rh) { + case 0: + DECODE_PRINTF("ADD\t"); + break; + case 1: + DECODE_PRINTF("OR\t"); + break; + case 2: + DECODE_PRINTF("ADC\t"); + break; + case 3: + DECODE_PRINTF("SBB\t"); + break; + case 4: + DECODE_PRINTF("AND\t"); + break; + case 5: + DECODE_PRINTF("SUB\t"); + break; + case 6: + DECODE_PRINTF("XOR\t"); + break; + case 7: + DECODE_PRINTF("CMP\t"); + break; + } + } +#endif + /* + * Know operation, decode the mod byte to find the addressing + * mode. + */ + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + imm = fetch_long_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc81_long_operation[rh]) (destval, imm); + if (rh != 7) + store_data_long(destoffset, destval); + } + else { + u16 destval, imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + imm = fetch_word_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc81_word_operation[rh]) (destval, imm); + if (rh != 7) + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + imm = fetch_long_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc81_long_operation[rh]) (destval, imm); + if (rh != 7) + store_data_long(destoffset, destval); + } + else { + u16 destval, imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + imm = fetch_word_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc81_word_operation[rh]) (destval, imm); + if (rh != 7) + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + imm = fetch_long_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc81_long_operation[rh]) (destval, imm); + if (rh != 7) + store_data_long(destoffset, destval); + } + else { + u16 destval, imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + imm = fetch_word_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc81_word_operation[rh]) (destval, imm); + if (rh != 7) + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 destval, imm; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + imm = fetch_long_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc81_long_operation[rh]) (*destreg, imm); + if (rh != 7) + *destreg = destval; + } + else { + u16 *destreg; + u16 destval, imm; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + imm = fetch_word_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc81_word_operation[rh]) (*destreg, imm); + if (rh != 7) + *destreg = destval; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +static u8(*opc82_byte_operation[]) (u8 s, u8 d) = { + add_byte, /*00 */ + or_byte, /*01 *//*YYY UNUSED ???? */ + adc_byte, /*02 */ + sbb_byte, /*03 */ + and_byte, /*04 *//*YYY UNUSED ???? */ + sub_byte, /*05 */ + xor_byte, /*06 *//*YYY UNUSED ???? */ + cmp_byte, /*07 */ +}; + +/**************************************************************************** +REMARKS: +Handles opcode 0x82 +****************************************************************************/ +static void +x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg; + uint destoffset; + u8 imm; + u8 destval; + + /* + * Weirdo special case instruction format. Part of the opcode + * held below in "RH". Doubly nested case would result, except + * that the decoded instruction Similar to opcode 81, except that + * the immediate byte is sign extended to a word length. + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + switch (rh) { + case 0: + DECODE_PRINTF("ADD\t"); + break; + case 1: + DECODE_PRINTF("OR\t"); + break; + case 2: + DECODE_PRINTF("ADC\t"); + break; + case 3: + DECODE_PRINTF("SBB\t"); + break; + case 4: + DECODE_PRINTF("AND\t"); + break; + case 5: + DECODE_PRINTF("SUB\t"); + break; + case 6: + DECODE_PRINTF("XOR\t"); + break; + case 7: + DECODE_PRINTF("CMP\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + switch (mod) { + case 0: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm00_address(rl); + destval = fetch_data_byte(destoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc82_byte_operation[rh]) (destval, imm); + if (rh != 7) + store_data_byte(destoffset, destval); + break; + case 1: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm01_address(rl); + destval = fetch_data_byte(destoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc82_byte_operation[rh]) (destval, imm); + if (rh != 7) + store_data_byte(destoffset, destval); + break; + case 2: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm10_address(rl); + destval = fetch_data_byte(destoffset); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc82_byte_operation[rh]) (destval, imm); + if (rh != 7) + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc82_byte_operation[rh]) (*destreg, imm); + if (rh != 7) + *destreg = destval; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +static u16(*opc83_word_operation[]) (u16 s, u16 d) = { + add_word, /*00 */ + or_word, /*01 *//*YYY UNUSED ???? */ + adc_word, /*02 */ + sbb_word, /*03 */ + and_word, /*04 *//*YYY UNUSED ???? */ + sub_word, /*05 */ + xor_word, /*06 *//*YYY UNUSED ???? */ + cmp_word, /*07 */ +}; + +static u32(*opc83_long_operation[]) (u32 s, u32 d) = { + add_long, /*00 */ + or_long, /*01 *//*YYY UNUSED ???? */ + adc_long, /*02 */ + sbb_long, /*03 */ + and_long, /*04 *//*YYY UNUSED ???? */ + sub_long, /*05 */ + xor_long, /*06 *//*YYY UNUSED ???? */ + cmp_long, /*07 */ +}; + +/**************************************************************************** +REMARKS: +Handles opcode 0x83 +****************************************************************************/ +static void +x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + /* + * Weirdo special case instruction format. Part of the opcode + * held below in "RH". Doubly nested case would result, except + * that the decoded instruction Similar to opcode 81, except that + * the immediate byte is sign extended to a word length. + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + switch (rh) { + case 0: + DECODE_PRINTF("ADD\t"); + break; + case 1: + DECODE_PRINTF("OR\t"); + break; + case 2: + DECODE_PRINTF("ADC\t"); + break; + case 3: + DECODE_PRINTF("SBB\t"); + break; + case 4: + DECODE_PRINTF("AND\t"); + break; + case 5: + DECODE_PRINTF("SUB\t"); + break; + case 6: + DECODE_PRINTF("XOR\t"); + break; + case 7: + DECODE_PRINTF("CMP\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm00_address(rl); + destval = fetch_data_long(destoffset); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc83_long_operation[rh]) (destval, imm); + if (rh != 7) + store_data_long(destoffset, destval); + } + else { + u16 destval, imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm00_address(rl); + destval = fetch_data_word(destoffset); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc83_word_operation[rh]) (destval, imm); + if (rh != 7) + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm01_address(rl); + destval = fetch_data_long(destoffset); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc83_long_operation[rh]) (destval, imm); + if (rh != 7) + store_data_long(destoffset, destval); + } + else { + u16 destval, imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm01_address(rl); + destval = fetch_data_word(destoffset); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc83_word_operation[rh]) (destval, imm); + if (rh != 7) + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm10_address(rl); + destval = fetch_data_long(destoffset); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc83_long_operation[rh]) (destval, imm); + if (rh != 7) + store_data_long(destoffset, destval); + } + else { + u16 destval, imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm10_address(rl); + destval = fetch_data_word(destoffset); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc83_word_operation[rh]) (destval, imm); + if (rh != 7) + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 destval, imm; + + destreg = DECODE_RM_LONG_REGISTER(rl); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc83_long_operation[rh]) (*destreg, imm); + if (rh != 7) + *destreg = destval; + } + else { + u16 *destreg; + u16 destval, imm; + + destreg = DECODE_RM_WORD_REGISTER(rl); + imm = (s8) fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + destval = (*opc83_word_operation[rh]) (*destreg, imm); + if (rh != 7) + *destreg = destval; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x84 +****************************************************************************/ +static void +x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + u8 destval; + + START_OF_INSTR(); + DECODE_PRINTF("TEST\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_byte(destval, *srcreg); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_byte(destval, *srcreg); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_byte(destval, *srcreg); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_byte(*destreg, *srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x85 +****************************************************************************/ +static void +x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("TEST\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_long(destval, *srcreg); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_word(destval, *srcreg); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_long(destval, *srcreg); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_word(destval, *srcreg); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_long(destval, *srcreg); + } + else { + u16 destval; + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_word(destval, *srcreg); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_long(*destreg, *srcreg); + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + test_word(*destreg, *srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x86 +****************************************************************************/ +static void +x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + u8 destval; + u8 tmp; + + START_OF_INSTR(); + DECODE_PRINTF("XCHG\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_byte(destoffset, destval); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_byte(destoffset, destval); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_byte(destoffset); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = *destreg; + *destreg = tmp; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x87 +****************************************************************************/ +static void +x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("XCHG\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg; + u32 destval, tmp; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_long(destoffset, destval); + } + else { + u16 *srcreg; + u16 destval, tmp; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg; + u32 destval, tmp; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_long(destoffset, destval); + } + else { + u16 *srcreg; + u16 destval, tmp; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg; + u32 destval, tmp; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_long(destoffset); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_long(destoffset, destval); + } + else { + u16 *srcreg; + u16 destval, tmp; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + destval = fetch_data_word(destoffset); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = destval; + destval = tmp; + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + u32 tmp; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = *destreg; + *destreg = tmp; + } + else { + u16 *destreg, *srcreg; + u16 tmp; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + tmp = *srcreg; + *srcreg = *destreg; + *destreg = tmp; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x88 +****************************************************************************/ +static void +x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_byte(destoffset, *srcreg); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_byte(destoffset, *srcreg); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_byte(destoffset, *srcreg); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x89 +****************************************************************************/ +static void +x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u32 destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_long(destoffset, *srcreg); + } + else { + u16 *srcreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_word(destoffset, *srcreg); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_long(destoffset, *srcreg); + } + else { + u16 *srcreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_word(destoffset, *srcreg); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_long(destoffset, *srcreg); + } + else { + u16 *srcreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + store_data_word(destoffset, *srcreg); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x8a +****************************************************************************/ +static void +x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg, *srcreg; + uint srcoffset; + u8 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 1: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 2: + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x8b +****************************************************************************/ +static void +x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + } + else { + u16 *destreg, *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x8c +****************************************************************************/ +static void +x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u16 *destreg, *srcreg; + uint destoffset; + u16 destval; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + srcreg = decode_rm_seg_register(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = *srcreg; + store_data_word(destoffset, destval); + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + srcreg = decode_rm_seg_register(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = *srcreg; + store_data_word(destoffset, destval); + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + srcreg = decode_rm_seg_register(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = *srcreg; + store_data_word(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcreg = decode_rm_seg_register(rh); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x8d +****************************************************************************/ +static void +x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("LEA\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); + + DECODE_PRINTF(","); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u32) destoffset; + } + else { + u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); + + DECODE_PRINTF(","); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u16) destoffset; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); + + DECODE_PRINTF(","); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u32) destoffset; + } + else { + u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); + + DECODE_PRINTF(","); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u16) destoffset; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); + + DECODE_PRINTF(","); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u32) destoffset; + } + else { + u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); + + DECODE_PRINTF(","); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u16) destoffset; + } + break; + case 3: /* register to register */ + /* undefined. Do nothing. */ + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x8e +****************************************************************************/ +static void +x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u16 *destreg, *srcreg; + uint srcoffset; + u16 srcval; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = decode_rm_seg_register(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 1: + destreg = decode_rm_seg_register(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 2: + destreg = decode_rm_seg_register(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 3: /* register to register */ + destreg = decode_rm_seg_register(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + break; + } + /* + * Clean up, and reset all the R_xSP pointers to the correct + * locations. This is about 3x too much overhead (doing all the + * segreg ptrs when only one is needed, but this instruction + * *cannot* be that common, and this isn't too much work anyway. + */ + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x8f +****************************************************************************/ +static void +x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("POP\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + if (rh != 0) { + DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); + HALT_SYS(); + } + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = pop_long(); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = pop_word(); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = pop_long(); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = pop_word(); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = pop_long(); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + destval = pop_word(); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = pop_long(); + } + else { + u16 *destreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = pop_word(); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x90 +****************************************************************************/ +static void +x86emuOp_nop(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("NOP\n"); + TRACE_AND_STEP(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x91 +****************************************************************************/ +static void +x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1)) +{ + u32 tmp; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("XCHG\tEAX,ECX\n"); + } + else { + DECODE_PRINTF("XCHG\tAX,CX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + tmp = M.x86.R_EAX; + M.x86.R_EAX = M.x86.R_ECX; + M.x86.R_ECX = tmp; + } + else { + tmp = M.x86.R_AX; + M.x86.R_AX = M.x86.R_CX; + M.x86.R_CX = (u16) tmp; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x92 +****************************************************************************/ +static void +x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1)) +{ + u32 tmp; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("XCHG\tEAX,EDX\n"); + } + else { + DECODE_PRINTF("XCHG\tAX,DX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + tmp = M.x86.R_EAX; + M.x86.R_EAX = M.x86.R_EDX; + M.x86.R_EDX = tmp; + } + else { + tmp = M.x86.R_AX; + M.x86.R_AX = M.x86.R_DX; + M.x86.R_DX = (u16) tmp; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x93 +****************************************************************************/ +static void +x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1)) +{ + u32 tmp; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("XCHG\tEAX,EBX\n"); + } + else { + DECODE_PRINTF("XCHG\tAX,BX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + tmp = M.x86.R_EAX; + M.x86.R_EAX = M.x86.R_EBX; + M.x86.R_EBX = tmp; + } + else { + tmp = M.x86.R_AX; + M.x86.R_AX = M.x86.R_BX; + M.x86.R_BX = (u16) tmp; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x94 +****************************************************************************/ +static void +x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1)) +{ + u32 tmp; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("XCHG\tEAX,ESP\n"); + } + else { + DECODE_PRINTF("XCHG\tAX,SP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + tmp = M.x86.R_EAX; + M.x86.R_EAX = M.x86.R_ESP; + M.x86.R_ESP = tmp; + } + else { + tmp = M.x86.R_AX; + M.x86.R_AX = M.x86.R_SP; + M.x86.R_SP = (u16) tmp; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x95 +****************************************************************************/ +static void +x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1)) +{ + u32 tmp; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("XCHG\tEAX,EBP\n"); + } + else { + DECODE_PRINTF("XCHG\tAX,BP\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + tmp = M.x86.R_EAX; + M.x86.R_EAX = M.x86.R_EBP; + M.x86.R_EBP = tmp; + } + else { + tmp = M.x86.R_AX; + M.x86.R_AX = M.x86.R_BP; + M.x86.R_BP = (u16) tmp; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x96 +****************************************************************************/ +static void +x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1)) +{ + u32 tmp; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("XCHG\tEAX,ESI\n"); + } + else { + DECODE_PRINTF("XCHG\tAX,SI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + tmp = M.x86.R_EAX; + M.x86.R_EAX = M.x86.R_ESI; + M.x86.R_ESI = tmp; + } + else { + tmp = M.x86.R_AX; + M.x86.R_AX = M.x86.R_SI; + M.x86.R_SI = (u16) tmp; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x97 +****************************************************************************/ +static void +x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1)) +{ + u32 tmp; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("XCHG\tEAX,EDI\n"); + } + else { + DECODE_PRINTF("XCHG\tAX,DI\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + tmp = M.x86.R_EAX; + M.x86.R_EAX = M.x86.R_EDI; + M.x86.R_EDI = tmp; + } + else { + tmp = M.x86.R_AX; + M.x86.R_AX = M.x86.R_DI; + M.x86.R_DI = (u16) tmp; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x98 +****************************************************************************/ +static void +x86emuOp_cbw(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("CWDE\n"); + } + else { + DECODE_PRINTF("CBW\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + if (M.x86.R_AX & 0x8000) { + M.x86.R_EAX |= 0xffff0000; + } + else { + M.x86.R_EAX &= 0x0000ffff; + } + } + else { + if (M.x86.R_AL & 0x80) { + M.x86.R_AH = 0xff; + } + else { + M.x86.R_AH = 0x0; + } + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x99 +****************************************************************************/ +static void +x86emuOp_cwd(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("CDQ\n"); + } + else { + DECODE_PRINTF("CWD\n"); + } + DECODE_PRINTF("CWD\n"); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + if (M.x86.R_EAX & 0x80000000) { + M.x86.R_EDX = 0xffffffff; + } + else { + M.x86.R_EDX = 0x0; + } + } + else { + if (M.x86.R_AX & 0x8000) { + M.x86.R_DX = 0xffff; + } + else { + M.x86.R_DX = 0x0; + } + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x9a +****************************************************************************/ +static void +x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 farseg, faroff; + + START_OF_INSTR(); + DECODE_PRINTF("CALL\t"); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + faroff = fetch_long_imm(); + farseg = fetch_word_imm(); + } + else { + faroff = fetch_word_imm(); + farseg = fetch_word_imm(); + } + DECODE_PRINTF2("%04x:", farseg); + DECODE_PRINTF2("%04x\n", faroff); + CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR "); + + /* XXX + * + * Hooked interrupt vectors calling into our "BIOS" will cause + * problems unless all intersegment stuff is checked for BIOS + * access. Check needed here. For moment, let it alone. + */ + TRACE_AND_STEP(); + push_word(M.x86.R_CS); + M.x86.R_CS = farseg; + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_EIP); + } + else { + push_word(M.x86.R_IP); + } + M.x86.R_EIP = faroff & 0xffff; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x9b +****************************************************************************/ +static void +x86emuOp_wait(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("WAIT"); + TRACE_AND_STEP(); + /* NADA. */ + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x9c +****************************************************************************/ +static void +x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1)) +{ + u32 flags; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("PUSHFD\n"); + } + else { + DECODE_PRINTF("PUSHF\n"); + } + TRACE_AND_STEP(); + + /* clear out *all* bits not representing flags, and turn on real bits */ + flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON; + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(flags); + } + else { + push_word((u16) flags); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x9d +****************************************************************************/ +static void +x86emuOp_popf_word(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("POPFD\n"); + } + else { + DECODE_PRINTF("POPF\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EFLG = pop_long(); + } + else { + M.x86.R_FLG = pop_word(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x9e +****************************************************************************/ +static void +x86emuOp_sahf(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("SAHF\n"); + TRACE_AND_STEP(); + /* clear the lower bits of the flag register */ + M.x86.R_FLG &= 0xffffff00; + /* or in the AH register into the flags register */ + M.x86.R_FLG |= M.x86.R_AH; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x9f +****************************************************************************/ +static void +x86emuOp_lahf(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("LAHF\n"); + TRACE_AND_STEP(); + M.x86.R_AH = (u8) (M.x86.R_FLG & 0xff); + /*undocumented TC++ behavior??? Nope. It's documented, but + you have too look real hard to notice it. */ + M.x86.R_AH |= 0x2; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa0 +****************************************************************************/ +static void +x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1)) +{ + u16 offset; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tAL,"); + offset = fetch_word_imm(); + DECODE_PRINTF2("[%04x]\n", offset); + TRACE_AND_STEP(); + M.x86.R_AL = fetch_data_byte(offset); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa1 +****************************************************************************/ +static void +x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1)) +{ + u16 offset; + + START_OF_INSTR(); + offset = fetch_word_imm(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset); + } + else { + DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = fetch_data_long(offset); + } + else { + M.x86.R_AX = fetch_data_word(offset); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa2 +****************************************************************************/ +static void +x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u16 offset; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + offset = fetch_word_imm(); + DECODE_PRINTF2("[%04x],AL\n", offset); + TRACE_AND_STEP(); + store_data_byte(offset, M.x86.R_AL); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa3 +****************************************************************************/ +static void +x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u16 offset; + + START_OF_INSTR(); + offset = fetch_word_imm(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset); + } + else { + DECODE_PRINTF2("MOV\t[%04x],AX\n", offset); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + store_data_long(offset, M.x86.R_EAX); + } + else { + store_data_word(offset, M.x86.R_AX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa4 +****************************************************************************/ +static void +x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) +{ + u8 val; + u32 count; + int inc; + + START_OF_INSTR(); + DECODE_PRINTF("MOVS\tBYTE\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + TRACE_AND_STEP(); + count = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + count = M.x86.R_CX; + M.x86.R_CX = 0; + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { + val = fetch_data_byte(M.x86.R_SI); + store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); + M.x86.R_SI += inc; + M.x86.R_DI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa5 +****************************************************************************/ +static void +x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) +{ + u32 val; + int inc; + u32 count; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOVS\tDWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -4; + else + inc = 4; + } + else { + DECODE_PRINTF("MOVS\tWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -2; + else + inc = 2; + } + TRACE_AND_STEP(); + count = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + count = M.x86.R_CX; + M.x86.R_CX = 0; + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_data_long(M.x86.R_SI); + store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val); + } + else { + val = fetch_data_word(M.x86.R_SI); + store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val); + } + M.x86.R_SI += inc; + M.x86.R_DI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa6 +****************************************************************************/ +static void +x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) +{ + s8 val1, val2; + int inc; + + START_OF_INSTR(); + DECODE_PRINTF("CMPS\tBYTE\n"); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + + if (M.x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + val1 = fetch_data_byte(M.x86.R_SI); + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(val1, val2); + M.x86.R_CX -= 1; + M.x86.R_SI += inc; + M.x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF) == 0) + break; + } + M.x86.mode &= ~SYSMODE_PREFIX_REPE; + } + else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { + /* REPNE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + val1 = fetch_data_byte(M.x86.R_SI); + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(val1, val2); + M.x86.R_CX -= 1; + M.x86.R_SI += inc; + M.x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF)) + break; /* zero flag set means equal */ + } + M.x86.mode &= ~SYSMODE_PREFIX_REPNE; + } + else { + val1 = fetch_data_byte(M.x86.R_SI); + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(val1, val2); + M.x86.R_SI += inc; + M.x86.R_DI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa7 +****************************************************************************/ +static void +x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) +{ + u32 val1, val2; + int inc; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("CMPS\tDWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -4; + else + inc = 4; + } + else { + DECODE_PRINTF("CMPS\tWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -2; + else + inc = 2; + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val1 = fetch_data_long(M.x86.R_SI); + val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); + cmp_long(val1, val2); + } + else { + val1 = fetch_data_word(M.x86.R_SI); + val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word((u16) val1, (u16) val2); + } + M.x86.R_CX -= 1; + M.x86.R_SI += inc; + M.x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF) == 0) + break; + } + M.x86.mode &= ~SYSMODE_PREFIX_REPE; + } + else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { + /* REPNE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val1 = fetch_data_long(M.x86.R_SI); + val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); + cmp_long(val1, val2); + } + else { + val1 = fetch_data_word(M.x86.R_SI); + val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word((u16) val1, (u16) val2); + } + M.x86.R_CX -= 1; + M.x86.R_SI += inc; + M.x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF)) + break; /* zero flag set means equal */ + } + M.x86.mode &= ~SYSMODE_PREFIX_REPNE; + } + else { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val1 = fetch_data_long(M.x86.R_SI); + val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); + cmp_long(val1, val2); + } + else { + val1 = fetch_data_word(M.x86.R_SI); + val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word((u16) val1, (u16) val2); + } + M.x86.R_SI += inc; + M.x86.R_DI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa8 +****************************************************************************/ +static void +x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + int imm; + + START_OF_INSTR(); + DECODE_PRINTF("TEST\tAL,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%04x\n", imm); + TRACE_AND_STEP(); + test_byte(M.x86.R_AL, (u8) imm); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xa9 +****************************************************************************/ +static void +x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("TEST\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("TEST\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + test_long(M.x86.R_EAX, srcval); + } + else { + test_word(M.x86.R_AX, (u16) srcval); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xaa +****************************************************************************/ +static void +x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) +{ + int inc; + + START_OF_INSTR(); + DECODE_PRINTF("STOS\tBYTE\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + TRACE_AND_STEP(); + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); + M.x86.R_CX -= 1; + M.x86.R_DI += inc; + } + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + else { + store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); + M.x86.R_DI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xab +****************************************************************************/ +static void +x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) +{ + int inc; + u32 count; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("STOS\tDWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -4; + else + inc = 4; + } + else { + DECODE_PRINTF("STOS\tWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -2; + else + inc = 2; + } + TRACE_AND_STEP(); + count = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + count = M.x86.R_CX; + M.x86.R_CX = 0; + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX); + } + else { + store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); + } + M.x86.R_DI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xac +****************************************************************************/ +static void +x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) +{ + int inc; + + START_OF_INSTR(); + DECODE_PRINTF("LODS\tBYTE\n"); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + M.x86.R_AL = fetch_data_byte(M.x86.R_SI); + M.x86.R_CX -= 1; + M.x86.R_SI += inc; + } + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + else { + M.x86.R_AL = fetch_data_byte(M.x86.R_SI); + M.x86.R_SI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xad +****************************************************************************/ +static void +x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) +{ + int inc; + u32 count; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("LODS\tDWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -4; + else + inc = 4; + } + else { + DECODE_PRINTF("LODS\tWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -2; + else + inc = 2; + } + TRACE_AND_STEP(); + count = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* move them until CX is ZERO. */ + count = M.x86.R_CX; + M.x86.R_CX = 0; + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = fetch_data_long(M.x86.R_SI); + } + else { + M.x86.R_AX = fetch_data_word(M.x86.R_SI); + } + M.x86.R_SI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xae +****************************************************************************/ +static void +x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) +{ + s8 val2; + int inc; + + START_OF_INSTR(); + DECODE_PRINTF("SCAS\tBYTE\n"); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -1; + else + inc = 1; + if (M.x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(M.x86.R_AL, val2); + M.x86.R_CX -= 1; + M.x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF) == 0) + break; + } + M.x86.mode &= ~SYSMODE_PREFIX_REPE; + } + else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { + /* REPNE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(M.x86.R_AL, val2); + M.x86.R_CX -= 1; + M.x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF)) + break; /* zero flag set means equal */ + } + M.x86.mode &= ~SYSMODE_PREFIX_REPNE; + } + else { + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(M.x86.R_AL, val2); + M.x86.R_DI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xaf +****************************************************************************/ +static void +x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) +{ + int inc; + u32 val; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("SCAS\tDWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -4; + else + inc = 4; + } + else { + DECODE_PRINTF("SCAS\tWORD\n"); + if (ACCESS_FLAG(F_DF)) /* down */ + inc = -2; + else + inc = 2; + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); + cmp_long(M.x86.R_EAX, val); + } + else { + val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word(M.x86.R_AX, (u16) val); + } + M.x86.R_CX -= 1; + M.x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF) == 0) + break; + } + M.x86.mode &= ~SYSMODE_PREFIX_REPE; + } + else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { + /* REPNE */ + /* move them until CX is ZERO. */ + while (M.x86.R_CX != 0) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); + cmp_long(M.x86.R_EAX, val); + } + else { + val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word(M.x86.R_AX, (u16) val); + } + M.x86.R_CX -= 1; + M.x86.R_DI += inc; + if (ACCESS_FLAG(F_ZF)) + break; /* zero flag set means equal */ + } + M.x86.mode &= ~SYSMODE_PREFIX_REPNE; + } + else { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); + cmp_long(M.x86.R_EAX, val); + } + else { + val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word(M.x86.R_AX, (u16) val); + } + M.x86.R_DI += inc; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb0 +****************************************************************************/ +static void +x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tAL,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + M.x86.R_AL = imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb1 +****************************************************************************/ +static void +x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tCL,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + M.x86.R_CL = imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb2 +****************************************************************************/ +static void +x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tDL,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + M.x86.R_DL = imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb3 +****************************************************************************/ +static void +x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tBL,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + M.x86.R_BL = imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb4 +****************************************************************************/ +static void +x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tAH,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + M.x86.R_AH = imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb5 +****************************************************************************/ +static void +x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tCH,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + M.x86.R_CH = imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb6 +****************************************************************************/ +static void +x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tDH,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + M.x86.R_DH = imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb7 +****************************************************************************/ +static void +x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\tBH,"); + imm = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", imm); + TRACE_AND_STEP(); + M.x86.R_BH = imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb8 +****************************************************************************/ +static void +x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOV\tEAX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("MOV\tAX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = srcval; + } + else { + M.x86.R_AX = (u16) srcval; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xb9 +****************************************************************************/ +static void +x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOV\tECX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("MOV\tCX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ECX = srcval; + } + else { + M.x86.R_CX = (u16) srcval; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xba +****************************************************************************/ +static void +x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOV\tEDX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("MOV\tDX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDX = srcval; + } + else { + M.x86.R_DX = (u16) srcval; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xbb +****************************************************************************/ +static void +x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOV\tEBX,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("MOV\tBX,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EBX = srcval; + } + else { + M.x86.R_BX = (u16) srcval; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xbc +****************************************************************************/ +static void +x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOV\tESP,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("MOV\tSP,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ESP = srcval; + } + else { + M.x86.R_SP = (u16) srcval; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xbd +****************************************************************************/ +static void +x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOV\tEBP,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("MOV\tBP,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EBP = srcval; + } + else { + M.x86.R_BP = (u16) srcval; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xbe +****************************************************************************/ +static void +x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOV\tESI,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("MOV\tSI,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ESI = srcval; + } + else { + M.x86.R_SI = (u16) srcval; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xbf +****************************************************************************/ +static void +x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 srcval; + + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("MOV\tEDI,"); + srcval = fetch_long_imm(); + } + else { + DECODE_PRINTF("MOV\tDI,"); + srcval = fetch_word_imm(); + } + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EDI = srcval; + } + else { + M.x86.R_DI = (u16) srcval; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/* used by opcodes c0, d0, and d2. */ +static u8(*opcD0_byte_operation[]) (u8 d, u8 s) = { + rol_byte, ror_byte, rcl_byte, rcr_byte, shl_byte, shr_byte, shl_byte, /* sal_byte === shl_byte by definition */ +sar_byte,}; + +/**************************************************************************** +REMARKS: +Handles opcode 0xc0 +****************************************************************************/ +static void +x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg; + uint destoffset; + u8 destval; + u8 amt; + + /* + * Yet another weirdo special case instruction format. Part of + * the opcode held below in "RH". Doubly nested case would + * result, except that the decoded instruction + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + + switch (rh) { + case 0: + DECODE_PRINTF("ROL\t"); + break; + case 1: + DECODE_PRINTF("ROR\t"); + break; + case 2: + DECODE_PRINTF("RCL\t"); + break; + case 3: + DECODE_PRINTF("RCR\t"); + break; + case 4: + DECODE_PRINTF("SHL\t"); + break; + case 5: + DECODE_PRINTF("SHR\t"); + break; + case 6: + DECODE_PRINTF("SAL\t"); + break; + case 7: + DECODE_PRINTF("SAR\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + switch (mod) { + case 0: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm00_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, amt); + store_data_byte(destoffset, destval); + break; + case 1: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm01_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, amt); + store_data_byte(destoffset, destval); + break; + case 2: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm10_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, amt); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (*destreg, amt); + *destreg = destval; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/* used by opcodes c1, d1, and d3. */ +static u16(*opcD1_word_operation[]) (u16 s, u8 d) = { + rol_word, ror_word, rcl_word, rcr_word, shl_word, shr_word, shl_word, /* sal_byte === shl_byte by definition */ +sar_word,}; + +/* used by opcodes c1, d1, and d3. */ +static u32(*opcD1_long_operation[]) (u32 s, u8 d) = { + rol_long, ror_long, rcl_long, rcr_long, shl_long, shr_long, shl_long, /* sal_byte === shl_byte by definition */ +sar_long,}; + +/**************************************************************************** +REMARKS: +Handles opcode 0xc1 +****************************************************************************/ +static void +x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + u8 amt; + + /* + * Yet another weirdo special case instruction format. Part of + * the opcode held below in "RH". Doubly nested case would + * result, except that the decoded instruction + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + + switch (rh) { + case 0: + DECODE_PRINTF("ROL\t"); + break; + case 1: + DECODE_PRINTF("ROR\t"); + break; + case 2: + DECODE_PRINTF("RCL\t"); + break; + case 3: + DECODE_PRINTF("RCR\t"); + break; + case 4: + DECODE_PRINTF("SHL\t"); + break; + case 5: + DECODE_PRINTF("SHR\t"); + break; + case 6: + DECODE_PRINTF("SAL\t"); + break; + case 7: + DECODE_PRINTF("SAR\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm00_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, amt); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm00_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, amt); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm01_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, amt); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm01_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, amt); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm10_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, amt); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm10_address(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, amt); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + TRACE_AND_STEP(); + *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); + } + else { + u16 *destreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + amt = fetch_byte_imm(); + DECODE_PRINTF2(",%x\n", amt); + TRACE_AND_STEP(); + *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xc2 +****************************************************************************/ +static void +x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1)) +{ + u16 imm; + + START_OF_INSTR(); + DECODE_PRINTF("RET\t"); + imm = fetch_word_imm(); + DECODE_PRINTF2("%x\n", imm); + RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip); + TRACE_AND_STEP(); + M.x86.R_IP = pop_word(); + M.x86.R_SP += imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xc3 +****************************************************************************/ +static void +x86emuOp_ret_near(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("RET\n"); + RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip); + TRACE_AND_STEP(); + M.x86.R_IP = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xc4 +****************************************************************************/ +static void +x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rh, rl; + u16 *dstreg; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("LES\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_ES = fetch_data_word(srcoffset + 2); + break; + case 1: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_ES = fetch_data_word(srcoffset + 2); + break; + case 2: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_ES = fetch_data_word(srcoffset + 2); + break; + case 3: /* register to register */ + /* UNDEFINED! */ + TRACE_AND_STEP(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xc5 +****************************************************************************/ +static void +x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rh, rl; + u16 *dstreg; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("LDS\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_DS = fetch_data_word(srcoffset + 2); + break; + case 1: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_DS = fetch_data_word(srcoffset + 2); + break; + case 2: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_DS = fetch_data_word(srcoffset + 2); + break; + case 3: /* register to register */ + /* UNDEFINED! */ + TRACE_AND_STEP(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xc6 +****************************************************************************/ +static void +x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg; + uint destoffset; + u8 imm; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + if (rh != 0) { + DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); + HALT_SYS(); + } + switch (mod) { + case 0: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm00_address(rl); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%2x\n", imm); + TRACE_AND_STEP(); + store_data_byte(destoffset, imm); + break; + case 1: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm01_address(rl); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%2x\n", imm); + TRACE_AND_STEP(); + store_data_byte(destoffset, imm); + break; + case 2: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm10_address(rl); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%2x\n", imm); + TRACE_AND_STEP(); + store_data_byte(destoffset, imm); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + imm = fetch_byte_imm(); + DECODE_PRINTF2(",%2x\n", imm); + TRACE_AND_STEP(); + *destreg = imm; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xc7 +****************************************************************************/ +static void +x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("MOV\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + if (rh != 0) { + DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); + HALT_SYS(); + } + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm00_address(rl); + imm = fetch_long_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + store_data_long(destoffset, imm); + } + else { + u16 imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm00_address(rl); + imm = fetch_word_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + store_data_word(destoffset, imm); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm01_address(rl); + imm = fetch_long_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + store_data_long(destoffset, imm); + } + else { + u16 imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm01_address(rl); + imm = fetch_word_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + store_data_word(destoffset, imm); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 imm; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm10_address(rl); + imm = fetch_long_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + store_data_long(destoffset, imm); + } + else { + u16 imm; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm10_address(rl); + imm = fetch_word_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + store_data_word(destoffset, imm); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 imm; + + destreg = DECODE_RM_LONG_REGISTER(rl); + imm = fetch_long_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + *destreg = imm; + } + else { + u16 *destreg; + u16 imm; + + destreg = DECODE_RM_WORD_REGISTER(rl); + imm = fetch_word_imm(); + DECODE_PRINTF2(",%x\n", imm); + TRACE_AND_STEP(); + *destreg = imm; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xc8 +****************************************************************************/ +static void +x86emuOp_enter(u8 X86EMU_UNUSED(op1)) +{ + u16 local, frame_pointer; + u8 nesting; + int i; + + START_OF_INSTR(); + local = fetch_word_imm(); + nesting = fetch_byte_imm(); + DECODE_PRINTF2("ENTER %x\n", local); + DECODE_PRINTF2(",%x\n", nesting); + TRACE_AND_STEP(); + push_word(M.x86.R_BP); + frame_pointer = M.x86.R_SP; + if (nesting > 0) { + for (i = 1; i < nesting; i++) { + M.x86.R_BP -= 2; + push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP)); + } + push_word(frame_pointer); + } + M.x86.R_BP = frame_pointer; + M.x86.R_SP = (u16) (M.x86.R_SP - local); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xc9 +****************************************************************************/ +static void +x86emuOp_leave(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("LEAVE\n"); + TRACE_AND_STEP(); + M.x86.R_SP = M.x86.R_BP; + M.x86.R_BP = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xca +****************************************************************************/ +static void +x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1)) +{ + u16 imm; + + START_OF_INSTR(); + DECODE_PRINTF("RETF\t"); + imm = fetch_word_imm(); + DECODE_PRINTF2("%x\n", imm); + RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip); + TRACE_AND_STEP(); + M.x86.R_IP = pop_word(); + M.x86.R_CS = pop_word(); + M.x86.R_SP += imm; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xcb +****************************************************************************/ +static void +x86emuOp_ret_far(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("RETF\n"); + RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip); + TRACE_AND_STEP(); + M.x86.R_IP = pop_word(); + M.x86.R_CS = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xcc +****************************************************************************/ +static void +x86emuOp_int3(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("INT 3\n"); + TRACE_AND_STEP(); + if (_X86EMU_intrTab[3]) { + (*_X86EMU_intrTab[3]) (3); + } + else { + push_word((u16) M.x86.R_FLG); + CLEAR_FLAG(F_IF); + CLEAR_FLAG(F_TF); + push_word(M.x86.R_CS); + M.x86.R_CS = mem_access_word(3 * 4 + 2); + push_word(M.x86.R_IP); + M.x86.R_IP = mem_access_word(3 * 4); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xcd +****************************************************************************/ +static void +x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 intnum; + + START_OF_INSTR(); + DECODE_PRINTF("INT\t"); + intnum = fetch_byte_imm(); + DECODE_PRINTF2("%x\n", intnum); + TRACE_AND_STEP(); + if (_X86EMU_intrTab[intnum]) { + (*_X86EMU_intrTab[intnum]) (intnum); + } + else { + push_word((u16) M.x86.R_FLG); + CLEAR_FLAG(F_IF); + CLEAR_FLAG(F_TF); + push_word(M.x86.R_CS); + M.x86.R_CS = mem_access_word(intnum * 4 + 2); + push_word(M.x86.R_IP); + M.x86.R_IP = mem_access_word(intnum * 4); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xce +****************************************************************************/ +static void +x86emuOp_into(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("INTO\n"); + TRACE_AND_STEP(); + if (ACCESS_FLAG(F_OF)) { + if (_X86EMU_intrTab[4]) { + (*_X86EMU_intrTab[4]) (4); + } + else { + push_word((u16) M.x86.R_FLG); + CLEAR_FLAG(F_IF); + CLEAR_FLAG(F_TF); + push_word(M.x86.R_CS); + M.x86.R_CS = mem_access_word(4 * 4 + 2); + push_word(M.x86.R_IP); + M.x86.R_IP = mem_access_word(4 * 4); + } + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xcf +****************************************************************************/ +static void +x86emuOp_iret(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("IRET\n"); + + TRACE_AND_STEP(); + + M.x86.R_IP = pop_word(); + M.x86.R_CS = pop_word(); + M.x86.R_FLG = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xd0 +****************************************************************************/ +static void +x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg; + uint destoffset; + u8 destval; + + /* + * Yet another weirdo special case instruction format. Part of + * the opcode held below in "RH". Doubly nested case would + * result, except that the decoded instruction + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + switch (rh) { + case 0: + DECODE_PRINTF("ROL\t"); + break; + case 1: + DECODE_PRINTF("ROR\t"); + break; + case 2: + DECODE_PRINTF("RCL\t"); + break; + case 3: + DECODE_PRINTF("RCR\t"); + break; + case 4: + DECODE_PRINTF("SHL\t"); + break; + case 5: + DECODE_PRINTF("SHR\t"); + break; + case 6: + DECODE_PRINTF("SAL\t"); + break; + case 7: + DECODE_PRINTF("SAR\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + switch (mod) { + case 0: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, 1); + store_data_byte(destoffset, destval); + break; + case 1: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, 1); + store_data_byte(destoffset, destval); + break; + case 2: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, 1); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(",1\n"); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (*destreg, 1); + *destreg = destval; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xd1 +****************************************************************************/ +static void +x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + /* + * Yet another weirdo special case instruction format. Part of + * the opcode held below in "RH". Doubly nested case would + * result, except that the decoded instruction + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + switch (rh) { + case 0: + DECODE_PRINTF("ROL\t"); + break; + case 1: + DECODE_PRINTF("ROR\t"); + break; + case 2: + DECODE_PRINTF("RCL\t"); + break; + case 3: + DECODE_PRINTF("RCR\t"); + break; + case 4: + DECODE_PRINTF("SHL\t"); + break; + case 5: + DECODE_PRINTF("SHR\t"); + break; + case 6: + DECODE_PRINTF("SAL\t"); + break; + case 7: + DECODE_PRINTF("SAR\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, 1); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, 1); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, 1); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, 1); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, 1); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(",1\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, 1); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *destreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(",1\n"); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (*destreg, 1); + *destreg = destval; + } + else { + u16 destval; + u16 *destreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(",1\n"); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (*destreg, 1); + *destreg = destval; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xd2 +****************************************************************************/ +static void +x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg; + uint destoffset; + u8 destval; + u8 amt; + + /* + * Yet another weirdo special case instruction format. Part of + * the opcode held below in "RH". Doubly nested case would + * result, except that the decoded instruction + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + switch (rh) { + case 0: + DECODE_PRINTF("ROL\t"); + break; + case 1: + DECODE_PRINTF("ROR\t"); + break; + case 2: + DECODE_PRINTF("RCL\t"); + break; + case 3: + DECODE_PRINTF("RCR\t"); + break; + case 4: + DECODE_PRINTF("SHL\t"); + break; + case 5: + DECODE_PRINTF("SHR\t"); + break; + case 6: + DECODE_PRINTF("SAL\t"); + break; + case 7: + DECODE_PRINTF("SAR\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + amt = M.x86.R_CL; + switch (mod) { + case 0: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, amt); + store_data_byte(destoffset, destval); + break; + case 1: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, amt); + store_data_byte(destoffset, destval); + break; + case 2: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (destval, amt); + store_data_byte(destoffset, destval); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = (*opcD0_byte_operation[rh]) (*destreg, amt); + *destreg = destval; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xd3 +****************************************************************************/ +static void +x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + u8 amt; + + /* + * Yet another weirdo special case instruction format. Part of + * the opcode held below in "RH". Doubly nested case would + * result, except that the decoded instruction + */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + switch (rh) { + case 0: + DECODE_PRINTF("ROL\t"); + break; + case 1: + DECODE_PRINTF("ROR\t"); + break; + case 2: + DECODE_PRINTF("RCL\t"); + break; + case 3: + DECODE_PRINTF("RCR\t"); + break; + case 4: + DECODE_PRINTF("SHL\t"); + break; + case 5: + DECODE_PRINTF("SHR\t"); + break; + case 6: + DECODE_PRINTF("SAL\t"); + break; + case 7: + DECODE_PRINTF("SAR\t"); + break; + } + } +#endif + /* know operation, decode the mod byte to find the addressing + mode. */ + amt = M.x86.R_CL; + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, amt); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, amt); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, amt); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, amt); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_long_operation[rh]) (destval, amt); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("WORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(",CL\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = (*opcD1_word_operation[rh]) (destval, amt); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); + } + else { + u16 *destreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xd4 +****************************************************************************/ +static void +x86emuOp_aam(u8 X86EMU_UNUSED(op1)) +{ + u8 a; + + START_OF_INSTR(); + DECODE_PRINTF("AAM\n"); + a = fetch_byte_imm(); /* this is a stupid encoding. */ + if (a != 10) { + /* fix: add base decoding + aam_word(u8 val, int base a) */ + DECODE_PRINTF("ERROR DECODING AAM\n"); + TRACE_REGS(); + HALT_SYS(); + } + TRACE_AND_STEP(); + /* note the type change here --- returning AL and AH in AX. */ + M.x86.R_AX = aam_word(M.x86.R_AL); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xd5 +****************************************************************************/ +static void +x86emuOp_aad(u8 X86EMU_UNUSED(op1)) +{ + u8 a; + + START_OF_INSTR(); + DECODE_PRINTF("AAD\n"); + a = fetch_byte_imm(); + if (a != 10) { + /* fix: add base decoding + aad_word(u16 val, int base a) */ + DECODE_PRINTF("ERROR DECODING AAM\n"); + TRACE_REGS(); + HALT_SYS(); + } + TRACE_AND_STEP(); + M.x86.R_AX = aad_word(M.x86.R_AX); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/* opcode 0xd6 ILLEGAL OPCODE */ + +/**************************************************************************** +REMARKS: +Handles opcode 0xd7 +****************************************************************************/ +static void +x86emuOp_xlat(u8 X86EMU_UNUSED(op1)) +{ + u16 addr; + + START_OF_INSTR(); + DECODE_PRINTF("XLAT\n"); + TRACE_AND_STEP(); + addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL); + M.x86.R_AL = fetch_data_byte(addr); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/* instuctions D8 .. DF are in i87_ops.c */ + +/**************************************************************************** +REMARKS: +Handles opcode 0xe0 +****************************************************************************/ +static void +x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) +{ + s16 ip; + + START_OF_INSTR(); + DECODE_PRINTF("LOOPNE\t"); + ip = (s8) fetch_byte_imm(); + ip += (s16) M.x86.R_IP; + DECODE_PRINTF2("%04x\n", ip); + TRACE_AND_STEP(); + M.x86.R_CX -= 1; + if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ + M.x86.R_IP = ip; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe1 +****************************************************************************/ +static void +x86emuOp_loope(u8 X86EMU_UNUSED(op1)) +{ + s16 ip; + + START_OF_INSTR(); + DECODE_PRINTF("LOOPE\t"); + ip = (s8) fetch_byte_imm(); + ip += (s16) M.x86.R_IP; + DECODE_PRINTF2("%04x\n", ip); + TRACE_AND_STEP(); + M.x86.R_CX -= 1; + if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ + M.x86.R_IP = ip; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe2 +****************************************************************************/ +static void +x86emuOp_loop(u8 X86EMU_UNUSED(op1)) +{ + s16 ip; + + START_OF_INSTR(); + DECODE_PRINTF("LOOP\t"); + ip = (s8) fetch_byte_imm(); + ip += (s16) M.x86.R_IP; + DECODE_PRINTF2("%04x\n", ip); + TRACE_AND_STEP(); + M.x86.R_CX -= 1; + if (M.x86.R_CX != 0) + M.x86.R_IP = ip; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe3 +****************************************************************************/ +static void +x86emuOp_jcxz(u8 X86EMU_UNUSED(op1)) +{ + u16 target; + s8 offset; + + /* jump to byte offset if overflow flag is set */ + START_OF_INSTR(); + DECODE_PRINTF("JCXZ\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + if (M.x86.R_CX == 0) + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe4 +****************************************************************************/ +static void +x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 port; + + START_OF_INSTR(); + DECODE_PRINTF("IN\t"); + port = (u8) fetch_byte_imm(); + DECODE_PRINTF2("%x,AL\n", port); + TRACE_AND_STEP(); + M.x86.R_AL = (*sys_inb) (port); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe5 +****************************************************************************/ +static void +x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1)) +{ + u8 port; + + START_OF_INSTR(); + DECODE_PRINTF("IN\t"); + port = (u8) fetch_byte_imm(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF2("EAX,%x\n", port); + } + else { + DECODE_PRINTF2("AX,%x\n", port); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = (*sys_inl) (port); + } + else { + M.x86.R_AX = (*sys_inw) (port); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe6 +****************************************************************************/ +static void +x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1)) +{ + u8 port; + + START_OF_INSTR(); + DECODE_PRINTF("OUT\t"); + port = (u8) fetch_byte_imm(); + DECODE_PRINTF2("%x,AL\n", port); + TRACE_AND_STEP(); + (*sys_outb) (port, M.x86.R_AL); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe7 +****************************************************************************/ +static void +x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1)) +{ + u8 port; + + START_OF_INSTR(); + DECODE_PRINTF("OUT\t"); + port = (u8) fetch_byte_imm(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF2("%x,EAX\n", port); + } + else { + DECODE_PRINTF2("%x,AX\n", port); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + (*sys_outl) (port, M.x86.R_EAX); + } + else { + (*sys_outw) (port, M.x86.R_AX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe8 +****************************************************************************/ +static void +x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1)) +{ + s16 ip16 = 0; + s32 ip32 = 0; + + START_OF_INSTR(); + DECODE_PRINTF("CALL\t"); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + ip32 = (s32) fetch_long_imm(); + ip32 += (s16) M.x86.R_IP; /* CHECK SIGN */ + DECODE_PRINTF2("%04x\n", (u16) ip32); + CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, ""); + } + else { + ip16 = (s16) fetch_word_imm(); + ip16 += (s16) M.x86.R_IP; /* CHECK SIGN */ + DECODE_PRINTF2("%04x\n", (u16) ip16); + CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, ""); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + push_long(M.x86.R_EIP); + M.x86.R_EIP = ip32 & 0xffff; + } + else { + push_word(M.x86.R_IP); + M.x86.R_EIP = ip16; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xe9 +****************************************************************************/ +static void +x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) +{ + u32 ip; + + START_OF_INSTR(); + DECODE_PRINTF("JMP\t"); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + ip = (u32) fetch_long_imm(); + ip += (u32) M.x86.R_EIP; + DECODE_PRINTF2("%08x\n", (u32) ip); + TRACE_AND_STEP(); + M.x86.R_EIP = (u32) ip; + } + else { + ip = (s16) fetch_word_imm(); + ip += (s16) M.x86.R_IP; + DECODE_PRINTF2("%04x\n", (u16) ip); + TRACE_AND_STEP(); + M.x86.R_IP = (u16) ip; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xea +****************************************************************************/ +static void +x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1)) +{ + u16 cs; + u32 ip; + + START_OF_INSTR(); + DECODE_PRINTF("JMP\tFAR "); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + ip = fetch_long_imm(); + } + else { + ip = fetch_word_imm(); + } + cs = fetch_word_imm(); + DECODE_PRINTF2("%04x:", cs); + DECODE_PRINTF2("%04x\n", ip); + TRACE_AND_STEP(); + M.x86.R_EIP = ip & 0xffff; + M.x86.R_CS = cs; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xeb +****************************************************************************/ +static void +x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1)) +{ + u16 target; + s8 offset; + + START_OF_INSTR(); + DECODE_PRINTF("JMP\t"); + offset = (s8) fetch_byte_imm(); + target = (u16) (M.x86.R_IP + offset); + DECODE_PRINTF2("%x\n", target); + TRACE_AND_STEP(); + M.x86.R_IP = target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xec +****************************************************************************/ +static void +x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("IN\tAL,DX\n"); + TRACE_AND_STEP(); + M.x86.R_AL = (*sys_inb) (M.x86.R_DX); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xed +****************************************************************************/ +static void +x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("IN\tEAX,DX\n"); + } + else { + DECODE_PRINTF("IN\tAX,DX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_EAX = (*sys_inl) (M.x86.R_DX); + } + else { + M.x86.R_AX = (*sys_inw) (M.x86.R_DX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xee +****************************************************************************/ +static void +x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("OUT\tDX,AL\n"); + TRACE_AND_STEP(); + (*sys_outb) (M.x86.R_DX, M.x86.R_AL); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xef +****************************************************************************/ +static void +x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("OUT\tDX,EAX\n"); + } + else { + DECODE_PRINTF("OUT\tDX,AX\n"); + } + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + (*sys_outl) (M.x86.R_DX, M.x86.R_EAX); + } + else { + (*sys_outw) (M.x86.R_DX, M.x86.R_AX); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xf0 +****************************************************************************/ +static void +x86emuOp_lock(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("LOCK:\n"); + TRACE_AND_STEP(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/*opcode 0xf1 ILLEGAL OPERATION */ + +/**************************************************************************** +REMARKS: +Handles opcode 0xf2 +****************************************************************************/ +static void +x86emuOp_repne(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("REPNE\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_PREFIX_REPNE; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xf3 +****************************************************************************/ +static void +x86emuOp_repe(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("REPE\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_PREFIX_REPE; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xf4 +****************************************************************************/ +static void +x86emuOp_halt(u8 X86EMU_UNUSED(op1)) +{ + START_OF_INSTR(); + DECODE_PRINTF("HALT\n"); + TRACE_AND_STEP(); + HALT_SYS(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xf5 +****************************************************************************/ +static void +x86emuOp_cmc(u8 X86EMU_UNUSED(op1)) +{ + /* complement the carry flag. */ + START_OF_INSTR(); + DECODE_PRINTF("CMC\n"); + TRACE_AND_STEP(); + TOGGLE_FLAG(F_CF); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xf6 +****************************************************************************/ +static void +x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + u8 *destreg; + uint destoffset; + u8 destval, srcval; + + /* long, drawn out code follows. Double switch for a total + of 32 cases. */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: /* mod=00 */ + switch (rh) { + case 0: /* test byte imm */ + DECODE_PRINTF("TEST\tBYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%02x\n", srcval); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + test_byte(destval, srcval); + break; + case 1: + DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); + HALT_SYS(); + break; + case 2: + DECODE_PRINTF("NOT\tBYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = not_byte(destval); + store_data_byte(destoffset, destval); + break; + case 3: + DECODE_PRINTF("NEG\tBYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = neg_byte(destval); + store_data_byte(destoffset, destval); + break; + case 4: + DECODE_PRINTF("MUL\tBYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + mul_byte(destval); + break; + case 5: + DECODE_PRINTF("IMUL\tBYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + imul_byte(destval); + break; + case 6: + DECODE_PRINTF("DIV\tBYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + div_byte(destval); + break; + case 7: + DECODE_PRINTF("IDIV\tBYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + idiv_byte(destval); + break; + } + break; /* end mod==00 */ + case 1: /* mod=01 */ + switch (rh) { + case 0: /* test byte imm */ + DECODE_PRINTF("TEST\tBYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%02x\n", srcval); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + test_byte(destval, srcval); + break; + case 1: + DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); + HALT_SYS(); + break; + case 2: + DECODE_PRINTF("NOT\tBYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = not_byte(destval); + store_data_byte(destoffset, destval); + break; + case 3: + DECODE_PRINTF("NEG\tBYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = neg_byte(destval); + store_data_byte(destoffset, destval); + break; + case 4: + DECODE_PRINTF("MUL\tBYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + mul_byte(destval); + break; + case 5: + DECODE_PRINTF("IMUL\tBYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + imul_byte(destval); + break; + case 6: + DECODE_PRINTF("DIV\tBYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + div_byte(destval); + break; + case 7: + DECODE_PRINTF("IDIV\tBYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + idiv_byte(destval); + break; + } + break; /* end mod==01 */ + case 2: /* mod=10 */ + switch (rh) { + case 0: /* test byte imm */ + DECODE_PRINTF("TEST\tBYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%02x\n", srcval); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + test_byte(destval, srcval); + break; + case 1: + DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); + HALT_SYS(); + break; + case 2: + DECODE_PRINTF("NOT\tBYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = not_byte(destval); + store_data_byte(destoffset, destval); + break; + case 3: + DECODE_PRINTF("NEG\tBYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = neg_byte(destval); + store_data_byte(destoffset, destval); + break; + case 4: + DECODE_PRINTF("MUL\tBYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + mul_byte(destval); + break; + case 5: + DECODE_PRINTF("IMUL\tBYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + imul_byte(destval); + break; + case 6: + DECODE_PRINTF("DIV\tBYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + div_byte(destval); + break; + case 7: + DECODE_PRINTF("IDIV\tBYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + idiv_byte(destval); + break; + } + break; /* end mod==10 */ + case 3: /* mod=11 */ + switch (rh) { + case 0: /* test byte imm */ + DECODE_PRINTF("TEST\t"); + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF(","); + srcval = fetch_byte_imm(); + DECODE_PRINTF2("%02x\n", srcval); + TRACE_AND_STEP(); + test_byte(*destreg, srcval); + break; + case 1: + DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); + HALT_SYS(); + break; + case 2: + DECODE_PRINTF("NOT\t"); + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = not_byte(*destreg); + break; + case 3: + DECODE_PRINTF("NEG\t"); + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = neg_byte(*destreg); + break; + case 4: + DECODE_PRINTF("MUL\t"); + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + mul_byte(*destreg); /*!!! */ + break; + case 5: + DECODE_PRINTF("IMUL\t"); + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + imul_byte(*destreg); + break; + case 6: + DECODE_PRINTF("DIV\t"); + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + div_byte(*destreg); + break; + case 7: + DECODE_PRINTF("IDIV\t"); + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + idiv_byte(*destreg); + break; + } + break; /* end mod==11 */ + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xf7 +****************************************************************************/ +static void +x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rl, rh; + uint destoffset; + + /* long, drawn out code follows. Double switch for a total + of 32 cases. */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: /* mod=00 */ + switch (rh) { + case 0: /* test word imm */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, srcval; + + DECODE_PRINTF("TEST\tDWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + srcval = fetch_long_imm(); + DECODE_PRINTF2("%x\n", srcval); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + test_long(destval, srcval); + } + else { + u16 destval, srcval; + + DECODE_PRINTF("TEST\tWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + srcval = fetch_word_imm(); + DECODE_PRINTF2("%x\n", srcval); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + test_word(destval, srcval); + } + break; + case 1: + DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); + HALT_SYS(); + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("NOT\tDWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = not_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("NOT\tWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = not_word(destval); + store_data_word(destoffset, destval); + } + break; + case 3: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("NEG\tDWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = neg_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("NEG\tWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = neg_word(destval); + store_data_word(destoffset, destval); + } + break; + case 4: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("MUL\tDWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + mul_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("MUL\tWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + mul_word(destval); + } + break; + case 5: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("IMUL\tDWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + imul_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("IMUL\tWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + imul_word(destval); + } + break; + case 6: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DIV\tDWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + div_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("DIV\tWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + div_word(destval); + } + break; + case 7: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("IDIV\tDWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + idiv_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("IDIV\tWORD PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + idiv_word(destval); + } + break; + } + break; /* end mod==00 */ + case 1: /* mod=01 */ + switch (rh) { + case 0: /* test word imm */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, srcval; + + DECODE_PRINTF("TEST\tDWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + srcval = fetch_long_imm(); + DECODE_PRINTF2("%x\n", srcval); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + test_long(destval, srcval); + } + else { + u16 destval, srcval; + + DECODE_PRINTF("TEST\tWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + srcval = fetch_word_imm(); + DECODE_PRINTF2("%x\n", srcval); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + test_word(destval, srcval); + } + break; + case 1: + DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); + HALT_SYS(); + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("NOT\tDWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = not_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("NOT\tWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = not_word(destval); + store_data_word(destoffset, destval); + } + break; + case 3: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("NEG\tDWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = neg_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("NEG\tWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = neg_word(destval); + store_data_word(destoffset, destval); + } + break; + case 4: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("MUL\tDWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + mul_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("MUL\tWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + mul_word(destval); + } + break; + case 5: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("IMUL\tDWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + imul_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("IMUL\tWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + imul_word(destval); + } + break; + case 6: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DIV\tDWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + div_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("DIV\tWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + div_word(destval); + } + break; + case 7: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("IDIV\tDWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + idiv_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("IDIV\tWORD PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + idiv_word(destval); + } + break; + } + break; /* end mod==01 */ + case 2: /* mod=10 */ + switch (rh) { + case 0: /* test word imm */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval, srcval; + + DECODE_PRINTF("TEST\tDWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + srcval = fetch_long_imm(); + DECODE_PRINTF2("%x\n", srcval); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + test_long(destval, srcval); + } + else { + u16 destval, srcval; + + DECODE_PRINTF("TEST\tWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + srcval = fetch_word_imm(); + DECODE_PRINTF2("%x\n", srcval); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + test_word(destval, srcval); + } + break; + case 1: + DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); + HALT_SYS(); + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("NOT\tDWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = not_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("NOT\tWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = not_word(destval); + store_data_word(destoffset, destval); + } + break; + case 3: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("NEG\tDWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = neg_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + DECODE_PRINTF("NEG\tWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = neg_word(destval); + store_data_word(destoffset, destval); + } + break; + case 4: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("MUL\tDWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + mul_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("MUL\tWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + mul_word(destval); + } + break; + case 5: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("IMUL\tDWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + imul_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("IMUL\tWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + imul_word(destval); + } + break; + case 6: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("DIV\tDWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + div_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("DIV\tWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + div_word(destval); + } + break; + case 7: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + DECODE_PRINTF("IDIV\tDWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + idiv_long(destval); + } + else { + u16 destval; + + DECODE_PRINTF("IDIV\tWORD PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + idiv_word(destval); + } + break; + } + break; /* end mod==10 */ + case 3: /* mod=11 */ + switch (rh) { + case 0: /* test word imm */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + DECODE_PRINTF("TEST\t"); + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + srcval = fetch_long_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + test_long(*destreg, srcval); + } + else { + u16 *destreg; + u16 srcval; + + DECODE_PRINTF("TEST\t"); + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + srcval = fetch_word_imm(); + DECODE_PRINTF2("%x\n", srcval); + TRACE_AND_STEP(); + test_word(*destreg, srcval); + } + break; + case 1: + DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); + HALT_SYS(); + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + DECODE_PRINTF("NOT\t"); + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = not_long(*destreg); + } + else { + u16 *destreg; + + DECODE_PRINTF("NOT\t"); + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = not_word(*destreg); + } + break; + case 3: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + DECODE_PRINTF("NEG\t"); + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = neg_long(*destreg); + } + else { + u16 *destreg; + + DECODE_PRINTF("NEG\t"); + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = neg_word(*destreg); + } + break; + case 4: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + DECODE_PRINTF("MUL\t"); + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + mul_long(*destreg); /*!!! */ + } + else { + u16 *destreg; + + DECODE_PRINTF("MUL\t"); + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + mul_word(*destreg); /*!!! */ + } + break; + case 5: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + DECODE_PRINTF("IMUL\t"); + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + imul_long(*destreg); + } + else { + u16 *destreg; + + DECODE_PRINTF("IMUL\t"); + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + imul_word(*destreg); + } + break; + case 6: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + DECODE_PRINTF("DIV\t"); + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + div_long(*destreg); + } + else { + u16 *destreg; + + DECODE_PRINTF("DIV\t"); + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + div_word(*destreg); + } + break; + case 7: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + DECODE_PRINTF("IDIV\t"); + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + idiv_long(*destreg); + } + else { + u16 *destreg; + + DECODE_PRINTF("IDIV\t"); + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + idiv_word(*destreg); + } + break; + } + break; /* end mod==11 */ + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xf8 +****************************************************************************/ +static void +x86emuOp_clc(u8 X86EMU_UNUSED(op1)) +{ + /* clear the carry flag. */ + START_OF_INSTR(); + DECODE_PRINTF("CLC\n"); + TRACE_AND_STEP(); + CLEAR_FLAG(F_CF); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xf9 +****************************************************************************/ +static void +x86emuOp_stc(u8 X86EMU_UNUSED(op1)) +{ + /* set the carry flag. */ + START_OF_INSTR(); + DECODE_PRINTF("STC\n"); + TRACE_AND_STEP(); + SET_FLAG(F_CF); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xfa +****************************************************************************/ +static void +x86emuOp_cli(u8 X86EMU_UNUSED(op1)) +{ + /* clear interrupts. */ + START_OF_INSTR(); + DECODE_PRINTF("CLI\n"); + TRACE_AND_STEP(); + CLEAR_FLAG(F_IF); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xfb +****************************************************************************/ +static void +x86emuOp_sti(u8 X86EMU_UNUSED(op1)) +{ + /* enable interrupts. */ + START_OF_INSTR(); + DECODE_PRINTF("STI\n"); + TRACE_AND_STEP(); + SET_FLAG(F_IF); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xfc +****************************************************************************/ +static void +x86emuOp_cld(u8 X86EMU_UNUSED(op1)) +{ + /* clear interrupts. */ + START_OF_INSTR(); + DECODE_PRINTF("CLD\n"); + TRACE_AND_STEP(); + CLEAR_FLAG(F_DF); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xfd +****************************************************************************/ +static void +x86emuOp_std(u8 X86EMU_UNUSED(op1)) +{ + /* clear interrupts. */ + START_OF_INSTR(); + DECODE_PRINTF("STD\n"); + TRACE_AND_STEP(); + SET_FLAG(F_DF); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xfe +****************************************************************************/ +static void +x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rh, rl; + u8 destval; + uint destoffset; + u8 *destreg; + + /* Yet another special case instruction. */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + + switch (rh) { + case 0: + DECODE_PRINTF("INC\t"); + break; + case 1: + DECODE_PRINTF("DEC\t"); + break; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); + HALT_SYS(); + break; + } + } +#endif + switch (mod) { + case 0: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + switch (rh) { + case 0: /* inc word ptr ... */ + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = inc_byte(destval); + store_data_byte(destoffset, destval); + break; + case 1: /* dec word ptr ... */ + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = dec_byte(destval); + store_data_byte(destoffset, destval); + break; + } + break; + case 1: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + switch (rh) { + case 0: + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = inc_byte(destval); + store_data_byte(destoffset, destval); + break; + case 1: + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = dec_byte(destval); + store_data_byte(destoffset, destval); + break; + } + break; + case 2: + DECODE_PRINTF("BYTE PTR "); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + switch (rh) { + case 0: + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = inc_byte(destval); + store_data_byte(destoffset, destval); + break; + case 1: + destval = fetch_data_byte(destoffset); + TRACE_AND_STEP(); + destval = dec_byte(destval); + store_data_byte(destoffset, destval); + break; + } + break; + case 3: + destreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + switch (rh) { + case 0: + TRACE_AND_STEP(); + *destreg = inc_byte(*destreg); + break; + case 1: + TRACE_AND_STEP(); + *destreg = dec_byte(*destreg); + break; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0xff +****************************************************************************/ +static void +x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) +{ + int mod, rh, rl; + uint destoffset = 0; + u16 *destreg; + u16 destval, destval2; + + /* Yet another special case instruction. */ + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); +#ifdef DEBUG + if (DEBUG_DECODE()) { + /* XXX DECODE_PRINTF may be changed to something more + general, so that it is important to leave the strings + in the same format, even though the result is that the + above test is done twice. */ + + switch (rh) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("INC\tDWORD PTR "); + } + else { + DECODE_PRINTF("INC\tWORD PTR "); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + DECODE_PRINTF("DEC\tDWORD PTR "); + } + else { + DECODE_PRINTF("DEC\tWORD PTR "); + } + break; + case 2: + DECODE_PRINTF("CALL\t"); + break; + case 3: + DECODE_PRINTF("CALL\tFAR "); + break; + case 4: + DECODE_PRINTF("JMP\t"); + break; + case 5: + DECODE_PRINTF("JMP\tFAR "); + break; + case 6: + DECODE_PRINTF("PUSH\t"); + break; + case 7: + DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); + HALT_SYS(); + break; + } + } +#endif + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + switch (rh) { + case 0: /* inc word ptr ... */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = inc_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = inc_word(destval); + store_data_word(destoffset, destval); + } + break; + case 1: /* dec word ptr ... */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = dec_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = dec_word(destval); + store_data_word(destoffset, destval); + } + break; + case 2: /* call word ptr ... */ + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + push_word(M.x86.R_IP); + M.x86.R_IP = destval; + break; + case 3: /* call far ptr ... */ + destval = fetch_data_word(destoffset); + destval2 = fetch_data_word(destoffset + 2); + TRACE_AND_STEP(); + push_word(M.x86.R_CS); + M.x86.R_CS = destval2; + push_word(M.x86.R_IP); + M.x86.R_IP = destval; + break; + case 4: /* jmp word ptr ... */ + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + M.x86.R_IP = destval; + break; + case 5: /* jmp far ptr ... */ + destval = fetch_data_word(destoffset); + destval2 = fetch_data_word(destoffset + 2); + TRACE_AND_STEP(); + M.x86.R_IP = destval; + M.x86.R_CS = destval2; + break; + case 6: /* push word ptr ... */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + push_long(destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + push_word(destval); + } + break; + } + break; + case 1: + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + switch (rh) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = inc_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = inc_word(destval); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = dec_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = dec_word(destval); + store_data_word(destoffset, destval); + } + break; + case 2: /* call word ptr ... */ + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + push_word(M.x86.R_IP); + M.x86.R_IP = destval; + break; + case 3: /* call far ptr ... */ + destval = fetch_data_word(destoffset); + destval2 = fetch_data_word(destoffset + 2); + TRACE_AND_STEP(); + push_word(M.x86.R_CS); + M.x86.R_CS = destval2; + push_word(M.x86.R_IP); + M.x86.R_IP = destval; + break; + case 4: /* jmp word ptr ... */ + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + M.x86.R_IP = destval; + break; + case 5: /* jmp far ptr ... */ + destval = fetch_data_word(destoffset); + destval2 = fetch_data_word(destoffset + 2); + TRACE_AND_STEP(); + M.x86.R_IP = destval; + M.x86.R_CS = destval2; + break; + case 6: /* push word ptr ... */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + push_long(destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + push_word(destval); + } + break; + } + break; + case 2: + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + switch (rh) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = inc_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = inc_word(destval); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + destval = dec_long(destval); + store_data_long(destoffset, destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + destval = dec_word(destval); + store_data_word(destoffset, destval); + } + break; + case 2: /* call word ptr ... */ + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + push_word(M.x86.R_IP); + M.x86.R_IP = destval; + break; + case 3: /* call far ptr ... */ + destval = fetch_data_word(destoffset); + destval2 = fetch_data_word(destoffset + 2); + TRACE_AND_STEP(); + push_word(M.x86.R_CS); + M.x86.R_CS = destval2; + push_word(M.x86.R_IP); + M.x86.R_IP = destval; + break; + case 4: /* jmp word ptr ... */ + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + M.x86.R_IP = destval; + break; + case 5: /* jmp far ptr ... */ + destval = fetch_data_word(destoffset); + destval2 = fetch_data_word(destoffset + 2); + TRACE_AND_STEP(); + M.x86.R_IP = destval; + M.x86.R_CS = destval2; + break; + case 6: /* push word ptr ... */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + + destval = fetch_data_long(destoffset); + TRACE_AND_STEP(); + push_long(destval); + } + else { + u16 destval; + + destval = fetch_data_word(destoffset); + TRACE_AND_STEP(); + push_word(destval); + } + break; + } + break; + case 3: + switch (rh) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = inc_long(*destreg); + } + else { + u16 *destreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = inc_word(*destreg); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = dec_long(*destreg); + } + else { + u16 *destreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = dec_word(*destreg); + } + break; + case 2: /* call word ptr ... */ + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + push_word(M.x86.R_IP); + M.x86.R_IP = *destreg; + break; + case 3: /* jmp far ptr ... */ + DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); + TRACE_AND_STEP(); + HALT_SYS(); + break; + + case 4: /* jmp ... */ + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + M.x86.R_IP = (u16) (*destreg); + break; + case 5: /* jmp far ptr ... */ + DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); + TRACE_AND_STEP(); + HALT_SYS(); + break; + case 6: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + push_long(*destreg); + } + else { + u16 *destreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + push_word(*destreg); + } + break; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/*************************************************************************** + * Single byte operation code table: + **************************************************************************/ +void (*x86emu_optab[256]) (u8) = { +/* 0x00 */ x86emuOp_add_byte_RM_R, +/* 0x01 */ x86emuOp_add_word_RM_R, +/* 0x02 */ x86emuOp_add_byte_R_RM, +/* 0x03 */ x86emuOp_add_word_R_RM, +/* 0x04 */ x86emuOp_add_byte_AL_IMM, +/* 0x05 */ x86emuOp_add_word_AX_IMM, +/* 0x06 */ x86emuOp_push_ES, +/* 0x07 */ x86emuOp_pop_ES, +/* 0x08 */ x86emuOp_or_byte_RM_R, +/* 0x09 */ x86emuOp_or_word_RM_R, +/* 0x0a */ x86emuOp_or_byte_R_RM, +/* 0x0b */ x86emuOp_or_word_R_RM, +/* 0x0c */ x86emuOp_or_byte_AL_IMM, +/* 0x0d */ x86emuOp_or_word_AX_IMM, +/* 0x0e */ x86emuOp_push_CS, +/* 0x0f */ x86emuOp_two_byte, +/* 0x10 */ x86emuOp_adc_byte_RM_R, +/* 0x11 */ x86emuOp_adc_word_RM_R, +/* 0x12 */ x86emuOp_adc_byte_R_RM, +/* 0x13 */ x86emuOp_adc_word_R_RM, +/* 0x14 */ x86emuOp_adc_byte_AL_IMM, +/* 0x15 */ x86emuOp_adc_word_AX_IMM, +/* 0x16 */ x86emuOp_push_SS, +/* 0x17 */ x86emuOp_pop_SS, +/* 0x18 */ x86emuOp_sbb_byte_RM_R, +/* 0x19 */ x86emuOp_sbb_word_RM_R, +/* 0x1a */ x86emuOp_sbb_byte_R_RM, +/* 0x1b */ x86emuOp_sbb_word_R_RM, +/* 0x1c */ x86emuOp_sbb_byte_AL_IMM, +/* 0x1d */ x86emuOp_sbb_word_AX_IMM, +/* 0x1e */ x86emuOp_push_DS, +/* 0x1f */ x86emuOp_pop_DS, +/* 0x20 */ x86emuOp_and_byte_RM_R, +/* 0x21 */ x86emuOp_and_word_RM_R, +/* 0x22 */ x86emuOp_and_byte_R_RM, +/* 0x23 */ x86emuOp_and_word_R_RM, +/* 0x24 */ x86emuOp_and_byte_AL_IMM, +/* 0x25 */ x86emuOp_and_word_AX_IMM, +/* 0x26 */ x86emuOp_segovr_ES, +/* 0x27 */ x86emuOp_daa, +/* 0x28 */ x86emuOp_sub_byte_RM_R, +/* 0x29 */ x86emuOp_sub_word_RM_R, +/* 0x2a */ x86emuOp_sub_byte_R_RM, +/* 0x2b */ x86emuOp_sub_word_R_RM, +/* 0x2c */ x86emuOp_sub_byte_AL_IMM, +/* 0x2d */ x86emuOp_sub_word_AX_IMM, +/* 0x2e */ x86emuOp_segovr_CS, +/* 0x2f */ x86emuOp_das, +/* 0x30 */ x86emuOp_xor_byte_RM_R, +/* 0x31 */ x86emuOp_xor_word_RM_R, +/* 0x32 */ x86emuOp_xor_byte_R_RM, +/* 0x33 */ x86emuOp_xor_word_R_RM, +/* 0x34 */ x86emuOp_xor_byte_AL_IMM, +/* 0x35 */ x86emuOp_xor_word_AX_IMM, +/* 0x36 */ x86emuOp_segovr_SS, +/* 0x37 */ x86emuOp_aaa, +/* 0x38 */ x86emuOp_cmp_byte_RM_R, +/* 0x39 */ x86emuOp_cmp_word_RM_R, +/* 0x3a */ x86emuOp_cmp_byte_R_RM, +/* 0x3b */ x86emuOp_cmp_word_R_RM, +/* 0x3c */ x86emuOp_cmp_byte_AL_IMM, +/* 0x3d */ x86emuOp_cmp_word_AX_IMM, +/* 0x3e */ x86emuOp_segovr_DS, +/* 0x3f */ x86emuOp_aas, +/* 0x40 */ x86emuOp_inc_AX, +/* 0x41 */ x86emuOp_inc_CX, +/* 0x42 */ x86emuOp_inc_DX, +/* 0x43 */ x86emuOp_inc_BX, +/* 0x44 */ x86emuOp_inc_SP, +/* 0x45 */ x86emuOp_inc_BP, +/* 0x46 */ x86emuOp_inc_SI, +/* 0x47 */ x86emuOp_inc_DI, +/* 0x48 */ x86emuOp_dec_AX, +/* 0x49 */ x86emuOp_dec_CX, +/* 0x4a */ x86emuOp_dec_DX, +/* 0x4b */ x86emuOp_dec_BX, +/* 0x4c */ x86emuOp_dec_SP, +/* 0x4d */ x86emuOp_dec_BP, +/* 0x4e */ x86emuOp_dec_SI, +/* 0x4f */ x86emuOp_dec_DI, +/* 0x50 */ x86emuOp_push_AX, +/* 0x51 */ x86emuOp_push_CX, +/* 0x52 */ x86emuOp_push_DX, +/* 0x53 */ x86emuOp_push_BX, +/* 0x54 */ x86emuOp_push_SP, +/* 0x55 */ x86emuOp_push_BP, +/* 0x56 */ x86emuOp_push_SI, +/* 0x57 */ x86emuOp_push_DI, +/* 0x58 */ x86emuOp_pop_AX, +/* 0x59 */ x86emuOp_pop_CX, +/* 0x5a */ x86emuOp_pop_DX, +/* 0x5b */ x86emuOp_pop_BX, +/* 0x5c */ x86emuOp_pop_SP, +/* 0x5d */ x86emuOp_pop_BP, +/* 0x5e */ x86emuOp_pop_SI, +/* 0x5f */ x86emuOp_pop_DI, +/* 0x60 */ x86emuOp_push_all, +/* 0x61 */ x86emuOp_pop_all, + /* 0x62 */ x86emuOp_illegal_op, + /* bound */ + /* 0x63 */ x86emuOp_illegal_op, + /* arpl */ +/* 0x64 */ x86emuOp_segovr_FS, +/* 0x65 */ x86emuOp_segovr_GS, +/* 0x66 */ x86emuOp_prefix_data, +/* 0x67 */ x86emuOp_prefix_addr, +/* 0x68 */ x86emuOp_push_word_IMM, +/* 0x69 */ x86emuOp_imul_word_IMM, +/* 0x6a */ x86emuOp_push_byte_IMM, +/* 0x6b */ x86emuOp_imul_byte_IMM, +/* 0x6c */ x86emuOp_ins_byte, +/* 0x6d */ x86emuOp_ins_word, +/* 0x6e */ x86emuOp_outs_byte, +/* 0x6f */ x86emuOp_outs_word, +/* 0x70 */ x86emuOp_jump_near_O, +/* 0x71 */ x86emuOp_jump_near_NO, +/* 0x72 */ x86emuOp_jump_near_B, +/* 0x73 */ x86emuOp_jump_near_NB, +/* 0x74 */ x86emuOp_jump_near_Z, +/* 0x75 */ x86emuOp_jump_near_NZ, +/* 0x76 */ x86emuOp_jump_near_BE, +/* 0x77 */ x86emuOp_jump_near_NBE, +/* 0x78 */ x86emuOp_jump_near_S, +/* 0x79 */ x86emuOp_jump_near_NS, +/* 0x7a */ x86emuOp_jump_near_P, +/* 0x7b */ x86emuOp_jump_near_NP, +/* 0x7c */ x86emuOp_jump_near_L, +/* 0x7d */ x86emuOp_jump_near_NL, +/* 0x7e */ x86emuOp_jump_near_LE, +/* 0x7f */ x86emuOp_jump_near_NLE, +/* 0x80 */ x86emuOp_opc80_byte_RM_IMM, +/* 0x81 */ x86emuOp_opc81_word_RM_IMM, +/* 0x82 */ x86emuOp_opc82_byte_RM_IMM, +/* 0x83 */ x86emuOp_opc83_word_RM_IMM, +/* 0x84 */ x86emuOp_test_byte_RM_R, +/* 0x85 */ x86emuOp_test_word_RM_R, +/* 0x86 */ x86emuOp_xchg_byte_RM_R, +/* 0x87 */ x86emuOp_xchg_word_RM_R, +/* 0x88 */ x86emuOp_mov_byte_RM_R, +/* 0x89 */ x86emuOp_mov_word_RM_R, +/* 0x8a */ x86emuOp_mov_byte_R_RM, +/* 0x8b */ x86emuOp_mov_word_R_RM, +/* 0x8c */ x86emuOp_mov_word_RM_SR, +/* 0x8d */ x86emuOp_lea_word_R_M, +/* 0x8e */ x86emuOp_mov_word_SR_RM, +/* 0x8f */ x86emuOp_pop_RM, +/* 0x90 */ x86emuOp_nop, +/* 0x91 */ x86emuOp_xchg_word_AX_CX, +/* 0x92 */ x86emuOp_xchg_word_AX_DX, +/* 0x93 */ x86emuOp_xchg_word_AX_BX, +/* 0x94 */ x86emuOp_xchg_word_AX_SP, +/* 0x95 */ x86emuOp_xchg_word_AX_BP, +/* 0x96 */ x86emuOp_xchg_word_AX_SI, +/* 0x97 */ x86emuOp_xchg_word_AX_DI, +/* 0x98 */ x86emuOp_cbw, +/* 0x99 */ x86emuOp_cwd, +/* 0x9a */ x86emuOp_call_far_IMM, +/* 0x9b */ x86emuOp_wait, +/* 0x9c */ x86emuOp_pushf_word, +/* 0x9d */ x86emuOp_popf_word, +/* 0x9e */ x86emuOp_sahf, +/* 0x9f */ x86emuOp_lahf, +/* 0xa0 */ x86emuOp_mov_AL_M_IMM, +/* 0xa1 */ x86emuOp_mov_AX_M_IMM, +/* 0xa2 */ x86emuOp_mov_M_AL_IMM, +/* 0xa3 */ x86emuOp_mov_M_AX_IMM, +/* 0xa4 */ x86emuOp_movs_byte, +/* 0xa5 */ x86emuOp_movs_word, +/* 0xa6 */ x86emuOp_cmps_byte, +/* 0xa7 */ x86emuOp_cmps_word, +/* 0xa8 */ x86emuOp_test_AL_IMM, +/* 0xa9 */ x86emuOp_test_AX_IMM, +/* 0xaa */ x86emuOp_stos_byte, +/* 0xab */ x86emuOp_stos_word, +/* 0xac */ x86emuOp_lods_byte, +/* 0xad */ x86emuOp_lods_word, +/* 0xac */ x86emuOp_scas_byte, +/* 0xad */ x86emuOp_scas_word, +/* 0xb0 */ x86emuOp_mov_byte_AL_IMM, +/* 0xb1 */ x86emuOp_mov_byte_CL_IMM, +/* 0xb2 */ x86emuOp_mov_byte_DL_IMM, +/* 0xb3 */ x86emuOp_mov_byte_BL_IMM, +/* 0xb4 */ x86emuOp_mov_byte_AH_IMM, +/* 0xb5 */ x86emuOp_mov_byte_CH_IMM, +/* 0xb6 */ x86emuOp_mov_byte_DH_IMM, +/* 0xb7 */ x86emuOp_mov_byte_BH_IMM, +/* 0xb8 */ x86emuOp_mov_word_AX_IMM, +/* 0xb9 */ x86emuOp_mov_word_CX_IMM, +/* 0xba */ x86emuOp_mov_word_DX_IMM, +/* 0xbb */ x86emuOp_mov_word_BX_IMM, +/* 0xbc */ x86emuOp_mov_word_SP_IMM, +/* 0xbd */ x86emuOp_mov_word_BP_IMM, +/* 0xbe */ x86emuOp_mov_word_SI_IMM, +/* 0xbf */ x86emuOp_mov_word_DI_IMM, +/* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM, +/* 0xc1 */ x86emuOp_opcC1_word_RM_MEM, +/* 0xc2 */ x86emuOp_ret_near_IMM, +/* 0xc3 */ x86emuOp_ret_near, +/* 0xc4 */ x86emuOp_les_R_IMM, +/* 0xc5 */ x86emuOp_lds_R_IMM, +/* 0xc6 */ x86emuOp_mov_byte_RM_IMM, +/* 0xc7 */ x86emuOp_mov_word_RM_IMM, +/* 0xc8 */ x86emuOp_enter, +/* 0xc9 */ x86emuOp_leave, +/* 0xca */ x86emuOp_ret_far_IMM, +/* 0xcb */ x86emuOp_ret_far, +/* 0xcc */ x86emuOp_int3, +/* 0xcd */ x86emuOp_int_IMM, +/* 0xce */ x86emuOp_into, +/* 0xcf */ x86emuOp_iret, +/* 0xd0 */ x86emuOp_opcD0_byte_RM_1, +/* 0xd1 */ x86emuOp_opcD1_word_RM_1, +/* 0xd2 */ x86emuOp_opcD2_byte_RM_CL, +/* 0xd3 */ x86emuOp_opcD3_word_RM_CL, +/* 0xd4 */ x86emuOp_aam, +/* 0xd5 */ x86emuOp_aad, + /* 0xd6 */ x86emuOp_illegal_op, + /* Undocumented SETALC instruction */ +/* 0xd7 */ x86emuOp_xlat, +/* 0xd8 */ x86emuOp_esc_coprocess_d8, +/* 0xd9 */ x86emuOp_esc_coprocess_d9, +/* 0xda */ x86emuOp_esc_coprocess_da, +/* 0xdb */ x86emuOp_esc_coprocess_db, +/* 0xdc */ x86emuOp_esc_coprocess_dc, +/* 0xdd */ x86emuOp_esc_coprocess_dd, +/* 0xde */ x86emuOp_esc_coprocess_de, +/* 0xdf */ x86emuOp_esc_coprocess_df, +/* 0xe0 */ x86emuOp_loopne, +/* 0xe1 */ x86emuOp_loope, +/* 0xe2 */ x86emuOp_loop, +/* 0xe3 */ x86emuOp_jcxz, +/* 0xe4 */ x86emuOp_in_byte_AL_IMM, +/* 0xe5 */ x86emuOp_in_word_AX_IMM, +/* 0xe6 */ x86emuOp_out_byte_IMM_AL, +/* 0xe7 */ x86emuOp_out_word_IMM_AX, +/* 0xe8 */ x86emuOp_call_near_IMM, +/* 0xe9 */ x86emuOp_jump_near_IMM, +/* 0xea */ x86emuOp_jump_far_IMM, +/* 0xeb */ x86emuOp_jump_byte_IMM, +/* 0xec */ x86emuOp_in_byte_AL_DX, +/* 0xed */ x86emuOp_in_word_AX_DX, +/* 0xee */ x86emuOp_out_byte_DX_AL, +/* 0xef */ x86emuOp_out_word_DX_AX, +/* 0xf0 */ x86emuOp_lock, +/* 0xf1 */ x86emuOp_illegal_op, +/* 0xf2 */ x86emuOp_repne, +/* 0xf3 */ x86emuOp_repe, +/* 0xf4 */ x86emuOp_halt, +/* 0xf5 */ x86emuOp_cmc, +/* 0xf6 */ x86emuOp_opcF6_byte_RM, +/* 0xf7 */ x86emuOp_opcF7_word_RM, +/* 0xf8 */ x86emuOp_clc, +/* 0xf9 */ x86emuOp_stc, +/* 0xfa */ x86emuOp_cli, +/* 0xfb */ x86emuOp_sti, +/* 0xfc */ x86emuOp_cld, +/* 0xfd */ x86emuOp_std, +/* 0xfe */ x86emuOp_opcFE_byte_RM, +/* 0xff */ x86emuOp_opcFF_word_RM, +}; diff --git a/src/libs/x86emu/ops2.c b/src/libs/x86emu/ops2.c new file mode 100644 index 0000000000..5ed2bf68d3 --- /dev/null +++ b/src/libs/x86emu/ops2.c @@ -0,0 +1,3008 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: This file includes subroutines to implement the decoding +* and emulation of all the x86 extended two-byte processor +* instructions. +* +****************************************************************************/ + +#include "x86emu/x86emui.h" + +#undef bswap_32 +#define bswap_32(x) (((x & 0xff000000) >> 24) | \ + ((x & 0x00ff0000) >> 8) | \ + ((x & 0x0000ff00) << 8) | \ + ((x & 0x000000ff) << 24)) + +/*----------------------------- Implementation ----------------------------*/ + +/**************************************************************************** +PARAMETERS: +op1 - Instruction op code + +REMARKS: +Handles illegal opcodes. +****************************************************************************/ +static void +x86emuOp2_illegal_op(u8 op2) +{ + START_OF_INSTR(); + DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); + TRACE_REGS(); + printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n", + M.x86.R_CS, M.x86.R_IP - 2, op2); + HALT_SYS(); + END_OF_INSTR(); +} + +#define xorl(a,b) ((a) && !(b)) || (!(a) && (b)) + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0x31 +****************************************************************************/ +static void +x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2)) +{ +#ifdef __HAS_LONG_LONG__ + static u64 counter = 0; +#else + static u32 counter = 0; +#endif + + counter += 0x10000; + + /* read timestamp counter */ + /* + * Note that instead of actually trying to accurately measure this, we just + * increase the counter by a fixed amount every time we hit one of these + * instructions. Feel free to come up with a better method. + */ + START_OF_INSTR(); + DECODE_PRINTF("RDTSC\n"); + TRACE_AND_STEP(); +#ifdef __HAS_LONG_LONG__ + M.x86.R_EAX = counter & 0xffffffff; + M.x86.R_EDX = counter >> 32; +#else + M.x86.R_EAX = counter; + M.x86.R_EDX = 0; +#endif + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0x80-0x8F +****************************************************************************/ +static void +x86emuOp2_long_jump(u8 op2) +{ + s32 target; + const char *name = NULL; + int cond = 0; + + /* conditional jump to word offset. */ + START_OF_INSTR(); + switch (op2) { + case 0x80: + name = "JO\t"; + cond = ACCESS_FLAG(F_OF); + break; + case 0x81: + name = "JNO\t"; + cond = !ACCESS_FLAG(F_OF); + break; + case 0x82: + name = "JB\t"; + cond = ACCESS_FLAG(F_CF); + break; + case 0x83: + name = "JNB\t"; + cond = !ACCESS_FLAG(F_CF); + break; + case 0x84: + name = "JZ\t"; + cond = ACCESS_FLAG(F_ZF); + break; + case 0x85: + name = "JNZ\t"; + cond = !ACCESS_FLAG(F_ZF); + break; + case 0x86: + name = "JBE\t"; + cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); + break; + case 0x87: + name = "JNBE\t"; + cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); + break; + case 0x88: + name = "JS\t"; + cond = ACCESS_FLAG(F_SF); + break; + case 0x89: + name = "JNS\t"; + cond = !ACCESS_FLAG(F_SF); + break; + case 0x8a: + name = "JP\t"; + cond = ACCESS_FLAG(F_PF); + break; + case 0x8b: + name = "JNP\t"; + cond = !ACCESS_FLAG(F_PF); + break; + case 0x8c: + name = "JL\t"; + cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); + break; + case 0x8d: + name = "JNL\t"; + cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))); + break; + case 0x8e: + name = "JLE\t"; + cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || + ACCESS_FLAG(F_ZF)); + break; + case 0x8f: + name = "JNLE\t"; + cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || + ACCESS_FLAG(F_ZF)); + break; + } + DECODE_PRINTF(name); + (void) name; + target = (s16) fetch_word_imm(); + target += (s16) M.x86.R_IP; + DECODE_PRINTF2("%04x\n", target); + TRACE_AND_STEP(); + if (cond) + M.x86.R_IP = (u16) target; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0x90-0x9F +****************************************************************************/ +static void +x86emuOp2_set_byte(u8 op2) +{ + int mod, rl, rh; + uint destoffset; + u8 *destreg; + const char *name = NULL; + int cond = 0; + + START_OF_INSTR(); + switch (op2) { + case 0x90: + name = "SETO\t"; + cond = ACCESS_FLAG(F_OF); + break; + case 0x91: + name = "SETNO\t"; + cond = !ACCESS_FLAG(F_OF); + break; + case 0x92: + name = "SETB\t"; + cond = ACCESS_FLAG(F_CF); + break; + case 0x93: + name = "SETNB\t"; + cond = !ACCESS_FLAG(F_CF); + break; + case 0x94: + name = "SETZ\t"; + cond = ACCESS_FLAG(F_ZF); + break; + case 0x95: + name = "SETNZ\t"; + cond = !ACCESS_FLAG(F_ZF); + break; + case 0x96: + name = "SETBE\t"; + cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); + break; + case 0x97: + name = "SETNBE\t"; + cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); + break; + case 0x98: + name = "SETS\t"; + cond = ACCESS_FLAG(F_SF); + break; + case 0x99: + name = "SETNS\t"; + cond = !ACCESS_FLAG(F_SF); + break; + case 0x9a: + name = "SETP\t"; + cond = ACCESS_FLAG(F_PF); + break; + case 0x9b: + name = "SETNP\t"; + cond = !ACCESS_FLAG(F_PF); + break; + case 0x9c: + name = "SETL\t"; + cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); + break; + case 0x9d: + name = "SETNL\t"; + cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); + break; + case 0x9e: + name = "SETLE\t"; + cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || + ACCESS_FLAG(F_ZF)); + break; + case 0x9f: + name = "SETNLE\t"; + cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || + ACCESS_FLAG(F_ZF)); + break; + } + DECODE_PRINTF(name); + (void) name; + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destoffset = decode_rm00_address(rl); + TRACE_AND_STEP(); + store_data_byte(destoffset, cond ? 0x01 : 0x00); + break; + case 1: + destoffset = decode_rm01_address(rl); + TRACE_AND_STEP(); + store_data_byte(destoffset, cond ? 0x01 : 0x00); + break; + case 2: + destoffset = decode_rm10_address(rl); + TRACE_AND_STEP(); + store_data_byte(destoffset, cond ? 0x01 : 0x00); + break; + case 3: /* register to register */ + destreg = DECODE_RM_BYTE_REGISTER(rl); + TRACE_AND_STEP(); + *destreg = cond ? 0x01 : 0x00; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xa0 +****************************************************************************/ +static void +x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2)) +{ + START_OF_INSTR(); + DECODE_PRINTF("PUSH\tFS\n"); + TRACE_AND_STEP(); + push_word(M.x86.R_FS); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xa1 +****************************************************************************/ +static void +x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2)) +{ + START_OF_INSTR(); + DECODE_PRINTF("POP\tFS\n"); + TRACE_AND_STEP(); + M.x86.R_FS = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output +Handles opcode 0x0f,0xa2 +****************************************************************************/ +static void +x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2)) +{ + START_OF_INSTR(); + DECODE_PRINTF("CPUID\n"); + TRACE_AND_STEP(); + cpuid(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xa3 +****************************************************************************/ +static void +x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + int bit, disp; + + START_OF_INSTR(); + DECODE_PRINTF("BT\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval; + u32 *shiftreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); + } + else { + u16 srcval; + u16 *shiftreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval; + u32 *shiftreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); + } + else { + u16 srcval; + u16 *shiftreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval; + u32 *shiftreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); + } + else { + u16 srcval; + u16 *shiftreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg, *shiftreg; + + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF); + } + else { + u16 *srcreg, *shiftreg; + + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xa4 +****************************************************************************/ +static void +x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint destoffset; + u8 shift; + + START_OF_INSTR(); + DECODE_PRINTF("SHLD\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shld_long(destval, *shiftreg, shift); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shld_word(destval, *shiftreg, shift); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shld_long(destval, *shiftreg, shift); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shld_word(destval, *shiftreg, shift); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shld_long(destval, *shiftreg, shift); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shld_word(destval, *shiftreg, shift); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *shiftreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + *destreg = shld_long(*destreg, *shiftreg, shift); + } + else { + u16 *destreg, *shiftreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + *destreg = shld_word(*destreg, *shiftreg, shift); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xa5 +****************************************************************************/ +static void +x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("SHLD\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shld_long(destval, *shiftreg, M.x86.R_CL); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shld_word(destval, *shiftreg, M.x86.R_CL); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shld_long(destval, *shiftreg, M.x86.R_CL); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shld_word(destval, *shiftreg, M.x86.R_CL); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shld_long(destval, *shiftreg, M.x86.R_CL); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shld_word(destval, *shiftreg, M.x86.R_CL); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *shiftreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + *destreg = shld_long(*destreg, *shiftreg, M.x86.R_CL); + } + else { + u16 *destreg, *shiftreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + *destreg = shld_word(*destreg, *shiftreg, M.x86.R_CL); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xa8 +****************************************************************************/ +static void +x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2)) +{ + START_OF_INSTR(); + DECODE_PRINTF("PUSH\tGS\n"); + TRACE_AND_STEP(); + push_word(M.x86.R_GS); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xa9 +****************************************************************************/ +static void +x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2)) +{ + START_OF_INSTR(); + DECODE_PRINTF("POP\tGS\n"); + TRACE_AND_STEP(); + M.x86.R_GS = pop_word(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xab +****************************************************************************/ +static void +x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + int bit, disp; + + START_OF_INSTR(); + DECODE_PRINTF("BTS\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval | mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, srcval | mask); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval | mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, srcval | mask); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval | mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, srcval | mask); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg, *shiftreg; + u32 mask; + + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); + *srcreg |= mask; + } + else { + u16 *srcreg, *shiftreg; + u16 mask; + + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); + *srcreg |= mask; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xac +****************************************************************************/ +static void +x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint destoffset; + u8 shift; + + START_OF_INSTR(); + DECODE_PRINTF("SHLD\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shrd_long(destval, *shiftreg, shift); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shrd_word(destval, *shiftreg, shift); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shrd_long(destval, *shiftreg, shift); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shrd_word(destval, *shiftreg, shift); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shrd_long(destval, *shiftreg, shift); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shrd_word(destval, *shiftreg, shift); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *shiftreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + *destreg = shrd_long(*destreg, *shiftreg, shift); + } + else { + u16 *destreg, *shiftreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + DECODE_PRINTF2("%d\n", shift); + TRACE_AND_STEP(); + *destreg = shrd_word(*destreg, *shiftreg, shift); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xad +****************************************************************************/ +static void +x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint destoffset; + + START_OF_INSTR(); + DECODE_PRINTF("SHLD\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shrd_long(destval, *shiftreg, M.x86.R_CL); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shrd_word(destval, *shiftreg, M.x86.R_CL); + store_data_word(destoffset, destval); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shrd_long(destval, *shiftreg, M.x86.R_CL); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shrd_word(destval, *shiftreg, M.x86.R_CL); + store_data_word(destoffset, destval); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 destval; + u32 *shiftreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_long(destoffset); + destval = shrd_long(destval, *shiftreg, M.x86.R_CL); + store_data_long(destoffset, destval); + } + else { + u16 destval; + u16 *shiftreg; + + destoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + destval = fetch_data_word(destoffset); + destval = shrd_word(destval, *shiftreg, M.x86.R_CL); + store_data_word(destoffset, destval); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *shiftreg; + + destreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + *destreg = shrd_long(*destreg, *shiftreg, M.x86.R_CL); + } + else { + u16 *destreg, *shiftreg; + + destreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(",CL\n"); + TRACE_AND_STEP(); + *destreg = shrd_word(*destreg, *shiftreg, M.x86.R_CL); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xaf +****************************************************************************/ +static void +x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("IMUL\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_long(srcoffset); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + TRACE_AND_STEP(); + res = (s16) * destreg * (s16) srcval; + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_long(srcoffset); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + TRACE_AND_STEP(); + res = (s16) * destreg * (s16) srcval; + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + u32 res_lo, res_hi; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_long(srcoffset); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg; + u16 srcval; + u32 res; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + TRACE_AND_STEP(); + res = (s16) * destreg * (s16) srcval; + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg, *srcreg; + u32 res_lo, res_hi; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_LONG_REGISTER(rl); + TRACE_AND_STEP(); + imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) * srcreg); + if (res_hi != 0) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u32) res_lo; + } + else { + u16 *destreg, *srcreg; + u32 res; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + res = (s16) * destreg * (s16) * srcreg; + if (res > 0xFFFF) { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + *destreg = (u16) res; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xb2 +****************************************************************************/ +static void +x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rh, rl; + u16 *dstreg; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("LSS\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_SS = fetch_data_word(srcoffset + 2); + break; + case 1: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_SS = fetch_data_word(srcoffset + 2); + break; + case 2: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_SS = fetch_data_word(srcoffset + 2); + break; + case 3: /* register to register */ + /* UNDEFINED! */ + TRACE_AND_STEP(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xb3 +****************************************************************************/ +static void +x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + int bit, disp; + + START_OF_INSTR(); + DECODE_PRINTF("BTR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval & ~mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval & ~mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval & ~mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg, *shiftreg; + u32 mask; + + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); + *srcreg &= ~mask; + } + else { + u16 *srcreg, *shiftreg; + u16 mask; + + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); + *srcreg &= ~mask; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xb4 +****************************************************************************/ +static void +x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rh, rl; + u16 *dstreg; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("LFS\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_FS = fetch_data_word(srcoffset + 2); + break; + case 1: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_FS = fetch_data_word(srcoffset + 2); + break; + case 2: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_FS = fetch_data_word(srcoffset + 2); + break; + case 3: /* register to register */ + /* UNDEFINED! */ + TRACE_AND_STEP(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xb5 +****************************************************************************/ +static void +x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rh, rl; + u16 *dstreg; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("LGS\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_GS = fetch_data_word(srcoffset + 2); + break; + case 1: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_GS = fetch_data_word(srcoffset + 2); + break; + case 2: + dstreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *dstreg = fetch_data_word(srcoffset); + M.x86.R_GS = fetch_data_word(srcoffset + 2); + break; + case 3: /* register to register */ + /* UNDEFINED! */ + TRACE_AND_STEP(); + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xb6 +****************************************************************************/ +static void +x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("MOVZX\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_byte(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u8 *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + } + else { + u16 *destreg; + u8 *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xb7 +****************************************************************************/ +static void +x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + u32 *destreg; + u32 srcval; + u16 *srcreg; + + START_OF_INSTR(); + DECODE_PRINTF("MOVZX\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 1: + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 2: + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = fetch_data_word(srcoffset); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 3: /* register to register */ + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = *srcreg; + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xba +****************************************************************************/ +static void +x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + int bit; + + START_OF_INSTR(); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (rh) { + case 4: + DECODE_PRINTF("BT\t"); + break; + case 5: + DECODE_PRINTF("BTS\t"); + break; + case 6: + DECODE_PRINTF("BTR\t"); + break; + case 7: + DECODE_PRINTF("BTC\t"); + break; + default: + DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); + TRACE_REGS(); + printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n", + M.x86.R_CS, M.x86.R_IP - 3, op2, (mod << 6) | (rh << 3) | rl); + HALT_SYS(); + } + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u8 shift; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + TRACE_AND_STEP(); + bit = shift & 0x1F; + srcval = fetch_data_long(srcoffset); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + switch (rh) { + case 5: + store_data_long(srcoffset, srcval | mask); + break; + case 6: + store_data_long(srcoffset, srcval & ~mask); + break; + case 7: + store_data_long(srcoffset, srcval ^ mask); + break; + default: + break; + } + } + else { + u16 srcval, mask; + u8 shift; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + TRACE_AND_STEP(); + bit = shift & 0xF; + srcval = fetch_data_word(srcoffset); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + switch (rh) { + case 5: + store_data_word(srcoffset, srcval | mask); + break; + case 6: + store_data_word(srcoffset, srcval & ~mask); + break; + case 7: + store_data_word(srcoffset, srcval ^ mask); + break; + default: + break; + } + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u8 shift; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + TRACE_AND_STEP(); + bit = shift & 0x1F; + srcval = fetch_data_long(srcoffset); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + switch (rh) { + case 5: + store_data_long(srcoffset, srcval | mask); + break; + case 6: + store_data_long(srcoffset, srcval & ~mask); + break; + case 7: + store_data_long(srcoffset, srcval ^ mask); + break; + default: + break; + } + } + else { + u16 srcval, mask; + u8 shift; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + TRACE_AND_STEP(); + bit = shift & 0xF; + srcval = fetch_data_word(srcoffset); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + switch (rh) { + case 5: + store_data_word(srcoffset, srcval | mask); + break; + case 6: + store_data_word(srcoffset, srcval & ~mask); + break; + case 7: + store_data_word(srcoffset, srcval ^ mask); + break; + default: + break; + } + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u8 shift; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + TRACE_AND_STEP(); + bit = shift & 0x1F; + srcval = fetch_data_long(srcoffset); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + switch (rh) { + case 5: + store_data_long(srcoffset, srcval | mask); + break; + case 6: + store_data_long(srcoffset, srcval & ~mask); + break; + case 7: + store_data_long(srcoffset, srcval ^ mask); + break; + default: + break; + } + } + else { + u16 srcval, mask; + u8 shift; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + TRACE_AND_STEP(); + bit = shift & 0xF; + srcval = fetch_data_word(srcoffset); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + switch (rh) { + case 5: + store_data_word(srcoffset, srcval | mask); + break; + case 6: + store_data_word(srcoffset, srcval & ~mask); + break; + case 7: + store_data_word(srcoffset, srcval ^ mask); + break; + default: + break; + } + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg; + u32 mask; + u8 shift; + + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + TRACE_AND_STEP(); + bit = shift & 0x1F; + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); + switch (rh) { + case 5: + *srcreg |= mask; + break; + case 6: + *srcreg &= ~mask; + break; + case 7: + *srcreg ^= mask; + break; + default: + break; + } + } + else { + u16 *srcreg; + u16 mask; + u8 shift; + + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shift = fetch_byte_imm(); + TRACE_AND_STEP(); + bit = shift & 0xF; + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); + switch (rh) { + case 5: + *srcreg |= mask; + break; + case 6: + *srcreg &= ~mask; + break; + case 7: + *srcreg ^= mask; + break; + default: + break; + } + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xbb +****************************************************************************/ +static void +x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + int bit, disp; + + START_OF_INSTR(); + DECODE_PRINTF("BTC\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval ^ mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval ^ mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, mask; + u32 *shiftreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + disp = (s16) * shiftreg >> 5; + srcval = fetch_data_long(srcoffset + disp); + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_long(srcoffset + disp, srcval ^ mask); + } + else { + u16 srcval, mask; + u16 *shiftreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + disp = (s16) * shiftreg >> 4; + srcval = fetch_data_word(srcoffset + disp); + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(srcval & mask, F_CF); + store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *srcreg, *shiftreg; + u32 mask; + + srcreg = DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0x1F; + mask = (0x1 << bit); + CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); + *srcreg ^= mask; + } + else { + u16 *srcreg, *shiftreg; + u16 mask; + + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + shiftreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + bit = *shiftreg & 0xF; + mask = (u16) (0x1 << bit); + CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); + *srcreg ^= mask; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xbc +****************************************************************************/ +static void +x86emuOp2_bsf(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("BSF\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, *dstreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_long(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 32; (*dstreg)++) + if ((srcval >> *dstreg) & 1) + break; + } + else { + u16 srcval, *dstreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_word(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 16; (*dstreg)++) + if ((srcval >> *dstreg) & 1) + break; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, *dstreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_long(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 32; (*dstreg)++) + if ((srcval >> *dstreg) & 1) + break; + } + else { + u16 srcval, *dstreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_word(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 16; (*dstreg)++) + if ((srcval >> *dstreg) & 1) + break; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, *dstreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_long(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 32; (*dstreg)++) + if ((srcval >> *dstreg) & 1) + break; + } + else { + u16 srcval, *dstreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_word(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 16; (*dstreg)++) + if ((srcval >> *dstreg) & 1) + break; + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, *dstreg; + + srcval = *DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 32; (*dstreg)++) + if ((srcval >> *dstreg) & 1) + break; + } + else { + u16 srcval, *dstreg; + + srcval = *DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 0; *dstreg < 16; (*dstreg)++) + if ((srcval >> *dstreg) & 1) + break; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xbd +****************************************************************************/ +static void +x86emuOp2_bsr(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("BSR\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, *dstreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_long(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 31; *dstreg > 0; (*dstreg)--) + if ((srcval >> *dstreg) & 1) + break; + } + else { + u16 srcval, *dstreg; + + srcoffset = decode_rm00_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_word(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 15; *dstreg > 0; (*dstreg)--) + if ((srcval >> *dstreg) & 1) + break; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, *dstreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_long(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 31; *dstreg > 0; (*dstreg)--) + if ((srcval >> *dstreg) & 1) + break; + } + else { + u16 srcval, *dstreg; + + srcoffset = decode_rm01_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_word(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 15; *dstreg > 0; (*dstreg)--) + if ((srcval >> *dstreg) & 1) + break; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, *dstreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_long(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 31; *dstreg > 0; (*dstreg)--) + if ((srcval >> *dstreg) & 1) + break; + } + else { + u16 srcval, *dstreg; + + srcoffset = decode_rm10_address(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + srcval = fetch_data_word(srcoffset); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 15; *dstreg > 0; (*dstreg)--) + if ((srcval >> *dstreg) & 1) + break; + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 srcval, *dstreg; + + srcval = *DECODE_RM_LONG_REGISTER(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_LONG_REGISTER(rh); + TRACE_AND_STEP(); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 31; *dstreg > 0; (*dstreg)--) + if ((srcval >> *dstreg) & 1) + break; + } + else { + u16 srcval, *dstreg; + + srcval = *DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF(","); + dstreg = DECODE_RM_WORD_REGISTER(rh); + TRACE_AND_STEP(); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); + for (*dstreg = 15; *dstreg > 0; (*dstreg)--) + if ((srcval >> *dstreg) & 1) + break; + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xbe +****************************************************************************/ +static void +x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + + START_OF_INSTR(); + DECODE_PRINTF("MOVSX\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = (s32) ((s8) fetch_data_byte(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = (s16) ((s8) fetch_data_byte(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 1: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = (s32) ((s8) fetch_data_byte(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = (s16) ((s8) fetch_data_byte(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 2: + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u32 srcval; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = (s32) ((s8) fetch_data_byte(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + else { + u16 *destreg; + u16 srcval; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = (s16) ((s8) fetch_data_byte(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + } + break; + case 3: /* register to register */ + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + u32 *destreg; + u8 *srcreg; + + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = (s32) ((s8) * srcreg); + } + else { + u16 *destreg; + u8 *srcreg; + + destreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_BYTE_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = (s16) ((s8) * srcreg); + } + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: +Handles opcode 0x0f,0xbf +****************************************************************************/ +static void +x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2)) +{ + int mod, rl, rh; + uint srcoffset; + u32 *destreg; + u32 srcval; + u16 *srcreg; + + START_OF_INSTR(); + DECODE_PRINTF("MOVSX\t"); + FETCH_DECODE_MODRM(mod, rh, rl); + switch (mod) { + case 0: + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm00_address(rl); + srcval = (s32) ((s16) fetch_data_word(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 1: + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm01_address(rl); + srcval = (s32) ((s16) fetch_data_word(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 2: + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcoffset = decode_rm10_address(rl); + srcval = (s32) ((s16) fetch_data_word(srcoffset)); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = srcval; + break; + case 3: /* register to register */ + destreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + srcreg = DECODE_RM_WORD_REGISTER(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *destreg = (s32) ((s16) * srcreg); + break; + } + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/* Handles opcodes 0xc8-0xcf */ +static void +x86emuOp2_bswap(u8 X86EMU_UNUSED(op2)) +{ + START_OF_INSTR(); + DECODE_PRINTF("BSWAP\n"); + TRACE_AND_STEP(); + + switch (op2) { + case 0xc8: + M.x86.R_EAX = bswap_32(M.x86.R_EAX); + break; + case 0xc9: + M.x86.R_ECX = bswap_32(M.x86.R_ECX); + break; + case 0xca: + M.x86.R_EDX = bswap_32(M.x86.R_EDX); + break; + case 0xcb: + M.x86.R_EBX = bswap_32(M.x86.R_EBX); + break; + case 0xcc: + M.x86.R_ESP = bswap_32(M.x86.R_ESP); + break; + case 0xcd: + M.x86.R_EBP = bswap_32(M.x86.R_EBP); + break; + case 0xce: + M.x86.R_ESI = bswap_32(M.x86.R_ESI); + break; + case 0xcf: + M.x86.R_EDI = bswap_32(M.x86.R_EDI); + break; + default: + /* can't happen */ + break; + } + + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/*************************************************************************** + * Double byte operation code table: + **************************************************************************/ +void (*x86emu_optab2[256]) (u8) = { + /* 0x00 */ x86emuOp2_illegal_op, + /* Group F (ring 0 PM) */ + /* 0x01 */ x86emuOp2_illegal_op, + /* Group G (ring 0 PM) */ + /* 0x02 */ x86emuOp2_illegal_op, + /* lar (ring 0 PM) */ + /* 0x03 */ x86emuOp2_illegal_op, + /* lsl (ring 0 PM) */ +/* 0x04 */ x86emuOp2_illegal_op, + /* 0x05 */ x86emuOp2_illegal_op, + /* loadall (undocumented) */ + /* 0x06 */ x86emuOp2_illegal_op, + /* clts (ring 0 PM) */ + /* 0x07 */ x86emuOp2_illegal_op, + /* loadall (undocumented) */ + /* 0x08 */ x86emuOp2_illegal_op, + /* invd (ring 0 PM) */ + /* 0x09 */ x86emuOp2_illegal_op, + /* wbinvd (ring 0 PM) */ +/* 0x0a */ x86emuOp2_illegal_op, +/* 0x0b */ x86emuOp2_illegal_op, +/* 0x0c */ x86emuOp2_illegal_op, +/* 0x0d */ x86emuOp2_illegal_op, +/* 0x0e */ x86emuOp2_illegal_op, +/* 0x0f */ x86emuOp2_illegal_op, +/* 0x10 */ x86emuOp2_illegal_op, +/* 0x11 */ x86emuOp2_illegal_op, +/* 0x12 */ x86emuOp2_illegal_op, +/* 0x13 */ x86emuOp2_illegal_op, +/* 0x14 */ x86emuOp2_illegal_op, +/* 0x15 */ x86emuOp2_illegal_op, +/* 0x16 */ x86emuOp2_illegal_op, +/* 0x17 */ x86emuOp2_illegal_op, +/* 0x18 */ x86emuOp2_illegal_op, +/* 0x19 */ x86emuOp2_illegal_op, +/* 0x1a */ x86emuOp2_illegal_op, +/* 0x1b */ x86emuOp2_illegal_op, +/* 0x1c */ x86emuOp2_illegal_op, +/* 0x1d */ x86emuOp2_illegal_op, +/* 0x1e */ x86emuOp2_illegal_op, +/* 0x1f */ x86emuOp2_illegal_op, + /* 0x20 */ x86emuOp2_illegal_op, + /* mov reg32,creg (ring 0 PM) */ + /* 0x21 */ x86emuOp2_illegal_op, + /* mov reg32,dreg (ring 0 PM) */ + /* 0x22 */ x86emuOp2_illegal_op, + /* mov creg,reg32 (ring 0 PM) */ + /* 0x23 */ x86emuOp2_illegal_op, + /* mov dreg,reg32 (ring 0 PM) */ + /* 0x24 */ x86emuOp2_illegal_op, + /* mov reg32,treg (ring 0 PM) */ +/* 0x25 */ x86emuOp2_illegal_op, + /* 0x26 */ x86emuOp2_illegal_op, + /* mov treg,reg32 (ring 0 PM) */ +/* 0x27 */ x86emuOp2_illegal_op, +/* 0x28 */ x86emuOp2_illegal_op, +/* 0x29 */ x86emuOp2_illegal_op, +/* 0x2a */ x86emuOp2_illegal_op, +/* 0x2b */ x86emuOp2_illegal_op, +/* 0x2c */ x86emuOp2_illegal_op, +/* 0x2d */ x86emuOp2_illegal_op, +/* 0x2e */ x86emuOp2_illegal_op, +/* 0x2f */ x86emuOp2_illegal_op, +/* 0x30 */ x86emuOp2_illegal_op, +/* 0x31 */ x86emuOp2_rdtsc, +/* 0x32 */ x86emuOp2_illegal_op, +/* 0x33 */ x86emuOp2_illegal_op, +/* 0x34 */ x86emuOp2_illegal_op, +/* 0x35 */ x86emuOp2_illegal_op, +/* 0x36 */ x86emuOp2_illegal_op, +/* 0x37 */ x86emuOp2_illegal_op, +/* 0x38 */ x86emuOp2_illegal_op, +/* 0x39 */ x86emuOp2_illegal_op, +/* 0x3a */ x86emuOp2_illegal_op, +/* 0x3b */ x86emuOp2_illegal_op, +/* 0x3c */ x86emuOp2_illegal_op, +/* 0x3d */ x86emuOp2_illegal_op, +/* 0x3e */ x86emuOp2_illegal_op, +/* 0x3f */ x86emuOp2_illegal_op, +/* 0x40 */ x86emuOp2_illegal_op, +/* 0x41 */ x86emuOp2_illegal_op, +/* 0x42 */ x86emuOp2_illegal_op, +/* 0x43 */ x86emuOp2_illegal_op, +/* 0x44 */ x86emuOp2_illegal_op, +/* 0x45 */ x86emuOp2_illegal_op, +/* 0x46 */ x86emuOp2_illegal_op, +/* 0x47 */ x86emuOp2_illegal_op, +/* 0x48 */ x86emuOp2_illegal_op, +/* 0x49 */ x86emuOp2_illegal_op, +/* 0x4a */ x86emuOp2_illegal_op, +/* 0x4b */ x86emuOp2_illegal_op, +/* 0x4c */ x86emuOp2_illegal_op, +/* 0x4d */ x86emuOp2_illegal_op, +/* 0x4e */ x86emuOp2_illegal_op, +/* 0x4f */ x86emuOp2_illegal_op, +/* 0x50 */ x86emuOp2_illegal_op, +/* 0x51 */ x86emuOp2_illegal_op, +/* 0x52 */ x86emuOp2_illegal_op, +/* 0x53 */ x86emuOp2_illegal_op, +/* 0x54 */ x86emuOp2_illegal_op, +/* 0x55 */ x86emuOp2_illegal_op, +/* 0x56 */ x86emuOp2_illegal_op, +/* 0x57 */ x86emuOp2_illegal_op, +/* 0x58 */ x86emuOp2_illegal_op, +/* 0x59 */ x86emuOp2_illegal_op, +/* 0x5a */ x86emuOp2_illegal_op, +/* 0x5b */ x86emuOp2_illegal_op, +/* 0x5c */ x86emuOp2_illegal_op, +/* 0x5d */ x86emuOp2_illegal_op, +/* 0x5e */ x86emuOp2_illegal_op, +/* 0x5f */ x86emuOp2_illegal_op, +/* 0x60 */ x86emuOp2_illegal_op, +/* 0x61 */ x86emuOp2_illegal_op, +/* 0x62 */ x86emuOp2_illegal_op, +/* 0x63 */ x86emuOp2_illegal_op, +/* 0x64 */ x86emuOp2_illegal_op, +/* 0x65 */ x86emuOp2_illegal_op, +/* 0x66 */ x86emuOp2_illegal_op, +/* 0x67 */ x86emuOp2_illegal_op, +/* 0x68 */ x86emuOp2_illegal_op, +/* 0x69 */ x86emuOp2_illegal_op, +/* 0x6a */ x86emuOp2_illegal_op, +/* 0x6b */ x86emuOp2_illegal_op, +/* 0x6c */ x86emuOp2_illegal_op, +/* 0x6d */ x86emuOp2_illegal_op, +/* 0x6e */ x86emuOp2_illegal_op, +/* 0x6f */ x86emuOp2_illegal_op, +/* 0x70 */ x86emuOp2_illegal_op, +/* 0x71 */ x86emuOp2_illegal_op, +/* 0x72 */ x86emuOp2_illegal_op, +/* 0x73 */ x86emuOp2_illegal_op, +/* 0x74 */ x86emuOp2_illegal_op, +/* 0x75 */ x86emuOp2_illegal_op, +/* 0x76 */ x86emuOp2_illegal_op, +/* 0x77 */ x86emuOp2_illegal_op, +/* 0x78 */ x86emuOp2_illegal_op, +/* 0x79 */ x86emuOp2_illegal_op, +/* 0x7a */ x86emuOp2_illegal_op, +/* 0x7b */ x86emuOp2_illegal_op, +/* 0x7c */ x86emuOp2_illegal_op, +/* 0x7d */ x86emuOp2_illegal_op, +/* 0x7e */ x86emuOp2_illegal_op, +/* 0x7f */ x86emuOp2_illegal_op, +/* 0x80 */ x86emuOp2_long_jump, +/* 0x81 */ x86emuOp2_long_jump, +/* 0x82 */ x86emuOp2_long_jump, +/* 0x83 */ x86emuOp2_long_jump, +/* 0x84 */ x86emuOp2_long_jump, +/* 0x85 */ x86emuOp2_long_jump, +/* 0x86 */ x86emuOp2_long_jump, +/* 0x87 */ x86emuOp2_long_jump, +/* 0x88 */ x86emuOp2_long_jump, +/* 0x89 */ x86emuOp2_long_jump, +/* 0x8a */ x86emuOp2_long_jump, +/* 0x8b */ x86emuOp2_long_jump, +/* 0x8c */ x86emuOp2_long_jump, +/* 0x8d */ x86emuOp2_long_jump, +/* 0x8e */ x86emuOp2_long_jump, +/* 0x8f */ x86emuOp2_long_jump, +/* 0x90 */ x86emuOp2_set_byte, +/* 0x91 */ x86emuOp2_set_byte, +/* 0x92 */ x86emuOp2_set_byte, +/* 0x93 */ x86emuOp2_set_byte, +/* 0x94 */ x86emuOp2_set_byte, +/* 0x95 */ x86emuOp2_set_byte, +/* 0x96 */ x86emuOp2_set_byte, +/* 0x97 */ x86emuOp2_set_byte, +/* 0x98 */ x86emuOp2_set_byte, +/* 0x99 */ x86emuOp2_set_byte, +/* 0x9a */ x86emuOp2_set_byte, +/* 0x9b */ x86emuOp2_set_byte, +/* 0x9c */ x86emuOp2_set_byte, +/* 0x9d */ x86emuOp2_set_byte, +/* 0x9e */ x86emuOp2_set_byte, +/* 0x9f */ x86emuOp2_set_byte, +/* 0xa0 */ x86emuOp2_push_FS, +/* 0xa1 */ x86emuOp2_pop_FS, +/* 0xa2 */ x86emuOp2_cpuid, +/* 0xa3 */ x86emuOp2_bt_R, +/* 0xa4 */ x86emuOp2_shld_IMM, +/* 0xa5 */ x86emuOp2_shld_CL, +/* 0xa6 */ x86emuOp2_illegal_op, +/* 0xa7 */ x86emuOp2_illegal_op, +/* 0xa8 */ x86emuOp2_push_GS, +/* 0xa9 */ x86emuOp2_pop_GS, +/* 0xaa */ x86emuOp2_illegal_op, +/* 0xab */ x86emuOp2_bts_R, +/* 0xac */ x86emuOp2_shrd_IMM, +/* 0xad */ x86emuOp2_shrd_CL, +/* 0xae */ x86emuOp2_illegal_op, +/* 0xaf */ x86emuOp2_imul_R_RM, + /* 0xb0 */ x86emuOp2_illegal_op, + /* TODO: cmpxchg */ + /* 0xb1 */ x86emuOp2_illegal_op, + /* TODO: cmpxchg */ +/* 0xb2 */ x86emuOp2_lss_R_IMM, +/* 0xb3 */ x86emuOp2_btr_R, +/* 0xb4 */ x86emuOp2_lfs_R_IMM, +/* 0xb5 */ x86emuOp2_lgs_R_IMM, +/* 0xb6 */ x86emuOp2_movzx_byte_R_RM, +/* 0xb7 */ x86emuOp2_movzx_word_R_RM, +/* 0xb8 */ x86emuOp2_illegal_op, +/* 0xb9 */ x86emuOp2_illegal_op, +/* 0xba */ x86emuOp2_btX_I, +/* 0xbb */ x86emuOp2_btc_R, +/* 0xbc */ x86emuOp2_bsf, +/* 0xbd */ x86emuOp2_bsr, +/* 0xbe */ x86emuOp2_movsx_byte_R_RM, +/* 0xbf */ x86emuOp2_movsx_word_R_RM, + /* 0xc0 */ x86emuOp2_illegal_op, + /* TODO: xadd */ + /* 0xc1 */ x86emuOp2_illegal_op, + /* TODO: xadd */ +/* 0xc2 */ x86emuOp2_illegal_op, +/* 0xc3 */ x86emuOp2_illegal_op, +/* 0xc4 */ x86emuOp2_illegal_op, +/* 0xc5 */ x86emuOp2_illegal_op, +/* 0xc6 */ x86emuOp2_illegal_op, +/* 0xc7 */ x86emuOp2_illegal_op, +/* 0xc8 */ x86emuOp2_bswap, +/* 0xc9 */ x86emuOp2_bswap, +/* 0xca */ x86emuOp2_bswap, +/* 0xcb */ x86emuOp2_bswap, +/* 0xcc */ x86emuOp2_bswap, +/* 0xcd */ x86emuOp2_bswap, +/* 0xce */ x86emuOp2_bswap, +/* 0xcf */ x86emuOp2_bswap, +/* 0xd0 */ x86emuOp2_illegal_op, +/* 0xd1 */ x86emuOp2_illegal_op, +/* 0xd2 */ x86emuOp2_illegal_op, +/* 0xd3 */ x86emuOp2_illegal_op, +/* 0xd4 */ x86emuOp2_illegal_op, +/* 0xd5 */ x86emuOp2_illegal_op, +/* 0xd6 */ x86emuOp2_illegal_op, +/* 0xd7 */ x86emuOp2_illegal_op, +/* 0xd8 */ x86emuOp2_illegal_op, +/* 0xd9 */ x86emuOp2_illegal_op, +/* 0xda */ x86emuOp2_illegal_op, +/* 0xdb */ x86emuOp2_illegal_op, +/* 0xdc */ x86emuOp2_illegal_op, +/* 0xdd */ x86emuOp2_illegal_op, +/* 0xde */ x86emuOp2_illegal_op, +/* 0xdf */ x86emuOp2_illegal_op, +/* 0xe0 */ x86emuOp2_illegal_op, +/* 0xe1 */ x86emuOp2_illegal_op, +/* 0xe2 */ x86emuOp2_illegal_op, +/* 0xe3 */ x86emuOp2_illegal_op, +/* 0xe4 */ x86emuOp2_illegal_op, +/* 0xe5 */ x86emuOp2_illegal_op, +/* 0xe6 */ x86emuOp2_illegal_op, +/* 0xe7 */ x86emuOp2_illegal_op, +/* 0xe8 */ x86emuOp2_illegal_op, +/* 0xe9 */ x86emuOp2_illegal_op, +/* 0xea */ x86emuOp2_illegal_op, +/* 0xeb */ x86emuOp2_illegal_op, +/* 0xec */ x86emuOp2_illegal_op, +/* 0xed */ x86emuOp2_illegal_op, +/* 0xee */ x86emuOp2_illegal_op, +/* 0xef */ x86emuOp2_illegal_op, +/* 0xf0 */ x86emuOp2_illegal_op, +/* 0xf1 */ x86emuOp2_illegal_op, +/* 0xf2 */ x86emuOp2_illegal_op, +/* 0xf3 */ x86emuOp2_illegal_op, +/* 0xf4 */ x86emuOp2_illegal_op, +/* 0xf5 */ x86emuOp2_illegal_op, +/* 0xf6 */ x86emuOp2_illegal_op, +/* 0xf7 */ x86emuOp2_illegal_op, +/* 0xf8 */ x86emuOp2_illegal_op, +/* 0xf9 */ x86emuOp2_illegal_op, +/* 0xfa */ x86emuOp2_illegal_op, +/* 0xfb */ x86emuOp2_illegal_op, +/* 0xfc */ x86emuOp2_illegal_op, +/* 0xfd */ x86emuOp2_illegal_op, +/* 0xfe */ x86emuOp2_illegal_op, +/* 0xff */ x86emuOp2_illegal_op, +}; diff --git a/src/libs/x86emu/prim_ops.c b/src/libs/x86emu/prim_ops.c new file mode 100644 index 0000000000..24f76b47fb --- /dev/null +++ b/src/libs/x86emu/prim_ops.c @@ -0,0 +1,2859 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: This file contains the code to implement the primitive +* machine operations used by the emulation code in ops.c +* +* Carry Chain Calculation +* +* This represents a somewhat expensive calculation which is +* apparently required to emulate the setting of the OF and AF flag. +* The latter is not so important, but the former is. The overflow +* flag is the XOR of the top two bits of the carry chain for an +* addition (similar for subtraction). Since we do not want to +* simulate the addition in a bitwise manner, we try to calculate the +* carry chain given the two operands and the result. +* +* So, given the following table, which represents the addition of two +* bits, we can derive a formula for the carry chain. +* +* a b cin r cout +* 0 0 0 0 0 +* 0 0 1 1 0 +* 0 1 0 1 0 +* 0 1 1 0 1 +* 1 0 0 1 0 +* 1 0 1 0 1 +* 1 1 0 0 1 +* 1 1 1 1 1 +* +* Construction of table for cout: +* +* ab +* r \ 00 01 11 10 +* |------------------ +* 0 | 0 1 1 1 +* 1 | 0 0 1 0 +* +* By inspection, one gets: cc = ab + r'(a + b) +* +* That represents alot of operations, but NO CHOICE.... +* +* Borrow Chain Calculation. +* +* The following table represents the subtraction of two bits, from +* which we can derive a formula for the borrow chain. +* +* a b bin r bout +* 0 0 0 0 0 +* 0 0 1 1 1 +* 0 1 0 1 1 +* 0 1 1 0 1 +* 1 0 0 1 0 +* 1 0 1 0 0 +* 1 1 0 0 0 +* 1 1 1 1 1 +* +* Construction of table for cout: +* +* ab +* r \ 00 01 11 10 +* |------------------ +* 0 | 0 1 0 0 +* 1 | 1 1 1 0 +* +* By inspection, one gets: bc = a'b + r(a' + b) +* +****************************************************************************/ + +#include + +#define PRIM_OPS_NO_REDEFINE_ASM +#include "x86emu/x86emui.h" + +#if defined(__GNUC__) +#if defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__amd64__) +#include "x86emu/prim_x86_gcc.h" +#endif +#endif + +/*------------------------- Global Variables ------------------------------*/ + +static u32 x86emu_parity_tab[8] = { + 0x96696996, + 0x69969669, + 0x69969669, + 0x96696996, + 0x69969669, + 0x96696996, + 0x96696996, + 0x69969669, +}; + +#define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0) +#define XOR2(x) (((x) ^ ((x)>>1)) & 0x1) + +/*----------------------------- Implementation ----------------------------*/ + +/**************************************************************************** +REMARKS: +Implements the AAA instruction and side effects. +****************************************************************************/ +u16 +aaa_word(u16 d) +{ + u16 res; + + if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) { + d += 0x6; + d += 0x100; + SET_FLAG(F_AF); + SET_FLAG(F_CF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + } + res = (u16) (d & 0xFF0F); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the AAA instruction and side effects. +****************************************************************************/ +u16 +aas_word(u16 d) +{ + u16 res; + + if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) { + d -= 0x6; + d -= 0x100; + SET_FLAG(F_AF); + SET_FLAG(F_CF); + } + else { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + } + res = (u16) (d & 0xFF0F); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the AAD instruction and side effects. +****************************************************************************/ +u16 +aad_word(u16 d) +{ + u16 l; + u8 hb, lb; + + hb = (u8) ((d >> 8) & 0xff); + lb = (u8) ((d & 0xff)); + l = (u16) ((lb + 10 * hb) & 0xFF); + + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(l & 0x80, F_SF); + CONDITIONAL_SET_FLAG(l == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF); + return l; +} + +/**************************************************************************** +REMARKS: +Implements the AAM instruction and side effects. +****************************************************************************/ +u16 +aam_word(u8 d) +{ + u16 h, l; + + h = (u16) (d / 10); + l = (u16) (d % 10); + l |= (u16) (h << 8); + + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(l & 0x80, F_SF); + CONDITIONAL_SET_FLAG(l == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF); + return l; +} + +/**************************************************************************** +REMARKS: +Implements the ADC instruction and side effects. +****************************************************************************/ +u8 +adc_byte(u8 d, u8 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 cc; + + if (ACCESS_FLAG(F_CF)) + res = 1 + d + s; + else + res = d + s; + + CONDITIONAL_SET_FLAG(res & 0x100, F_CF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the ADC instruction and side effects. +****************************************************************************/ +u16 +adc_word(u16 d, u16 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 cc; + + if (ACCESS_FLAG(F_CF)) + res = 1 + d + s; + else + res = d + s; + + CONDITIONAL_SET_FLAG(res & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the ADC instruction and side effects. +****************************************************************************/ +u32 +adc_long(u32 d, u32 s) +{ + register u32 lo; /* all operands in native machine order */ + register u32 hi; + register u32 res; + register u32 cc; + + if (ACCESS_FLAG(F_CF)) { + lo = 1 + (d & 0xFFFF) + (s & 0xFFFF); + res = 1 + d + s; + } + else { + lo = (d & 0xFFFF) + (s & 0xFFFF); + res = d + s; + } + hi = (lo >> 16) + (d >> 16) + (s >> 16); + + CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the ADD instruction and side effects. +****************************************************************************/ +u8 +add_byte(u8 d, u8 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 cc; + + res = d + s; + CONDITIONAL_SET_FLAG(res & 0x100, F_CF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the ADD instruction and side effects. +****************************************************************************/ +u16 +add_word(u16 d, u16 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 cc; + + res = d + s; + CONDITIONAL_SET_FLAG(res & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the ADD instruction and side effects. +****************************************************************************/ +u32 +add_long(u32 d, u32 s) +{ + register u32 lo; /* all operands in native machine order */ + register u32 hi; + register u32 res; + register u32 cc; + + lo = (d & 0xFFFF) + (s & 0xFFFF); + res = d + s; + hi = (lo >> 16) + (d >> 16) + (s >> 16); + + CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (s & d) | ((~res) & (s | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + + return res; +} + +/**************************************************************************** +REMARKS: +Implements the AND instruction and side effects. +****************************************************************************/ +u8 +and_byte(u8 d, u8 s) +{ + register u8 res; /* all operands in native machine order */ + + res = d & s; + + /* set the flags */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res), F_PF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the AND instruction and side effects. +****************************************************************************/ +u16 +and_word(u16 d, u16 s) +{ + register u16 res; /* all operands in native machine order */ + + res = d & s; + + /* set the flags */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the AND instruction and side effects. +****************************************************************************/ +u32 +and_long(u32 d, u32 s) +{ + register u32 res; /* all operands in native machine order */ + + res = d & s; + + /* set the flags */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the CMP instruction and side effects. +****************************************************************************/ +u8 +cmp_byte(u8 d, u8 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - s; + CLEAR_FLAG(F_CF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return d; +} + +/**************************************************************************** +REMARKS: +Implements the CMP instruction and side effects. +****************************************************************************/ +u16 +cmp_word(u16 d, u16 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return d; +} + +/**************************************************************************** +REMARKS: +Implements the CMP instruction and side effects. +****************************************************************************/ +u32 +cmp_long(u32 d, u32 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return d; +} + +/**************************************************************************** +REMARKS: +Implements the DAA instruction and side effects. +****************************************************************************/ +u8 +daa_byte(u8 d) +{ + u32 res = d; + + if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) { + res += 6; + SET_FLAG(F_AF); + } + if (res > 0x9F || ACCESS_FLAG(F_CF)) { + res += 0x60; + SET_FLAG(F_CF); + } + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the DAS instruction and side effects. +****************************************************************************/ +u8 +das_byte(u8 d) +{ + if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) { + d -= 6; + SET_FLAG(F_AF); + } + if (d > 0x9F || ACCESS_FLAG(F_CF)) { + d -= 0x60; + SET_FLAG(F_CF); + } + CONDITIONAL_SET_FLAG(d & 0x80, F_SF); + CONDITIONAL_SET_FLAG(d == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF); + return d; +} + +/**************************************************************************** +REMARKS: +Implements the DEC instruction and side effects. +****************************************************************************/ +u8 +dec_byte(u8 d) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - 1; + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + /* based on sub_byte, uses s==1. */ + bc = (res & (~d | 1)) | (~d & 1); + /* carry flag unchanged */ + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the DEC instruction and side effects. +****************************************************************************/ +u16 +dec_word(u16 d) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - 1; + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + /* based on the sub_byte routine, with s==1 */ + bc = (res & (~d | 1)) | (~d & 1); + /* carry flag unchanged */ + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the DEC instruction and side effects. +****************************************************************************/ +u32 +dec_long(u32 d) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - 1; + + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | 1)) | (~d & 1); + /* carry flag unchanged */ + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the INC instruction and side effects. +****************************************************************************/ +u8 +inc_byte(u8 d) +{ + register u32 res; /* all operands in native machine order */ + register u32 cc; + + res = d + 1; + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = ((1 & d) | (~res)) & (1 | d); + CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the INC instruction and side effects. +****************************************************************************/ +u16 +inc_word(u16 d) +{ + register u32 res; /* all operands in native machine order */ + register u32 cc; + + res = d + 1; + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (1 & d) | ((~res) & (1 | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the INC instruction and side effects. +****************************************************************************/ +u32 +inc_long(u32 d) +{ + register u32 res; /* all operands in native machine order */ + register u32 cc; + + res = d + 1; + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the carry chain SEE NOTE AT TOP. */ + cc = (1 & d) | ((~res) & (1 | d)); + CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF); + CONDITIONAL_SET_FLAG(cc & 0x8, F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the OR instruction and side effects. +****************************************************************************/ +u8 +or_byte(u8 d, u8 s) +{ + register u8 res; /* all operands in native machine order */ + + res = d | s; + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res), F_PF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the OR instruction and side effects. +****************************************************************************/ +u16 +or_word(u16 d, u16 s) +{ + register u16 res; /* all operands in native machine order */ + + res = d | s; + /* set the carry flag to be bit 8 */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the OR instruction and side effects. +****************************************************************************/ +u32 +or_long(u32 d, u32 s) +{ + register u32 res; /* all operands in native machine order */ + + res = d | s; + + /* set the carry flag to be bit 8 */ + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the OR instruction and side effects. +****************************************************************************/ +u8 +neg_byte(u8 s) +{ + register u8 res; + register u8 bc; + + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (u8) - s; + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res), F_PF); + /* calculate the borrow chain --- modified such that d=0. + substitutiing d=0 into bc= res&(~d|s)|(~d&s); + (the one used for sub) and simplifying, since ~d=0xff..., + ~d|s == 0xffff..., and res&0xfff... == res. Similarly + ~d&s == s. So the simplified result is: */ + bc = res | s; + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the OR instruction and side effects. +****************************************************************************/ +u16 +neg_word(u16 s) +{ + register u16 res; + register u16 bc; + + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (u16) - s; + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain --- modified such that d=0. + substitutiing d=0 into bc= res&(~d|s)|(~d&s); + (the one used for sub) and simplifying, since ~d=0xff..., + ~d|s == 0xffff..., and res&0xfff... == res. Similarly + ~d&s == s. So the simplified result is: */ + bc = res | s; + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the OR instruction and side effects. +****************************************************************************/ +u32 +neg_long(u32 s) +{ + register u32 res; + register u32 bc; + + CONDITIONAL_SET_FLAG(s != 0, F_CF); + res = (u32) - s; + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain --- modified such that d=0. + substitutiing d=0 into bc= res&(~d|s)|(~d&s); + (the one used for sub) and simplifying, since ~d=0xff..., + ~d|s == 0xffff..., and res&0xfff... == res. Similarly + ~d&s == s. So the simplified result is: */ + bc = res | s; + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the NOT instruction and side effects. +****************************************************************************/ +u8 +not_byte(u8 s) +{ + return ~s; +} + +/**************************************************************************** +REMARKS: +Implements the NOT instruction and side effects. +****************************************************************************/ +u16 +not_word(u16 s) +{ + return ~s; +} + +/**************************************************************************** +REMARKS: +Implements the NOT instruction and side effects. +****************************************************************************/ +u32 +not_long(u32 s) +{ + return ~s; +} + +/**************************************************************************** +REMARKS: +Implements the RCL instruction and side effects. +****************************************************************************/ +u8 +rcl_byte(u8 d, u8 s) +{ + register unsigned int res, cnt, mask, cf; + + /* s is the rotate distance. It varies from 0 - 8. */ + /* have + + CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 + + want to rotate through the carry by "s" bits. We could + loop, but that's inefficient. So the width is 9, + and we split into three parts: + + The new carry flag (was B_n) + the stuff in B_n-1 .. B_0 + the stuff in B_7 .. B_n+1 + + The new rotate is done mod 9, and given this, + for a rotation of n bits (mod 9) the new carry flag is + then located n bits from the MSB. The low part is + then shifted up cnt bits, and the high part is or'd + in. Using CAPS for new values, and lowercase for the + original values, this can be expressed as: + + IF n > 0 + 1) CF <- b_(8-n) + 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 + 3) B_(n-1) <- cf + 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) + */ + res = d; + if ((cnt = s % 9) != 0) { + /* extract the new CARRY FLAG. */ + /* CF <- b_(8-n) */ + cf = (d >> (8 - cnt)) & 0x1; + + /* get the low stuff which rotated + into the range B_7 .. B_cnt */ + /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */ + /* note that the right hand side done by the mask */ + res = (d << cnt) & 0xff; + + /* now the high stuff which rotated around + into the positions B_cnt-2 .. B_0 */ + /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */ + /* shift it downward, 7-(n-2) = 9-n positions. + and mask off the result before or'ing in. + */ + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (9 - cnt)) & mask; + + /* if the carry flag was set, or it in. */ + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + /* B_(n-1) <- cf */ + res |= 1 << (cnt - 1); + } + /* set the new carry flag, based on the variable "cf" */ + CONDITIONAL_SET_FLAG(cf, F_CF); + /* OVERFLOW is set *IFF* cnt==1, then it is the + xor of CF and the most significant bit. Blecck. */ + /* parenthesized this expression since it appears to + be causing OF to be misset */ + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)), F_OF); + + } + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the RCL instruction and side effects. +****************************************************************************/ +u16 +rcl_word(u16 d, u8 s) +{ + register unsigned int res, cnt, mask, cf; + + res = d; + if ((cnt = s % 17) != 0) { + cf = (d >> (16 - cnt)) & 0x1; + res = (d << cnt) & 0xffff; + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (17 - cnt)) & mask; + if (ACCESS_FLAG(F_CF)) { + res |= 1 << (cnt - 1); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), F_OF); + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the RCL instruction and side effects. +****************************************************************************/ +u32 +rcl_long(u32 d, u8 s) +{ + register u32 res, cnt, mask, cf; + + res = d; + if ((cnt = s % 33) != 0) { + cf = (d >> (32 - cnt)) & 0x1; + res = (d << cnt) & 0xffffffff; + mask = (1 << (cnt - 1)) - 1; + res |= (d >> (33 - cnt)) & mask; + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + res |= 1 << (cnt - 1); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), F_OF); + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the RCR instruction and side effects. +****************************************************************************/ +u8 +rcr_byte(u8 d, u8 s) +{ + u32 res, cnt; + u32 mask, cf, ocf = 0; + + /* rotate right through carry */ + /* + s is the rotate distance. It varies from 0 - 8. + d is the byte object rotated. + + have + + CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0 + + The new rotate is done mod 9, and given this, + for a rotation of n bits (mod 9) the new carry flag is + then located n bits from the LSB. The low part is + then shifted up cnt bits, and the high part is or'd + in. Using CAPS for new values, and lowercase for the + original values, this can be expressed as: + + IF n > 0 + 1) CF <- b_(n-1) + 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) + 3) B_(8-n) <- cf + 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) + */ + res = d; + if ((cnt = s % 9) != 0) { + /* extract the new CARRY FLAG. */ + /* CF <- b_(n-1) */ + if (cnt == 1) { + cf = d & 0x1; + /* note hackery here. Access_flag(..) evaluates to either + 0 if flag not set + non-zero if flag is set. + doing access_flag(..) != 0 casts that into either + 0..1 in any representation of the flags register + (i.e. packed bit array or unpacked.) + */ + ocf = ACCESS_FLAG(F_CF) != 0; + } + else + cf = (d >> (cnt - 1)) & 0x1; + + /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */ + /* note that the right hand side done by the mask + This is effectively done by shifting the + object to the right. The result must be masked, + in case the object came in and was treated + as a negative number. Needed??? */ + + mask = (1 << (8 - cnt)) - 1; + res = (d >> cnt) & mask; + + /* now the high stuff which rotated around + into the positions B_cnt-2 .. B_0 */ + /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */ + /* shift it downward, 7-(n-2) = 9-n positions. + and mask off the result before or'ing in. + */ + res |= (d << (9 - cnt)); + + /* if the carry flag was set, or it in. */ + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + /* B_(8-n) <- cf */ + res |= 1 << (8 - cnt); + } + /* set the new carry flag, based on the variable "cf" */ + CONDITIONAL_SET_FLAG(cf, F_CF); + /* OVERFLOW is set *IFF* cnt==1, then it is the + xor of CF and the most significant bit. Blecck. */ + /* parenthesized... */ + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), F_OF); + } + } + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the RCR instruction and side effects. +****************************************************************************/ +u16 +rcr_word(u16 d, u8 s) +{ + u32 res, cnt; + u32 mask, cf, ocf = 0; + + /* rotate right through carry */ + res = d; + if ((cnt = s % 17) != 0) { + if (cnt == 1) { + cf = d & 0x1; + ocf = ACCESS_FLAG(F_CF) != 0; + } + else + cf = (d >> (cnt - 1)) & 0x1; + mask = (1 << (16 - cnt)) - 1; + res = (d >> cnt) & mask; + res |= (d << (17 - cnt)); + if (ACCESS_FLAG(F_CF)) { + res |= 1 << (16 - cnt); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), F_OF); + } + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the RCR instruction and side effects. +****************************************************************************/ +u32 +rcr_long(u32 d, u8 s) +{ + u32 res, cnt; + u32 mask, cf, ocf = 0; + + /* rotate right through carry */ + res = d; + if ((cnt = s % 33) != 0) { + if (cnt == 1) { + cf = d & 0x1; + ocf = ACCESS_FLAG(F_CF) != 0; + } + else + cf = (d >> (cnt - 1)) & 0x1; + mask = (1 << (32 - cnt)) - 1; + res = (d >> cnt) & mask; + if (cnt != 1) + res |= (d << (33 - cnt)); + if (ACCESS_FLAG(F_CF)) { /* carry flag is set */ + res |= 1 << (32 - cnt); + } + CONDITIONAL_SET_FLAG(cf, F_CF); + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), F_OF); + } + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the ROL instruction and side effects. +****************************************************************************/ +u8 +rol_byte(u8 d, u8 s) +{ + register unsigned int res, cnt, mask; + + /* rotate left */ + /* + s is the rotate distance. It varies from 0 - 8. + d is the byte object rotated. + + have + + CF B_7 ... B_0 + + The new rotate is done mod 8. + Much simpler than the "rcl" or "rcr" operations. + + IF n > 0 + 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) + 2) B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) + */ + res = d; + if ((cnt = s % 8) != 0) { + /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */ + res = (d << cnt); + + /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */ + mask = (1 << cnt) - 1; + res |= (d >> (8 - cnt)) & mask; + + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + /* OVERFLOW is set *IFF* s==1, then it is the + xor of CF and the most significant bit. Blecck. */ + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 6) & 0x2)), F_OF); + } + if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the ROL instruction and side effects. +****************************************************************************/ +u16 +rol_word(u16 d, u8 s) +{ + register unsigned int res, cnt, mask; + + res = d; + if ((cnt = s % 16) != 0) { + res = (d << cnt); + mask = (1 << cnt) - 1; + res |= (d >> (16 - cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 14) & 0x2)), F_OF); + } + if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the ROL instruction and side effects. +****************************************************************************/ +u32 +rol_long(u32 d, u8 s) +{ + register u32 res, cnt, mask; + + res = d; + if ((cnt = s % 32) != 0) { + res = (d << cnt); + mask = (1 << cnt) - 1; + res |= (d >> (32 - cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && + XOR2((res & 0x1) + ((res >> 30) & 0x2)), F_OF); + } + if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x1, F_CF); + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the ROR instruction and side effects. +****************************************************************************/ +u8 +ror_byte(u8 d, u8 s) +{ + register unsigned int res, cnt, mask; + + /* rotate right */ + /* + s is the rotate distance. It varies from 0 - 8. + d is the byte object rotated. + + have + + B_7 ... B_0 + + The rotate is done mod 8. + + IF n > 0 + 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) + 2) B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) + */ + res = d; + if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */ + /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */ + res = (d << (8 - cnt)); + + /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */ + mask = (1 << (8 - cnt)) - 1; + res |= (d >> (cnt)) & mask; + + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80, F_CF); + /* OVERFLOW is set *IFF* s==1, then it is the + xor of the two most significant bits. Blecck. */ + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF); + } + else if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80, F_CF); + } + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the ROR instruction and side effects. +****************************************************************************/ +u16 +ror_word(u16 d, u8 s) +{ + register unsigned int res, cnt, mask; + + res = d; + if ((cnt = s % 16) != 0) { + res = (d << (16 - cnt)); + mask = (1 << (16 - cnt)) - 1; + res |= (d >> (cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF); + } + else if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x8000, F_CF); + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the ROR instruction and side effects. +****************************************************************************/ +u32 +ror_long(u32 d, u8 s) +{ + register u32 res, cnt, mask; + + res = d; + if ((cnt = s % 32) != 0) { + res = (d << (32 - cnt)); + mask = (1 << (32 - cnt)) - 1; + res |= (d >> (cnt)) & mask; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF); + } + else if (s != 0) { + /* set the new carry flag, Note that it is the low order + bit of the result!!! */ + CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF); + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the SHL instruction and side effects. +****************************************************************************/ +u8 +shl_byte(u8 d, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 8) { + cnt = s % 8; + + /* last bit shifted out goes into carry flag */ + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (8 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = (u8) d; + } + + if (cnt == 1) { + /* Needs simplification. */ + CONDITIONAL_SET_FLAG((((res & 0x80) == 0x80) ^ + (ACCESS_FLAG(F_CF) != 0)), + /* was (M.x86.R_FLG&F_CF)==F_CF)), */ + F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the SHL instruction and side effects. +****************************************************************************/ +u16 +shl_word(u16 d, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = (u16) d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the SHL instruction and side effects. +****************************************************************************/ +u32 +shl_long(u32 d, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + res = d << cnt; + cf = d & (1 << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the SHR instruction and side effects. +****************************************************************************/ +u8 +shr_byte(u8 d, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 8) { + cnt = s % 8; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = (u8) d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the SHR instruction and side effects. +****************************************************************************/ +u16 +shr_word(u16 d, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the SHR instruction and side effects. +****************************************************************************/ +u32 +shr_long(u32 d, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = d >> cnt; + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the SAR instruction and side effects. +****************************************************************************/ +u8 +sar_byte(u8 d, u8 s) +{ + unsigned int cnt, res, cf, mask, sf; + + res = d; + sf = d & 0x80; + cnt = s % 8; + if (cnt > 0 && cnt < 8) { + mask = (1 << (8 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + } + else if (cnt >= 8) { + if (sf) { + res = 0xff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } + else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the SAR instruction and side effects. +****************************************************************************/ +u16 +sar_word(u16 d, u8 s) +{ + unsigned int cnt, res, cf, mask, sf; + + sf = d & 0x8000; + cnt = s % 16; + res = d; + if (cnt > 0 && cnt < 16) { + mask = (1 << (16 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else if (cnt >= 16) { + if (sf) { + res = 0xffff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } + else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the SAR instruction and side effects. +****************************************************************************/ +u32 +sar_long(u32 d, u8 s) +{ + u32 cnt, res, cf, mask, sf; + + sf = d & 0x80000000; + cnt = s % 32; + res = d; + if (cnt > 0 && cnt < 32) { + mask = (1 << (32 - cnt)) - 1; + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) & mask; + CONDITIONAL_SET_FLAG(cf, F_CF); + if (sf) { + res |= ~mask; + } + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else if (cnt >= 32) { + if (sf) { + res = 0xffffffff; + SET_FLAG(F_CF); + CLEAR_FLAG(F_ZF); + SET_FLAG(F_SF); + SET_FLAG(F_PF); + } + else { + res = 0; + CLEAR_FLAG(F_CF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the SHLD instruction and side effects. +****************************************************************************/ +u16 +shld_word(u16 d, u16 fill, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + res = (d << cnt) | (fill >> (16 - cnt)); + cf = d & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the SHLD instruction and side effects. +****************************************************************************/ +u32 +shld_long(u32 d, u32 fill, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + res = (d << cnt) | (fill >> (32 - cnt)); + cf = d & (1 << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ + (ACCESS_FLAG(F_CF) != 0)), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF); + CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_PF); + SET_FLAG(F_ZF); + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the SHRD instruction and side effects. +****************************************************************************/ +u16 +shrd_word(u16 d, u16 fill, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 16) { + cnt = s % 16; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) | (fill << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = d; + } + + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the SHRD instruction and side effects. +****************************************************************************/ +u32 +shrd_long(u32 d, u32 fill, u8 s) +{ + unsigned int cnt, res, cf; + + if (s < 32) { + cnt = s % 32; + if (cnt > 0) { + cf = d & (1 << (cnt - 1)); + res = (d >> cnt) | (fill << (32 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + } + else { + res = d; + } + if (cnt == 1) { + CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); + } + else { + CLEAR_FLAG(F_OF); + } + } + else { + res = 0; + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + SET_FLAG(F_ZF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_PF); + } + return res; +} + +/**************************************************************************** +REMARKS: +Implements the SBB instruction and side effects. +****************************************************************************/ +u8 +sbb_byte(u8 d, u8 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the SBB instruction and side effects. +****************************************************************************/ +u16 +sbb_word(u16 d, u16 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the SBB instruction and side effects. +****************************************************************************/ +u32 +sbb_long(u32 d, u32 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + if (ACCESS_FLAG(F_CF)) + res = d - s - 1; + else + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the SUB instruction and side effects. +****************************************************************************/ +u8 +sub_byte(u8 d, u8 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u8) res; +} + +/**************************************************************************** +REMARKS: +Implements the SUB instruction and side effects. +****************************************************************************/ +u16 +sub_word(u16 d, u16 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return (u16) res; +} + +/**************************************************************************** +REMARKS: +Implements the SUB instruction and side effects. +****************************************************************************/ +u32 +sub_long(u32 d, u32 s) +{ + register u32 res; /* all operands in native machine order */ + register u32 bc; + + res = d - s; + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + + /* calculate the borrow chain. See note at top */ + bc = (res & (~d | s)) | (~d & s); + CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); + CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); + CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the TEST instruction and side effects. +****************************************************************************/ +void +test_byte(u8 d, u8 s) +{ + register u32 res; /* all operands in native machine order */ + + res = d & s; + + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + /* AF == dont care */ + CLEAR_FLAG(F_CF); +} + +/**************************************************************************** +REMARKS: +Implements the TEST instruction and side effects. +****************************************************************************/ +void +test_word(u16 d, u16 s) +{ + register u32 res; /* all operands in native machine order */ + + res = d & s; + + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + /* AF == dont care */ + CLEAR_FLAG(F_CF); +} + +/**************************************************************************** +REMARKS: +Implements the TEST instruction and side effects. +****************************************************************************/ +void +test_long(u32 d, u32 s) +{ + register u32 res; /* all operands in native machine order */ + + res = d & s; + + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + /* AF == dont care */ + CLEAR_FLAG(F_CF); +} + +/**************************************************************************** +REMARKS: +Implements the XOR instruction and side effects. +****************************************************************************/ +u8 +xor_byte(u8 d, u8 s) +{ + register u8 res; /* all operands in native machine order */ + + res = d ^ s; + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x80, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the XOR instruction and side effects. +****************************************************************************/ +u16 +xor_word(u16 d, u16 s) +{ + register u16 res; /* all operands in native machine order */ + + res = d ^ s; + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the XOR instruction and side effects. +****************************************************************************/ +u32 +xor_long(u32 d, u32 s) +{ + register u32 res; /* all operands in native machine order */ + + res = d ^ s; + CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF); + CONDITIONAL_SET_FLAG(res == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + return res; +} + +/**************************************************************************** +REMARKS: +Implements the IMUL instruction and side effects. +****************************************************************************/ +void +imul_byte(u8 s) +{ + s16 res = (s16) ((s8) M.x86.R_AL * (s8) s); + + M.x86.R_AX = res; + if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) || + ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/**************************************************************************** +REMARKS: +Implements the IMUL instruction and side effects. +****************************************************************************/ +void +imul_word(u16 s) +{ + s32 res = (s16) M.x86.R_AX * (s16) s; + + M.x86.R_AX = (u16) res; + M.x86.R_DX = (u16) (res >> 16); + if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x00) || + ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/**************************************************************************** +REMARKS: +Implements the IMUL instruction and side effects. +****************************************************************************/ +void +imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s) +{ +#ifdef __HAS_LONG_LONG__ + s64 res = (s64) (s32) d * (s32) s; + + *res_lo = (u32) res; + *res_hi = (u32) (res >> 32); +#else + u32 d_lo, d_hi, d_sign; + u32 s_lo, s_hi, s_sign; + u32 rlo_lo, rlo_hi, rhi_lo; + + if ((d_sign = d & 0x80000000) != 0) + d = -d; + d_lo = d & 0xFFFF; + d_hi = d >> 16; + if ((s_sign = s & 0x80000000) != 0) + s = -s; + s_lo = s & 0xFFFF; + s_hi = s >> 16; + rlo_lo = d_lo * s_lo; + rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16); + rhi_lo = d_hi * s_hi + (rlo_hi >> 16); + *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF); + *res_hi = rhi_lo; + if (d_sign != s_sign) { + d = ~*res_lo; + s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16); + *res_lo = ~*res_lo + 1; + *res_hi = ~*res_hi + (s >> 16); + } +#endif +} + +/**************************************************************************** +REMARKS: +Implements the IMUL instruction and side effects. +****************************************************************************/ +void +imul_long(u32 s) +{ + imul_long_direct(&M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s); + if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00) || + ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/**************************************************************************** +REMARKS: +Implements the MUL instruction and side effects. +****************************************************************************/ +void +mul_byte(u8 s) +{ + u16 res = (u16) (M.x86.R_AL * s); + + M.x86.R_AX = res; + if (M.x86.R_AH == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/**************************************************************************** +REMARKS: +Implements the MUL instruction and side effects. +****************************************************************************/ +void +mul_word(u16 s) +{ + u32 res = M.x86.R_AX * s; + + M.x86.R_AX = (u16) res; + M.x86.R_DX = (u16) (res >> 16); + if (M.x86.R_DX == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/**************************************************************************** +REMARKS: +Implements the MUL instruction and side effects. +****************************************************************************/ +void +mul_long(u32 s) +{ +#ifdef __HAS_LONG_LONG__ + u64 res = (u64) M.x86.R_EAX * s; + + M.x86.R_EAX = (u32) res; + M.x86.R_EDX = (u32) (res >> 32); +#else + u32 a, a_lo, a_hi; + u32 s_lo, s_hi; + u32 rlo_lo, rlo_hi, rhi_lo; + + a = M.x86.R_EAX; + a_lo = a & 0xFFFF; + a_hi = a >> 16; + s_lo = s & 0xFFFF; + s_hi = s >> 16; + rlo_lo = a_lo * s_lo; + rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16); + rhi_lo = a_hi * s_hi + (rlo_hi >> 16); + M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF); + M.x86.R_EDX = rhi_lo; +#endif + + if (M.x86.R_EDX == 0) { + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_OF); + } + else { + SET_FLAG(F_CF); + SET_FLAG(F_OF); + } +} + +/**************************************************************************** +REMARKS: +Implements the IDIV instruction and side effects. +****************************************************************************/ +void +idiv_byte(u8 s) +{ + s32 dvd, div, mod; + + dvd = (s16) M.x86.R_AX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (s8) s; + mod = dvd % (s8) s; + if (abs(div) > 0x7f) { + x86emu_intr_raise(0); + return; + } + M.x86.R_AL = (s8) div; + M.x86.R_AH = (s8) mod; +} + +/**************************************************************************** +REMARKS: +Implements the IDIV instruction and side effects. +****************************************************************************/ +void +idiv_word(u16 s) +{ + s32 dvd, div, mod; + + dvd = (((s32) M.x86.R_DX) << 16) | M.x86.R_AX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (s16) s; + mod = dvd % (s16) s; + if (abs(div) > 0x7fff) { + x86emu_intr_raise(0); + return; + } + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(div == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + + M.x86.R_AX = (u16) div; + M.x86.R_DX = (u16) mod; +} + +/**************************************************************************** +REMARKS: +Implements the IDIV instruction and side effects. +****************************************************************************/ +void +idiv_long(u32 s) +{ +#ifdef __HAS_LONG_LONG__ + s64 dvd, div, mod; + + dvd = (((s64) M.x86.R_EDX) << 32) | M.x86.R_EAX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (s32) s; + mod = dvd % (s32) s; + if (abs(div) > 0x7fffffff) { + x86emu_intr_raise(0); + return; + } +#else + s32 div = 0, mod; + s32 h_dvd = M.x86.R_EDX; + u32 l_dvd = M.x86.R_EAX; + u32 abs_s = s & 0x7FFFFFFF; + u32 abs_h_dvd = h_dvd & 0x7FFFFFFF; + u32 h_s = abs_s >> 1; + u32 l_s = abs_s << 31; + int counter = 31; + int carry; + + if (s == 0) { + x86emu_intr_raise(0); + return; + } + do { + div <<= 1; + carry = (l_dvd >= l_s) ? 0 : 1; + + if (abs_h_dvd < (h_s + carry)) { + h_s >>= 1; + l_s = abs_s << (--counter); + continue; + } + else { + abs_h_dvd -= (h_s + carry); + l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1) + : (l_dvd - l_s); + h_s >>= 1; + l_s = abs_s << (--counter); + div |= 1; + continue; + } + + } while (counter > -1); + /* overflow */ + if (abs_h_dvd || (l_dvd > abs_s)) { + x86emu_intr_raise(0); + return; + } + /* sign */ + div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000)); + mod = l_dvd; + +#endif + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_ZF); + CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + + M.x86.R_EAX = (u32) div; + M.x86.R_EDX = (u32) mod; +} + +/**************************************************************************** +REMARKS: +Implements the DIV instruction and side effects. +****************************************************************************/ +void +div_byte(u8 s) +{ + u32 dvd, div, mod; + + dvd = M.x86.R_AX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (u8) s; + mod = dvd % (u8) s; + if (abs(div) > 0xff) { + x86emu_intr_raise(0); + return; + } + M.x86.R_AL = (u8) div; + M.x86.R_AH = (u8) mod; +} + +/**************************************************************************** +REMARKS: +Implements the DIV instruction and side effects. +****************************************************************************/ +void +div_word(u16 s) +{ + u32 dvd, div, mod; + + dvd = (((u32) M.x86.R_DX) << 16) | M.x86.R_AX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (u16) s; + mod = dvd % (u16) s; + if (abs(div) > 0xffff) { + x86emu_intr_raise(0); + return; + } + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CONDITIONAL_SET_FLAG(div == 0, F_ZF); + CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + + M.x86.R_AX = (u16) div; + M.x86.R_DX = (u16) mod; +} + +/**************************************************************************** +REMARKS: +Implements the DIV instruction and side effects. +****************************************************************************/ +void +div_long(u32 s) +{ +#ifdef __HAS_LONG_LONG__ + u64 dvd, div, mod; + + dvd = (((u64) M.x86.R_EDX) << 32) | M.x86.R_EAX; + if (s == 0) { + x86emu_intr_raise(0); + return; + } + div = dvd / (u32) s; + mod = dvd % (u32) s; + if (abs(div) > 0xffffffff) { + x86emu_intr_raise(0); + return; + } +#else + s32 div = 0, mod; + s32 h_dvd = M.x86.R_EDX; + u32 l_dvd = M.x86.R_EAX; + + u32 h_s = s; + u32 l_s = 0; + int counter = 32; + int carry; + + if (s == 0) { + x86emu_intr_raise(0); + return; + } + do { + div <<= 1; + carry = (l_dvd >= l_s) ? 0 : 1; + + if (h_dvd < (h_s + carry)) { + h_s >>= 1; + l_s = s << (--counter); + continue; + } + else { + h_dvd -= (h_s + carry); + l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1) + : (l_dvd - l_s); + h_s >>= 1; + l_s = s << (--counter); + div |= 1; + continue; + } + + } while (counter > -1); + /* overflow */ + if (h_dvd || (l_dvd > s)) { + x86emu_intr_raise(0); + return; + } + mod = l_dvd; +#endif + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_SF); + SET_FLAG(F_ZF); + CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF); + + M.x86.R_EAX = (u32) div; + M.x86.R_EDX = (u32) mod; +} + +/**************************************************************************** +REMARKS: +Implements the IN string instruction and side effects. +****************************************************************************/ +void +ins(int size) +{ + int inc = size; + + if (ACCESS_FLAG(F_DF)) { + inc = -size; + } + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* in until CX is ZERO. */ + u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? + M.x86.R_ECX : M.x86.R_CX); + switch (size) { + case 1: + while (count--) { + store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, + (*sys_inb) (M.x86.R_DX)); + M.x86.R_DI += inc; + } + break; + + case 2: + while (count--) { + store_data_word_abs(M.x86.R_ES, M.x86.R_DI, + (*sys_inw) (M.x86.R_DX)); + M.x86.R_DI += inc; + } + break; + case 4: + while (count--) { + store_data_long_abs(M.x86.R_ES, M.x86.R_DI, + (*sys_inl) (M.x86.R_DX)); + M.x86.R_DI += inc; + break; + } + } + M.x86.R_CX = 0; + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ECX = 0; + } + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + else { + switch (size) { + case 1: + store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, + (*sys_inb) (M.x86.R_DX)); + break; + case 2: + store_data_word_abs(M.x86.R_ES, M.x86.R_DI, + (*sys_inw) (M.x86.R_DX)); + break; + case 4: + store_data_long_abs(M.x86.R_ES, M.x86.R_DI, + (*sys_inl) (M.x86.R_DX)); + break; + } + M.x86.R_DI += inc; + } +} + +/**************************************************************************** +REMARKS: +Implements the OUT string instruction and side effects. +****************************************************************************/ +void +outs(int size) +{ + int inc = size; + + if (ACCESS_FLAG(F_DF)) { + inc = -size; + } + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ + /* out until CX is ZERO. */ + u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? + M.x86.R_ECX : M.x86.R_CX); + switch (size) { + case 1: + while (count--) { + (*sys_outb) (M.x86.R_DX, + fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI)); + M.x86.R_SI += inc; + } + break; + + case 2: + while (count--) { + (*sys_outw) (M.x86.R_DX, + fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI)); + M.x86.R_SI += inc; + } + break; + case 4: + while (count--) { + (*sys_outl) (M.x86.R_DX, + fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI)); + M.x86.R_SI += inc; + break; + } + } + M.x86.R_CX = 0; + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + M.x86.R_ECX = 0; + } + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + else { + switch (size) { + case 1: + (*sys_outb) (M.x86.R_DX, + fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI)); + break; + case 2: + (*sys_outw) (M.x86.R_DX, + fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI)); + break; + case 4: + (*sys_outl) (M.x86.R_DX, + fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI)); + break; + } + M.x86.R_SI += inc; + } +} + +/**************************************************************************** +PARAMETERS: +addr - Address to fetch word from + +REMARKS: +Fetches a word from emulator memory using an absolute address. +****************************************************************************/ +u16 +mem_access_word(int addr) +{ + DB(if (CHECK_MEM_ACCESS()) + x86emu_check_mem_access(addr);) + return (*sys_rdw) (addr); +} + +/**************************************************************************** +REMARKS: +Pushes a word onto the stack. + +NOTE: Do not inline this, as (*sys_wrX) is already inline! +****************************************************************************/ +void +push_word(u16 w) +{ + DB(if (CHECK_SP_ACCESS()) + x86emu_check_sp_access();) + M.x86.R_SP -= 2; + (*sys_wrw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w); +} + +/**************************************************************************** +REMARKS: +Pushes a long onto the stack. + +NOTE: Do not inline this, as (*sys_wrX) is already inline! +****************************************************************************/ +void +push_long(u32 w) +{ + DB(if (CHECK_SP_ACCESS()) + x86emu_check_sp_access();) + M.x86.R_SP -= 4; + (*sys_wrl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w); +} + +/**************************************************************************** +REMARKS: +Pops a word from the stack. + +NOTE: Do not inline this, as (*sys_rdX) is already inline! +****************************************************************************/ +u16 +pop_word(void) +{ + register u16 res; + + DB(if (CHECK_SP_ACCESS()) + x86emu_check_sp_access();) + res = (*sys_rdw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP); + M.x86.R_SP += 2; + return res; +} + +/**************************************************************************** +REMARKS: +Pops a long from the stack. + +NOTE: Do not inline this, as (*sys_rdX) is already inline! +****************************************************************************/ +u32 +pop_long(void) +{ + register u32 res; + + DB(if (CHECK_SP_ACCESS()) + x86emu_check_sp_access();) + res = (*sys_rdl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP); + M.x86.R_SP += 4; + return res; +} + +/**************************************************************************** +REMARKS: +CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output +****************************************************************************/ +void +cpuid(void) +{ + u32 feature = M.x86.R_EAX; + +#ifdef X86EMU_HAS_HW_CPUID + /* If the platform allows it, we will base our values on the real + * results from the CPUID instruction. We limit support to the + * first two features, and the results of those are sanitized. + */ + if (feature <= 1) + hw_cpuid(&M.x86.R_EAX, &M.x86.R_EBX, &M.x86.R_ECX, &M.x86.R_EDX); +#endif + + switch (feature) { + case 0: + /* Regardless if we have real data from the hardware, the emulator + * will only support upto feature 1, which we set in register EAX. + * Registers EBX:EDX:ECX contain a string identifying the CPU. + */ + M.x86.R_EAX = 1; +#ifndef X86EMU_HAS_HW_CPUID + /* EBX:EDX:ECX = "GenuineIntel" */ + M.x86.R_EBX = 0x756e6547; + M.x86.R_EDX = 0x49656e69; + M.x86.R_ECX = 0x6c65746e; +#endif + break; + case 1: +#ifndef X86EMU_HAS_HW_CPUID + /* If we don't have x86 compatible hardware, we return values from an + * Intel 486dx4; which was one of the first processors to have CPUID. + */ + M.x86.R_EAX = 0x00000480; + M.x86.R_EBX = 0x00000000; + M.x86.R_ECX = 0x00000000; + M.x86.R_EDX = 0x00000002; /* VME */ +#else + /* In the case that we have hardware CPUID instruction, we make sure + * that the features reported are limited to TSC and VME. + */ + M.x86.R_EDX &= 0x00000012; +#endif + break; + default: + /* Finally, we don't support any additional features. Most CPUs + * return all zeros when queried for invalid or unsupported feature + * numbers. + */ + M.x86.R_EAX = 0; + M.x86.R_EBX = 0; + M.x86.R_ECX = 0; + M.x86.R_EDX = 0; + break; + } +} diff --git a/src/libs/x86emu/sys.c b/src/libs/x86emu/sys.c new file mode 100644 index 0000000000..031f44f534 --- /dev/null +++ b/src/libs/x86emu/sys.c @@ -0,0 +1,550 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Any +* Developer: Kendall Bennett +* +* Description: This file includes subroutines which are related to +* programmed I/O and memory access. Included in this module +* are default functions with limited usefulness. For real +* uses these functions will most likely be overriden by the +* user library. +* +****************************************************************************/ + +#include "x86emu.h" +#include "x86emu/x86emui.h" +#include "x86emu/regs.h" +#include "x86emu/debug.h" +#include "x86emu/prim_ops.h" +#ifndef NO_SYS_HEADERS +#include +#endif + +#ifdef __GNUC__ + +/* Define some packed structures to use with unaligned accesses */ + +struct __una_u64 { + u64 x __attribute__ ((packed)); +}; +struct __una_u32 { + u32 x __attribute__ ((packed)); +}; +struct __una_u16 { + u16 x __attribute__ ((packed)); +}; + +/* Elemental unaligned loads */ + +static __inline__ u64 +ldq_u(u64 * p) +{ + const struct __una_u64 *ptr = (const struct __una_u64 *) p; + + return ptr->x; +} + +static __inline__ u32 +ldl_u(u32 * p) +{ + const struct __una_u32 *ptr = (const struct __una_u32 *) p; + + return ptr->x; +} + +static __inline__ u16 +ldw_u(u16 * p) +{ + const struct __una_u16 *ptr = (const struct __una_u16 *) p; + + return ptr->x; +} + +/* Elemental unaligned stores */ + +static __inline__ void +stq_u(u64 val, u64 * p) +{ + struct __una_u64 *ptr = (struct __una_u64 *) p; + + ptr->x = val; +} + +static __inline__ void +stl_u(u32 val, u32 * p) +{ + struct __una_u32 *ptr = (struct __una_u32 *) p; + + ptr->x = val; +} + +static __inline__ void +stw_u(u16 val, u16 * p) +{ + struct __una_u16 *ptr = (struct __una_u16 *) p; + + ptr->x = val; +} +#else /* !__GNUC__ */ + +static __inline__ u64 +ldq_u(u64 * p) +{ + u64 ret; + + memmove(&ret, p, sizeof(*p)); + return ret; +} + +static __inline__ u32 +ldl_u(u32 * p) +{ + u32 ret; + + memmove(&ret, p, sizeof(*p)); + return ret; +} + +static __inline__ u16 +ldw_u(u16 * p) +{ + u16 ret; + + memmove(&ret, p, sizeof(*p)); + return ret; +} + +static __inline__ void +stq_u(u64 val, u64 * p) +{ + u64 tmp = val; + + memmove(p, &tmp, sizeof(*p)); +} + +static __inline__ void +stl_u(u32 val, u32 * p) +{ + u32 tmp = val; + + memmove(p, &tmp, sizeof(*p)); +} + +static __inline__ void +stw_u(u16 val, u16 * p) +{ + u16 tmp = val; + + memmove(p, &tmp, sizeof(*p)); +} + +#endif /* __GNUC__ */ +/*------------------------- Global Variables ------------------------------*/ + +X86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */ +X86EMU_intrFuncs _X86EMU_intrTab[256]; + +/*----------------------------- Implementation ----------------------------*/ + +/**************************************************************************** +PARAMETERS: +addr - Emulator memory address to read + +RETURNS: +Byte value read from emulator memory. + +REMARKS: +Reads a byte value from the emulator memory. +****************************************************************************/ +u8 X86API +rdb(u32 addr) +{ + u8 val; + + if (addr > M.mem_size - 1) { + DB(printk("mem_read: address %#x out of range!\n", addr); + ) + HALT_SYS(); + } + val = *(u8 *) (M.mem_base + addr); + DB(if (DEBUG_MEM_TRACE()) + printk("%#08x 1 -> %#x\n", addr, val);) + return val; +} + +/**************************************************************************** +PARAMETERS: +addr - Emulator memory address to read + +RETURNS: +Word value read from emulator memory. + +REMARKS: +Reads a word value from the emulator memory. +****************************************************************************/ +u16 X86API +rdw(u32 addr) +{ + u16 val = 0; + + if (addr > M.mem_size - 2) { + DB(printk("mem_read: address %#x out of range!\n", addr); + ) + HALT_SYS(); + } +#ifdef __BIG_ENDIAN__ + if (addr & 0x1) { + val = (*(u8 *) (M.mem_base + addr) | + (*(u8 *) (M.mem_base + addr + 1) << 8)); + } + else +#endif + val = ldw_u((u16 *) (M.mem_base + addr)); + DB(if (DEBUG_MEM_TRACE()) + printk("%#08x 2 -> %#x\n", addr, val);) + return val; +} + +/**************************************************************************** +PARAMETERS: +addr - Emulator memory address to read + +RETURNS: +Long value read from emulator memory. +REMARKS: +Reads a long value from the emulator memory. +****************************************************************************/ +u32 X86API +rdl(u32 addr) +{ + u32 val = 0; + + if (addr > M.mem_size - 4) { + DB(printk("mem_read: address %#x out of range!\n", addr); + ) + HALT_SYS(); + } +#ifdef __BIG_ENDIAN__ + if (addr & 0x3) { + val = (*(u8 *) (M.mem_base + addr + 0) | + (*(u8 *) (M.mem_base + addr + 1) << 8) | + (*(u8 *) (M.mem_base + addr + 2) << 16) | + (*(u8 *) (M.mem_base + addr + 3) << 24)); + } + else +#endif + val = ldl_u((u32 *) (M.mem_base + addr)); + DB(if (DEBUG_MEM_TRACE()) + printk("%#08x 4 -> %#x\n", addr, val);) + return val; +} + +/**************************************************************************** +PARAMETERS: +addr - Emulator memory address to read +val - Value to store + +REMARKS: +Writes a byte value to emulator memory. +****************************************************************************/ +void X86API +wrb(u32 addr, u8 val) +{ + DB(if (DEBUG_MEM_TRACE()) + printk("%#08x 1 <- %#x\n", addr, val);) + if (addr > M.mem_size - 1) { + DB(printk("mem_write: address %#x out of range!\n", addr); + ) + HALT_SYS(); + } + *(u8 *) (M.mem_base + addr) = val; +} + +/**************************************************************************** +PARAMETERS: +addr - Emulator memory address to read +val - Value to store + +REMARKS: +Writes a word value to emulator memory. +****************************************************************************/ +void X86API +wrw(u32 addr, u16 val) +{ + DB(if (DEBUG_MEM_TRACE()) + printk("%#08x 2 <- %#x\n", addr, val);) + if (addr > M.mem_size - 2) { + DB(printk("mem_write: address %#x out of range!\n", addr); + ) + HALT_SYS(); + } +#ifdef __BIG_ENDIAN__ + if (addr & 0x1) { + *(u8 *) (M.mem_base + addr + 0) = (val >> 0) & 0xff; + *(u8 *) (M.mem_base + addr + 1) = (val >> 8) & 0xff; + } + else +#endif + stw_u(val, (u16 *) (M.mem_base + addr)); +} + +/**************************************************************************** +PARAMETERS: +addr - Emulator memory address to read +val - Value to store + +REMARKS: +Writes a long value to emulator memory. +****************************************************************************/ +void X86API +wrl(u32 addr, u32 val) +{ + DB(if (DEBUG_MEM_TRACE()) + printk("%#08x 4 <- %#x\n", addr, val);) + if (addr > M.mem_size - 4) { + DB(printk("mem_write: address %#x out of range!\n", addr); + ) + HALT_SYS(); + } +#ifdef __BIG_ENDIAN__ + if (addr & 0x1) { + *(u8 *) (M.mem_base + addr + 0) = (val >> 0) & 0xff; + *(u8 *) (M.mem_base + addr + 1) = (val >> 8) & 0xff; + *(u8 *) (M.mem_base + addr + 2) = (val >> 16) & 0xff; + *(u8 *) (M.mem_base + addr + 3) = (val >> 24) & 0xff; + } + else +#endif + stl_u(val, (u32 *) (M.mem_base + addr)); +} + +/**************************************************************************** +PARAMETERS: +addr - PIO address to read +RETURN: +0 +REMARKS: +Default PIO byte read function. Doesn't perform real inb. +****************************************************************************/ +static u8 X86API +p_inb(X86EMU_pioAddr addr) +{ + DB(if (DEBUG_IO_TRACE()) + printk("inb %#04x \n", addr);) + return 0; +} + +/**************************************************************************** +PARAMETERS: +addr - PIO address to read +RETURN: +0 +REMARKS: +Default PIO word read function. Doesn't perform real inw. +****************************************************************************/ +static u16 X86API +p_inw(X86EMU_pioAddr addr) +{ + DB(if (DEBUG_IO_TRACE()) + printk("inw %#04x \n", addr);) + return 0; +} + +/**************************************************************************** +PARAMETERS: +addr - PIO address to read +RETURN: +0 +REMARKS: +Default PIO long read function. Doesn't perform real inl. +****************************************************************************/ +static u32 X86API +p_inl(X86EMU_pioAddr addr) +{ + DB(if (DEBUG_IO_TRACE()) + printk("inl %#04x \n", addr);) + return 0; +} + +/**************************************************************************** +PARAMETERS: +addr - PIO address to write +val - Value to store +REMARKS: +Default PIO byte write function. Doesn't perform real outb. +****************************************************************************/ +static void X86API +p_outb(X86EMU_pioAddr addr, u8 val) +{ + DB(if (DEBUG_IO_TRACE()) + printk("outb %#02x -> %#04x \n", val, addr);) + return; +} + +/**************************************************************************** +PARAMETERS: +addr - PIO address to write +val - Value to store +REMARKS: +Default PIO word write function. Doesn't perform real outw. +****************************************************************************/ +static void X86API +p_outw(X86EMU_pioAddr addr, u16 val) +{ + DB(if (DEBUG_IO_TRACE()) + printk("outw %#04x -> %#04x \n", val, addr);) + return; +} + +/**************************************************************************** +PARAMETERS: +addr - PIO address to write +val - Value to store +REMARKS: +Default PIO ;ong write function. Doesn't perform real outl. +****************************************************************************/ +static void X86API +p_outl(X86EMU_pioAddr addr, u32 val) +{ + DB(if (DEBUG_IO_TRACE()) + printk("outl %#08x -> %#04x \n", val, addr);) + return; +} + +/*------------------------- Global Variables ------------------------------*/ + +u8(X86APIP sys_rdb) (u32 addr) = rdb; +u16(X86APIP sys_rdw) (u32 addr) = rdw; +u32(X86APIP sys_rdl) (u32 addr) = rdl; +void (X86APIP sys_wrb) (u32 addr, u8 val) = wrb; +void (X86APIP sys_wrw) (u32 addr, u16 val) = wrw; +void (X86APIP sys_wrl) (u32 addr, u32 val) = wrl; + +u8(X86APIP sys_inb) (X86EMU_pioAddr addr) = p_inb; +u16(X86APIP sys_inw) (X86EMU_pioAddr addr) = p_inw; +u32(X86APIP sys_inl) (X86EMU_pioAddr addr) = p_inl; +void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val) = p_outb; +void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val) = p_outw; +void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val) = p_outl; + +/*----------------------------- Setup -------------------------------------*/ + +/**************************************************************************** +PARAMETERS: +funcs - New memory function pointers to make active + +REMARKS: +This function is used to set the pointers to functions which access +memory space, allowing the user application to override these functions +and hook them out as necessary for their application. +****************************************************************************/ +void +X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs) +{ + sys_rdb = funcs->rdb; + sys_rdw = funcs->rdw; + sys_rdl = funcs->rdl; + sys_wrb = funcs->wrb; + sys_wrw = funcs->wrw; + sys_wrl = funcs->wrl; +} + +/**************************************************************************** +PARAMETERS: +funcs - New programmed I/O function pointers to make active + +REMARKS: +This function is used to set the pointers to functions which access +I/O space, allowing the user application to override these functions +and hook them out as necessary for their application. +****************************************************************************/ +void +X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs) +{ + sys_inb = funcs->inb; + sys_inw = funcs->inw; + sys_inl = funcs->inl; + sys_outb = funcs->outb; + sys_outw = funcs->outw; + sys_outl = funcs->outl; +} + +/**************************************************************************** +PARAMETERS: +funcs - New interrupt vector table to make active + +REMARKS: +This function is used to set the pointers to functions which handle +interrupt processing in the emulator, allowing the user application to +hook interrupts as necessary for their application. Any interrupts that +are not hooked by the user application, and reflected and handled internally +in the emulator via the interrupt vector table. This allows the application +to get control when the code being emulated executes specific software +interrupts. +****************************************************************************/ +void +X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]) +{ + int i; + + for (i = 0; i < 256; i++) + _X86EMU_intrTab[i] = NULL; + if (funcs) { + for (i = 0; i < 256; i++) + _X86EMU_intrTab[i] = funcs[i]; + } +} + +/**************************************************************************** +PARAMETERS: +int - New software interrupt to prepare for + +REMARKS: +This function is used to set up the emulator state to exceute a software +interrupt. This can be used by the user application code to allow an +interrupt to be hooked, examined and then reflected back to the emulator +so that the code in the emulator will continue processing the software +interrupt as per normal. This essentially allows system code to actively +hook and handle certain software interrupts as necessary. +****************************************************************************/ +void +X86EMU_prepareForInt(int num) +{ + push_word((u16) M.x86.R_FLG); + CLEAR_FLAG(F_IF); + CLEAR_FLAG(F_TF); + push_word(M.x86.R_CS); + M.x86.R_CS = mem_access_word(num * 4 + 2); + push_word(M.x86.R_IP); + M.x86.R_IP = mem_access_word(num * 4); + M.x86.intr = 0; +} diff --git a/src/libs/x86emu/validate.c b/src/libs/x86emu/validate.c new file mode 100644 index 0000000000..4c36e1df51 --- /dev/null +++ b/src/libs/x86emu/validate.c @@ -0,0 +1,769 @@ +/**************************************************************************** +* +* Realmode X86 Emulator Library +* +* Copyright (C) 1996-1999 SciTech Software, Inc. +* Copyright (C) David Mosberger-Tang +* Copyright (C) 1999 Egbert Eich +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: Watcom C 10.6 or later +* Environment: 32-bit DOS +* Developer: Kendall Bennett +* +* Description: Program to validate the x86 emulator library for +* correctness. We run the emulator primitive operations +* functions against the real x86 CPU, and compare the result +* and flags to ensure correctness. +* +* We use inline assembler to compile and build this program. +* +****************************************************************************/ + +#include +#include +#include +#include +#include "x86emu.h" +#include "x86emu/prim_asm.h" + +/*-------------------------- Implementation -------------------------------*/ + +#define true 1 +#define false 0 + +#define ALL_FLAGS (F_CF | F_PF | F_AF | F_ZF | F_SF | F_OF) + +#define VAL_START_BINARY(parm_type,res_type,dmax,smax,dincr,sincr) \ +{ \ + parm_type d,s; \ + res_type r,r_asm; \ + ulong flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < dmax; d += dincr) { \ + for (s = 0; s < smax; s += sincr) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { + +#define VAL_TEST_BINARY(name) \ + r_asm = name##_asm(&flags,d,s); \ + r = name(d,s); \ + if (r != r_asm || M.x86.R_EFLG != flags) \ + failed = true; \ + if (failed || trace) { + +#define VAL_TEST_BINARY_VOID(name) \ + name##_asm(&flags,d,s); \ + name(d,s); \ + r = r_asm = 0; \ + if (M.x86.R_EFLG != flags) \ + failed = true; \ + if (failed || trace) { + +#define VAL_FAIL_BYTE_BYTE_BINARY(name) \ + if (failed) \ + printk("fail\n"); \ + printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \ + r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); + +#define VAL_FAIL_WORD_WORD_BINARY(name) \ + if (failed) \ + printk("fail\n"); \ + printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \ + r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); + +#define VAL_FAIL_LONG_LONG_BINARY(name) \ + if (failed) \ + printk("fail\n"); \ + printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \ + r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); + +#define VAL_END_BINARY() \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +#define VAL_BYTE_BYTE_BINARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1) \ + VAL_TEST_BINARY(name) \ + VAL_FAIL_BYTE_BYTE_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_WORD_WORD_BINARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \ + VAL_TEST_BINARY(name) \ + VAL_FAIL_WORD_WORD_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_LONG_LONG_BINARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \ + VAL_TEST_BINARY(name) \ + VAL_FAIL_LONG_LONG_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_VOID_BYTE_BINARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1) \ + VAL_TEST_BINARY_VOID(name) \ + VAL_FAIL_BYTE_BYTE_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_VOID_WORD_BINARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \ + VAL_TEST_BINARY_VOID(name) \ + VAL_FAIL_WORD_WORD_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_VOID_LONG_BINARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \ + VAL_TEST_BINARY_VOID(name) \ + VAL_FAIL_LONG_LONG_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_BYTE_ROTATE(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u8,u8,0xFF,8,1,1) \ + VAL_TEST_BINARY(name) \ + VAL_FAIL_BYTE_BYTE_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_WORD_ROTATE(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u16,u16,0xFF00,16,0x100,1) \ + VAL_TEST_BINARY(name) \ + VAL_FAIL_WORD_WORD_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_LONG_ROTATE(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_BINARY(u32,u32,0xFF000000,32,0x1000000,1) \ + VAL_TEST_BINARY(name) \ + VAL_FAIL_LONG_LONG_BINARY(name) \ + VAL_END_BINARY() + +#define VAL_START_TERNARY(parm_type,res_type,dmax,smax,dincr,sincr,maxshift)\ +{ \ + parm_type d,s; \ + res_type r,r_asm; \ + u8 shift; \ + u32 flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < dmax; d += dincr) { \ + for (s = 0; s < smax; s += sincr) { \ + for (shift = 0; shift < maxshift; shift += 1) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { + +#define VAL_TEST_TERNARY(name) \ + r_asm = name##_asm(&flags,d,s,shift); \ + r = name(d,s,shift); \ + if (r != r_asm || M.x86.R_EFLG != flags) \ + failed = true; \ + if (failed || trace) { + +#define VAL_FAIL_WORD_WORD_TERNARY(name) \ + if (failed) \ + printk("fail\n"); \ + printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n", \ + r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags)); + +#define VAL_FAIL_LONG_LONG_TERNARY(name) \ + if (failed) \ + printk("fail\n"); \ + printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n", \ + r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags)); + +#define VAL_END_TERNARY() \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +#define VAL_WORD_ROTATE_DBL(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_TERNARY(u16,u16,0xFF00,0xFF00,0x100,0x100,16) \ + VAL_TEST_TERNARY(name) \ + VAL_FAIL_WORD_WORD_TERNARY(name) \ + VAL_END_TERNARY() + +#define VAL_LONG_ROTATE_DBL(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_TERNARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000,32) \ + VAL_TEST_TERNARY(name) \ + VAL_FAIL_LONG_LONG_TERNARY(name) \ + VAL_END_TERNARY() + +#define VAL_START_UNARY(parm_type,max,incr) \ +{ \ + parm_type d,r,r_asm; \ + u32 flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < max; d += incr) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { + +#define VAL_TEST_UNARY(name) \ + r_asm = name##_asm(&flags,d); \ + r = name(d); \ + if (r != r_asm || M.x86.R_EFLG != flags) { \ + failed = true; + +#define VAL_FAIL_BYTE_UNARY(name) \ + printk("fail\n"); \ + printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n", \ + r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags)); + +#define VAL_FAIL_WORD_UNARY(name) \ + printk("fail\n"); \ + printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n", \ + r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags)); + +#define VAL_FAIL_LONG_UNARY(name) \ + printk("fail\n"); \ + printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n", \ + r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags)); + +#define VAL_END_UNARY() \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | ALL_FLAGS; \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +#define VAL_BYTE_UNARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_UNARY(u8,0xFF,0x1) \ + VAL_TEST_UNARY(name) \ + VAL_FAIL_BYTE_UNARY(name) \ + VAL_END_UNARY() + +#define VAL_WORD_UNARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_UNARY(u16,0xFF00,0x100) \ + VAL_TEST_UNARY(name) \ + VAL_FAIL_WORD_UNARY(name) \ + VAL_END_UNARY() + +#define VAL_WORD_BYTE_UNARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_UNARY(u16,0xFF,0x1) \ + VAL_TEST_UNARY(name) \ + VAL_FAIL_WORD_UNARY(name) \ + VAL_END_UNARY() + +#define VAL_LONG_UNARY(name) \ + printk("Validating %s ... ", #name); \ + VAL_START_UNARY(u32,0xFF000000,0x1000000) \ + VAL_TEST_UNARY(name) \ + VAL_FAIL_LONG_UNARY(name) \ + VAL_END_UNARY() + +#define VAL_BYTE_MUL(name) \ + printk("Validating %s ... ", #name); \ +{ \ + u8 d,s; \ + u16 r,r_asm; \ + u32 flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < 0xFF; d += 1) { \ + for (s = 0; s < 0xFF; s += 1) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { \ + name##_asm(&flags,&r_asm,d,s); \ + M.x86.R_AL = d; \ + name(s); \ + r = M.x86.R_AX; \ + if (r != r_asm || M.x86.R_EFLG != flags) \ + failed = true; \ + if (failed || trace) { \ + if (failed) \ + printk("fail\n"); \ + printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \ + r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \ + r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +#define VAL_WORD_MUL(name) \ + printk("Validating %s ... ", #name); \ +{ \ + u16 d,s; \ + u16 r_lo,r_asm_lo; \ + u16 r_hi,r_asm_hi; \ + u32 flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < 0xFF00; d += 0x100) { \ + for (s = 0; s < 0xFF00; s += 0x100) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { \ + name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s); \ + M.x86.R_AX = d; \ + name(s); \ + r_lo = M.x86.R_AX; \ + r_hi = M.x86.R_DX; \ + if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\ + failed = true; \ + if (failed || trace) { \ + if (failed) \ + printk("fail\n"); \ + printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \ + r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \ + r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +#define VAL_LONG_MUL(name) \ + printk("Validating %s ... ", #name); \ +{ \ + u32 d,s; \ + u32 r_lo,r_asm_lo; \ + u32 r_hi,r_asm_hi; \ + u32 flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < 0xFF000000; d += 0x1000000) { \ + for (s = 0; s < 0xFF000000; s += 0x1000000) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { \ + name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s); \ + M.x86.R_EAX = d; \ + name(s); \ + r_lo = M.x86.R_EAX; \ + r_hi = M.x86.R_EDX; \ + if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\ + failed = true; \ + if (failed || trace) { \ + if (failed) \ + printk("fail\n"); \ + printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \ + r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \ + r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +#define VAL_BYTE_DIV(name) \ + printk("Validating %s ... ", #name); \ +{ \ + u16 d,s; \ + u8 r_quot,r_rem,r_asm_quot,r_asm_rem; \ + u32 flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < 0xFF00; d += 0x100) { \ + for (s = 1; s < 0xFF; s += 1) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { \ + M.x86.intr = 0; \ + M.x86.R_AX = d; \ + name(s); \ + r_quot = M.x86.R_AL; \ + r_rem = M.x86.R_AH; \ + if (M.x86.intr & INTR_SYNCH) \ + continue; \ + name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,s); \ + if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \ + failed = true; \ + if (failed || trace) { \ + if (failed) \ + printk("fail\n"); \ + printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n", \ + r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n", \ + r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +#define VAL_WORD_DIV(name) \ + printk("Validating %s ... ", #name); \ +{ \ + u32 d,s; \ + u16 r_quot,r_rem,r_asm_quot,r_asm_rem; \ + u32 flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < 0xFF000000; d += 0x1000000) { \ + for (s = 0x100; s < 0xFF00; s += 0x100) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { \ + M.x86.intr = 0; \ + M.x86.R_AX = d & 0xFFFF; \ + M.x86.R_DX = d >> 16; \ + name(s); \ + r_quot = M.x86.R_AX; \ + r_rem = M.x86.R_DX; \ + if (M.x86.intr & INTR_SYNCH) \ + continue; \ + name##_asm(&flags,&r_asm_quot,&r_asm_rem,d & 0xFFFF,d >> 16,s);\ + if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \ + failed = true; \ + if (failed || trace) { \ + if (failed) \ + printk("fail\n"); \ + printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n", \ + r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n", \ + r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +#define VAL_LONG_DIV(name) \ + printk("Validating %s ... ", #name); \ +{ \ + u32 d,s; \ + u32 r_quot,r_rem,r_asm_quot,r_asm_rem; \ + u32 flags,inflags; \ + int f,failed = false; \ + char buf1[80],buf2[80]; \ + for (d = 0; d < 0xFF000000; d += 0x1000000) { \ + for (s = 0x100; s < 0xFF00; s += 0x100) { \ + M.x86.R_EFLG = inflags = flags = def_flags; \ + for (f = 0; f < 2; f++) { \ + M.x86.intr = 0; \ + M.x86.R_EAX = d; \ + M.x86.R_EDX = 0; \ + name(s); \ + r_quot = M.x86.R_EAX; \ + r_rem = M.x86.R_EDX; \ + if (M.x86.intr & INTR_SYNCH) \ + continue; \ + name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,0,s); \ + if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \ + failed = true; \ + if (failed || trace) { \ + if (failed) \ + printk("fail\n"); \ + printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n", \ + r_quot, r_rem, #name, 0, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ + printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n", \ + r_asm_quot, r_asm_rem, #name"_asm", 0, d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ + } \ + M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (failed) \ + break; \ + } \ + if (!failed) \ + printk("passed\n"); \ +} + +void +printk(const char *fmt, ...) +{ + va_list argptr; + + va_start(argptr, fmt); + vfprintf(stdout, fmt, argptr); + fflush(stdout); + va_end(argptr); +} + +char * +print_flags(char *buf, ulong flags) +{ + char *separator = ""; + + buf[0] = 0; + if (flags & F_CF) { + strcat(buf, separator); + strcat(buf, "CF"); + separator = ","; + } + if (flags & F_PF) { + strcat(buf, separator); + strcat(buf, "PF"); + separator = ","; + } + if (flags & F_AF) { + strcat(buf, separator); + strcat(buf, "AF"); + separator = ","; + } + if (flags & F_ZF) { + strcat(buf, separator); + strcat(buf, "ZF"); + separator = ","; + } + if (flags & F_SF) { + strcat(buf, separator); + strcat(buf, "SF"); + separator = ","; + } + if (flags & F_OF) { + strcat(buf, separator); + strcat(buf, "OF"); + separator = ","; + } + if (separator[0] == 0) + strcpy(buf, "None"); + return buf; +} + +int +main(int argc) +{ + ulong def_flags; + int trace = false; + + if (argc > 1) + trace = true; + memset(&M, 0, sizeof(M)); + def_flags = get_flags_asm() & ~ALL_FLAGS; + + VAL_WORD_UNARY(aaa_word); + VAL_WORD_UNARY(aas_word); + + VAL_WORD_UNARY(aad_word); + VAL_WORD_UNARY(aam_word); + + VAL_BYTE_BYTE_BINARY(adc_byte); + VAL_WORD_WORD_BINARY(adc_word); + VAL_LONG_LONG_BINARY(adc_long); + + VAL_BYTE_BYTE_BINARY(add_byte); + VAL_WORD_WORD_BINARY(add_word); + VAL_LONG_LONG_BINARY(add_long); + + VAL_BYTE_BYTE_BINARY(and_byte); + VAL_WORD_WORD_BINARY(and_word); + VAL_LONG_LONG_BINARY(and_long); + + VAL_BYTE_BYTE_BINARY(cmp_byte); + VAL_WORD_WORD_BINARY(cmp_word); + VAL_LONG_LONG_BINARY(cmp_long); + + VAL_BYTE_UNARY(daa_byte); + VAL_BYTE_UNARY(das_byte); /* Fails for 0x9A (out of range anyway) */ + + VAL_BYTE_UNARY(dec_byte); + VAL_WORD_UNARY(dec_word); + VAL_LONG_UNARY(dec_long); + + VAL_BYTE_UNARY(inc_byte); + VAL_WORD_UNARY(inc_word); + VAL_LONG_UNARY(inc_long); + + VAL_BYTE_BYTE_BINARY(or_byte); + VAL_WORD_WORD_BINARY(or_word); + VAL_LONG_LONG_BINARY(or_long); + + VAL_BYTE_UNARY(neg_byte); + VAL_WORD_UNARY(neg_word); + VAL_LONG_UNARY(neg_long); + + VAL_BYTE_UNARY(not_byte); + VAL_WORD_UNARY(not_word); + VAL_LONG_UNARY(not_long); + + VAL_BYTE_ROTATE(rcl_byte); + VAL_WORD_ROTATE(rcl_word); + VAL_LONG_ROTATE(rcl_long); + + VAL_BYTE_ROTATE(rcr_byte); + VAL_WORD_ROTATE(rcr_word); + VAL_LONG_ROTATE(rcr_long); + + VAL_BYTE_ROTATE(rol_byte); + VAL_WORD_ROTATE(rol_word); + VAL_LONG_ROTATE(rol_long); + + VAL_BYTE_ROTATE(ror_byte); + VAL_WORD_ROTATE(ror_word); + VAL_LONG_ROTATE(ror_long); + + VAL_BYTE_ROTATE(shl_byte); + VAL_WORD_ROTATE(shl_word); + VAL_LONG_ROTATE(shl_long); + + VAL_BYTE_ROTATE(shr_byte); + VAL_WORD_ROTATE(shr_word); + VAL_LONG_ROTATE(shr_long); + + VAL_BYTE_ROTATE(sar_byte); + VAL_WORD_ROTATE(sar_word); + VAL_LONG_ROTATE(sar_long); + + VAL_WORD_ROTATE_DBL(shld_word); + VAL_LONG_ROTATE_DBL(shld_long); + + VAL_WORD_ROTATE_DBL(shrd_word); + VAL_LONG_ROTATE_DBL(shrd_long); + + VAL_BYTE_BYTE_BINARY(sbb_byte); + VAL_WORD_WORD_BINARY(sbb_word); + VAL_LONG_LONG_BINARY(sbb_long); + + VAL_BYTE_BYTE_BINARY(sub_byte); + VAL_WORD_WORD_BINARY(sub_word); + VAL_LONG_LONG_BINARY(sub_long); + + VAL_BYTE_BYTE_BINARY(xor_byte); + VAL_WORD_WORD_BINARY(xor_word); + VAL_LONG_LONG_BINARY(xor_long); + + VAL_VOID_BYTE_BINARY(test_byte); + VAL_VOID_WORD_BINARY(test_word); + VAL_VOID_LONG_BINARY(test_long); + + VAL_BYTE_MUL(imul_byte); + VAL_WORD_MUL(imul_word); + VAL_LONG_MUL(imul_long); + + VAL_BYTE_MUL(mul_byte); + VAL_WORD_MUL(mul_word); + VAL_LONG_MUL(mul_long); + + VAL_BYTE_DIV(idiv_byte); + VAL_WORD_DIV(idiv_word); + VAL_LONG_DIV(idiv_long); + + VAL_BYTE_DIV(div_byte); + VAL_WORD_DIV(div_word); + VAL_LONG_DIV(div_long); + + return 0; +} diff --git a/src/preferences/appearance/FontSelectionView.cpp b/src/preferences/appearance/FontSelectionView.cpp index e638b50386..9e5c0a2e55 100644 --- a/src/preferences/appearance/FontSelectionView.cpp +++ b/src/preferences/appearance/FontSelectionView.cpp @@ -258,7 +258,7 @@ FontSelectionView::_BuildSizesMenu() continue; char label[32]; - snprintf(label, sizeof(label), "%ld", size); + snprintf(label, sizeof(label), "%" B_PRId32, size); BMessage* message = new BMessage(kMsgSetSize); message->AddInt32("size", size); @@ -297,7 +297,7 @@ void FontSelectionView::_SelectCurrentSize(bool select) { char label[16]; - snprintf(label, sizeof(label), "%ld", (int32)fCurrentFont.Size()); + snprintf(label, sizeof(label), "%" B_PRId32, (int32)fCurrentFont.Size()); BMenuItem* item = fSizesMenu->FindItem(label); if (item != NULL) diff --git a/src/preferences/appearance/LookAndFeelSettingsView.cpp b/src/preferences/appearance/LookAndFeelSettingsView.cpp index 5c7bd75725..5a6b12c455 100644 --- a/src/preferences/appearance/LookAndFeelSettingsView.cpp +++ b/src/preferences/appearance/LookAndFeelSettingsView.cpp @@ -226,8 +226,8 @@ LookAndFeelSettingsView::_BuildDecorMenu() for (int32 i = 0; i < count; ++i) { DecorInfo* decorator = fDecorUtility.DecoratorAt(i); if (decorator == NULL) { - fprintf(stderr, "Decorator : error NULL entry @ %li / %li\n", - i, count); + fprintf(stderr, "Decorator : error NULL entry @ %" B_PRId32 + " / %" B_PRId32 "\n", i, count); continue; } diff --git a/src/preferences/filetypes/ApplicationTypeWindow.cpp b/src/preferences/filetypes/ApplicationTypeWindow.cpp index 77fc74f06d..d556cd6dd2 100644 --- a/src/preferences/filetypes/ApplicationTypeWindow.cpp +++ b/src/preferences/filetypes/ApplicationTypeWindow.cpp @@ -610,11 +610,11 @@ ApplicationTypeWindow::_SetTo(const BEntry& entry) // version info char text[256]; - snprintf(text, sizeof(text), "%ld", versionInfo.major); + snprintf(text, sizeof(text), "%" B_PRId32, versionInfo.major); fMajorVersionControl->SetText(text); - snprintf(text, sizeof(text), "%ld", versionInfo.middle); + snprintf(text, sizeof(text), "%" B_PRId32, versionInfo.middle); fMiddleVersionControl->SetText(text); - snprintf(text, sizeof(text), "%ld", versionInfo.minor); + snprintf(text, sizeof(text), "%" B_PRId32, versionInfo.minor); fMinorVersionControl->SetText(text); if (versionInfo.variety >= (uint32)fVarietyMenu->CountItems()) @@ -623,7 +623,7 @@ ApplicationTypeWindow::_SetTo(const BEntry& entry) if (item != NULL) item->SetMarked(true); - snprintf(text, sizeof(text), "%ld", versionInfo.internal); + snprintf(text, sizeof(text), "%" B_PRId32, versionInfo.internal); fInternalVersionControl->SetText(text); fShortDescriptionControl->SetText(versionInfo.short_info); diff --git a/src/preferences/filetypes/ApplicationTypesWindow.cpp b/src/preferences/filetypes/ApplicationTypesWindow.cpp index bd659603d8..b485d0f2bc 100644 --- a/src/preferences/filetypes/ApplicationTypesWindow.cpp +++ b/src/preferences/filetypes/ApplicationTypesWindow.cpp @@ -108,7 +108,7 @@ ProgressWindow::ProgressWindow(const char* message, fQuitListener(signalQuit) { char count[100]; - snprintf(count, sizeof(count), "/%ld", max); + snprintf(count, sizeof(count), "/%" B_PRId32, max); fStatusBar = new BStatusBar("status", message, count); fStatusBar->SetMaxValue(max); @@ -141,7 +141,8 @@ ProgressWindow::MessageReceived(BMessage* message) switch (message->what) { case B_UPDATE_STATUS_BAR: char count[100]; - snprintf(count, sizeof(count), "%ld", (int32)fStatusBar->CurrentValue() + 1); + snprintf(count, sizeof(count), "%" B_PRId32, + (int32)fStatusBar->CurrentValue() + 1); fStatusBar->Update(1, NULL, count); break; @@ -431,7 +432,8 @@ ApplicationTypesWindow::_SetType(BMimeType* type, int32 forceUpdate) && appInfo.GetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK) { char version[256]; - snprintf(version, sizeof(version), "%lu.%lu.%lu, %s/%lu", + snprintf(version, sizeof(version), + "%" B_PRIu32 ".%" B_PRIu32 ".%" B_PRIu32 ", %s/%" B_PRIu32, versionInfo.major, versionInfo.middle, versionInfo.minor, variety_to_text(versionInfo.variety), diff --git a/src/preferences/filetypes/AttributeListView.cpp b/src/preferences/filetypes/AttributeListView.cpp index ebdc8f73d9..8c9510283f 100644 --- a/src/preferences/filetypes/AttributeListView.cpp +++ b/src/preferences/filetypes/AttributeListView.cpp @@ -82,7 +82,7 @@ name_for_type(BString& string, type_code type, const char* displayAs) buffer[i] = '.'; } - snprintf(buffer + 6, sizeof(buffer), " (0x%lx)", type); + snprintf(buffer + 6, sizeof(buffer), " (0x%" B_PRIx32 ")", type); string = buffer; } @@ -278,7 +278,7 @@ AttributeListView::SetTo(BMimeType* type) // Remove the current items but remember them for now. Also remember // the currently selected item. BObjectList previousItems(CountItems(), true); - while (AttributeItem* item = (AttributeItem*)RemoveItem(0L)) + while (AttributeItem* item = (AttributeItem*)RemoveItem((int32)0)) previousItems.AddItem(item); // fill it again diff --git a/src/preferences/filetypes/AttributeWindow.cpp b/src/preferences/filetypes/AttributeWindow.cpp index 65f8276697..ad77bab679 100644 --- a/src/preferences/filetypes/AttributeWindow.cpp +++ b/src/preferences/filetypes/AttributeWindow.cpp @@ -173,7 +173,7 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType, fSpecialControl->SetEnabled(false); char text[64]; - snprintf(text, sizeof(text), "%ld", fAttribute.Width()); + snprintf(text, sizeof(text), "%" B_PRId32, fAttribute.Width()); fWidthControl = new BTextControl(B_TRANSLATE_COMMENT("Width:", "Default column width in Tracker for this attribute."), text, NULL); diff --git a/src/preferences/filetypes/FileTypesWindow.cpp b/src/preferences/filetypes/FileTypesWindow.cpp index ed2b153be3..ad9748b93d 100644 --- a/src/preferences/filetypes/FileTypesWindow.cpp +++ b/src/preferences/filetypes/FileTypesWindow.cpp @@ -965,7 +965,7 @@ FileTypesWindow::QuitRequested() { BMessage update(kMsgSettingsChanged); update.AddRect("file_types_frame", Frame()); - update.AddFloat("left_split_weight", fMainSplitView->ItemWeight(0L)); + update.AddFloat("left_split_weight", fMainSplitView->ItemWeight((int32)0)); update.AddFloat("right_split_weight", fMainSplitView->ItemWeight(1)); be_app_messenger.SendMessage(&update); diff --git a/src/preferences/keyboard/KeyboardSettings.cpp b/src/preferences/keyboard/KeyboardSettings.cpp index 6b9994ac85..4846203aea 100644 --- a/src/preferences/keyboard/KeyboardSettings.cpp +++ b/src/preferences/keyboard/KeyboardSettings.cpp @@ -98,8 +98,8 @@ KeyboardSettings::SetKeyboardRepeatDelay(bigtime_t delay) void KeyboardSettings::Dump() { - printf("repeat rate: %ld\n", fSettings.key_repeat_rate); - printf("repeat delay: %Ld\n", fSettings.key_repeat_delay); + printf("repeat rate: %" B_PRId32 "\n", fSettings.key_repeat_rate); + printf("repeat delay: %" B_PRId64 "\n", fSettings.key_repeat_delay); } diff --git a/src/preferences/keymap/KeyboardLayout.cpp b/src/preferences/keymap/KeyboardLayout.cpp index caabcbac3c..d2942011f7 100644 --- a/src/preferences/keymap/KeyboardLayout.cpp +++ b/src/preferences/keymap/KeyboardLayout.cpp @@ -332,7 +332,7 @@ KeyboardLayout::_Error(const parse_state& state, const char* reason, ...) va_list args; va_start(args, reason); - fprintf(stderr, "Syntax error in line %ld: ", state.line); + fprintf(stderr, "Syntax error in line %" B_PRId32 ": ", state.line); vfprintf(stderr, reason, args); fprintf(stderr, "\n"); diff --git a/src/preferences/keymap/KeyboardLayoutView.cpp b/src/preferences/keymap/KeyboardLayoutView.cpp index 467e6a303b..82f3a31dfa 100644 --- a/src/preferences/keymap/KeyboardLayoutView.cpp +++ b/src/preferences/keymap/KeyboardLayoutView.cpp @@ -590,7 +590,7 @@ KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key, fDeadKey); } else { // Show the key code if there is no keymap - snprintf(text, sizeof(text), "%02lx", key->code); + snprintf(text, sizeof(text), "%02" B_PRIx32, key->code); } _SetFontSize(view, keyKind); @@ -827,7 +827,7 @@ bool KeyboardLayoutView::_FunctionKeyLabel(uint32 code, char* text, size_t textSize) { if (code >= B_F1_KEY && code <= B_F12_KEY) { - snprintf(text, textSize, "F%ld", code + 1 - B_F1_KEY); + snprintf(text, textSize, "F%" B_PRId32, code + 1 - B_F1_KEY); return true; } @@ -1022,7 +1022,7 @@ KeyboardLayoutView::_KeyChanged(const BMessage* message) checkSingle = false; if (_KeyForCode(key) == NULL) - printf("no key for code %ld\n", key); + printf("no key for code %" B_PRId32 "\n", key); } for (int32 i = 0; i < 16; i++) { diff --git a/src/preferences/notifications/GeneralView.cpp b/src/preferences/notifications/GeneralView.cpp index 6145e8d3b9..ecce5b67d5 100644 --- a/src/preferences/notifications/GeneralView.cpp +++ b/src/preferences/notifications/GeneralView.cpp @@ -239,7 +239,7 @@ GeneralView::Load() int32 timeout; if (settings.FindInt32(kTimeoutName, &timeout) != B_OK) timeout = kDefaultTimeout; - (void)sprintf(buffer, "%ld", timeout); + (void)sprintf(buffer, "%" B_PRId32, timeout); fTimeout->SetText(buffer); return B_OK; diff --git a/src/preferences/screen/ScreenWindow.cpp b/src/preferences/screen/ScreenWindow.cpp index 5055cdbfc7..c0f7b45dd1 100644 --- a/src/preferences/screen/ScreenWindow.cpp +++ b/src/preferences/screen/ScreenWindow.cpp @@ -823,10 +823,10 @@ ScreenWindow::_UpdateWorkspaceButtons() BPrivate::get_workspaces_layout(&columns, &rows); char text[32]; - snprintf(text, sizeof(text), "%ld", columns); + snprintf(text, sizeof(text), "%" B_PRId32, columns); fColumnsControl->SetText(text); - snprintf(text, sizeof(text), "%ld", rows); + snprintf(text, sizeof(text), "%" B_PRId32, rows); fRowsControl->SetText(text); _GetColumnRowButton(true, false)->SetEnabled(columns != 1 && rows != 32); @@ -1107,8 +1107,8 @@ ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const return status; char buffer[256]; - snprintf(buffer, sizeof(buffer), "mode %ld %ld %ld\n", - mode.width, mode.height, mode.BitsPerPixel()); + snprintf(buffer, sizeof(buffer), "mode %" B_PRId32 " %" B_PRId32 " %" + B_PRId32 "\n", mode.width, mode.height, mode.BitsPerPixel()); ssize_t bytesWritten = file.Write(buffer, strlen(buffer)); if (bytesWritten < B_OK) diff --git a/src/preferences/time/NetworkTimeView.cpp b/src/preferences/time/NetworkTimeView.cpp index 55efc8cc0a..c0dbfc5523 100644 --- a/src/preferences/time/NetworkTimeView.cpp +++ b/src/preferences/time/NetworkTimeView.cpp @@ -479,7 +479,7 @@ NetworkTimeView::_InitView() void NetworkTimeView::_UpdateServerList() { - while (fServerListView->RemoveItem(0L) != NULL); + while (fServerListView->RemoveItem((int32)0) != NULL); const char* server; int32 index = 0; diff --git a/src/preferences/virtualmemory/Settings.cpp b/src/preferences/virtualmemory/Settings.cpp index c326e36c7e..3923544c07 100644 --- a/src/preferences/virtualmemory/Settings.cpp +++ b/src/preferences/virtualmemory/Settings.cpp @@ -224,9 +224,9 @@ Settings::WriteSwapSettings() return B_ERROR; char buffer[1024]; - snprintf(buffer, sizeof(buffer), "vm %s\nswap_auto %s\nswap_size %lld\n" - "swap_volume_name %s\nswap_volume_device %s\n" - "swap_volume_filesystem %s\nswap_volume_capacity %lld\n", + snprintf(buffer, sizeof(buffer), "vm %s\nswap_auto %s\nswap_size %" + B_PRIdOFF "\nswap_volume_name %s\nswap_volume_device %s\n" + "swap_volume_filesystem %s\nswap_volume_capacity %" B_PRIdOFF "\n", SwapEnabled() ? "on" : "off", SwapAutomatic() ? "yes" : "no", SwapSize(), info.volume_name, info.device_name, info.fsh_name, info.total_blocks * info.block_size); diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index 76e09927c3..a17a9d0e64 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -189,9 +189,9 @@ AppServer::_DispatchMessage(int32 code, BPrivate::LinkReceiver& msg) int32 version; if (msg.Read(&version) < B_OK || version != AS_PROTOCOL_VERSION) { - syslog(LOG_ERR, "Application for user %ld with port %ld does " - "not support the current server protocol.\n", userID, - replyPort); + syslog(LOG_ERR, "Application for user %" B_PRId32 " with port " + "%" B_PRId32 " does not support the current server " + "protocol.\n", userID, replyPort); } else { desktop = _FindDesktop(userID, targetScreen); if (desktop == NULL) { @@ -245,8 +245,8 @@ AppServer::_DispatchMessage(int32 code, BPrivate::LinkReceiver& msg) #endif default: - STRACE(("Server::MainLoop received unexpected code %ld (offset %ld)\n", - code, code - SERVER_TRUE)); + STRACE(("Server::MainLoop received unexpected code %" B_PRId32 " " + "(offset %" B_PRId32 ")\n", code, code - SERVER_TRUE)); break; } } diff --git a/src/servers/app/ClientMemoryAllocator.cpp b/src/servers/app/ClientMemoryAllocator.cpp index a1ab4cfce8..8f3001d992 100644 --- a/src/servers/app/ClientMemoryAllocator.cpp +++ b/src/servers/app/ClientMemoryAllocator.cpp @@ -189,14 +189,14 @@ ClientMemoryAllocator::Free(block* freeBlock) void ClientMemoryAllocator::Dump() { - debug_printf("Application %ld, %s: chunks:\n", fApplication->ClientTeam(), - fApplication->Signature()); + debug_printf("Application %" B_PRId32 ", %s: chunks:\n", + fApplication->ClientTeam(), fApplication->Signature()); chunk_list::Iterator iterator = fChunks.GetIterator(); int32 i = 0; while (struct chunk* chunk = iterator.Next()) { - debug_printf(" [%4ld] %p, area %ld, base %p, size %lu\n", i++, chunk, - chunk->area, chunk->base, chunk->size); + debug_printf(" [%4" B_PRId32 "] %p, area %" B_PRId32 ", base %p, " + "size %lu\n", i++, chunk, chunk->area, chunk->base, chunk->size); } debug_printf("free blocks:\n"); @@ -204,8 +204,8 @@ ClientMemoryAllocator::Dump() block_list::Iterator blockIterator = fFreeBlocks.GetIterator(); i = 0; while (struct block* block = blockIterator.Next()) { - debug_printf(" [%6ld] %p, chunk %p, base %p, size %lu\n", i++, block, - block->chunk, block->base, block->size); + debug_printf(" [%6" B_PRId32 "] %p, chunk %p, base %p, size %lu\n", + i++, block, block->chunk, block->base, block->size); } } @@ -254,8 +254,8 @@ ClientMemoryAllocator::_AllocateChunk(size_t size, bool& newArea) #ifdef HAIKU_TARGET_PLATFORM_LIBBE_TEST strcpy(name, "client heap"); #else - snprintf(name, sizeof(name), "heap:%ld:%s", fApplication->ClientTeam(), - fApplication->SignatureLeaf()); + snprintf(name, sizeof(name), "heap:%" B_PRId32 ":%s", + fApplication->ClientTeam(), fApplication->SignatureLeaf()); #endif area_id area = create_area(name, (void**)&address, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 7c74093605..845414aad1 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -203,7 +203,7 @@ KeyboardFilter::Filter(BMessage* message, EventTarget** _target, if ((modifiers & B_CONTROL_KEY) != 0) #endif { - STRACE(("Set Workspace %ld\n", key - 1)); + STRACE(("Set Workspace %" B_PRId32 "\n", key - 1)); fDesktop->SetWorkspaceAsync(key - B_F1_KEY, takeWindow); return B_SKIP_MESSAGE; @@ -2654,8 +2654,8 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) } default: - printf("Desktop %d:%s received unexpected code %ld\n", 0, "baron", - code); + printf("Desktop %d:%s received unexpected code %" B_PRId32 "\n", 0, + "baron", code); if (link.NeedsReply()) { // the client is now blocking and waiting for a reply! @@ -3380,8 +3380,8 @@ Desktop::_SetCurrentWorkspaceConfiguration() if (status != B_OK) { // The application having the direct screen lock didn't give it up in // time, make it crash - syslog(LOG_ERR, "Team %ld did not give up its direct screen lock.\n", - fDirectScreenTeam); + syslog(LOG_ERR, "Team %" B_PRId32 " did not give up its direct screen " + "lock.\n", fDirectScreenTeam); debug_thread(fDirectScreenTeam); fDirectScreenTeam = -1; diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index a634905d31..6c3a0d297d 100644 --- a/src/servers/app/DesktopSettings.cpp +++ b/src/servers/app/DesktopSettings.cpp @@ -293,7 +293,7 @@ DesktopSettingsPrivate::_Load() // colors for (int32 i = 0; i < kNumColors; i++) { char colorName[12]; - snprintf(colorName, sizeof(colorName), "color%ld", + snprintf(colorName, sizeof(colorName), "color%" B_PRId32, (int32)index_to_color_which(i)); settings.FindInt32(colorName, (int32*)&fShared.colors[i]); @@ -438,7 +438,7 @@ DesktopSettingsPrivate::Save(uint32 mask) for (int32 i = 0; i < kNumColors; i++) { char colorName[12]; - snprintf(colorName, sizeof(colorName), "color%ld", + snprintf(colorName, sizeof(colorName), "color%" B_PRId32, (int32)index_to_color_which(i)); settings.AddInt32(colorName, (const int32&)fShared.colors[i]); } diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index f1c16c649f..da95451036 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -635,10 +635,10 @@ DrawState::PrintToStream() const fHighColor.red, fHighColor.green, fHighColor.blue, fHighColor.alpha); printf("\t LowColor: r=%d g=%d b=%d a=%d\n", fLowColor.red, fLowColor.green, fLowColor.blue, fLowColor.alpha); - printf("\t Pattern: %llu\n", fPattern.GetInt64()); + printf("\t Pattern: %" B_PRIu64 "\n", fPattern.GetInt64()); - printf("\t DrawMode: %lu\n", (uint32)fDrawingMode); - printf("\t AlphaSrcMode: %ld\t AlphaFncMode: %ld\n", + printf("\t DrawMode: %" B_PRIu32 "\n", (uint32)fDrawingMode); + printf("\t AlphaSrcMode: %" B_PRId32 "\t AlphaFncMode: %" B_PRId32 "\n", (int32)fAlphaSrcMode, (int32)fAlphaFncMode); printf("\t LineCap: %d\t LineJoin: %d\t MiterLimit: %.2f\n", @@ -652,9 +652,9 @@ DrawState::PrintToStream() const printf("\t Size: %.1f (%.1f)\n", fFont.Size(), fUnscaledFontSize); printf("\t Shear: %.2f\n", fFont.Shear()); printf("\t Rotation: %.2f\n", fFont.Rotation()); - printf("\t Spacing: %ld\n", fFont.Spacing()); - printf("\t Encoding: %ld\n", fFont.Encoding()); + printf("\t Spacing: %" B_PRId32 "\n", fFont.Spacing()); + printf("\t Encoding: %" B_PRId32 "\n", fFont.Encoding()); printf("\t Face: %d\n", fFont.Face()); - printf("\t Flags: %lu\n", fFont.Flags()); + printf("\t Flags: %" B_PRIu32 "\n", fFont.Flags()); } diff --git a/src/servers/app/EventStream.cpp b/src/servers/app/EventStream.cpp index 73f968680f..803467b1de 100644 --- a/src/servers/app/EventStream.cpp +++ b/src/servers/app/EventStream.cpp @@ -266,9 +266,9 @@ InputServerStream::_MessageFromPort(BMessage** _message, bigtime_t timeout) delete[] buffer; if (status != B_OK) { - printf("Unflatten event failed: %s, port message code was: %ld - %c%c%c%c\n", - strerror(status), code, (int8)(code >> 24), (int8)(code >> 16), - (int8)(code >> 8), (int8)code); + printf("Unflatten event failed: %s, port message code was: %" B_PRId32 + " - %c%c%c%c\n", strerror(status), code, (int8)(code >> 24), + (int8)(code >> 16), (int8)(code >> 8), (int8)code); delete message; return status; } diff --git a/src/servers/app/IntPoint.cpp b/src/servers/app/IntPoint.cpp index 4a6fe90c32..d974e49e86 100644 --- a/src/servers/app/IntPoint.cpp +++ b/src/servers/app/IntPoint.cpp @@ -26,7 +26,7 @@ IntPoint::ConstrainTo(const IntRect& r) void IntPoint::PrintToStream() const { - printf("IntPoint(x:%ld, y:%ld)\n", x, y); + printf("IntPoint(x:%" B_PRId32 ", y:%" B_PRId32 ")\n", x, y); } diff --git a/src/servers/app/IntRect.cpp b/src/servers/app/IntRect.cpp index f3e0c39105..7c9a53d4c0 100644 --- a/src/servers/app/IntRect.cpp +++ b/src/servers/app/IntRect.cpp @@ -209,7 +209,8 @@ IntRect::OffsetToCopy(int32 dx, int32 dy) void IntRect::PrintToStream() const { - printf("IntRect(l:%ld, t:%ld, r:%ld, b:%ld)\n", left, top, right, bottom); + printf("IntRect(l:%" B_PRId32 ", t:%" B_PRId32 ", r:%" B_PRId32 ", b:%" + B_PRId32 ")\n", left, top, right, bottom); } diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 7011f32ad6..3974d1221a 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -36,6 +36,11 @@ Includes [ FGristFiles AppServer.cpp BitmapManager.cpp : $(HAIKU_FREETYPE_HEADERS_DEPENDENCY) ; +local BROKEN_64 = ; +if $(TARGET_ARCH) != x86_64 { + BROKEN_64 = "" ; +} + Server app_server : Angle.cpp AppServer.cpp @@ -87,7 +92,7 @@ Server app_server : # libraries : libtranslation.so libbe.so libbnetapi.so - libasdrawing.a libasremote.a libashtml5.a + libasdrawing.a $(BROKEN_64)libasremote.a $(BROKEN_64)libashtml5.a libpainter.a libagg.a $(HAIKU_FREETYPE_LIB) libstackandtile.a liblinprog.a libtextencoding.so libshared.a $(TARGET_LIBSTDC++) diff --git a/src/servers/app/MessageLooper.cpp b/src/servers/app/MessageLooper.cpp index 507092da50..e801712eed 100644 --- a/src/servers/app/MessageLooper.cpp +++ b/src/servers/app/MessageLooper.cpp @@ -147,8 +147,8 @@ MessageLooper::_MessageLooper() // that shouldn't happen, it's our port char name[256]; _GetLooperName(name, 256); - printf("MessageLooper \"%s\": Someone deleted our message port %ld, %s!\n", - name, receiver.Port(), strerror(status)); + printf("MessageLooper \"%s\": Someone deleted our message port %" + B_PRId32 ", %s!\n", name, receiver.Port(), strerror(status)); break; } diff --git a/src/servers/app/MultiLocker.cpp b/src/servers/app/MultiLocker.cpp index f693a31060..979a360635 100644 --- a/src/servers/app/MultiLocker.cpp +++ b/src/servers/app/MultiLocker.cpp @@ -149,7 +149,7 @@ MultiLocker::InitCheck() contained. */ bool -MultiLocker::IsWriteLocked(uint32* _stackBase, thread_id* _thread) const +MultiLocker::IsWriteLocked(addr_t* _stackBase, thread_id* _thread) const { #if TIMING bigtime_t start = system_time(); @@ -163,7 +163,7 @@ MultiLocker::IsWriteLocked(uint32* _stackBase, thread_id* _thread) const // this is managed by taking the address of the item on the // stack and dividing it by the size of the memory pages // if it is the same as the cached stack_page, there is a match - uint32 stackBase = (uint32)&writeLockHolder / B_PAGE_SIZE; + addr_t stackBase = (addr_t)&writeLockHolder / B_PAGE_SIZE; thread_id thread = 0; if (fWriterStackBase == stackBase) { @@ -248,7 +248,7 @@ MultiLocker::WriteLock() bool locked = false; if (fInit == B_OK) { - uint32 stackBase = 0; + addr_t stackBase = 0; thread_id thread = -1; if (IsWriteLocked(&stackBase, &thread)) { @@ -434,7 +434,7 @@ MultiLocker::WriteLock() if (fInit != B_OK) debugger("lock not initialized"); - uint32 stackBase = 0; + addr_t stackBase = 0; thread_id thread = -1; if (IsWriteLocked(&stackBase, &thread)) { @@ -508,7 +508,7 @@ MultiLocker::WriteUnlock() } else { char message[256]; snprintf(message, sizeof(message), "Non-writer attempting to " - "WriteUnlock() - write holder: %ld", fWriterThread); + "WriteUnlock() - write holder: %" B_PRId32, fWriterThread); debugger(message); } diff --git a/src/servers/app/MultiLocker.h b/src/servers/app/MultiLocker.h index 318aea9012..eac9ea5ea6 100644 --- a/src/servers/app/MultiLocker.h +++ b/src/servers/app/MultiLocker.h @@ -57,7 +57,7 @@ public: bool WriteUnlock(); // does the current thread hold a write lock ? - bool IsWriteLocked(uint32 *stackBase = NULL, + bool IsWriteLocked(addr_t *stackBase = NULL, thread_id *thread = NULL) const; #if MULTI_LOCKER_DEBUG @@ -97,7 +97,7 @@ private: status_t fInit; int32 fWriterNest; thread_id fWriterThread; - uint32 fWriterStackBase; + addr_t fWriterStackBase; #if MULTI_LOCKER_TIMING uint32 rl_count; diff --git a/src/servers/app/ScreenManager.cpp b/src/servers/app/ScreenManager.cpp index 064bb79f2d..fda23d34c7 100644 --- a/src/servers/app/ScreenManager.cpp +++ b/src/servers/app/ScreenManager.cpp @@ -105,7 +105,7 @@ ScreenManager::AcquireScreens(ScreenOwner* owner, int32* wishList, } } -#if TEST_MODE == 0 +#if TEST_MODE == 0 && !defined(__x86_64__) if (added == 0 && target != NULL) { // there's a specific target screen we want to initialize // TODO: right now we only support remote screens, but we could diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 6f7a6b92d5..90651ea40d 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -109,7 +109,8 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, fSignature = "application/no-signature"; char name[B_OS_NAME_LENGTH]; - snprintf(name, sizeof(name), "a<%ld:%s", clientTeam, SignatureLeaf()); + snprintf(name, sizeof(name), "a<%" B_PRId32 ":%s", clientTeam, + SignatureLeaf()); fMessagePort = create_port(DEFAULT_MONITOR_PORT_SIZE, name); if (fMessagePort < B_OK) @@ -141,8 +142,8 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, desktop->UnlockSingleWindow(); STRACE(("ServerApp %s:\n", Signature())); - STRACE(("\tBApp port: %ld\n", fClientReplyPort)); - STRACE(("\tReceiver port: %ld\n", fMessagePort)); + STRACE(("\tBApp port: %" B_PRId32 "\n", fClientReplyPort)); + STRACE(("\tReceiver port: %" B_PRId32 "\n", fMessagePort)); } @@ -505,7 +506,7 @@ ServerApp::NotifyDeleteClientArea(area_id serverArea) void ServerApp::_GetLooperName(char* name, size_t length) { - snprintf(name, length, "a:%ld:%s", ClientTeam(), SignatureLeaf()); + snprintf(name, length, "a:%" B_PRId32 ":%s", ClientTeam(), SignatureLeaf()); } @@ -567,13 +568,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { fMapLocker.Lock(); - debug_printf("Application %ld, %s: %d bitmaps:\n", ClientTeam(), - Signature(), (int)fBitmapMap.size()); + debug_printf("Application %" B_PRId32 ", %s: %d bitmaps:\n", + ClientTeam(), Signature(), (int)fBitmapMap.size()); BitmapMap::const_iterator iterator = fBitmapMap.begin(); for (; iterator != fBitmapMap.end(); iterator++) { ServerBitmap* bitmap = iterator->second; - debug_printf(" [%ld] %ldx%ld, area %ld, size %ld\n", + debug_printf(" [%" B_PRId32 "] %" B_PRId32 "x%" B_PRId32 ", " + "area %" B_PRId32 ", size %" B_PRId32 "\n", bitmap->Token(), bitmap->Width(), bitmap->Height(), bitmap->Area(), bitmap->BitsLength()); } @@ -765,8 +767,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) ServerBitmap* bitmap = _FindBitmap(token); if (bitmap != NULL) { - STRACE(("ServerApp %s: Deleting Bitmap %ld\n", Signature(), - token)); + STRACE(("ServerApp %s: Deleting Bitmap %" B_PRId32 "\n", + Signature(), token)); _DeleteBitmap(bitmap); } @@ -787,7 +789,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) ServerBitmap* bitmap = GetBitmap(token); if (bitmap != NULL) { STRACE(("ServerApp %s: Get overlay restrictions for bitmap " - "%ld\n", Signature(), token)); + "%" B_PRId32 "\n", Signature(), token)); status = fDesktop->HWInterface()->GetOverlayRestrictions( bitmap->Overlay(), &restrictions); @@ -3161,8 +3163,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) } default: - printf("ServerApp %s received unhandled message code %ld\n", - Signature(), code); + printf("ServerApp %s received unhandled message code %" B_PRId32 + "\n", Signature(), code); if (link.NeedsReply()) { // the client is now blocking and waiting for a reply! @@ -3199,8 +3201,8 @@ ServerApp::_MessageLooper() status_t err = B_OK; while (!fQuitting) { - STRACE(("info: ServerApp::_MessageLooper() listening on port %ld.\n", - fMessagePort)); + STRACE(("info: ServerApp::_MessageLooper() listening on port %" B_PRId32 + ".\n", fMessagePort)); err = receiver.GetNextMessage(code, B_INFINITE_TIMEOUT); if (err != B_OK || code == B_QUIT_REQUESTED) { diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index be3806fdb3..0123bbfb21 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -209,8 +209,9 @@ ServerBitmap::Owner() const void ServerBitmap::PrintToStream() { - printf("Bitmap@%p: (%ld:%ld), space %ld, bpr %ld, buffer %p\n", - this, fWidth, fHeight, (int32)fSpace, fBytesPerRow, fBuffer); + printf("Bitmap@%p: (%" B_PRId32 ":%" B_PRId32 "), space %" B_PRId32 ", " + "bpr %" B_PRId32 ", buffer %p\n", this, fWidth, fHeight, (int32)fSpace, + fBytesPerRow, fBuffer); } diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp index 6102961bce..0c5a616387 100644 --- a/src/servers/app/ServerFont.cpp +++ b/src/servers/app/ServerFont.cpp @@ -666,7 +666,7 @@ class BoundingBoxConsumer { BoundingBoxConsumer(Transformable& transform, BRect* rectArray, bool asString) : rectArray(rectArray) - , stringBoundingBox(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN) + , stringBoundingBox(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN) , fAsString(asString) , fCurves(fPathAdaptor) , fContour(fCurves) diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 04c5a46c50..34517a30a9 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -234,14 +234,14 @@ ServerWindow::~ServerWindow() for (int32 i = 0; i < count; i++) { profile* p = (profile*)profiles.ItemAtFast(i); string_for_message_code(p->code, codeName); - printf("[%s] called %ld times, %g secs (%Ld usecs per call)\n", - codeName.String(), p->count, p->time / 1000000.0, + printf("[%s] called %" B_PRId32 " times, %g secs (%" B_PRId64 " usecs " + "per call)\n", codeName.String(), p->count, p->time / 1000000.0, p->time / p->count); } if (sRedrawProcessingTime.count > 0) { - printf("average redraw processing time: %g secs, count: %ld (%lld " - "usecs per call)\n", sRedrawProcessingTime.time / 1000000.0, - sRedrawProcessingTime.count, + printf("average redraw processing time: %g secs, count: %" B_PRId32 " " + "(%" B_PRId64 " usecs per call)\n", + sRedrawProcessingTime.time / 1000000.0, sRedrawProcessingTime.count, sRedrawProcessingTime.time / sRedrawProcessingTime.count); } // if (sNextMessageTime.count > 0) { @@ -326,7 +326,7 @@ ServerWindow::_GetLooperName(char* name, size_t length) if (title == NULL || !title[0]) title = "Unnamed Window"; - snprintf(name, length, "w:%ld:%s", ClientTeam(), title); + snprintf(name, length, "w:%" B_PRId32 ":%s", ClientTeam(), title); } @@ -522,7 +522,7 @@ ServerWindow::_CreateView(BPrivate::LinkReceiver& link, View** _parent) link.Read(&viewColor); link.Read(&parentToken); - STRACE(("ServerWindow(%s)::_CreateView()-> view %s, token %ld\n", + STRACE(("ServerWindow(%s)::_CreateView()-> view %s, token %" B_PRId32 "\n", fTitle, name, token)); View* newView; @@ -857,7 +857,7 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (link.Read(&newWorkspaces) != B_OK) break; - DTRACE(("ServerWindow %s: Message AS_SET_WORKSPACES %lx\n", + DTRACE(("ServerWindow %s: Message AS_SET_WORKSPACES %" B_PRIx32 "\n", Title(), newWorkspaces)); fDesktop->SetWindowWorkspaces(fWindow, newWorkspaces); @@ -938,8 +938,8 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) link.Read(&maxHeight); */ DTRACE(("ServerWindow %s: Message AS_SET_SIZE_LIMITS: " - "x: %ld-%ld, y: %ld-%ld\n", - Title(), minWidth, maxWidth, minHeight, maxHeight)); + "x: %" B_PRId32 "-%" B_PRId32 ", y: %" B_PRId32 "-%" B_PRId32 + "\n", Title(), minWidth, maxWidth, minHeight, maxHeight)); fWindow->SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight); @@ -1108,12 +1108,12 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) // TODO: if this happens, we probably want to kill the app and // clean up debug_printf("ServerWindow %s: Message " - "\n\n\nAS_SET_CURRENT_VIEW: view not found, token %ld\n", - fTitle, token); + "\n\n\nAS_SET_CURRENT_VIEW: view not found, token %" + B_PRId32 "\n", fTitle, token); current = NULL; } else { DTRACE(("\n\n\nServerWindow %s: Message AS_SET_CURRENT_VIEW: %s, " - "token %ld\n", fTitle, current->Name(), token)); + "token %" B_PRId32 "\n", fTitle, current->Name(), token)); _SetCurrentView(current); } break; @@ -1453,7 +1453,7 @@ fDesktop->LockSingleWindow(); break; DTRACE(("ServerWindow %s: Message AS_VIEW_RESIZE_MODE: " - "View: %s -> %ld\n", Title(), fCurrentView->Name(), + "View: %s -> %" B_PRId32 "\n", Title(), fCurrentView->Name(), resizeMode)); fCurrentView->SetResizeMode(resizeMode); @@ -1478,8 +1478,8 @@ fDesktop->LockSingleWindow(); } DTRACE(("ServerWindow %s: Message AS_VIEW_SET_FLAGS: " - "View: %s -> flags: %lu\n", Title(), fCurrentView->Name(), - flags)); + "View: %s -> flags: %" B_PRIu32 "\n", Title(), + fCurrentView->Name(), flags)); break; } case AS_VIEW_HIDE: @@ -1925,7 +1925,7 @@ fDesktop->LockSingleWindow(); break; DTRACE(("ServerWindow %s: Message AS_VIEW_SET_CLIP_REGION: " - "View: %s -> rect count: %ld, frame = " + "View: %s -> rect count: %" B_PRId32 ", frame = " "BRect(%.1f, %.1f, %.1f, %.1f)\n", Title(), fCurrentView->Name(), rectCount, region.Frame().left, region.Frame().top, @@ -1972,8 +1972,8 @@ fDesktop->LockSingleWindow(); break; DTRACE(("ServerWindow %s: Message AS_VIEW_INVALIDATE_REGION: " - "View: %s -> rect count: %ld, frame: BRect(%.1f, %.1f, " - "%.1f, %.1f)\n", Title(), + "View: %s -> rect count: %" B_PRId32 ", frame: BRect(%.1f, " + "%.1f, %.1f, %.1f)\n", Title(), fCurrentView->Name(), region.CountRects(), region.Frame().left, region.Frame().top, region.Frame().right, region.Frame().bottom)); @@ -2137,7 +2137,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, if (!fCurrentView->IsVisible() || !fWindow->IsVisible()) { if (link.NeedsReply()) { debug_printf("ServerWindow::DispatchViewDrawingMessage() got " - "message %ld that needs a reply!\n", code); + "message %" B_PRId32 " that needs a reply!\n", code); // the client is now blocking and waiting for a reply! fLink.StartMessage(B_ERROR); fLink.Flush(); @@ -2281,8 +2281,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, ServerBitmap* bitmap = fServerApp->GetBitmap(info.bitmapToken); if (bitmap != NULL) { DTRACE(("ServerWindow %s: Message AS_VIEW_DRAW_BITMAP: " - "View: %s, bitmap: %ld (size %ld x %ld), " - "BRect(%.1f, %.1f, %.1f, %.1f) -> " + "View: %s, bitmap: %" B_PRId32 " (size %" B_PRId32 " x " + "%" B_PRId32 "), BRect(%.1f, %.1f, %.1f, %.1f) -> " "BRect(%.1f, %.1f, %.1f, %.1f)\n", fTitle, fCurrentView->Name(), info.bitmapToken, bitmap->Width(), bitmap->Height(), @@ -3384,7 +3384,7 @@ ServerWindow::_MessageLooper() #ifdef PROFILE_MESSAGE_LOOP bigtime_t diff = system_time() - start; if (diff > 10000) { - printf("ServerWindow %s: lock acquisition took %Ld usecs\n", + printf("ServerWindow %s: lock acquisition took %" B_PRId64 " usecs\n", Title(), diff); } #endif @@ -3466,8 +3466,8 @@ ServerWindow::_MessageLooper() sMessageProfile[code].time += diff; #endif if (diff > 10000) { - printf("ServerWindow %s: message %ld took %Ld usecs\n", - Title(), code, diff); + printf("ServerWindow %s: message %" B_PRId32 " took %" + B_PRId64 " usecs\n", Title(), code, diff); } } #endif @@ -3550,8 +3550,8 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState) if (fDirectWindowInfo == NULL) return; - STRACE(("HandleDirectConnection(bufferState = %ld, driverState = %ld)\n", - bufferState, driverState)); + STRACE(("HandleDirectConnection(bufferState = %" B_PRId32 ", driverState = " + "%" B_PRId32 ")\n", bufferState, driverState)); status_t status = fDirectWindowInfo->SetState( (direct_buffer_state)bufferState, (direct_driver_state)driverState, diff --git a/src/servers/app/View.cpp b/src/servers/app/View.cpp index 26141c49d2..cbc0aadd88 100644 --- a/src/servers/app/View.cpp +++ b/src/servers/app/View.cpp @@ -1614,9 +1614,11 @@ void View::PrintToStream() const { printf("View: %s\n", Name()); - printf(" fToken: %ld\n", fToken); - printf(" fFrame: IntRect(%ld, %ld, %ld, %ld)\n", fFrame.left, fFrame.top, fFrame.right, fFrame.bottom); - printf(" fScrollingOffset: IntPoint(%ld, %ld)\n", fScrollingOffset.x, fScrollingOffset.y); + printf(" fToken: %" B_PRId32 "\n", fToken); + printf(" fFrame: IntRect(%" B_PRId32 ", %" B_PRId32 ", %" B_PRId32 ", %" B_PRId32 ")\n", + fFrame.left, fFrame.top, fFrame.right, fFrame.bottom); + printf(" fScrollingOffset: IntPoint(%" B_PRId32 ", %" B_PRId32 ")\n", + fScrollingOffset.x, fScrollingOffset.y); printf(" fHidden: %d\n", fHidden); printf(" fVisible: %d\n", fVisible); printf(" fWindow: %p\n", fWindow); diff --git a/src/servers/app/drawing/AccelerantHWInterface.cpp b/src/servers/app/drawing/AccelerantHWInterface.cpp index fe6e4427f6..5c606951b1 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.cpp +++ b/src/servers/app/drawing/AccelerantHWInterface.cpp @@ -962,7 +962,7 @@ AccelerantHWInterface::GetMonitorInfo(monitor_info* info) memset(info, 0, sizeof(monitor_info)); strlcpy(info->vendor, edid.vendor.manufacturer, sizeof(info->vendor)); if (edid.vendor.serial != 0) { - snprintf(info->serial_number, sizeof(info->serial_number), "%lu", + snprintf(info->serial_number, sizeof(info->serial_number), "%" B_PRIu32, edid.vendor.serial); } info->product_id = edid.vendor.prod_id; diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index 4e3a8367a6..4ec70d7695 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -1513,7 +1513,7 @@ DrawingEngine::CopyRect(BRect src, int32 xOffset, int32 yOffset) const src = src & dst; // calc offset in buffer - bits += (int32)src.left * 4 + (int32)src.top * bytesPerRow; + bits += (ssize_t)src.left * 4 + (ssize_t)src.top * bytesPerRow; uint32 width = src.IntegerWidth() + 1; uint32 height = src.IntegerHeight() + 1; @@ -1554,7 +1554,7 @@ DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height, yIncrement = bytesPerRow; } - uint8* dst = src + yOffset * bytesPerRow + xOffset * 4; + uint8* dst = src + (ssize_t)yOffset * bytesPerRow + (ssize_t)xOffset * 4; if (xIncrement == 1) { uint8 tmpBuffer[width * 4]; diff --git a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp index 7c4a0775c2..754ea5172f 100644 --- a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp @@ -131,7 +131,7 @@ public: fDryRun(dryRun), fSubpixelAntiAliased(subpixelAntiAliased), fVector(false), - fBounds(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN), + fBounds(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN), fNextCharPos(nextCharPos), fTransformedGlyph(transformedGlyph), diff --git a/src/servers/app/font/FontCacheEntry.cpp b/src/servers/app/font/FontCacheEntry.cpp index 5b11338828..306f99de67 100644 --- a/src/servers/app/font/FontCacheEntry.cpp +++ b/src/servers/app/font/FontCacheEntry.cpp @@ -371,7 +371,7 @@ FontCacheEntry::GenerateSignature(char* signature, size_t signatureSize, bool hinting = font.Hinting(); uint8 averageWeight = gSubpixelAverageWeight; - snprintf(signature, signatureSize, "%ld,%u,%d,%d,%.1f,%d,%d", + snprintf(signature, signatureSize, "%" B_PRId32 ",%u,%d,%d,%.1f,%d,%d", font.GetFamilyAndStyle(), charMap, font.Face(), int(renderingType), font.Size(), hinting, averageWeight); } diff --git a/src/servers/app/font/FontFamily.cpp b/src/servers/app/font/FontFamily.cpp index e75f79e24d..3d1532e60a 100644 --- a/src/servers/app/font/FontFamily.cpp +++ b/src/servers/app/font/FontFamily.cpp @@ -17,7 +17,7 @@ #include -const uint32 kInvalidFamilyFlags = ~0UL; +const uint32 kInvalidFamilyFlags = ~(uint32)0; static int diff --git a/src/servers/app/font/FontManager.cpp b/src/servers/app/font/FontManager.cpp index 357243e8b7..1e5e2cfdef 100644 --- a/src/servers/app/font/FontManager.cpp +++ b/src/servers/app/font/FontManager.cpp @@ -642,7 +642,8 @@ FontManager::_FindDirectory(node_ref& nodeRef) void FontManager::_RemoveDirectory(font_directory* directory) { - FTRACE(("FontManager: Remove directory (%Ld)!\n", directory->directory.node)); + FTRACE(("FontManager: Remove directory (%" B_PRIdINO ")!\n", + directory->directory.node)); fDirectories.RemoveItem(directory, false); @@ -704,8 +705,8 @@ FontManager::_AddPath(BEntry& entry, font_directory** _newDirectory) if (status != B_OK) { // we cannot watch this directory - while this is unfortunate, // it's not a critical error - printf("could not watch directory %ld:%Ld\n", nodeRef.device, - nodeRef.node); + printf("could not watch directory %" B_PRIdDEV ":%" B_PRIdINO "\n", + nodeRef.device, nodeRef.node); // TODO: should go into syslog() } else { BPath path(&entry); diff --git a/src/servers/debug/DebugServer.cpp b/src/servers/debug/DebugServer.cpp index 26f542128b..fe795b59ae 100644 --- a/src/servers/debug/DebugServer.cpp +++ b/src/servers/debug/DebugServer.cpp @@ -67,14 +67,15 @@ KillTeam(team_id team, const char *appName = NULL) status_t error = get_team_info(team, &info); if (error != B_OK) { debug_printf("debug_server: KillTeam(): Error getting info for " - "team %ld: %s\n", team, strerror(error)); + "team %" B_PRId32 ": %s\n", team, strerror(error)); info.args[0] = '\0'; } appName = info.args; } - debug_printf("debug_server: Killing team %ld (%s)\n", team, appName); + debug_printf("debug_server: Killing team %" B_PRId32 " (%s)\n", team, + appName); kill_team(team); } @@ -341,7 +342,7 @@ TeamDebugHandler::Init(port_id nubPort) status_t error = get_team_info(fTeam, &fTeamInfo); if (error != B_OK) { debug_printf("debug_server: TeamDebugHandler::Init(): Failed to get " - "info for team %ld: %s\n", fTeam, strerror(error)); + "info for team %" B_PRId32 ": %s\n", fTeam, strerror(error)); return error; } @@ -349,7 +350,8 @@ TeamDebugHandler::Init(port_id nubPort) error = BPrivate::get_app_path(fTeam, fExecutablePath); if (error != B_OK) { debug_printf("debug_server: TeamDebugHandler::Init(): Failed to get " - "executable path of team %ld: %s\n", fTeam, strerror(error)); + "executable path of team %" B_PRId32 ": %s\n", fTeam, + strerror(error)); fExecutablePath[0] = '\0'; } @@ -358,8 +360,8 @@ TeamDebugHandler::Init(port_id nubPort) error = init_debug_context(&fDebugContext, fTeam, nubPort); if (error != B_OK) { debug_printf("debug_server: TeamDebugHandler::Init(): Failed to init " - "debug context for team %ld, port %ld: %s\n", fTeam, nubPort, - strerror(error)); + "debug context for team %" B_PRId32 ", port %" B_PRId32 ": %s\n", + fTeam, nubPort, strerror(error)); return error; } @@ -372,7 +374,7 @@ TeamDebugHandler::Init(port_id nubPort) // create the message count semaphore char name[B_OS_NAME_LENGTH]; - snprintf(name, sizeof(name), "team %ld message count", fTeam); + snprintf(name, sizeof(name), "team %" B_PRId32 " message count", fTeam); fMessageCountSem = create_sem(0, name); if (fMessageCountSem < 0) { debug_printf("debug_server: TeamDebugHandler::Init(): Failed to create " @@ -381,7 +383,7 @@ TeamDebugHandler::Init(port_id nubPort) } // spawn the handler thread - snprintf(name, sizeof(name), "team %ld handler", fTeam); + snprintf(name, sizeof(name), "team %" B_PRId32 " handler", fTeam); fHandlerThread = spawn_thread(&_HandlerThreadEntry, name, B_NORMAL_PRIORITY, this); if (fHandlerThread < 0) { @@ -442,7 +444,7 @@ TeamDebugHandler::_SetupGDBArguments(BStringList &arguments, bool usingConsoled) { // prepare the argument vector BString teamString; - teamString.SetToFormat("--pid=%ld", fTeam); + teamString.SetToFormat("--pid=%" B_PRId32, fTeam); status_t error; BPath terminalPath; @@ -480,7 +482,7 @@ TeamDebugHandler::_SetupGDBArguments(BStringList &arguments, bool usingConsoled) if (!usingConsoled) { BString windowTitle; - windowTitle.SetToFormat("Debug of Team %ld: %s", fTeam, + windowTitle.SetToFormat("Debug of Team %" B_PRId32 ": %s", fTeam, _LastPathComponent(fExecutablePath)); if (!arguments.Add("-t") || !arguments.Add(windowTitle)) return B_NO_MEMORY; @@ -512,12 +514,12 @@ TeamDebugHandler::_SetupGDBArguments(BStringList &arguments, bool usingConsoled) thread_id TeamDebugHandler::_EnterDebugger() { - TRACE(("debug_server: TeamDebugHandler::_EnterDebugger(): team %ld\n", - fTeam)); + TRACE(("debug_server: TeamDebugHandler::_EnterDebugger(): team %" B_PRId32 + "\n", fTeam)); // prepare a debugger handover TRACE(("debug_server: TeamDebugHandler::_EnterDebugger(): preparing " - "debugger handover for team %ld...\n", fTeam)); + "debugger handover for team %" B_PRId32 "...\n", fTeam)); status_t error = send_debug_message(&fDebugContext, B_DEBUG_MESSAGE_PREPARE_HANDOVER, NULL, 0, NULL, 0); @@ -543,7 +545,7 @@ TeamDebugHandler::_EnterDebugger() // start the terminal TRACE(("debug_server: TeamDebugHandler::_EnterDebugger(): starting " - "terminal (debugger) for team %ld...\n", fTeam)); + "terminal (debugger) for team %" B_PRId32 "...\n", fTeam)); #elif defined(HANDOVER_USE_DEBUGGER) if (debugInConsoled) { @@ -572,13 +574,13 @@ TeamDebugHandler::_EnterDebugger() return B_NO_MEMORY; BString debuggerParam; - debuggerParam.SetToFormat("%ld", fTeam); + debuggerParam.SetToFormat("%" B_PRId32, fTeam); if (!arguments.Add("--team") || !arguments.Add(debuggerParam)) return B_NO_MEMORY; // start the debugger TRACE(("debug_server: TeamDebugHandler::_EnterDebugger(): starting " - "graphical debugger for team %ld...\n", fTeam)); + "graphical debugger for team %" B_PRId32 "...\n", fTeam)); } #endif @@ -595,7 +597,7 @@ TeamDebugHandler::_EnterDebugger() resume_thread(thread); TRACE(("debug_server: TeamDebugHandler::_EnterDebugger(): debugger started " - "for team %ld: thread: %ld\n", fTeam, thread)); + "for team %" B_PRId32 ": thread: %" B_PRId32 "\n", fTeam, thread)); return thread; } @@ -615,8 +617,8 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message) // a team. That means only a few messages are actually possible, while // others wouldn't trigger the debugger in the first place. So we deal with // all of them the same way, by popping up an alert. - TRACE(("debug_server: TeamDebugHandler::_HandleMessage(): team %ld, code: " - "%ld\n", fTeam, (int32)message->Code())); + TRACE(("debug_server: TeamDebugHandler::_HandleMessage(): team %" B_PRId32 + ", code: %" B_PRId32 "\n", fTeam, (int32)message->Code())); thread_id thread = message->Data().origin.thread; @@ -626,8 +628,8 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message) case B_DEBUGGER_MESSAGE_TEAM_DELETED: // This shouldn't happen. debug_printf("debug_server: Got a spurious " - "B_DEBUGGER_MESSAGE_TEAM_DELETED message for team %ld\n", - fTeam); + "B_DEBUGGER_MESSAGE_TEAM_DELETED message for team %" B_PRId32 + "\n", fTeam); return true; case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED: @@ -662,8 +664,8 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message) break; } - debug_printf("debug_server: Thread %ld entered the debugger: %s\n", thread, - buffer); + debug_printf("debug_server: Thread %" B_PRId32 " entered the debugger: %s\n", + thread, buffer); _PrintStackTrace(thread); @@ -735,7 +737,7 @@ TeamDebugHandler::_LookupSymbolAddress( // lookup failed: find area containing the IP bool useAreaInfo = false; area_info info; - int32 cookie = 0; + ssize_t cookie = 0; while (get_next_area_info(fTeam, &cookie, &info) == B_OK) { if ((addr_t)info.address <= (addr_t)address && (addr_t)info.address + info.size > (addr_t)address) { @@ -847,12 +849,12 @@ TeamDebugHandler::_HandlerThreadEntry(void *data) status_t TeamDebugHandler::_HandlerThread() { - TRACE(("debug_server: TeamDebugHandler::_HandlerThread(): team %ld\n", - fTeam)); + TRACE(("debug_server: TeamDebugHandler::_HandlerThread(): team %" B_PRId32 + "\n", fTeam)); // get initial message - TRACE(("debug_server: TeamDebugHandler::_HandlerThread(): team %ld: " - "getting message...\n", fTeam)); + TRACE(("debug_server: TeamDebugHandler::_HandlerThread(): team %" B_PRId32 + ": getting message...\n", fTeam)); DebugMessage *message; status_t error = _PopMessage(message); @@ -902,8 +904,8 @@ TeamDebugHandler::_HandlerThread() thread_info threadInfo; if (get_thread_info(debuggerThread, &threadInfo) != B_OK) { // the debugger is gone - debug_printf("debug_server: The debugger for team %ld " - "seems to be gone.", fTeam); + debug_printf("debug_server: The debugger for team %" + B_PRId32 " seems to be gone.", fTeam); kill = true; terminate = true; @@ -1088,8 +1090,8 @@ DebugServer::_Listener() "%s. Terminating!\n", strerror(bytesRead)); exit(1); } -TRACE(("debug_server: Got debug message: team: %ld, code: %ld\n", -message->Data().origin.team, code)); +TRACE(("debug_server: Got debug message: team: %" B_PRId32 ", code: %" B_PRId32 + "\n", message->Data().origin.team, code)); message->SetCode((debug_debugger_message)code); diff --git a/src/servers/input/MethodMenuItem.cpp b/src/servers/input/MethodMenuItem.cpp index daa66b0cc9..5df7b75f8a 100644 --- a/src/servers/input/MethodMenuItem.cpp +++ b/src/servers/input/MethodMenuItem.cpp @@ -17,7 +17,7 @@ #include #include "MethodMenuItem.h" -MethodMenuItem::MethodMenuItem(int32 cookie, const char* name, const uchar* icon, BMenu *subMenu, BMessenger &messenger) +MethodMenuItem::MethodMenuItem(void* cookie, const char* name, const uchar* icon, BMenu* subMenu, BMessenger& messenger) : BMenuItem(subMenu), fIcon(BRect(0, 0, MENUITEM_ICON_SIZE - 1, MENUITEM_ICON_SIZE - 1), B_CMAP8), fCookie(cookie) @@ -28,7 +28,7 @@ MethodMenuItem::MethodMenuItem(int32 cookie, const char* name, const uchar* icon } -MethodMenuItem::MethodMenuItem(int32 cookie, const char* name, const uchar* icon) +MethodMenuItem::MethodMenuItem(void* cookie, const char* name, const uchar* icon) : BMenuItem(name, NULL), fIcon(BRect(0, 0, MENUITEM_ICON_SIZE - 1, MENUITEM_ICON_SIZE - 1), B_CMAP8), fCookie(cookie) diff --git a/src/servers/input/MethodMenuItem.h b/src/servers/input/MethodMenuItem.h index f2608dbdc3..25aa5c90dd 100644 --- a/src/servers/input/MethodMenuItem.h +++ b/src/servers/input/MethodMenuItem.h @@ -24,8 +24,8 @@ class MethodMenuItem : public BMenuItem { public: - MethodMenuItem(int32 cookie, const char *label, const uchar *icon, BMenu *subMenu, BMessenger &messenger); - MethodMenuItem(int32 cookie, const char *label, const uchar *icon); + MethodMenuItem(void *cookie, const char *label, const uchar *icon, BMenu *subMenu, BMessenger &messenger); + MethodMenuItem(void *cookie, const char *label, const uchar *icon); virtual ~MethodMenuItem(); @@ -38,10 +38,10 @@ class MethodMenuItem : public BMenuItem { void SetIcon(const uchar *icon); const uchar *Icon() { return(uchar *)fIcon.Bits(); }; - int32 Cookie() { return fCookie; }; + void *Cookie() { return fCookie; }; private: BBitmap fIcon; - int32 fCookie; + void *fCookie; BMessenger fMessenger; }; diff --git a/src/servers/input/MethodReplicant.cpp b/src/servers/input/MethodReplicant.cpp index 9210cfc2da..18823ed67b 100644 --- a/src/servers/input/MethodReplicant.cpp +++ b/src/servers/input/MethodReplicant.cpp @@ -198,7 +198,7 @@ MethodReplicant::MouseDown(BPoint point) if (dynamic_cast(item) != NULL) { BMessage msg(IS_SET_METHOD); - msg.AddInt32("cookie", ((MethodMenuItem*)item)->Cookie()); + msg.AddPointer("cookie", ((MethodMenuItem*)item)->Cookie()); BMessenger messenger(fSignature); messenger.SendMessage(&msg); } @@ -216,15 +216,15 @@ void MethodReplicant::UpdateMethod(BMessage* message) { CALLED(); - int32 cookie; - if (message->FindInt32("cookie", &cookie) != B_OK) { + void* cookie; + if (message->FindPointer("cookie", &cookie) != B_OK) { fprintf(stderr, "can't find cookie in message\n"); return; } MethodMenuItem* item = FindItemByCookie(cookie); if (item == NULL) { - fprintf(stderr, "can't find item with cookie %lx\n", cookie); + fprintf(stderr, "can't find item with cookie %p\n", cookie); return; } item->SetMarked(true); @@ -239,8 +239,8 @@ void MethodReplicant::UpdateMethodIcon(BMessage* message) { CALLED(); - int32 cookie; - if (message->FindInt32("cookie", &cookie) != B_OK) { + void* cookie; + if (message->FindPointer("cookie", &cookie) != B_OK) { fprintf(stderr, "can't find cookie in message\n"); return; } @@ -255,7 +255,7 @@ MethodReplicant::UpdateMethodIcon(BMessage* message) MethodMenuItem* item = FindItemByCookie(cookie); if (item == NULL) { - fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie); + fprintf(stderr, "can't find item with cookie %p\n", cookie); return; } @@ -267,8 +267,8 @@ void MethodReplicant::UpdateMethodMenu(BMessage* message) { CALLED(); - int32 cookie; - if (message->FindInt32("cookie", &cookie) != B_OK) { + void* cookie; + if (message->FindPointer("cookie", &cookie) != B_OK) { fprintf(stderr, "can't find cookie in message\n"); return; } @@ -294,7 +294,7 @@ MethodReplicant::UpdateMethodMenu(BMessage* message) MethodMenuItem* item = FindItemByCookie(cookie); if (item == NULL) { - fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie); + fprintf(stderr, "can't find item with cookie %p\n", cookie); return; } int32 index = fMenu.IndexOf(item); @@ -317,8 +317,8 @@ void MethodReplicant::UpdateMethodName(BMessage* message) { CALLED(); - int32 cookie; - if (message->FindInt32("cookie", &cookie) != B_OK) { + void* cookie; + if (message->FindPointer("cookie", &cookie) != B_OK) { fprintf(stderr, "can't find cookie in message\n"); return; } @@ -331,7 +331,7 @@ MethodReplicant::UpdateMethodName(BMessage* message) MethodMenuItem* item = FindItemByCookie(cookie); if (item == NULL) { - fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie); + fprintf(stderr, "can't find item with cookie %p\n", cookie); return; } @@ -340,11 +340,11 @@ MethodReplicant::UpdateMethodName(BMessage* message) MethodMenuItem* -MethodReplicant::FindItemByCookie(int32 cookie) +MethodReplicant::FindItemByCookie(void* cookie) { for (int32 i = 0; i < fMenu.CountItems(); i++) { MethodMenuItem* item = (MethodMenuItem*)fMenu.ItemAt(i); - PRINT(("cookie : 0x%lx\n", item->Cookie())); + PRINT(("cookie : %p\n", item->Cookie())); if (item->Cookie() == cookie) return item; } @@ -357,8 +357,8 @@ void MethodReplicant::AddMethod(BMessage* message) { CALLED(); - int32 cookie; - if (message->FindInt32("cookie", &cookie) != B_OK) { + void* cookie; + if (message->FindPointer("cookie", &cookie) != B_OK) { fprintf(stderr, "can't find cookie in message\n"); return; } @@ -379,7 +379,7 @@ MethodReplicant::AddMethod(BMessage* message) MethodMenuItem* item = FindItemByCookie(cookie); if (item != NULL) { - fprintf(stderr, "item with cookie %lx already exists\n", cookie); + fprintf(stderr, "item with cookie %p already exists\n", cookie); return; } @@ -396,15 +396,15 @@ void MethodReplicant::RemoveMethod(BMessage* message) { CALLED(); - int32 cookie; - if (message->FindInt32("cookie", &cookie) != B_OK) { + void* cookie; + if (message->FindPointer("cookie", &cookie) != B_OK) { fprintf(stderr, "can't find cookie in message\n"); return; } MethodMenuItem* item = FindItemByCookie(cookie); if (item == NULL) { - fprintf(stderr, "can't find item with cookie %lx\n", cookie); + fprintf(stderr, "can't find item with cookie %p\n", cookie); return; } fMenu.RemoveItem(item); diff --git a/src/servers/input/MethodReplicant.h b/src/servers/input/MethodReplicant.h index b826fba17c..d40c704b98 100644 --- a/src/servers/input/MethodReplicant.h +++ b/src/servers/input/MethodReplicant.h @@ -57,7 +57,7 @@ class MethodReplicant : public BView { void UpdateMethodName(BMessage *); void AddMethod(BMessage *message); void RemoveMethod(BMessage *message); - MethodMenuItem *FindItemByCookie(int32 cookie); + MethodMenuItem *FindItemByCookie(void *cookie); }; #endif diff --git a/src/servers/mount/AutoMounter.cpp b/src/servers/mount/AutoMounter.cpp index cf6fb72163..8248ed706e 100644 --- a/src/servers/mount/AutoMounter.cpp +++ b/src/servers/mount/AutoMounter.cpp @@ -718,7 +718,7 @@ AutoMounter::_UnmountAndEjectVolume(BMessage* message) if (status == B_OK) status = volume.GetName(name); if (status < B_OK) - snprintf(name, sizeof(name), "device:%ld", device); + snprintf(name, sizeof(name), "device:%" B_PRIdDEV, device); BPath path; if (status == B_OK) { diff --git a/src/servers/net/Services.cpp b/src/servers/net/Services.cpp index 7b15ea4350..95ea5bd1e5 100644 --- a/src/servers/net/Services.cpp +++ b/src/servers/net/Services.cpp @@ -341,7 +341,7 @@ Services::_StopService(struct service& service) // Shutdown the running server, if any if (service.process != -1) { - printf(" Sending SIGTERM to process %ld\n", service.process); + printf(" Sending SIGTERM to process %" B_PRId32 "\n", service.process); kill(-service.process, SIGTERM); } diff --git a/src/servers/registrar/AuthenticationManager.cpp b/src/servers/registrar/AuthenticationManager.cpp index d5a2c7632b..d841ad7632 100644 --- a/src/servers/registrar/AuthenticationManager.cpp +++ b/src/servers/registrar/AuthenticationManager.cpp @@ -975,7 +975,8 @@ AuthenticationManager::_RequestThread() debug_printf("B_REG_UPDATE_GROUP done: currently unsupported!\n"); break; default: - debug_printf("REG: invalid message: %lu\n", message.What()); + debug_printf("REG: invalid message: %" B_PRIu32 "\n", + message.What()); } } diff --git a/src/servers/registrar/EventQueue.cpp b/src/servers/registrar/EventQueue.cpp index f9e31c3817..cdb46b9064 100644 --- a/src/servers/registrar/EventQueue.cpp +++ b/src/servers/registrar/EventQueue.cpp @@ -114,7 +114,7 @@ EventQueue::EventQueue(const char *name) EventQueue::~EventQueue() { Die(); - while (Event *event = (Event*)fEvents.RemoveItem(0L)) { + while (Event *event = (Event*)fEvents.RemoveItem((int32)0)) { if (event->IsAutoDelete()) delete event; } @@ -347,7 +347,7 @@ EventQueue::_EventLooper() // do events, that are supposed to go off while (!fTerminating && Lock() && !fEvents.IsEmpty() && system_time() >= _EventAt(0)->Time()) { - Event *event = (Event*)fEvents.RemoveItem(0L); + Event *event = (Event*)fEvents.RemoveItem((int32)0); Unlock(); bool autoDeleteEvent = event->IsAutoDelete(); bool deleteEvent = event->Do(this) || autoDeleteEvent; diff --git a/src/servers/registrar/MIMEManager.cpp b/src/servers/registrar/MIMEManager.cpp index c5a8ff19ea..e357fb9e4e 100644 --- a/src/servers/registrar/MIMEManager.cpp +++ b/src/servers/registrar/MIMEManager.cpp @@ -181,7 +181,7 @@ MIMEManager::MessageReceived(BMessage *message) err = fDatabase.GuessMimeType(&ref, &str); else if (err == B_NAME_NOT_FOUND) { const void *data; - int32 dataSize; + ssize_t dataSize; err = message->FindData("data", B_RAW_TYPE, &data, &dataSize); if (!err) @@ -290,8 +290,8 @@ MIMEManager::MessageReceived(BMessage *message) } default: - printf("MIMEMan: msg->what == %lx (%.4s)\n", message->what, - (char*)&(message->what)); + printf("MIMEMan: msg->what == %" B_PRIx32 " (%.4s)\n", + message->what, (char*)&(message->what)); BLooper::MessageReceived(message); break; } diff --git a/src/servers/registrar/MessagingService.cpp b/src/servers/registrar/MessagingService.cpp index 5d1758f729..bd8ba8544f 100644 --- a/src/servers/registrar/MessagingService.cpp +++ b/src/servers/registrar/MessagingService.cpp @@ -408,12 +408,13 @@ MessagingService::_CommandProcessor() const messaging_command *command = area->PopCommand(); if (!command) { // something's seriously wrong - ERROR("MessagingService::_CommandProcessor(): area %p (%ld) " - "has command count %ld, but doesn't return any more " - "commands.", area, area->ID(), area->CountCommands()); + ERROR("MessagingService::_CommandProcessor(): area %p (%" + B_PRId32 ") has command count %" B_PRId32 ", but doesn't " + "return any more commands.", area, area->ID(), + area->CountCommands()); break; } -PRINT("MessagingService::_CommandProcessor(): got command %lu\n", +PRINT("MessagingService::_CommandProcessor(): got command %" B_PRIu32 "\n", command->command); // dispatch the command @@ -424,7 +425,7 @@ command->command); command->size - sizeof(messaging_command)); } else { WARNING("MessagingService::_CommandProcessor(): No handler " - "found for command %lu\n", command->command); + "found for command %" B_PRIu32 "\n", command->command); } } @@ -440,7 +441,7 @@ command->command); } else { // Bad, but what can we do? ERROR("MessagingService::_CommandProcessor(): Failed to clone " - "kernel area %ld: %s\n", area->NextKernelAreaID(), + "kernel area %" B_PRId32 ": %s\n", area->NextKernelAreaID(), strerror(error)); } diff --git a/src/servers/registrar/RecentEntries.cpp b/src/servers/registrar/RecentEntries.cpp index 2281864274..ed3d5828a0 100644 --- a/src/servers/registrar/RecentEntries.cpp +++ b/src/servers/registrar/RecentEntries.cpp @@ -245,10 +245,10 @@ RecentEntries::Print() std::list::iterator item; int counter = 1; for (item = fEntryList.begin(); item != fEntryList.end(); item++) { - printf("%d: device == '%ld', dir == '%lld', name == '%s', app == '%s', " - "index == %ld\n", counter++, (*item)->ref.device, - (*item)->ref.directory, (*item)->ref.name, (*item)->sig.c_str(), - (*item)->index); + printf("%d: device == '%" B_PRIdDEV "', dir == '%" B_PRIdINO "', " + "name == '%s', app == '%s', index == %" B_PRId32 "\n", counter++, + (*item)->ref.device, (*item)->ref.directory, (*item)->ref.name, + (*item)->sig.c_str(), (*item)->index); } return B_OK; } @@ -308,9 +308,10 @@ RecentEntries::Save(FILE* file, const char *description, const char *tag) for (std::list::iterator item = list.begin(); item != list.end(); i++, item++) { recent_entry *entry = *item; - if (entry) - fprintf(file, " \"%s\" %ld", entry->sig.c_str(), entry->index); - else { + if (entry) { + fprintf(file, " \"%s\" %" B_PRId32, entry->sig.c_str(), + entry->index); + } else { D(PRINT("WARNING: RecentEntries::Save(): The entry %ld " "entries from the front of the compiled recent_entry* " "list for the entry ref (%ld, %lld, '%s') was found to " diff --git a/src/servers/registrar/TRoster.cpp b/src/servers/registrar/TRoster.cpp index 5b34d55b3c..b3276b0789 100644 --- a/src/servers/registrar/TRoster.cpp +++ b/src/servers/registrar/TRoster.cpp @@ -1934,7 +1934,7 @@ TRoster::_LoadRosterSettings(const char* path) char app[B_PATH_NAME_LENGTH]; char rank[B_PATH_NAME_LENGTH]; entry_ref ref; - uint32 index = 0; + ulong index = 0; // Convert the given path to an entry ref streamError = stream.GetString(path); diff --git a/src/servers/registrar/mime/AssociatedTypes.cpp b/src/servers/registrar/mime/AssociatedTypes.cpp index 7e507cda36..8865da9e81 100644 --- a/src/servers/registrar/mime/AssociatedTypes.cpp +++ b/src/servers/registrar/mime/AssociatedTypes.cpp @@ -398,9 +398,10 @@ AssociatedTypes::BuildAssociatedTypesTable() if (!err) { fHaveDoneFullBuild = true; // PrintToStream(); + } else { + DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable() failed, " + "error code == 0x%" B_PRIx32 "\n", err)); } - else - DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable() failed, error code == 0x%lx\n", err)); return err; } diff --git a/src/servers/registrar/mime/InstalledTypes.cpp b/src/servers/registrar/mime/InstalledTypes.cpp index 8823786d08..12b0c20ba0 100644 --- a/src/servers/registrar/mime/InstalledTypes.cpp +++ b/src/servers/registrar/mime/InstalledTypes.cpp @@ -406,7 +406,8 @@ InstalledTypes::_BuildInstalledTypesList() // Add this supertype std::map::iterator i; if (_AddSupertype(supertype, i) != B_OK) - DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList() -- Error adding supertype '%s': 0x%lx\n", + DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList()" + " -- Error adding supertype '%s': 0x%" B_PRIx32 "\n", supertype, err)); Supertype &supertypeRef = fSupertypes[supertype]; @@ -435,7 +436,8 @@ InstalledTypes::_BuildInstalledTypesList() // Add the subtype if (_AddSubtype(supertypeRef, type.String() + subStart + 1) != B_OK) { - DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList() -- Error adding subtype '%s/%s': 0x%lx\n", + DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList()" + " -- Error adding subtype '%s/%s': 0x%" B_PRIx32 "\n", supertype, type.String() + subStart + 1, err)); } } diff --git a/src/servers/registrar/mime/MimeUpdateThread.cpp b/src/servers/registrar/mime/MimeUpdateThread.cpp index d68ea3cb94..5b530fbc1b 100644 --- a/src/servers/registrar/mime/MimeUpdateThread.cpp +++ b/src/servers/registrar/mime/MimeUpdateThread.cpp @@ -125,9 +125,9 @@ MimeUpdateThread::ThreadFunction() status_t error = fManagerMessenger.SendMessage(&msg, (BHandler*)NULL, 500000); if (error) OUT("WARNING: ThreadManager::ThreadEntryFunction(): Termination notification " - "failed with error 0x%lx\n", error); + "failed with error 0x%" B_PRIx32 "\n", error); } - DBG(OUT("(id: %ld) exiting mime update thread with result 0x%lx\n", + DBG(OUT("(id: %ld) exiting mime update thread with result 0x%" B_PRIx32 "\n", find_thread(NULL), err)); return err; } diff --git a/src/servers/registrar/mime/RegistrarThreadManager.cpp b/src/servers/registrar/mime/RegistrarThreadManager.cpp index a8cff5a201..7c924d9058 100644 --- a/src/servers/registrar/mime/RegistrarThreadManager.cpp +++ b/src/servers/registrar/mime/RegistrarThreadManager.cpp @@ -199,8 +199,9 @@ RegistrarThreadManager::KillThreads() (*i)->Id())); status_t err = kill_thread((*i)->Id()); if (err) - OUT("WARNING: RegistrarThreadManager::KillThreads(): kill_thread(%ld) failed with " - "error code 0x%lx\n", (*i)->Id(), err); + OUT("WARNING: RegistrarThreadManager::KillThreads(): kill_thread(%" + B_PRId32 ") failed with error code 0x%" B_PRIx32 "\n", + (*i)->Id(), err); } DBG(OUT("RegistrarThreadManager::KillThreads(): Cleaning up thread %ld\n", (*i)->Id())); diff --git a/src/servers/registrar/mime/SnifferRules.cpp b/src/servers/registrar/mime/SnifferRules.cpp index 287461fd6b..e61885f31d 100644 --- a/src/servers/registrar/mime/SnifferRules.cpp +++ b/src/servers/registrar/mime/SnifferRules.cpp @@ -408,8 +408,10 @@ SnifferRules::BuildRuleList() fMaxBytesNeeded = maxBytesNeeded; fHaveDoneFullBuild = true; // PrintToStream(); - } else - DBG(OUT("Mime::SnifferRules::BuildRuleList() failed, error code == 0x%lx\n", err)); + } else { + DBG(OUT("Mime::SnifferRules::BuildRuleList() failed, error code == 0x%" + B_PRIx32 "\n", err)); + } return err; } diff --git a/src/servers/syslog_daemon/syslog_output.cpp b/src/servers/syslog_daemon/syslog_output.cpp index a751e40d36..270ee27884 100644 --- a/src/servers/syslog_daemon/syslog_output.cpp +++ b/src/servers/syslog_daemon/syslog_output.cpp @@ -50,7 +50,7 @@ prepare_output() // check file size struct stat stat; if (fstat(sLog, &stat) == 0) { - if (stat.st_size < sLogMaxSize) + if (stat.st_size < (off_t)sLogMaxSize) needNew = false; else tooLarge = true; @@ -100,7 +100,7 @@ write_to_log(const char *buffer, int32 length) if (sRepeatCount > 0) { char repeat[64]; ssize_t size = snprintf(repeat, sizeof(repeat), - "Last message repeated %ld time%s\n", sRepeatCount, + "Last message repeated %" B_PRId32 " time%s\n", sRepeatCount, sRepeatCount > 1 ? "s" : ""); sRepeatCount = 0; if (write(sLog, repeat, strlen(repeat)) < size) @@ -144,7 +144,7 @@ syslog_output(syslog_message &message) } if ((message.options & LOG_PID) != 0) { - pos += snprintf(header + pos, sizeof(header) - pos, "[%ld]", + pos += snprintf(header + pos, sizeof(header) - pos, "[%" B_PRId32 "]", message.from); } diff --git a/src/system/boot/Jamfile b/src/system/boot/Jamfile index 0260857d8d..69379a5fc2 100644 --- a/src/system/boot/Jamfile +++ b/src/system/boot/Jamfile @@ -1,28 +1,38 @@ SubDir HAIKU_TOP src system boot ; -local librootFunctions = - abs.o - ctype.o - LocaleData.o - qsort.o - kernel_vsprintf.o - memchr.o - memcmp.o - memmove.o - strdup.o - strndup.o - strlen.o - strnlen.o - strcmp.o - strcasecmp.o - strncmp.o - strcat.o - strcpy.o - strlcat.o - strlcpy.o - strchr.o - strrchr.o - strtol.o +DEFINES += _BOOT_MODE ; + +SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix string ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix stdlib ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix locale ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) kernel lib ] ; + +UsePrivateHeaders [ FDirName libroot locale ] ; + +BootMergeObject boot_libroot.o : + abs.c + ctype.cpp + LocaleData.cpp + qsort.c + kernel_vsprintf.cpp + memchr.c + memcmp.c + memmove.c + strdup.c + strndup.cpp + strlen.cpp + strnlen.cpp + strcmp.c + strcasecmp.c + strncmp.c + strcat.c + strcpy.c + strlcat.c + strlcpy.c + strchr.c + strrchr.c + strtol.c + : -fno-pic ; local extraLinkerArgs = ; @@ -32,9 +42,9 @@ if $(HAIKU_BOARD_LOADER_BASE) { AddResources haiku_loader : boot_loader.rdef ; -KernelLd boot_loader_$(TARGET_BOOT_PLATFORM) : +BootLd boot_loader_$(TARGET_BOOT_PLATFORM) : boot_platform_$(TARGET_BOOT_PLATFORM).o - boot_arch_$(TARGET_ARCH).o + boot_arch_$(TARGET_KERNEL_ARCH).o boot_loader.a boot_net.a boot_partitions.a @@ -48,9 +58,8 @@ KernelLd boot_loader_$(TARGET_BOOT_PLATFORM) : # needed by tarfs and video_splash.cpp boot_zlib.a - # libroot functions needed by the stage2 boot loader (compiled for the - # kernel) - $(librootFunctions:G=src!system!kernel!lib) + # libroot functions needed by the stage2 boot loader + boot_libroot.o : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/boot_loader_$(TARGET_BOOT_PLATFORM).ld : -Bstatic $(extraLinkerArgs) @@ -101,6 +110,6 @@ BuildBiosLoader haiku_loader : boot_loader_$(TARGET_BOOT_PLATFORM) ; # different target for PXE, to be build with TARGET_BOOT_PLATFORM=pxe_ia32 jam pxehaiku-loader BuildBiosLoader pxehaiku-loader : boot_loader_$(TARGET_BOOT_PLATFORM) ; -SubInclude HAIKU_TOP src system boot arch $(TARGET_ARCH) ; +SubInclude HAIKU_TOP src system boot arch $(TARGET_KERNEL_ARCH) ; SubInclude HAIKU_TOP src system boot loader ; SubInclude HAIKU_TOP src system boot platform ; diff --git a/src/system/boot/arch/arm/Jamfile b/src/system/boot/arch/arm/Jamfile index fbdd4d8b2d..2fdee42c2c 100644 --- a/src/system/boot/arch/arm/Jamfile +++ b/src/system/boot/arch/arm/Jamfile @@ -1,7 +1,7 @@ SubDir HAIKU_TOP src system boot arch arm ; #XXX: should not be needed here -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOARD) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ; { local defines = _BOOT_MODE ; @@ -22,7 +22,7 @@ local kernelLibArchObjects = memset.o ; -KernelMergeObject boot_arch_$(TARGET_ARCH).o : +BootMergeObject boot_arch_$(TARGET_KERNEL_ARCH).o : debug_uart_8250.cpp arch_uart_8250.cpp arch_uart_pl011.cpp @@ -40,7 +40,7 @@ KernelMergeObject boot_arch_$(TARGET_ARCH).o : ; SEARCH on [ FGristFiles arch_elf.cpp uart.cpp arch_uart_8250.cpp arch_uart_pl011.cpp ] - = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ; SEARCH on [ FGristFiles debug_uart_8250.cpp ] = [ FDirName $(HAIKU_TOP) src system kernel arch generic ] ; diff --git a/src/system/boot/arch/arm/arch_mmu.cpp b/src/system/boot/arch/arm/arch_mmu.cpp index d3e88cdac7..c1ea5922fa 100644 --- a/src/system/boot/arch/arm/arch_mmu.cpp +++ b/src/system/boot/arch/arm/arch_mmu.cpp @@ -579,7 +579,7 @@ mmu_init_for_kernel(void) dprintf("allocated virt memory ranges:\n"); for (i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", gKernelArgs.virtual_allocated_range[i].start, gKernelArgs.virtual_allocated_range[i].size); } diff --git a/src/system/boot/arch/m68k/Jamfile b/src/system/boot/arch/m68k/Jamfile index a63209089a..26e9d2ad52 100644 --- a/src/system/boot/arch/m68k/Jamfile +++ b/src/system/boot/arch/m68k/Jamfile @@ -13,7 +13,7 @@ local kernelLibArchObjects = memset.o ; -KernelMergeObject boot_arch_$(TARGET_ARCH).o : +BootMergeObject boot_arch_$(TARGET_KERNEL_ARCH).o : arch_elf.cpp $(librootArchObjects) : -fno-pic @@ -21,23 +21,23 @@ KernelMergeObject boot_arch_$(TARGET_ARCH).o : $(kernelLibArchObjects) ; -KernelMergeObject boot_arch_$(TARGET_ARCH)_030.o : +BootMergeObject boot_arch_m68k_030.o : mmu_030.cpp : -fno-pic -Wno-unused -m68030 ; -KernelMergeObject boot_arch_$(TARGET_ARCH)_040.o : +BootMergeObject boot_arch_m68k_040.o : mmu_040.cpp : -fno-pic -Wno-unused -m68040 ; -KernelMergeObject boot_arch_$(TARGET_ARCH)_060.o : +BootMergeObject boot_arch_m68k_060.o : mmu_060.cpp : -fno-pic -Wno-unused -m68060 ; SEARCH on [ FGristFiles arch_elf.cpp ] - = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ; SEARCH on [ FGristFiles $(librootArchObjects) ] = [ FDirName $(HAIKU_TOP) src system libroot posix string arch $(TARGET_ARCH) ] ; diff --git a/src/system/boot/arch/m68k/mmu.cpp b/src/system/boot/arch/m68k/mmu.cpp index 9c459b1e88..b7c2526d4a 100644 --- a/src/system/boot/arch/m68k/mmu.cpp +++ b/src/system/boot/arch/m68k/mmu.cpp @@ -503,9 +503,9 @@ mmu_init_for_kernel(void) gKernelArgs.num_virtual_allocated_ranges = 1; // sort the address ranges - sort_physical_address_ranges(gKernelArgs.physical_memory_range, + sort_address_ranges(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges); - sort_physical_address_ranges(gKernelArgs.physical_allocated_range, + sort_address_ranges(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges); sort_address_ranges(gKernelArgs.virtual_allocated_range, gKernelArgs.num_virtual_allocated_ranges); @@ -516,17 +516,23 @@ mmu_init_for_kernel(void) dprintf("phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.physical_memory_range[i].start, gKernelArgs.physical_memory_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.physical_memory_range[i].start, + gKernelArgs.physical_memory_range[i].size); } dprintf("allocated phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.physical_allocated_range[i].start, gKernelArgs.physical_allocated_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.physical_allocated_range[i].start, + gKernelArgs.physical_allocated_range[i].size); } dprintf("allocated virt memory ranges:\n"); for (i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.virtual_allocated_range[i].start, gKernelArgs.virtual_allocated_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.virtual_allocated_range[i].start, + gKernelArgs.virtual_allocated_range[i].size); } } #endif diff --git a/src/system/boot/arch/mipsel/Jamfile b/src/system/boot/arch/mipsel/Jamfile index 55f63e6d73..aafa31d30a 100644 --- a/src/system/boot/arch/mipsel/Jamfile +++ b/src/system/boot/arch/mipsel/Jamfile @@ -8,7 +8,7 @@ local kernelLibArchObjects = memset.o ; -KernelMergeObject boot_arch_$(TARGET_ARCH).o : +BootMergeObject boot_arch_$(TARGET_KERNEL_ARCH).o : arch_elf.cpp : # additional flags : @@ -17,5 +17,5 @@ KernelMergeObject boot_arch_$(TARGET_ARCH).o : ; SEARCH on [ FGristFiles arch_elf.cpp ] - = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ; diff --git a/src/system/boot/arch/ppc/Jamfile b/src/system/boot/arch/ppc/Jamfile index c2b817b54c..ea1c5a600a 100644 --- a/src/system/boot/arch/ppc/Jamfile +++ b/src/system/boot/arch/ppc/Jamfile @@ -15,7 +15,7 @@ local kernelLibArchObjects = memset.o ; -KernelMergeObject boot_arch_$(TARGET_ARCH).o : +BootMergeObject boot_arch_$(TARGET_KERNEL_ARCH).o : debug_uart_8250.cpp arch_uart_8250.cpp arch_elf.cpp @@ -26,7 +26,7 @@ KernelMergeObject boot_arch_$(TARGET_ARCH).o : ; SEARCH on [ FGristFiles arch_elf.cpp arch_uart_8250.cpp ] - = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ; SEARCH on [ FGristFiles debug_uart_8250.cpp ] = [ FDirName $(HAIKU_TOP) src system kernel arch generic ] ; diff --git a/src/system/boot/arch/x86/Jamfile b/src/system/boot/arch/x86/Jamfile index 7315dc73fe..0fd15d01f3 100644 --- a/src/system/boot/arch/x86/Jamfile +++ b/src/system/boot/arch/x86/Jamfile @@ -6,28 +6,31 @@ local kernelArchSources = arch_elf.cpp ; -local kernelArchObjects = - cpuid.o +local kernelArch32Sources = + cpuid.S ; local kernelLibArchSources = arch_string.S ; -local kernelLibArchObjects = - byteorder.o +local librootOsArchSources = + byteorder.S ; -KernelMergeObject boot_arch_$(TARGET_ARCH).o : +BootMergeObject boot_arch_$(TARGET_KERNEL_ARCH).o : $(kernelArchSources) + $(kernelArch32Sources) $(kernelLibArchSources) + $(librootOsArchSources) : # additional flags - : - $(kernelArchObjects) - $(kernelLibArchObjects) ; SEARCH on [ FGristFiles $(kernelArchSources) ] - = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel arch x86 ] ; +SEARCH on [ FGristFiles $(kernelArch32Sources) ] + = [ FDirName $(HAIKU_TOP) src system kernel arch x86 32 ] ; SEARCH on [ FGristFiles $(kernelLibArchSources) ] - = [ FDirName $(HAIKU_TOP) src system kernel lib arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel lib arch x86 ] ; +SEARCH on [ FGristFiles $(librootOsArchSources) ] + = [ FDirName $(HAIKU_TOP) src system libroot os arch x86 ] ; diff --git a/src/system/boot/loader/Jamfile b/src/system/boot/loader/Jamfile index 671ca94580..089f0dedea 100644 --- a/src/system/boot/loader/Jamfile +++ b/src/system/boot/loader/Jamfile @@ -12,7 +12,7 @@ UsePrivateHeaders shared storage ; { local defines = _BOOT_MODE - BOOT_ARCH=\\\"$(TARGET_ARCH)\\\" + BOOT_ARCH=\\\"$(TARGET_KERNEL_ARCH)\\\" KMESSAGE_CONTAINER_ONLY BOOT_SUPPORT_PARTITION_INTEL @@ -25,7 +25,7 @@ UsePrivateHeaders shared storage ; # Add architecture specific partition/file system modules - switch $(TARGET_ARCH) { + switch $(TARGET_KERNEL_ARCH) { case "ppc" : { defines += @@ -38,6 +38,9 @@ UsePrivateHeaders shared storage ; case "x86" : { defines += + ALTERNATE_BOOT_ARCH=\\\"x86_64\\\" + BOOT_SUPPORT_ELF64 + BOOT_SUPPORT_PARTITION_EFI #BOOT_SUPPORT_FILE_SYSTEM_FAT @@ -50,7 +53,7 @@ UsePrivateHeaders shared storage ; SubDirC++Flags $(defines) -fno-rtti ; } -KernelStaticLibrary boot_loader : +BootStaticLibrary boot_loader : elf.cpp heap.cpp kernel_args.cpp @@ -81,7 +84,7 @@ KernelStaticLibrary boot_loader : # The partition support is built in an extra static library # so that only the ones that are used will be included. -KernelStaticLibrary boot_partitions : +BootStaticLibrary boot_partitions : FileMapDisk.cpp amiga_rdb.cpp apple.cpp @@ -118,7 +121,7 @@ SEARCH on [ FGristFiles intel.cpp PartitionMap.cpp PartitionMapParser.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel partitioning_systems intel ] ; SEARCH on [ FGristFiles stage2_crt0.S ] - = [ FDirName $(HAIKU_TOP) src system boot arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system boot arch $(TARGET_KERNEL_ARCH) ] ; SubInclude HAIKU_TOP src system boot loader file_systems ; diff --git a/src/system/boot/loader/elf.cpp b/src/system/boot/loader/elf.cpp index 1e56c90453..d12e3b11da 100644 --- a/src/system/boot/loader/elf.cpp +++ b/src/system/boot/loader/elf.cpp @@ -1,5 +1,6 @@ /* * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Distributed under the terms of the MIT License. */ @@ -29,114 +30,432 @@ static bool sLoadElfSymbols = true; -void -elf_init() -{ -// TODO: This cannot work, since the driver settings are loaded *after* the -// kernel has been loaded successfully. -#if 0 - void *settings = load_driver_settings("kernel"); - if (settings == NULL) - return; - - sLoadElfSymbols = !get_driver_boolean_parameter(settings, "load_symbols", - false, false); - unload_driver_settings(settings); -#endif -} +// #pragma mark - Generic ELF loader -static status_t -verify_elf_header(struct Elf32_Ehdr &header) -{ - if (memcmp(header.e_ident, ELF_MAGIC, 4) != 0 - || header.e_ident[4] != ELFCLASS32 - || header.e_phoff == 0 - || !header.IsHostEndian() - || header.e_phentsize != sizeof(struct Elf32_Phdr)) - return B_BAD_TYPE; +template +class ELFLoader { +private: + typedef typename Class::ImageType ImageType; + typedef typename Class::RegionType RegionType; + typedef typename Class::AddrType AddrType; + typedef typename Class::EhdrType EhdrType; + typedef typename Class::PhdrType PhdrType; + typedef typename Class::ShdrType ShdrType; + typedef typename Class::DynType DynType; + typedef typename Class::SymType SymType; + typedef typename Class::RelType RelType; + typedef typename Class::RelaType RelaType; - return B_OK; -} +public: + static status_t Create(int fd, preloaded_image** _image); + static status_t Load(int fd, preloaded_image* image); + static status_t Relocate(preloaded_image* image); + static status_t Resolve(ImageType* image, SymType* symbol, + AddrType* symbolAddress); + +private: + static status_t _LoadSymbolTable(int fd, ImageType* image); + static status_t _ParseDynamicSection(ImageType* image); +}; -static status_t -elf_parse_dynamic_section(struct preloaded_image *image) -{ - image->syms = 0; - image->rel = 0; - image->rel_len = 0; - image->rela = 0; - image->rela_len = 0; - image->pltrel = 0; - image->pltrel_len = 0; - image->pltrel_type = 0; +struct ELF32Class { + static const uint8 kIdentClass = ELFCLASS32; - struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_section.start; - if (!d) - return B_ERROR; + typedef preloaded_elf32_image ImageType; + typedef elf32_region RegionType; + typedef Elf32_Addr AddrType; + typedef Elf32_Ehdr EhdrType; + typedef Elf32_Phdr PhdrType; + typedef Elf32_Shdr ShdrType; + typedef Elf32_Dyn DynType; + typedef Elf32_Sym SymType; + typedef Elf32_Rel RelType; + typedef Elf32_Rela RelaType; - for (int i = 0; d[i].d_tag != DT_NULL; i++) { - switch (d[i].d_tag) { - case DT_HASH: - case DT_STRTAB: - break; - case DT_SYMTAB: - image->syms = (struct Elf32_Sym *)(d[i].d_un.d_ptr - + image->text_region.delta); - break; - case DT_REL: - image->rel = (struct Elf32_Rel *)(d[i].d_un.d_ptr - + image->text_region.delta); - break; - case DT_RELSZ: - image->rel_len = d[i].d_un.d_val; - break; - case DT_RELA: - image->rela = (struct Elf32_Rela *)(d[i].d_un.d_ptr - + image->text_region.delta); - break; - case DT_RELASZ: - image->rela_len = d[i].d_un.d_val; - break; - case DT_JMPREL: - image->pltrel = (struct Elf32_Rel *)(d[i].d_un.d_ptr - + image->text_region.delta); - break; - case DT_PLTRELSZ: - image->pltrel_len = d[i].d_un.d_val; - break; - case DT_PLTREL: - image->pltrel_type = d[i].d_un.d_val; - break; + static inline status_t + AllocateRegion(AddrType* _address, AddrType size, uint8 protection, + void** _mappedAddress) + { + status_t status = platform_allocate_region((void**)_address, size, + protection, false); + if (status != B_OK) + return status; - default: - continue; - } + *_mappedAddress = (void*)*_address; + return B_OK; } - // lets make sure we found all the required sections - if (image->syms == NULL) - return B_ERROR; + static inline void* + Map(AddrType address) + { + return (void*)address; + } +}; +typedef ELFLoader ELF32Loader; + + +#ifdef BOOT_SUPPORT_ELF64 +struct ELF64Class { + static const uint8 kIdentClass = ELFCLASS64; + + typedef preloaded_elf64_image ImageType; + typedef elf64_region RegionType; + typedef Elf64_Addr AddrType; + typedef Elf64_Ehdr EhdrType; + typedef Elf64_Phdr PhdrType; + typedef Elf64_Shdr ShdrType; + typedef Elf64_Dyn DynType; + typedef Elf64_Sym SymType; + typedef Elf64_Rel RelType; + typedef Elf64_Rela RelaType; + + static inline status_t + AllocateRegion(AddrType* _address, AddrType size, uint8 protection, + void **_mappedAddress) + { + // Assume the real 64-bit base address is KERNEL_LOAD_BASE_64_BIT and + // the mappings in the loader address space are at KERNEL_LOAD_BASE. + + void* address = (void*)(addr_t)(*_address & 0xffffffff); + + status_t status = platform_allocate_region(&address, size, protection, + false); + if (status != B_OK) + return status; + + *_mappedAddress = address; + *_address = (AddrType)(addr_t)address + KERNEL_LOAD_BASE_64_BIT + - KERNEL_LOAD_BASE; + return B_OK; + } + + static inline void* + Map(AddrType address) + { + return (void*)(addr_t)(address - KERNEL_LOAD_BASE_64_BIT + + KERNEL_LOAD_BASE); + } +}; + +typedef ELFLoader ELF64Loader; +#endif + + +template +/*static*/ status_t +ELFLoader::Create(int fd, preloaded_image** _image) +{ + ImageType* image = (ImageType*)kernel_args_malloc(sizeof(ImageType)); + if (image == NULL) + return B_NO_MEMORY; + + EhdrType& elfHeader = image->elf_header; + + ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(EhdrType)); + if (length < (ssize_t)sizeof(EhdrType)) { + kernel_args_free(image); + return B_BAD_TYPE; + } + + if (memcmp(elfHeader.e_ident, ELF_MAGIC, 4) != 0 + || elfHeader.e_ident[4] != Class::kIdentClass + || elfHeader.e_phoff == 0 + || !elfHeader.IsHostEndian() + || elfHeader.e_phentsize != sizeof(PhdrType)) { + kernel_args_free(image); + return B_BAD_TYPE; + } + + image->elf_class = elfHeader.e_ident[EI_CLASS]; + + *_image = image; return B_OK; } -static status_t -load_elf_symbol_table(int fd, preloaded_image *image) +template +/*static*/ status_t +ELFLoader::Load(int fd, preloaded_image* _image) { - struct Elf32_Ehdr &elfHeader = image->elf_header; - Elf32_Sym *symbolTable = NULL; - Elf32_Shdr *stringHeader = NULL; + size_t totalSize; + ssize_t length; + status_t status; + void* mappedRegion = NULL; + + ImageType* image = static_cast(_image); + EhdrType& elfHeader = image->elf_header; + + ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize; + PhdrType* programHeaders = (PhdrType*)malloc(size); + if (programHeaders == NULL) { + dprintf("error allocating space for program headers\n"); + status = B_NO_MEMORY; + goto error1; + } + + length = read_pos(fd, elfHeader.e_phoff, programHeaders, size); + if (length < size) { + TRACE(("error reading in program headers\n")); + status = B_ERROR; + goto error1; + } + + // create an area large enough to hold the image + + image->data_region.size = 0; + image->text_region.size = 0; + + for (int32 i = 0; i < elfHeader.e_phnum; i++) { + PhdrType& header = programHeaders[i]; + + switch (header.p_type) { + case PT_LOAD: + break; + case PT_DYNAMIC: + image->dynamic_section.start = header.p_vaddr; + image->dynamic_section.size = header.p_memsz; + continue; + case PT_INTERP: + case PT_PHDR: + // known but unused type + continue; + default: + dprintf("unhandled pheader type 0x%lx\n", header.p_type); + continue; + } + + RegionType* region; + if (header.IsReadWrite()) { + if (image->data_region.size != 0) { + dprintf("elf: rw already handled!\n"); + continue; + } + region = &image->data_region; + } else if (header.IsExecutable()) { + if (image->text_region.size != 0) { + dprintf("elf: ro already handled!\n"); + continue; + } + region = &image->text_region; + } else + continue; + + region->start = ROUNDDOWN(header.p_vaddr, B_PAGE_SIZE); + region->size = ROUNDUP(header.p_memsz + (header.p_vaddr % B_PAGE_SIZE), + B_PAGE_SIZE); + region->delta = -region->start; + + TRACE(("segment %ld: start = 0x%llx, size = %llu, delta = %llx\n", i, + (uint64)region->start, (uint64)region->size, + (int64)(AddrType)region->delta)); + } + + // found both, text and data? + if (image->data_region.size == 0 || image->text_region.size == 0) { + dprintf("Couldn't find both text and data segment!\n"); + status = B_BAD_DATA; + goto error1; + } + + // get the segment order + RegionType* firstRegion; + RegionType* secondRegion; + if (image->text_region.start < image->data_region.start) { + firstRegion = &image->text_region; + secondRegion = &image->data_region; + } else { + firstRegion = &image->data_region; + secondRegion = &image->text_region; + } + + // Check whether the segments have an unreasonable amount of unused space + // inbetween. + totalSize = secondRegion->start + secondRegion->size - firstRegion->start; + if (totalSize > image->text_region.size + image->data_region.size + + 8 * 1024) { + status = B_BAD_DATA; + goto error1; + } + + // The kernel and the modules are relocatable, thus AllocateRegion() + // can automatically allocate an address, but shall prefer the specified + // base address. + if (Class::AllocateRegion(&firstRegion->start, totalSize, + B_READ_AREA | B_WRITE_AREA, &mappedRegion) != B_OK) { + status = B_NO_MEMORY; + goto error1; + } + + // initialize the region pointers to the allocated region + secondRegion->start += firstRegion->start + firstRegion->delta; + + image->data_region.delta += image->data_region.start; + image->text_region.delta += image->text_region.start; + + TRACE(("text: start 0x%llx, size 0x%llx, delta 0x%llx\n", + (uint64)image->text_region.start, (uint64)image->text_region.size, + (int64)(AddrType)image->text_region.delta)); + TRACE(("data: start 0x%llx, size 0x%llx, delta 0x%llx\n", + (uint64)image->data_region.start, (uint64)image->data_region.size, + (int64)(AddrType)image->data_region.delta)); + + // load program data + + for (int32 i = 0; i < elfHeader.e_phnum; i++) { + PhdrType& header = programHeaders[i]; + + if (header.p_type != PT_LOAD) + continue; + + RegionType* region; + if (header.IsReadWrite()) + region = &image->data_region; + else if (header.IsExecutable()) + region = &image->text_region; + else + continue; + + TRACE(("load segment %ld (%llu bytes) mapped at %p...\n", i, + (uint64)header.p_filesz, Class::Map(region->start))); + + length = read_pos(fd, header.p_offset, + Class::Map(region->start + (header.p_vaddr % B_PAGE_SIZE)), + header.p_filesz); + if (length < (ssize_t)header.p_filesz) { + status = B_BAD_DATA; + dprintf("error reading in seg %ld\n", i); + goto error2; + } + + // Clear anything above the file size (that may also contain the BSS + // area) + + uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz; + if (offset < region->size) + memset(Class::Map(region->start + offset), 0, region->size - offset); + } + + // offset dynamic section, and program entry addresses by the delta of the + // regions + image->dynamic_section.start += image->text_region.delta; + image->elf_header.e_entry += image->text_region.delta; + + image->num_debug_symbols = 0; + image->debug_symbols = NULL; + image->debug_string_table = NULL; + + if (sLoadElfSymbols) + _LoadSymbolTable(fd, image); + + free(programHeaders); + + return B_OK; + +error2: + if (mappedRegion != NULL) + platform_free_region(mappedRegion, totalSize); +error1: + free(programHeaders); + kernel_args_free(image); + + return status; +} + + +template +/*static*/ status_t +ELFLoader::Relocate(preloaded_image* _image) +{ + ImageType* image = static_cast(_image); + + status_t status = _ParseDynamicSection(image); + if (status != B_OK) + return status; + + // deal with the rels first + if (image->rel) { + TRACE(("total %i relocs\n", + (int)image->rel_len / (int)sizeof(RelType))); + + status = boot_arch_elf_relocate_rel(image, image->rel, image->rel_len); + if (status != B_OK) + return status; + } + + if (image->pltrel) { + RelType* pltrel = image->pltrel; + if (image->pltrel_type == DT_REL) { + TRACE(("total %i plt-relocs\n", + (int)image->pltrel_len / (int)sizeof(RelType))); + + status = boot_arch_elf_relocate_rel(image, pltrel, + image->pltrel_len); + } else { + TRACE(("total %i plt-relocs\n", + (int)image->pltrel_len / (int)sizeof(RelaType))); + + status = boot_arch_elf_relocate_rela(image, (RelaType*)pltrel, + image->pltrel_len); + } + if (status != B_OK) + return status; + } + + if (image->rela) { + TRACE(("total %i rela relocs\n", + (int)image->rela_len / (int)sizeof(RelaType))); + status = boot_arch_elf_relocate_rela(image, image->rela, + image->rela_len); + if (status != B_OK) + return status; + } + + return B_OK; +} + +template +/*static*/ status_t +ELFLoader::Resolve(ImageType* image, SymType* symbol, + AddrType* symbolAddress) +{ + switch (symbol->st_shndx) { + case SHN_UNDEF: + // Since we do that only for the kernel, there shouldn't be + // undefined symbols. + return B_MISSING_SYMBOL; + case SHN_ABS: + *symbolAddress = symbol->st_value; + return B_NO_ERROR; + case SHN_COMMON: + // ToDo: finish this + TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n")); + return B_ERROR; + default: + // standard symbol + *symbolAddress = symbol->st_value + image->text_region.delta; + return B_OK; + } +} + + +template +/*static*/ status_t +ELFLoader::_LoadSymbolTable(int fd, ImageType* image) +{ + EhdrType& elfHeader = image->elf_header; + SymType* symbolTable = NULL; + ShdrType* stringHeader = NULL; uint32 numSymbols = 0; - char *stringTable; + char* stringTable; status_t status; // get section headers ssize_t size = elfHeader.e_shnum * elfHeader.e_shentsize; - Elf32_Shdr *sectionHeaders = (struct Elf32_Shdr *)malloc(size); + ShdrType* sectionHeaders = (ShdrType*)malloc(size); if (sectionHeaders == NULL) { dprintf("error allocating space for section headers\n"); return B_NO_MEMORY; @@ -162,8 +481,8 @@ load_elf_symbol_table(int fd, preloaded_image *image) } // read in symbol table - symbolTable = (Elf32_Sym *)kernel_args_malloc( - size = sectionHeaders[i].sh_size); + size = sectionHeaders[i].sh_size; + symbolTable = (SymType*)kernel_args_malloc(size); if (symbolTable == NULL) { status = B_NO_MEMORY; goto error1; @@ -177,7 +496,7 @@ load_elf_symbol_table(int fd, preloaded_image *image) goto error1; } - numSymbols = size / sizeof(Elf32_Sym); + numSymbols = size / sizeof(SymType); break; } } @@ -190,7 +509,8 @@ load_elf_symbol_table(int fd, preloaded_image *image) // read in string table - stringTable = (char *)kernel_args_malloc(size = stringHeader->sh_size); + size = stringHeader->sh_size; + stringTable = (char*)kernel_args_malloc(size); if (stringTable == NULL) { status = B_NO_MEMORY; goto error2; @@ -225,194 +545,124 @@ error1: } -status_t -elf_load_image(int fd, preloaded_image *image) +template +/*static*/ status_t +ELFLoader::_ParseDynamicSection(ImageType* image) { - size_t totalSize; - status_t status; + image->syms = 0; + image->rel = 0; + image->rel_len = 0; + image->rela = 0; + image->rela_len = 0; + image->pltrel = 0; + image->pltrel_len = 0; + image->pltrel_type = 0; - TRACE(("elf_load_image(fd = %d, image = %p)\n", fd, image)); + if(image->dynamic_section.start == 0) + return B_ERROR; - struct Elf32_Ehdr &elfHeader = image->elf_header; + DynType* d = (DynType*)Class::Map(image->dynamic_section.start); - ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr)); - if (length < (ssize_t)sizeof(Elf32_Ehdr)) - return B_BAD_TYPE; - - status = verify_elf_header(elfHeader); - if (status < B_OK) - return status; - - ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize; - Elf32_Phdr *programHeaders = (struct Elf32_Phdr *)malloc(size); - if (programHeaders == NULL) { - dprintf("error allocating space for program headers\n"); - return B_NO_MEMORY; - } - - length = read_pos(fd, elfHeader.e_phoff, programHeaders, size); - if (length < size) { - TRACE(("error reading in program headers\n")); - status = B_ERROR; - goto error1; - } - - // create an area large enough to hold the image - - image->data_region.size = 0; - image->text_region.size = 0; - - for (int32 i = 0; i < elfHeader.e_phnum; i++) { - Elf32_Phdr &header = programHeaders[i]; - - switch (header.p_type) { - case PT_LOAD: + for (int i = 0; d[i].d_tag != DT_NULL; i++) { + switch (d[i].d_tag) { + case DT_HASH: + case DT_STRTAB: break; - case PT_DYNAMIC: - image->dynamic_section.start = header.p_vaddr; - image->dynamic_section.size = header.p_memsz; - continue; - case PT_INTERP: - case PT_PHDR: - // known but unused type - continue; + case DT_SYMTAB: + image->syms = (SymType*)Class::Map(d[i].d_un.d_ptr + + image->text_region.delta); + break; + case DT_REL: + image->rel = (RelType*)Class::Map(d[i].d_un.d_ptr + + image->text_region.delta); + break; + case DT_RELSZ: + image->rel_len = d[i].d_un.d_val; + break; + case DT_RELA: + image->rela = (RelaType*)Class::Map(d[i].d_un.d_ptr + + image->text_region.delta); + break; + case DT_RELASZ: + image->rela_len = d[i].d_un.d_val; + break; + case DT_JMPREL: + image->pltrel = (RelType*)Class::Map(d[i].d_un.d_ptr + + image->text_region.delta); + break; + case DT_PLTRELSZ: + image->pltrel_len = d[i].d_un.d_val; + break; + case DT_PLTREL: + image->pltrel_type = d[i].d_un.d_val; + break; + default: - dprintf("unhandled pheader type 0x%lx\n", header.p_type); continue; } - - elf_region *region; - if (header.IsReadWrite()) { - if (image->data_region.size != 0) { - dprintf("elf: rw already handled!\n"); - continue; - } - region = &image->data_region; - } else if (header.IsExecutable()) { - if (image->text_region.size != 0) { - dprintf("elf: ro already handled!\n"); - continue; - } - region = &image->text_region; - } else - continue; - - region->start = ROUNDDOWN(header.p_vaddr, B_PAGE_SIZE); - region->size = ROUNDUP(header.p_memsz + (header.p_vaddr % B_PAGE_SIZE), - B_PAGE_SIZE); - region->delta = -region->start; - - TRACE(("segment %d: start = %p, size = %lu, delta = %lx\n", i, - region->start, region->size, region->delta)); } - // found both, text and data? - if (image->data_region.size == 0 || image->text_region.size == 0) { - dprintf("Couldn't find both text and data segment!\n"); - status = B_BAD_DATA; - goto error1; - } - - // get the segment order - elf_region *firstRegion; - elf_region *secondRegion; - if (image->text_region.start < image->data_region.start) { - firstRegion = &image->text_region; - secondRegion = &image->data_region; - } else { - firstRegion = &image->data_region; - secondRegion = &image->text_region; - } - - // Check whether the segments have an unreasonable amount of unused space - // inbetween. - totalSize = secondRegion->start + secondRegion->size - firstRegion->start; - if (totalSize > image->text_region.size + image->data_region.size - + 8 * 1024) { - status = B_BAD_DATA; - goto error1; - } - - // The kernel and the modules are relocatable, thus - // platform_allocate_region() can automatically allocate an address, - // but shall prefer the specified base address. - if (platform_allocate_region((void **)&firstRegion->start, totalSize, - B_READ_AREA | B_WRITE_AREA, false) < B_OK) { - status = B_NO_MEMORY; - goto error1; - } - - // initialize the region pointers to the allocated region - secondRegion->start += firstRegion->start + firstRegion->delta; - - image->data_region.delta += image->data_region.start; - image->text_region.delta += image->text_region.start; - - // load program data - - for (int i = 0; i < elfHeader.e_phnum; i++) { - Elf32_Phdr &header = programHeaders[i]; - - if (header.p_type != PT_LOAD) - continue; - - elf_region *region; - if (header.IsReadWrite()) - region = &image->data_region; - else if (header.IsExecutable()) - region = &image->text_region; - else - continue; - - TRACE(("load segment %d (%ld bytes)...\n", i, header.p_filesz)); - - length = read_pos(fd, header.p_offset, - (void *)(region->start + (header.p_vaddr % B_PAGE_SIZE)), - header.p_filesz); - if (length < (ssize_t)header.p_filesz) { - status = B_BAD_DATA; - dprintf("error reading in seg %d\n", i); - goto error2; - } - - // Clear anything above the file size (that may also contain the BSS - // area) - - uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz; - if (offset < region->size) - memset((void *)(region->start + offset), 0, region->size - offset); - } - - // offset dynamic section, and program entry addresses by the delta of the - // regions - image->dynamic_section.start += image->text_region.delta; - image->elf_header.e_entry += image->text_region.delta; - - image->num_debug_symbols = 0; - image->debug_symbols = NULL; - image->debug_string_table = NULL; - - if (sLoadElfSymbols) - load_elf_symbol_table(fd, image); - - free(programHeaders); + // lets make sure we found all the required sections + if (image->syms == NULL) + return B_ERROR; return B_OK; +} -error2: - if (image->text_region.start != 0) - platform_free_region((void *)image->text_region.start, totalSize); -error1: - free(programHeaders); + +// #pragma mark - + + +void +elf_init() +{ +// TODO: This cannot work, since the driver settings are loaded *after* the +// kernel has been loaded successfully. +#if 0 + void *settings = load_driver_settings("kernel"); + if (settings == NULL) + return; + + sLoadElfSymbols = !get_driver_boolean_parameter(settings, "load_symbols", + false, false); + unload_driver_settings(settings); +#endif +} + + +status_t +elf_load_image(int fd, preloaded_image** _image) +{ + status_t status = B_ERROR; + + TRACE(("elf_load_image(fd = %d, _image = %p)\n", fd, _image)); + +#if BOOT_SUPPORT_ELF64 + if (gKernelArgs.kernel_image == NULL + || gKernelArgs.kernel_image->elf_class == ELFCLASS64) { + status = ELF64Loader::Create(fd, _image); + if (status == B_OK) + return ELF64Loader::Load(fd, *_image); + else if (status != B_BAD_TYPE) + return status; + } +#endif + + if (gKernelArgs.kernel_image == NULL + || gKernelArgs.kernel_image->elf_class == ELFCLASS32) { + status = ELF32Loader::Create(fd, _image); + if (status == B_OK) + return ELF32Loader::Load(fd, *_image); + } return status; } status_t -elf_load_image(Directory *directory, const char *path) +elf_load_image(Directory* directory, const char* path) { - preloaded_image *image; + preloaded_image* image; TRACE(("elf_load_image(directory = %p, \"%s\")\n", directory, path)); @@ -437,13 +687,7 @@ elf_load_image(Directory *directory, const char *path) // we still need to load it, so do it - image = (preloaded_image *)kernel_args_malloc(sizeof(preloaded_image)); - if (image == NULL) { - close(fd); - return B_NO_MEMORY; - } - - status_t status = elf_load_image(fd, image); + status_t status = elf_load_image(fd, &image); if (status == B_OK) { image->name = kernel_args_strdup(path); image->inode = stat.st_ino; @@ -460,69 +704,37 @@ elf_load_image(Directory *directory, const char *path) status_t -elf_relocate_image(struct preloaded_image *image) +elf_relocate_image(preloaded_image* image) { - status_t status = elf_parse_dynamic_section(image); - if (status != B_OK) - return status; - - // deal with the rels first - if (image->rel) { - TRACE(("total %i relocs\n", - image->rel_len / (int)sizeof(struct Elf32_Rel))); - - status = boot_arch_elf_relocate_rel(image, image->rel, image->rel_len); - if (status < B_OK) - return status; - } - - if (image->pltrel) { - TRACE(("total %i plt-relocs\n", - image->pltrel_len / (int)sizeof(struct Elf32_Rel))); - - if (image->pltrel_type == DT_REL) { - status = boot_arch_elf_relocate_rel(image, image->pltrel, - image->pltrel_len); - } else { - status = boot_arch_elf_relocate_rela(image, - (struct Elf32_Rela *)image->pltrel, image->pltrel_len); - } - if (status < B_OK) - return status; - } - - if (image->rela) { - TRACE(("total %i rela relocs\n", - image->rela_len / (int)sizeof(struct Elf32_Rela))); - status = boot_arch_elf_relocate_rela(image, image->rela, - image->rela_len); - if (status < B_OK) - return status; - } - - return B_OK; +#ifdef BOOT_SUPPORT_ELF64 + if (image->elf_class == ELFCLASS64) + return ELF64Loader::Relocate(image); + else +#endif + return ELF32Loader::Relocate(image); } status_t -boot_elf_resolve_symbol(struct preloaded_image *image, - struct Elf32_Sym *symbol, addr_t *symbolAddress) +boot_elf_resolve_symbol(preloaded_elf32_image* image, struct Elf32_Sym* symbol, + Elf32_Addr* symbolAddress) { - switch (symbol->st_shndx) { - case SHN_UNDEF: - // Since we do that only for the kernel, there shouldn't be - // undefined symbols. - return B_MISSING_SYMBOL; - case SHN_ABS: - *symbolAddress = symbol->st_value; - return B_NO_ERROR; - case SHN_COMMON: - // ToDo: finish this - TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n")); - return B_ERROR; - default: - // standard symbol - *symbolAddress = symbol->st_value + image->text_region.delta; - return B_NO_ERROR; - } + return ELF32Loader::Resolve(image, symbol, symbolAddress); } + + +#ifdef BOOT_SUPPORT_ELF64 +status_t +boot_elf_resolve_symbol(preloaded_elf64_image* image, struct Elf64_Sym* symbol, + Elf64_Addr* symbolAddress) +{ + return ELF64Loader::Resolve(image, symbol, symbolAddress); +} + +void +boot_elf64_set_relocation(Elf64_Addr resolveAddress, Elf64_Addr finalAddress) +{ + Elf64_Addr* dest = (Elf64_Addr*)ELF64Class::Map(resolveAddress); + *dest = finalAddress; +} +#endif diff --git a/src/system/boot/loader/elf.h b/src/system/boot/loader/elf.h index 8a899b6aff..9a0e610936 100644 --- a/src/system/boot/loader/elf.h +++ b/src/system/boot/loader/elf.h @@ -11,9 +11,10 @@ extern void elf_init(); -extern status_t elf_load_image(Directory *directory, const char *path); -extern status_t elf_load_image(int fd, preloaded_image *image); +extern status_t elf_load_image(Directory* directory, const char* path); +extern status_t elf_load_image(int fd, preloaded_image** _image); + +extern status_t elf_relocate_image(preloaded_image* image); -extern status_t elf_relocate_image(struct preloaded_image *image); #endif /* LOADER_ELF_H */ diff --git a/src/system/boot/loader/file_systems/amiga_ffs/Jamfile b/src/system/boot/loader/file_systems/amiga_ffs/Jamfile index 222c7755b8..1b2d8bbc27 100644 --- a/src/system/boot/loader/file_systems/amiga_ffs/Jamfile +++ b/src/system/boot/loader/file_systems/amiga_ffs/Jamfile @@ -8,7 +8,7 @@ UsePrivateHeaders kernel storage ; SubDirC++Flags -fno-rtti ; -KernelStaticLibrary boot_amiga_ffs : +BootStaticLibrary boot_amiga_ffs : amiga_ffs.cpp Volume.cpp Directory.cpp diff --git a/src/system/boot/loader/file_systems/bfs/Jamfile b/src/system/boot/loader/file_systems/bfs/Jamfile index f5840e9e48..e91cf720d1 100644 --- a/src/system/boot/loader/file_systems/bfs/Jamfile +++ b/src/system/boot/loader/file_systems/bfs/Jamfile @@ -10,7 +10,7 @@ local defines = [ FDefines _BOOT_MODE ] ; SubDirCcFlags $(defines) ; SubDirC++Flags -fno-rtti $(defines) ; -KernelStaticLibrary boot_bfs : +BootStaticLibrary boot_bfs : bfs.cpp Directory.cpp File.cpp diff --git a/src/system/boot/loader/file_systems/fat/Jamfile b/src/system/boot/loader/file_systems/fat/Jamfile index 69aee03778..52de886b8c 100644 --- a/src/system/boot/loader/file_systems/fat/Jamfile +++ b/src/system/boot/loader/file_systems/fat/Jamfile @@ -13,7 +13,7 @@ local defines = [ FDefines _BOOT_MODE ] ; SubDirCcFlags $(defines) ; SubDirC++Flags -fno-rtti $(defines) ; -KernelStaticLibrary boot_fatfs : +BootStaticLibrary boot_fatfs : fatfs.cpp Volume.cpp CachedBlock.cpp diff --git a/src/system/boot/loader/file_systems/hfs_plus/Jamfile b/src/system/boot/loader/file_systems/hfs_plus/Jamfile index 9a02d8a6ff..13bbb378ac 100644 --- a/src/system/boot/loader/file_systems/hfs_plus/Jamfile +++ b/src/system/boot/loader/file_systems/hfs_plus/Jamfile @@ -6,7 +6,7 @@ UsePrivateHeaders kernel storage ; SubDirC++Flags -fno-rtti ; -KernelStaticLibrary boot_hfs_plus : +BootStaticLibrary boot_hfs_plus : hfs_plus.cpp : -fno-pic ; diff --git a/src/system/boot/loader/file_systems/tarfs/Jamfile b/src/system/boot/loader/file_systems/tarfs/Jamfile index 0b7008aa77..4e7f4793d3 100644 --- a/src/system/boot/loader/file_systems/tarfs/Jamfile +++ b/src/system/boot/loader/file_systems/tarfs/Jamfile @@ -14,7 +14,7 @@ SubDirC++Flags -fno-rtti $(defines) ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src libs zlib ] ; -KernelStaticLibrary boot_zlib : +BootStaticLibrary boot_zlib : inflate.c inffast.c inftrees.c @@ -25,7 +25,7 @@ KernelStaticLibrary boot_zlib : ; -KernelStaticLibrary boot_tarfs : +BootStaticLibrary boot_tarfs : tarfs.cpp : -fno-pic ; diff --git a/src/system/boot/loader/kernel_args.cpp b/src/system/boot/loader/kernel_args.cpp index bf7ebd4d92..d625728cf4 100644 --- a/src/system/boot/loader/kernel_args.cpp +++ b/src/system/boot/loader/kernel_args.cpp @@ -19,15 +19,27 @@ static const size_t kChunkSize = 16 * B_PAGE_SIZE; kernel_args gKernelArgs; +KMessage gBootVolume; static void* sFirstFree; static void* sLast; static size_t sFree = kChunkSize; -template +static status_t +add_kernel_args_range(void* start, size_t size) +{ + return insert_address_range(gKernelArgs.kernel_args_range, + &gKernelArgs.num_kernel_args_ranges, MAX_KERNEL_ARGS_RANGE, + (addr_t)start, size); +} + + +// #pragma mark - addr_range utility functions + + static void -remove_range_index(RangeType* ranges, uint32& numRanges, uint32 index) +remove_range_index(addr_range* ranges, uint32& numRanges, uint32 index) { if (index + 1 == numRanges) { // remove last range @@ -36,25 +48,31 @@ remove_range_index(RangeType* ranges, uint32& numRanges, uint32 index) } memmove(&ranges[index], &ranges[index + 1], - sizeof(RangeType) * (numRanges - 1 - index)); + sizeof(addr_range) * (numRanges - 1 - index)); numRanges--; } -template -static status_t -insert_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, - AddressType start, SizeType size) +/*! Inserts the specified (start, size) pair (aka range) in the + addr_range array. + It will extend existing ranges in order to have as little + ranges in the array as possible. + Returns B_OK on success, or B_ENTRY_NOT_FOUND if there was + no free array entry available anymore. +*/ +extern "C" status_t +insert_address_range(addr_range* ranges, uint32* _numRanges, uint32 maxRanges, + uint64 start, uint64 size) { uint32 numRanges = *_numRanges; start = ROUNDDOWN(start, B_PAGE_SIZE); size = ROUNDUP(size, B_PAGE_SIZE); - AddressType end = start + size; + uint64 end = start + size; for (uint32 i = 0; i < numRanges; i++) { - AddressType rangeStart = ranges[i].start; - AddressType rangeEnd = rangeStart + ranges[i].size; + uint64 rangeStart = ranges[i].start; + uint64 rangeEnd = rangeStart + ranges[i].size; if (end < rangeStart || start > rangeEnd) { // ranges don't intersect or touch each other @@ -83,8 +101,8 @@ insert_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, rangeStart = ranges[i].start; rangeEnd = rangeStart + ranges[i].size; - AddressType joinStart = ranges[j].start; - AddressType joinEnd = joinStart + ranges[j].size; + uint64 joinStart = ranges[j].start; + uint64 joinEnd = joinStart + ranges[j].size; if (rangeStart <= joinEnd && joinEnd <= rangeEnd) { // join range that used to be before the current one, or @@ -112,7 +130,7 @@ insert_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, if (numRanges >= maxRanges) return B_ENTRY_NOT_FOUND; - ranges[numRanges].start = (AddressType)start; + ranges[numRanges].start = (uint64)start; ranges[numRanges].size = size; (*_numRanges)++; @@ -120,19 +138,18 @@ insert_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, } -template -static status_t -remove_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, - AddressType start, SizeType size) +extern "C" status_t +remove_address_range(addr_range* ranges, uint32* _numRanges, uint32 maxRanges, + uint64 start, uint64 size) { uint32 numRanges = *_numRanges; - AddressType end = ROUNDUP(start + size, B_PAGE_SIZE); + uint64 end = ROUNDUP(start + size, B_PAGE_SIZE); start = ROUNDDOWN(start, B_PAGE_SIZE); for (uint32 i = 0; i < numRanges; i++) { - AddressType rangeStart = ranges[i].start; - AddressType rangeEnd = rangeStart + ranges[i].size; + uint64 rangeStart = ranges[i].start; + uint64 rangeEnd = rangeStart + ranges[i].size; if (start <= rangeStart) { if (end <= rangeStart) { @@ -157,8 +174,8 @@ remove_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, // the range. We keep the head of the range and insert its tail // as a new range. ranges[i].size = start - rangeStart; - return insert_range(ranges, - _numRanges, maxRanges, end, rangeEnd - end); + return insert_address_range(ranges, _numRanges, maxRanges, end, + rangeEnd - end); } } @@ -167,12 +184,11 @@ remove_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, } -template -static bool -get_free_range(RangeType* ranges, uint32 numRanges, AddressType base, - SizeType size, AddressType* _rangeBase) +bool +get_free_address_range(addr_range* ranges, uint32 numRanges, uint64 base, + uint64 size, uint64* _rangeBase) { - AddressType end = base + size - 1; + uint64 end = base + size - 1; if (end < base) return false; @@ -181,8 +197,8 @@ get_free_range(RangeType* ranges, uint32 numRanges, AddressType base, // intersects with an existing one. for (uint32 i = 0; i < numRanges;) { - AddressType rangeStart = ranges[i].start; - AddressType rangeEnd = ranges[i].start + ranges[i].size - 1; + uint64 rangeStart = ranges[i].start; + uint64 rangeEnd = ranges[i].start + ranges[i].size - 1; if (base <= rangeEnd && rangeStart <= end) { base = rangeEnd + 1; @@ -202,21 +218,20 @@ get_free_range(RangeType* ranges, uint32 numRanges, AddressType base, } -template -static bool -is_range_covered(RangeType* ranges, uint32 numRanges, AddressType base, - SizeType size) +bool +is_address_range_covered(addr_range* ranges, uint32 numRanges, uint64 base, + uint64 size) { // Note: We don't assume that the ranges are sorted, so we can't do this // in a simple loop. Instead we restart the loop whenever the start of the // given range intersects with an existing one. for (uint32 i = 0; i < numRanges;) { - AddressType rangeStart = ranges[i].start; - AddressType rangeSize = ranges[i].size; + uint64 rangeStart = ranges[i].start; + uint64 rangeSize = ranges[i].size; if (rangeStart <= base && rangeSize > base - rangeStart) { - SizeType intersect = std::min(rangeStart + rangeSize - base, size); + uint64 intersect = std::min(rangeStart + rangeSize - base, size); base += intersect; size -= intersect; if (size == 0) @@ -233,162 +248,50 @@ is_range_covered(RangeType* ranges, uint32 numRanges, AddressType base, } -template -static void -sort_ranges(RangeType* ranges, uint32 count) +void +sort_address_ranges(addr_range* ranges, uint32 numRanges) { // TODO: This is a pretty sucky bubble sort implementation! bool done; do { done = true; - for (uint32 i = 1; i < count; i++) { + for (uint32 i = 1; i < numRanges; i++) { if (ranges[i].start < ranges[i - 1].start) { done = false; - RangeType tempRange; - memcpy(&tempRange, &ranges[i], sizeof(RangeType)); - memcpy(&ranges[i], &ranges[i - 1], sizeof(RangeType)); - memcpy(&ranges[i - 1], &tempRange, sizeof(RangeType)); + addr_range tempRange; + memcpy(&tempRange, &ranges[i], sizeof(addr_range)); + memcpy(&ranges[i], &ranges[i - 1], sizeof(addr_range)); + memcpy(&ranges[i - 1], &tempRange, sizeof(addr_range)); } } } while (!done); } -// #pragma mark - - - -static status_t -add_kernel_args_range(void* start, size_t size) -{ - return insert_address_range(gKernelArgs.kernel_args_range, - &gKernelArgs.num_kernel_args_ranges, MAX_KERNEL_ARGS_RANGE, - (addr_t)start, size); -} - - -// #pragma mark - addr_range utility functions - - -/*! Inserts the specified (start, size) pair (aka range) in the - addr_range array. - It will extend existing ranges in order to have as little - ranges in the array as possible. - Returns B_OK on success, or B_ENTRY_NOT_FOUND if there was - no free array entry available anymore. -*/ -extern "C" status_t -insert_address_range(addr_range* ranges, uint32* _numRanges, uint32 maxRanges, - addr_t start, size_t size) -{ - return insert_range(ranges, _numRanges, - maxRanges, start, size); -} - - -extern "C" status_t -remove_address_range(addr_range* ranges, uint32* _numRanges, uint32 maxRanges, - addr_t start, size_t size) -{ - return remove_range(ranges, _numRanges, - maxRanges, start, size); -} - - -bool -get_free_address_range(addr_range* ranges, uint32 numRanges, addr_t base, - size_t size, addr_t* _rangeBase) -{ - return get_free_range(ranges, numRanges, base, - size, _rangeBase); -} - - -bool -is_address_range_covered(addr_range* ranges, uint32 numRanges, addr_t base, - size_t size) -{ - return is_range_covered(ranges, numRanges, base, - size); -} - - -void -sort_address_ranges(addr_range* ranges, uint32 numRanges) -{ - sort_ranges(ranges, numRanges); -} - - -// #pragma mark - phys_addr_range utility functions - - -status_t -insert_physical_address_range(phys_addr_range* ranges, uint32* _numRanges, - uint32 maxRanges, phys_addr_t start, phys_size_t size) -{ - return insert_range(ranges, - _numRanges, maxRanges, start, size); -} - - -status_t -remove_physical_address_range(phys_addr_range* ranges, uint32* _numRanges, - uint32 maxRanges, phys_addr_t start, phys_size_t size) -{ - return remove_range(ranges, - _numRanges, maxRanges, start, size); -} - - -bool -get_free_physical_address_range(phys_addr_range* ranges, uint32 numRanges, - phys_addr_t base, phys_size_t size, phys_addr_t* _rangeBase) -{ - return get_free_range(ranges, - numRanges, base, size, _rangeBase); -} - - -bool -is_physical_address_range_covered(phys_addr_range* ranges, uint32 numRanges, - phys_addr_t base, phys_size_t size) -{ - return is_range_covered(ranges, - numRanges, base, size); -} - - -void -sort_physical_address_ranges(phys_addr_range* ranges, uint32 numRanges) -{ - sort_ranges(ranges, numRanges); -} - - // #pragma mark - kernel args range functions status_t -insert_physical_memory_range(phys_addr_t start, phys_size_t size) +insert_physical_memory_range(uint64 start, uint64 size) { - return insert_physical_address_range(gKernelArgs.physical_memory_range, + return insert_address_range(gKernelArgs.physical_memory_range, &gKernelArgs.num_physical_memory_ranges, MAX_PHYSICAL_MEMORY_RANGE, start, size); } status_t -insert_physical_allocated_range(phys_addr_t start, phys_size_t size) +insert_physical_allocated_range(uint64 start, uint64 size) { - return insert_physical_address_range(gKernelArgs.physical_allocated_range, + return insert_address_range(gKernelArgs.physical_allocated_range, &gKernelArgs.num_physical_allocated_ranges, MAX_PHYSICAL_ALLOCATED_RANGE, start, size); } status_t -insert_virtual_allocated_range(addr_t start, size_t size) +insert_virtual_allocated_range(uint64 start, uint64 size) { return insert_address_range(gKernelArgs.virtual_allocated_range, &gKernelArgs.num_virtual_allocated_ranges, MAX_VIRTUAL_ALLOCATED_RANGE, @@ -402,19 +305,19 @@ void ignore_physical_memory_ranges_beyond_4gb() { // sort - sort_physical_address_ranges(gKernelArgs.physical_memory_range, + sort_address_ranges(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges); - static const phys_addr_t kLimit = (phys_addr_t)1 << 32; + static const uint64 kLimit = (uint64)1 << 32; // remove everything past 4 GB for (uint32 i = gKernelArgs.num_physical_memory_ranges; i > 0; i--) { - phys_addr_range& range = gKernelArgs.physical_memory_range[i - 1]; + addr_range& range = gKernelArgs.physical_memory_range[i - 1]; if (range.start >= kLimit) { // the complete range is beyond the limit dprintf("ignore_physical_memory_ranges_beyond_4gb(): ignoring " - "range: %#" B_PRIxPHYSADDR " - %#" B_PRIxPHYSADDR "\n", - range.start, range.start + range.size); + "range: %#" B_PRIx64 " - %#" B_PRIx64 "\n", range.start, + range.start + range.size); gKernelArgs.ignored_physical_memory += range.size; gKernelArgs.num_physical_memory_ranges = i - 1; continue; @@ -423,7 +326,7 @@ ignore_physical_memory_ranges_beyond_4gb() if (kLimit - range.start < range.size) { // the range is partially beyond the limit dprintf("ignore_physical_memory_ranges_beyond_4gb(): ignoring " - "range: %#" B_PRIxPHYSADDR " - %#" B_PRIxPHYSADDR "\n", kLimit, + "range: %#" B_PRIx64 " - %#" B_PRIx64 "\n", kLimit, range.start + range.size); gKernelArgs.ignored_physical_memory += range.size - (kLimit - range.start); diff --git a/src/system/boot/loader/loader.cpp b/src/system/boot/loader/loader.cpp index fb5c2b41dd..2edd7f2a68 100644 --- a/src/system/boot/loader/loader.cpp +++ b/src/system/boot/loader/loader.cpp @@ -24,11 +24,24 @@ # error BOOT_ARCH has to be defined to differentiate the kernel per platform #endif -#define KERNEL_IMAGE "kernel_" BOOT_ARCH -#define KERNEL_PATH "system/" KERNEL_IMAGE +#define KERNEL_IMAGE "kernel_" BOOT_ARCH +#define KERNEL_PATH "system/" KERNEL_IMAGE + +#ifdef ALTERNATE_BOOT_ARCH +# define ALTERNATE_KERNEL_IMAGE "kernel_" ALTERNATE_BOOT_ARCH +# define ALTERNATE_KERNEL_PATH "system/" ALTERNATE_KERNEL_IMAGE +#endif -static const char *sPaths[] = { +static const char *sKernelPaths[][2] = { + { KERNEL_PATH, KERNEL_IMAGE }, +#ifdef ALTERNATE_BOOT_ARCH + { ALTERNATE_KERNEL_PATH, ALTERNATE_KERNEL_IMAGE }, +#endif + { NULL, NULL }, +}; + +static const char *sAddonPaths[] = { kVolumeLocalSystemKernelAddonsDirectory, kVolumeLocalCommonKernelAddonsDirectory, kVolumeLocalUserKernelAddonsDirectory, @@ -36,6 +49,22 @@ static const char *sPaths[] = { }; +static int +find_kernel(Directory *volume, const char **name = NULL) +{ + for (int32 i = 0; sKernelPaths[i][0] != NULL; i++) { + int fd = open_from(volume, sKernelPaths[i][0], O_RDONLY); + if (fd >= 0) { + if (name) + *name = sKernelPaths[i][1]; + + return fd; + } + } + + return B_ENTRY_NOT_FOUND; +} + bool is_bootable(Directory *volume) { @@ -43,7 +72,7 @@ is_bootable(Directory *volume) return false; // check for the existance of a kernel (for our platform) - int fd = open_from(volume, KERNEL_PATH, O_RDONLY); + int fd = find_kernel(volume); if (fd < B_OK) return false; @@ -56,14 +85,16 @@ is_bootable(Directory *volume) status_t load_kernel(stage2_args *args, Directory *volume) { - int fd = open_from(volume, KERNEL_PATH, O_RDONLY); + const char *name; + int fd = find_kernel(volume, &name); if (fd < B_OK) return fd; - dprintf("load kernel...\n"); + dprintf("load kernel %s...\n", name); elf_init(); - status_t status = elf_load_image(fd, &gKernelArgs.kernel_image); + preloaded_image *image; + status_t status = elf_load_image(fd, &image); close(fd); @@ -72,13 +103,15 @@ load_kernel(stage2_args *args, Directory *volume) return status; } - status = elf_relocate_image(&gKernelArgs.kernel_image); + gKernelArgs.kernel_image = image; + + status = elf_relocate_image(gKernelArgs.kernel_image); if (status < B_OK) { dprintf("relocating kernel failed: %lx!\n", status); return status; } - gKernelArgs.kernel_image.name = kernel_args_strdup(KERNEL_IMAGE); + gKernelArgs.kernel_image->name = kernel_args_strdup(name); return B_OK; } @@ -129,9 +162,9 @@ load_module(Directory *volume, const char *name) if (strlcpy(moduleName, name, sizeof(moduleName)) > sizeof(moduleName)) return B_NAME_TOO_LONG; - for (int32 i = 0; sPaths[i]; i++) { + for (int32 i = 0; sAddonPaths[i]; i++) { // get base path - int baseFD = open_from(volume, sPaths[i], O_RDONLY); + int baseFD = open_from(volume, sAddonPaths[i], O_RDONLY); if (baseFD < B_OK) continue; @@ -179,9 +212,9 @@ load_modules(stage2_args *args, Directory *volume) // ToDo: this should be mostly replaced by a hardware oriented detection mechanism int32 i = 0; - for (; sPaths[i]; i++) { + for (; sAddonPaths[i]; i++) { char path[B_FILE_NAME_LENGTH]; - snprintf(path, sizeof(path), "%s/boot", sPaths[i]); + snprintf(path, sizeof(path), "%s/boot", sAddonPaths[i]); if (load_modules_from(volume, path) != B_OK) failed++; @@ -195,7 +228,7 @@ load_modules(stage2_args *args, Directory *volume) for (int32 i = 0; paths[i]; i++) { char path[B_FILE_NAME_LENGTH]; - snprintf(path, sizeof(path), "%s/%s", sPaths[0], paths[i]); + snprintf(path, sizeof(path), "%s/%s", sAddonPaths[0], paths[i]); load_modules_from(volume, path); } } @@ -203,8 +236,7 @@ load_modules(stage2_args *args, Directory *volume) // and now load all partitioning and file system modules // needed to identify the boot volume - if (!gKernelArgs.boot_volume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, - false)) { + if (!gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) { // iterate over the mounted volumes and load their file system Partition *partition; if (gRoot->GetPartitionFor(volume, &partition) == B_OK) { @@ -220,7 +252,7 @@ load_modules(stage2_args *args, Directory *volume) // as this piece will survive a more intelligent module // loading approach... char path[B_FILE_NAME_LENGTH]; - snprintf(path, sizeof(path), "%s/%s", sPaths[0], "file_systems"); + snprintf(path, sizeof(path), "%s/%s", sAddonPaths[0], "file_systems"); load_modules_from(volume, path); } diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index bc67e3a9ab..63a78a1e9a 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -40,9 +40,6 @@ main(stage2_args *args) gKernelArgs.keep_debug_output_buffer = true; #endif - // construct boot_volume KMessage explicitely - new(&gKernelArgs.boot_volume) KMessage; - add_stage2_driver_settings(args); platform_init_video(); @@ -123,16 +120,16 @@ main(stage2_args *args) // clone the boot_volume KMessage into kernel accessible memory // note, that we need to 4 byte align the buffer and thus allocate // 3 more bytes - KMessage& bootVolume = gKernelArgs.boot_volume; - void* buffer = kernel_args_malloc(bootVolume.ContentSize() + 3); + void* buffer = kernel_args_malloc(gBootVolume.ContentSize() + 3); if (!buffer) { panic("Could not allocate memory for the boot volume kernel " "arguments"); } buffer = (void*)(((addr_t)buffer + 3) & ~(addr_t)0x3); - memcpy(buffer, bootVolume.Buffer(), bootVolume.ContentSize()); - bootVolume.SetTo(buffer, bootVolume.ContentSize()); + memcpy(buffer, gBootVolume.Buffer(), gBootVolume.ContentSize()); + gKernelArgs.boot_volume = buffer; + gKernelArgs.boot_volume_size = gBootVolume.ContentSize(); // ToDo: cleanup, heap_release() etc. platform_start_kernel(); diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index ef15a2a9ff..fbb90d5427 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -481,7 +481,7 @@ user_menu_boot_volume(Menu* menu, MenuItem* item) bootItem->Select(true); bootItem->SetData(item->Data()); - gKernelArgs.boot_volume.SetBool(BOOT_VOLUME_USER_SELECTED, true); + gBootVolume.SetBool(BOOT_VOLUME_USER_SELECTED, true); return true; } @@ -534,7 +534,7 @@ debug_menu_display_current_log(Menu* menu, MenuItem* item) static bool debug_menu_display_previous_syslog(Menu* menu, MenuItem* item) { - ring_buffer* buffer = (ring_buffer*)gKernelArgs.debug_output; + ring_buffer* buffer = (ring_buffer*)gKernelArgs.debug_output.Pointer(); if (buffer == NULL) return true; @@ -595,7 +595,8 @@ save_previous_syslog_to_volume(Directory* directory) return fd; } - ring_buffer* syslogBuffer = (ring_buffer*)gKernelArgs.debug_output; + ring_buffer* syslogBuffer + = (ring_buffer*)gKernelArgs.debug_output.Pointer(); iovec vecs[2]; int32 vecCount = ring_buffer_get_vecs(syslogBuffer, vecs); if (vecCount > 0) { @@ -712,7 +713,7 @@ add_boot_volume_menu(Directory* bootVolume) menu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); item->SetType(MENU_ITEM_NO_CHOICE); - if (gKernelArgs.boot_volume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) + if (gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) menu->SetChoiceText("CD-ROM or hard drive"); return menu; @@ -747,8 +748,8 @@ add_safe_mode_menu() // check whether we have memory beyond 4 GB bool hasMemoryBeyond4GB = false; for (uint32 i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { - phys_addr_range& range = gKernelArgs.physical_memory_range[i]; - if (range.start >= (phys_addr_t)1 << 32) { + addr_range& range = gKernelArgs.physical_memory_range[i]; + if (range.start >= (uint64)1 << 32) { hasMemoryBeyond4GB = true; break; } @@ -899,7 +900,8 @@ add_debug_menu() "Displays the debug info the boot loader has logged."); } - ring_buffer* syslogBuffer = (ring_buffer*)gKernelArgs.debug_output; + ring_buffer* syslogBuffer + = (ring_buffer*)gKernelArgs.debug_output.Pointer(); if (syslogBuffer != NULL && ring_buffer_readable(syslogBuffer) > 0) { if (!currentLogItemVisible) menu->AddSeparatorItem(); diff --git a/src/system/boot/loader/net/Jamfile b/src/system/boot/loader/net/Jamfile index dda66c0fa7..5bb8291a3f 100644 --- a/src/system/boot/loader/net/Jamfile +++ b/src/system/boot/loader/net/Jamfile @@ -12,7 +12,7 @@ if $(TARGET_ARCH) = ppc { iscsi = iSCSITarget.cpp ; } -KernelStaticLibrary boot_net : +BootStaticLibrary boot_net : ARP.cpp ChainBuffer.cpp Ethernet.cpp diff --git a/src/system/boot/loader/partitions.cpp b/src/system/boot/loader/partitions.cpp index fd74561b1f..29d4f20f76 100644 --- a/src/system/boot/loader/partitions.cpp +++ b/src/system/boot/loader/partitions.cpp @@ -268,8 +268,8 @@ Partition::_Mount(file_system_module_info *module, Directory **_fileSystem) status_t Partition::Mount(Directory **_fileSystem, bool isBootDevice) { - if (isBootDevice && gKernelArgs.boot_volume.GetBool( - BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) { + if (isBootDevice && gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, + false)) { return _Mount(&gTarFileSystemModule, _fileSystem); } @@ -293,8 +293,8 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice) // if we were not booted from the real boot device, we won't scan // the device we were booted from (which is likely to be a slow // floppy or CD) - if (isBootDevice && gKernelArgs.boot_volume.GetBool( - BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) { + if (isBootDevice && gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, + false)) { return B_ENTRY_NOT_FOUND; } diff --git a/src/system/boot/loader/vfs.cpp b/src/system/boot/loader/vfs.cpp index 2d532309c0..9c1d5e1e1f 100644 --- a/src/system/boot/loader/vfs.cpp +++ b/src/system/boot/loader/vfs.cpp @@ -380,8 +380,7 @@ register_boot_file_system(Directory *volume) return status; } - gKernelArgs.boot_volume.SetInt64(BOOT_VOLUME_PARTITION_OFFSET, - partition->offset); + gBootVolume.SetInt64(BOOT_VOLUME_PARTITION_OFFSET, partition->offset); Node *device = get_node_from(partition->FD()); if (device == NULL) { diff --git a/src/system/boot/platform/amiga_m68k/Jamfile b/src/system/boot/platform/amiga_m68k/Jamfile index 9f223dd3cc..b867ef7f6f 100644 --- a/src/system/boot/platform/amiga_m68k/Jamfile +++ b/src/system/boot/platform/amiga_m68k/Jamfile @@ -19,13 +19,13 @@ UsePrivateHeaders [ FDirName storage ] ; #SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; -KernelMergeObject boot_platform_amiga_m68k_shell.o : +BootMergeObject boot_platform_amiga_m68k_shell.o : shell.S : -Wa,--pcrel ; -KernelMergeObject boot_platform_amiga_m68k_other.o : +BootMergeObject boot_platform_amiga_m68k_other.o : # shell.S start.cpp rom_calls.cpp @@ -54,7 +54,7 @@ KernelMergeObject boot_platform_amiga_m68k_other.o : ; -KernelMergeObject boot_platform_amiga_m68k.o : +BootMergeObject boot_platform_amiga_m68k.o : : : boot_platform_amiga_m68k_shell.o boot_platform_amiga_m68k_other.o diff --git a/src/system/boot/platform/amiga_m68k/devices.cpp b/src/system/boot/platform/amiga_m68k/devices.cpp index 5d4e73409e..4030f0242b 100644 --- a/src/system/boot/platform/amiga_m68k/devices.cpp +++ b/src/system/boot/platform/amiga_m68k/devices.cpp @@ -161,8 +161,7 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) TRACE(("boot drive ID: %x\n", gBootDriveID)); //TODO - gKernelArgs.boot_volume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, - gBootedFromImage); + gBootVolume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootedFromImage); return B_OK; } diff --git a/src/system/boot/platform/amiga_m68k/mmu.cpp b/src/system/boot/platform/amiga_m68k/mmu.cpp index b71af83067..03f56b9f4e 100644 --- a/src/system/boot/platform/amiga_m68k/mmu.cpp +++ b/src/system/boot/platform/amiga_m68k/mmu.cpp @@ -503,9 +503,9 @@ mmu_init_for_kernel(void) gKernelArgs.num_virtual_allocated_ranges = 1; // sort the address ranges - sort_physical_address_ranges(gKernelArgs.physical_memory_range, + sort_address_ranges(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges); - sort_physical_address_ranges(gKernelArgs.physical_allocated_range, + sort_address_ranges(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges); sort_address_ranges(gKernelArgs.virtual_allocated_range, gKernelArgs.num_virtual_allocated_ranges); @@ -516,17 +516,23 @@ mmu_init_for_kernel(void) dprintf("phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.physical_memory_range[i].start, gKernelArgs.physical_memory_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.physical_memory_range[i].start, + gKernelArgs.physical_memory_range[i].size); } dprintf("allocated phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.physical_allocated_range[i].start, gKernelArgs.physical_allocated_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.physical_allocated_range[i].start, + gKernelArgs.physical_allocated_range[i].size); } dprintf("allocated virt memory ranges:\n"); for (i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.virtual_allocated_range[i].start, gKernelArgs.virtual_allocated_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.virtual_allocated_range[i].start, + gKernelArgs.virtual_allocated_range[i].size); } } #endif diff --git a/src/system/boot/platform/amiga_m68k/start.cpp b/src/system/boot/platform/amiga_m68k/start.cpp index 4cc21558e8..8881ca7209 100644 --- a/src/system/boot/platform/amiga_m68k/start.cpp +++ b/src/system/boot/platform/amiga_m68k/start.cpp @@ -74,6 +74,9 @@ platform_start_kernel(void) addr_t stackTop = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; + preloaded_elf32_image *image = static_cast( + gKernelArgs.kernel_image.Pointer()); + //smp_init_other_cpus(); //serial_cleanup(); mmu_init_for_kernel(); @@ -81,8 +84,7 @@ platform_start_kernel(void) #warning M68K: stop ints - dprintf("kernel entry at %lx\n", - gKernelArgs.kernel_image.elf_header.e_entry); + dprintf("kernel entry at %lx\n", image->elf_header.e_entry); asm volatile ( "move.l %0,%%sp; " // move stack out of way @@ -97,7 +99,7 @@ platform_start_kernel(void) "move.l #0x0,-(%%sp);" // dummy retval for call to main "move.l %1,-(%%sp); " // this is the start address "rts; " // jump. - : : "g" (args), "g" (gKernelArgs.kernel_image.elf_header.e_entry)); + : : "g" (args), "g" (image->elf_header.e_entry)); // Huston, we have a problem! diff --git a/src/system/boot/platform/atari_m68k/Jamfile b/src/system/boot/platform/atari_m68k/Jamfile index 287666bf85..b71de5a25d 100644 --- a/src/system/boot/platform/atari_m68k/Jamfile +++ b/src/system/boot/platform/atari_m68k/Jamfile @@ -19,7 +19,7 @@ UsePrivateHeaders [ FDirName storage ] ; #SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; -KernelMergeObject boot_platform_atari_m68k_shell.o : +BootMergeObject boot_platform_atari_m68k_shell.o : shell.S : -Wa,--pcrel ; @@ -30,7 +30,7 @@ KernelMergeObject boot_platform_atari_m68k_shell.o : # TODO: add 020+68851 support -KernelMergeObject boot_platform_atari_m68k_other.o : +BootMergeObject boot_platform_atari_m68k_other.o : # shell.S start.cpp toscalls.cpp @@ -59,7 +59,7 @@ KernelMergeObject boot_platform_atari_m68k_other.o : ; -KernelMergeObject boot_platform_atari_m68k.o : +BootMergeObject boot_platform_atari_m68k.o : : : boot_platform_atari_m68k_shell.o boot_platform_atari_m68k_other.o diff --git a/src/system/boot/platform/atari_m68k/devices.cpp b/src/system/boot/platform/atari_m68k/devices.cpp index 8abfa678a4..93f9c5bf56 100644 --- a/src/system/boot/platform/atari_m68k/devices.cpp +++ b/src/system/boot/platform/atari_m68k/devices.cpp @@ -1182,8 +1182,7 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) } TRACE(("boot drive size: %Ld bytes\n", drive->Size())); - gKernelArgs.boot_volume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, - gBootedFromImage); + gBootVolume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootedFromImage); return B_OK; } @@ -1232,8 +1231,8 @@ platform_register_boot_device(Node *device) check_cd_boot(drive); #endif - gKernelArgs.boot_volume.SetInt64("boot drive number", drive->DriveID()); - gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, + gBootVolume.SetInt64("boot drive number", drive->DriveID()); + gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, &drive->Identifier(), sizeof(disk_identifier)); return B_OK; diff --git a/src/system/boot/platform/atari_m68k/mmu.cpp b/src/system/boot/platform/atari_m68k/mmu.cpp index 434c4623aa..7132119fd2 100644 --- a/src/system/boot/platform/atari_m68k/mmu.cpp +++ b/src/system/boot/platform/atari_m68k/mmu.cpp @@ -503,9 +503,9 @@ mmu_init_for_kernel(void) gKernelArgs.num_virtual_allocated_ranges = 1; // sort the address ranges - sort_physical_address_ranges(gKernelArgs.physical_memory_range, + sort_address_ranges(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges); - sort_physical_address_ranges(gKernelArgs.physical_allocated_range, + sort_address_ranges(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges); sort_address_ranges(gKernelArgs.virtual_allocated_range, gKernelArgs.num_virtual_allocated_ranges); @@ -516,17 +516,23 @@ mmu_init_for_kernel(void) dprintf("phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.physical_memory_range[i].start, gKernelArgs.physical_memory_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.physical_memory_range[i].start, + gKernelArgs.physical_memory_range[i].size); } dprintf("allocated phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.physical_allocated_range[i].start, gKernelArgs.physical_allocated_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.physical_allocated_range[i].start, + gKernelArgs.physical_allocated_range[i].size); } dprintf("allocated virt memory ranges:\n"); for (i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", gKernelArgs.virtual_allocated_range[i].start, gKernelArgs.virtual_allocated_range[i].size); + dprintf(" base 0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + gKernelArgs.virtual_allocated_range[i].start, + gKernelArgs.virtual_allocated_range[i].size); } } #endif diff --git a/src/system/boot/platform/atari_m68k/start.cpp b/src/system/boot/platform/atari_m68k/start.cpp index a7fd43ffbb..c0f6503bcc 100644 --- a/src/system/boot/platform/atari_m68k/start.cpp +++ b/src/system/boot/platform/atari_m68k/start.cpp @@ -74,6 +74,9 @@ platform_start_kernel(void) addr_t stackTop = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; + preloaded_elf32_image *image = static_cast( + gKernelArgs.kernel_image.Pointer()); + //smp_init_other_cpus(); //serial_cleanup(); mmu_init_for_kernel(); @@ -81,8 +84,7 @@ platform_start_kernel(void) #warning M68K: stop ints - dprintf("kernel entry at %lx\n", - gKernelArgs.kernel_image.elf_header.e_entry); + dprintf("kernel entry at %lx\n", image->elf_header.e_entry); asm volatile ( "move.l %0,%%sp; " // move stack out of way @@ -97,7 +99,7 @@ platform_start_kernel(void) "move.l #0x0,-(%%sp);" // dummy retval for call to main "move.l %1,-(%%sp); " // this is the start address "rts; " // jump. - : : "g" (args), "g" (gKernelArgs.kernel_image.elf_header.e_entry)); + : : "g" (args), "g" (image->elf_header.e_entry)); // Huston, we have a problem! diff --git a/src/system/boot/platform/bios_ia32/Jamfile b/src/system/boot/platform/bios_ia32/Jamfile index 9219e5b392..347d2b420f 100644 --- a/src/system/boot/platform/bios_ia32/Jamfile +++ b/src/system/boot/platform/bios_ia32/Jamfile @@ -17,7 +17,7 @@ UsePrivateHeaders [ FDirName storage ] ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; -KernelMergeObject boot_platform_bios_ia32.o : +BootMergeObject boot_platform_bios_ia32.o : shell.S start.cpp debug.cpp @@ -40,6 +40,8 @@ KernelMergeObject boot_platform_bios_ia32.o : hpet.cpp interrupts.cpp interrupts_asm.S + long.cpp + long_asm.S # VESA/DDC EDID decode_edid.c diff --git a/src/system/boot/platform/bios_ia32/devices.cpp b/src/system/boot/platform/bios_ia32/devices.cpp index a8cfd1b8c9..5c50c47f11 100644 --- a/src/system/boot/platform/bios_ia32/devices.cpp +++ b/src/system/boot/platform/bios_ia32/devices.cpp @@ -167,7 +167,7 @@ static bool sBlockDevicesAdded = false; static void check_cd_boot(BIOSDrive *drive) { - gKernelArgs.boot_volume.SetInt32(BOOT_METHOD, BOOT_METHOD_HARD_DISK); + gBootVolume.SetInt32(BOOT_METHOD, BOOT_METHOD_HARD_DISK); if (drive->DriveID() != 0) return; @@ -185,7 +185,7 @@ check_cd_boot(BIOSDrive *drive) specification_packet *packet = (specification_packet *)kDataSegmentScratch; if (packet->media_type != 0) - gKernelArgs.boot_volume.SetInt32(BOOT_METHOD, BOOT_METHOD_CD); + gBootVolume.SetInt32(BOOT_METHOD, BOOT_METHOD_CD); #if 0 dprintf("got CD boot spec:\n"); @@ -841,8 +841,7 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) } TRACE(("boot drive size: %Ld bytes\n", drive->Size())); - gKernelArgs.boot_volume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, - gBootedFromImage); + gBootVolume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootedFromImage); return B_OK; } @@ -888,8 +887,8 @@ platform_register_boot_device(Node *device) check_cd_boot(drive); - gKernelArgs.boot_volume.SetInt64("boot drive number", drive->DriveID()); - gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, + gBootVolume.SetInt64("boot drive number", drive->DriveID()); + gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, &drive->Identifier(), sizeof(disk_identifier)); return B_OK; diff --git a/src/system/boot/platform/bios_ia32/hpet.cpp b/src/system/boot/platform/bios_ia32/hpet.cpp index 42568d214b..de27385b33 100644 --- a/src/system/boot/platform/bios_ia32/hpet.cpp +++ b/src/system/boot/platform/bios_ia32/hpet.cpp @@ -50,6 +50,6 @@ hpet_init(void) TRACE(("hpet_init: found HPET at %x.\n", hpet->hpet_address.address)); gKernelArgs.arch_args.hpet_phys = hpet->hpet_address.address; - gKernelArgs.arch_args.hpet = (uint32 *)mmu_map_physical_memory( + gKernelArgs.arch_args.hpet = (void *)mmu_map_physical_memory( gKernelArgs.arch_args.hpet_phys, B_PAGE_SIZE, kDefaultPageFlags); } diff --git a/src/system/boot/platform/bios_ia32/interrupts.cpp b/src/system/boot/platform/bios_ia32/interrupts.cpp index 3b4505c0a3..2d5d0fa596 100644 --- a/src/system/boot/platform/bios_ia32/interrupts.cpp +++ b/src/system/boot/platform/bios_ia32/interrupts.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include "debug.h" #include "keyboard.h" @@ -83,11 +83,6 @@ struct interrupt_frame { uint32 eflags; }; -struct interrupt_descriptor { - uint32 a; - uint32 b; -}; - static interrupt_descriptor sDebugIDT[DEBUG_IDT_SLOT_COUNT]; diff --git a/src/system/boot/platform/bios_ia32/long.cpp b/src/system/boot/platform/bios_ia32/long.cpp new file mode 100644 index 0000000000..e6728462c6 --- /dev/null +++ b/src/system/boot/platform/bios_ia32/long.cpp @@ -0,0 +1,364 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include "long.h" + +#include + +#include + +// Include the x86_64 version of descriptors.h +#define __x86_64__ +#include +#undef __x86_64__ + +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "smp.h" +#include "mmu.h" + + +static const uint64 kTableMappingFlags = 0x7; +static const uint64 kLargePageMappingFlags = 0x183; +static const uint64 kPageMappingFlags = 0x103; + // Global, R/W, Present + +extern "C" void long_enter_kernel(int currentCPU, uint64 stackTop); + +extern uint32 gLongPhysicalGDT; +extern uint64 gLongVirtualGDT; +extern uint32 gLongPhysicalPML4; +extern uint64 gLongKernelEntry; + + +/*! Convert a 32-bit address to a 64-bit address. */ +static inline uint64 +fix_address(uint64 address) +{ + return address - KERNEL_LOAD_BASE + KERNEL_LOAD_BASE_64_BIT; +} + + +template +inline void +fix_address(FixedWidthPointer& p) +{ + if (p != NULL) + p.SetTo(fix_address(p.Get())); +} + + +static void +long_gdt_init() +{ + // Allocate memory for the GDT. + segment_descriptor* gdt = (segment_descriptor*) + mmu_allocate_page(&gKernelArgs.arch_args.phys_gdt); + gKernelArgs.arch_args.vir_gdt = fix_address((addr_t)gdt); + + dprintf("GDT at phys 0x%lx, virt 0x%llx\n", gKernelArgs.arch_args.phys_gdt, + gKernelArgs.arch_args.vir_gdt); + + clear_segment_descriptor(&gdt[0]); + + // Set up code/data segments (TSS segments set up later in the kernel). + set_segment_descriptor(&gdt[KERNEL_CODE_SEG / 8], DT_CODE_EXECUTE_ONLY, + DPL_KERNEL); + set_segment_descriptor(&gdt[KERNEL_DATA_SEG / 8], DT_DATA_WRITEABLE, + DPL_KERNEL); + set_segment_descriptor(&gdt[USER_CODE_SEG / 8], DT_CODE_EXECUTE_ONLY, + DPL_USER); + set_segment_descriptor(&gdt[USER_DATA_SEG / 8], DT_DATA_WRITEABLE, + DPL_USER); + + // Used by long_enter_kernel(). + gLongPhysicalGDT = gKernelArgs.arch_args.phys_gdt; + gLongVirtualGDT = gKernelArgs.arch_args.vir_gdt; +} + + +static void +long_idt_init() +{ + interrupt_descriptor* idt = (interrupt_descriptor*) + mmu_allocate_page(&gKernelArgs.arch_args.phys_idt); + gKernelArgs.arch_args.vir_idt = fix_address((addr_t)idt); + + dprintf("IDT at phys %#lx, virt %#llx\n", gKernelArgs.arch_args.phys_idt, + gKernelArgs.arch_args.vir_idt); + + // The 32-bit kernel gets an IDT with the loader's exception handlers until + // it can set up its own. Can't do that here because they won't work after + // switching to long mode. Therefore, just clear the IDT and leave the + // kernel to set it up. + memset(idt, 0, B_PAGE_SIZE); +} + + +static void +long_mmu_init() +{ + uint64* pml4; + uint64* pdpt; + uint64* pageDir; + uint64* pageTable; + addr_t physicalAddress; + + // Allocate the top level PML4. + pml4 = (uint64*)mmu_allocate_page(&gKernelArgs.arch_args.phys_pgdir); + memset(pml4, 0, B_PAGE_SIZE); + gKernelArgs.arch_args.vir_pgdir = fix_address((uint64)(addr_t)pml4); + + // Store the virtual memory usage information. + gKernelArgs.virtual_allocated_range[0].start = KERNEL_LOAD_BASE_64_BIT; + gKernelArgs.virtual_allocated_range[0].size = mmu_get_virtual_usage(); + gKernelArgs.num_virtual_allocated_ranges = 1; + gKernelArgs.arch_args.virtual_end = ROUNDUP(KERNEL_LOAD_BASE_64_BIT + + gKernelArgs.virtual_allocated_range[0].size, 0x200000); + + // Find the highest physical memory address. We map all physical memory + // into the kernel address space, so we want to make sure we map everything + // we have available. + uint64 maxAddress = 0; + for (uint32 i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { + maxAddress = std::max(maxAddress, + gKernelArgs.physical_memory_range[i].start + + gKernelArgs.physical_memory_range[i].size); + } + + // Want to map at least 4GB, there may be stuff other than usable RAM that + // could be in the first 4GB of physical address space. + maxAddress = std::max(maxAddress, (uint64)0x100000000ll); + maxAddress = ROUNDUP(maxAddress, 0x40000000); + + // Currently only use 1 PDPT (512GB). This will need to change if someone + // wants to use Haiku on a box with more than 512GB of RAM but that's + // probably not going to happen any time soon. + if (maxAddress / 0x40000000 > 512) + panic("Can't currently support more than 512GB of RAM!"); + + // Create page tables for the physical map area. Also map this PDPT + // temporarily at the bottom of the address space so that we are identity + // mapped. + + pdpt = (uint64*)mmu_allocate_page(&physicalAddress); + memset(pdpt, 0, B_PAGE_SIZE); + pml4[510] = physicalAddress | kTableMappingFlags; + pml4[0] = physicalAddress | kTableMappingFlags; + + for (uint64 i = 0; i < maxAddress; i += 0x40000000) { + pageDir = (uint64*)mmu_allocate_page(&physicalAddress); + memset(pageDir, 0, B_PAGE_SIZE); + pdpt[i / 0x40000000] = physicalAddress | kTableMappingFlags; + + for (uint64 j = 0; j < 0x40000000; j += 0x200000) { + pageDir[j / 0x200000] = (i + j) | kLargePageMappingFlags; + } + + mmu_free(pageDir, B_PAGE_SIZE); + } + + mmu_free(pdpt, B_PAGE_SIZE); + + // Allocate tables for the kernel mappings. + + pdpt = (uint64*)mmu_allocate_page(&physicalAddress); + memset(pdpt, 0, B_PAGE_SIZE); + pml4[511] = physicalAddress | kTableMappingFlags; + + pageDir = (uint64*)mmu_allocate_page(&physicalAddress); + memset(pageDir, 0, B_PAGE_SIZE); + pdpt[510] = physicalAddress | kTableMappingFlags; + + // We can now allocate page tables and duplicate the mappings across from + // the 32-bit address space to them. + pageTable = NULL; + for (uint32 i = 0; i < gKernelArgs.virtual_allocated_range[0].size + / B_PAGE_SIZE; i++) { + if ((i % 512) == 0) { + if (pageTable) + mmu_free(pageTable, B_PAGE_SIZE); + + pageTable = (uint64*)mmu_allocate_page(&physicalAddress); + memset(pageTable, 0, B_PAGE_SIZE); + pageDir[i / 512] = physicalAddress | kTableMappingFlags; + } + + // Get the physical address to map. + if (!mmu_get_virtual_mapping(KERNEL_LOAD_BASE + (i * B_PAGE_SIZE), + &physicalAddress)) + continue; + + pageTable[i % 512] = physicalAddress | kPageMappingFlags; + } + + if (pageTable) + mmu_free(pageTable, B_PAGE_SIZE); + mmu_free(pageDir, B_PAGE_SIZE); + mmu_free(pdpt, B_PAGE_SIZE); + + // Sort the address ranges. + sort_address_ranges(gKernelArgs.physical_memory_range, + gKernelArgs.num_physical_memory_ranges); + sort_address_ranges(gKernelArgs.physical_allocated_range, + gKernelArgs.num_physical_allocated_ranges); + sort_address_ranges(gKernelArgs.virtual_allocated_range, + gKernelArgs.num_virtual_allocated_ranges); + + dprintf("phys memory ranges:\n"); + for (uint32 i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { + dprintf(" base %#018" B_PRIx64 ", length %#018" B_PRIx64 "\n", + gKernelArgs.physical_memory_range[i].start, + gKernelArgs.physical_memory_range[i].size); + } + + dprintf("allocated phys memory ranges:\n"); + for (uint32 i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) { + dprintf(" base %#018" B_PRIx64 ", length %#018" B_PRIx64 "\n", + gKernelArgs.physical_allocated_range[i].start, + gKernelArgs.physical_allocated_range[i].size); + } + + dprintf("allocated virt memory ranges:\n"); + for (uint32 i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { + dprintf(" base %#018" B_PRIx64 ", length %#018" B_PRIx64 "\n", + gKernelArgs.virtual_allocated_range[i].start, + gKernelArgs.virtual_allocated_range[i].size); + } + + gLongPhysicalPML4 = gKernelArgs.arch_args.phys_pgdir; +} + + +static void +convert_preloaded_image(preloaded_elf64_image* image) +{ + fix_address(image->next); + fix_address(image->name); + fix_address(image->debug_string_table); + fix_address(image->syms); + fix_address(image->rel); + fix_address(image->rela); + fix_address(image->pltrel); + fix_address(image->debug_symbols); +} + + +/*! Convert all addresses in kernel_args to 64-bit addresses. */ +static void +convert_kernel_args() +{ + fix_address(gKernelArgs.boot_volume); + fix_address(gKernelArgs.vesa_modes); + fix_address(gKernelArgs.edid_info); + fix_address(gKernelArgs.debug_output); + fix_address(gKernelArgs.boot_splash); + fix_address(gKernelArgs.arch_args.apic); + fix_address(gKernelArgs.arch_args.hpet); + + convert_preloaded_image(static_cast( + gKernelArgs.kernel_image.Pointer())); + fix_address(gKernelArgs.kernel_image); + + // Iterate over the preloaded images. Must save the next address before + // converting, as the next pointer will be converted. + preloaded_image* image = gKernelArgs.preloaded_images; + fix_address(gKernelArgs.preloaded_images); + while (image != NULL) { + preloaded_image* next = image->next; + convert_preloaded_image(static_cast(image)); + image = next; + } + + // Set correct kernel args range addresses. + dprintf("kernel args ranges:\n"); + for (uint32 i = 0; i < gKernelArgs.num_kernel_args_ranges; i++) { + gKernelArgs.kernel_args_range[i].start = fix_address( + gKernelArgs.kernel_args_range[i].start); + dprintf(" base %#018" B_PRIx64 ", length %#018" B_PRIx64 "\n", + gKernelArgs.kernel_args_range[i].start, + gKernelArgs.kernel_args_range[i].size); + } + + // Fix driver settings files. + driver_settings_file* file = gKernelArgs.driver_settings; + fix_address(gKernelArgs.driver_settings); + while (file != NULL) { + driver_settings_file* next = file->next; + fix_address(file->next); + fix_address(file->buffer); + file = next; + } +} + + +static void +long_smp_start_kernel(void) +{ + uint32 cpu = smp_get_current_cpu(); + + // Important. Make sure supervisor threads can fault on read only pages... + asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1)); + asm("cld"); + asm("fninit"); + + // Fix our kernel stack address. + gKernelArgs.cpu_kstack[cpu].start + = fix_address(gKernelArgs.cpu_kstack[cpu].start); + + long_enter_kernel(cpu, gKernelArgs.cpu_kstack[cpu].start + + gKernelArgs.cpu_kstack[cpu].size); + + panic("Shouldn't get here"); +} + + +void +long_start_kernel() +{ + // Check whether long mode is supported. + cpuid_info info; + get_current_cpuid(&info, 0x80000001); + if ((info.regs.edx & (1 << 29)) == 0) + panic("64-bit kernel requires a 64-bit CPU"); + + preloaded_elf64_image *image = static_cast( + gKernelArgs.kernel_image.Pointer()); + + smp_init_other_cpus(); + + long_gdt_init(); + long_idt_init(); + long_mmu_init(); + convert_kernel_args(); + + debug_cleanup(); + + // Save the kernel entry point address. + gLongKernelEntry = image->elf_header.e_entry; + dprintf("kernel entry at %#llx\n", gLongKernelEntry); + + // Fix our kernel stack address. + gKernelArgs.cpu_kstack[0].start + = fix_address(gKernelArgs.cpu_kstack[0].start); + + // We're about to enter the kernel -- disable console output. + stdout = NULL; + + smp_boot_other_cpus(long_smp_start_kernel); + + // Enter the kernel! + long_enter_kernel(0, gKernelArgs.cpu_kstack[0].start + + gKernelArgs.cpu_kstack[0].size); + + panic("Shouldn't get here"); +} diff --git a/src/system/boot/platform/bios_ia32/long.h b/src/system/boot/platform/bios_ia32/long.h new file mode 100644 index 0000000000..e29d2aa66f --- /dev/null +++ b/src/system/boot/platform/bios_ia32/long.h @@ -0,0 +1,15 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef LONG_H +#define LONG_H + + +#include + + +extern void long_start_kernel(); + + +#endif /* LONG_H */ diff --git a/src/system/boot/platform/bios_ia32/long_asm.S b/src/system/boot/platform/bios_ia32/long_asm.S new file mode 100644 index 0000000000..72b30c26cf --- /dev/null +++ b/src/system/boot/platform/bios_ia32/long_asm.S @@ -0,0 +1,111 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + +#define __x86_64__ +#include +#undef __x86_64__ + + +#define GDT_LIMIT 0x800 + + +.code32 + + +/*! void long_enter_kernel(int currentCPU, uint64 stackTop); */ +FUNCTION(long_enter_kernel): + // Preserve the arguments. We may no longer be able to use the stack once + // paging is disabled. + movl 4(%esp), %ebx + movl 8(%esp), %edi + movl 12(%esp), %esi + + // We're about to disable paging, so we need to load the the physical + // address of our GDT. + lgdtl long_phys_gdtr + + // Currently running with 32-bit paging tables at an identity mapped + // address. To switch to 64-bit paging we must first disable 32-bit paging, + // otherwise loading the new CR3 will fault. + movl %cr0, %eax + andl $~(1 << 31), %eax + movl %eax, %cr0 + + // Enable PAE and PGE + movl %cr4, %eax + orl $(1 << 5) | (1 << 7), %eax + movl %eax, %cr4 + + // Point CR3 to the kernel's PML4. + movl gLongPhysicalPML4, %eax + movl %eax, %cr3 + + // Enable long mode by setting EFER.LME. + movl $0xc0000080, %ecx + rdmsr + orl $(1 << 8), %eax + wrmsr + + // Re-enable paging, which will put us in compatibility mode as we are + // currently in a 32-bit code segment. + movl %cr0, %ecx + orl $(1 << 31), %ecx + movl %ecx, %cr0 + + // Jump into the 64-bit code segment. + ljmp $KERNEL_CODE_SEG, $.Llmode +.align 8 +.code64 +.Llmode: + // Set data segments. + mov $KERNEL_DATA_SEG, %ax + mov %ax, %ss + xor %ax, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + // Load the virtual address of the GDT. + lgdtq long_virt_gdtr(%rip) + + // Set the stack pointer. + movl %edi, %esp + shl $32, %rsi + orq %rsi, %rsp + + // Clear the stack frame/RFLAGS. + xorq %rbp, %rbp + push $0 + popf + + // Get arguments and call the kernel entry point. + leaq gKernelArgs(%rip), %rdi + movl %ebx, %esi + movq gLongKernelEntry(%rip), %rax + call *%rax + + +.data + + +long_phys_gdtr: + .word GDT_LIMIT - 1 +SYMBOL(gLongPhysicalGDT): + .long 0 + +long_virt_gdtr: + .word GDT_LIMIT - 1 +SYMBOL(gLongVirtualGDT): + .quad 0 + +SYMBOL(gLongPhysicalPML4): + .long 0 + +SYMBOL(gLongKernelEntry): + .quad 0 diff --git a/src/system/boot/platform/bios_ia32/mmu.cpp b/src/system/boot/platform/bios_ia32/mmu.cpp index a808be9eaf..4eef5defa5 100644 --- a/src/system/boot/platform/bios_ia32/mmu.cpp +++ b/src/system/boot/platform/bios_ia32/mmu.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -77,7 +78,7 @@ static uint32 *sPageDirectory = 0; #ifdef _PXE_ENV static addr_t sNextPhysicalAddress = 0x112000; -static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize; +static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE + kMaxKernelSize; static addr_t sNextPageTableAddress = 0x7d000; static const uint32 kPageTableRegionEnd = 0x8b000; @@ -86,7 +87,7 @@ static const uint32 kPageTableRegionEnd = 0x8b000; #else static addr_t sNextPhysicalAddress = 0x100000; -static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize; +static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE + kMaxKernelSize; static addr_t sNextPageTableAddress = 0x90000; static const uint32 kPageTableRegionEnd = 0x9e000; @@ -108,8 +109,8 @@ get_next_virtual_address(size_t size) static addr_t get_next_physical_address(size_t size) { - phys_addr_t base; - if (!get_free_physical_address_range(gKernelArgs.physical_allocated_range, + uint64 base; + if (!get_free_address_range(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges, sNextPhysicalAddress, size, &base)) { panic("Out of physical memory!"); @@ -194,7 +195,7 @@ unmap_page(addr_t virtualAddress) { TRACE("unmap_page(virtualAddress = %p)\n", (void *)virtualAddress); - if (virtualAddress < KERNEL_BASE) { + if (virtualAddress < KERNEL_LOAD_BASE) { panic("unmap_page: asked to unmap invalid page %p!\n", (void *)virtualAddress); } @@ -219,7 +220,7 @@ map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags) TRACE("map_page: vaddr 0x%lx, paddr 0x%lx\n", virtualAddress, physicalAddress); - if (virtualAddress < KERNEL_BASE) { + if (virtualAddress < KERNEL_LOAD_BASE) { panic("map_page: asked to map invalid page %p!\n", (void *)virtualAddress); } @@ -396,8 +397,8 @@ mmu_allocate(void *virtualAddress, size_t size) addr_t address = (addr_t)virtualAddress; // is the address within the valid range? - if (address < KERNEL_BASE - || address + size >= KERNEL_BASE + kMaxKernelSize) + if (address < KERNEL_LOAD_BASE + || address + size >= KERNEL_LOAD_BASE + kMaxKernelSize) return NULL; for (uint32 i = 0; i < size; i++) { @@ -419,6 +420,24 @@ mmu_allocate(void *virtualAddress, size_t size) } +/*! Allocates a single page and returns both its virtual and physical + addresses. +*/ +void * +mmu_allocate_page(addr_t *_physicalAddress) +{ + addr_t virt = get_next_virtual_page(); + addr_t phys = get_next_physical_page(); + + map_page(virt, phys, kDefaultPageFlags); + + if (_physicalAddress) + *_physicalAddress = phys; + + return (void *)virt; +} + + /*! Allocates the given physical range. \return \c true, if the range could be allocated, \c false otherwise. */ @@ -426,14 +445,14 @@ bool mmu_allocate_physical(addr_t base, size_t size) { // check whether the physical memory range exists at all - if (!is_physical_address_range_covered(gKernelArgs.physical_memory_range, + if (!is_address_range_covered(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges, base, size)) { return false; } // check whether the physical range is still free - phys_addr_t foundBase; - if (!get_free_physical_address_range(gKernelArgs.physical_allocated_range, + uint64 foundBase; + if (!get_free_address_range(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges, base, size, &foundBase) || foundBase != base) { return false; @@ -460,7 +479,7 @@ mmu_free(void *virtualAddress, size_t size) size = (size + pageOffset + B_PAGE_SIZE - 1) / B_PAGE_SIZE * B_PAGE_SIZE; // is the address within the valid range? - if (address < KERNEL_BASE || address + size > sNextVirtualAddress) { + if (address < KERNEL_LOAD_BASE || address + size > sNextVirtualAddress) { panic("mmu_free: asked to unmap out of range region (%p, size %lx)\n", (void *)address, size); } @@ -478,6 +497,36 @@ mmu_free(void *virtualAddress, size_t size) } +size_t +mmu_get_virtual_usage() +{ + return sNextVirtualAddress - KERNEL_LOAD_BASE; +} + + +bool +mmu_get_virtual_mapping(addr_t virtualAddress, addr_t *_physicalAddress) +{ + if (virtualAddress < KERNEL_LOAD_BASE) { + panic("mmu_get_virtual_mapping: asked to lookup invalid page %p!\n", + (void *)virtualAddress); + } + + uint32 dirEntry = sPageDirectory[virtualAddress / (B_PAGE_SIZE * 1024)]; + if ((dirEntry & (1 << 0)) == 0) + return false; + + uint32 *pageTable = (uint32 *)(dirEntry & 0xfffff000); + uint32 tableEntry = pageTable[(virtualAddress % (B_PAGE_SIZE * 1024)) + / B_PAGE_SIZE]; + if ((tableEntry & (1 << 0)) == 0) + return false; + + *_physicalAddress = tableEntry & 0xfffff000; + return true; +} + + /*! Sets up the final and kernel accessible GDT and IDT tables. BIOS calls won't work any longer after this function has been called. @@ -501,10 +550,10 @@ mmu_init_for_kernel(void) map_page(gKernelArgs.arch_args.vir_idt, (uint32)idt, kDefaultPageFlags); // initialize it - interrupts_init_kernel_idt((void*)gKernelArgs.arch_args.vir_idt, + interrupts_init_kernel_idt((void*)(addr_t)gKernelArgs.arch_args.vir_idt, IDT_LIMIT); - TRACE("idt at virtual address 0x%lx\n", gKernelArgs.arch_args.vir_idt); + TRACE("idt at virtual address 0x%llx\n", gKernelArgs.arch_args.vir_idt); } // set up a new gdt @@ -524,7 +573,7 @@ mmu_init_for_kernel(void) // put standard segment descriptors in it segment_descriptor* virtualGDT - = (segment_descriptor*)gKernelArgs.arch_args.vir_gdt; + = (segment_descriptor*)(addr_t)gKernelArgs.arch_args.vir_gdt; clear_segment_descriptor(&virtualGDT[0]); // seg 0x08 - kernel 4GB code @@ -548,7 +597,7 @@ mmu_init_for_kernel(void) // load the GDT gdtDescriptor.limit = GDT_LIMIT - 1; - gdtDescriptor.base = (void*)gKernelArgs.arch_args.vir_gdt; + gdtDescriptor.base = (void*)(addr_t)gKernelArgs.arch_args.vir_gdt; asm("lgdt %0;" : : "m" (gdtDescriptor)); @@ -559,15 +608,15 @@ mmu_init_for_kernel(void) // Save the memory we've virtually allocated (for the kernel and other // stuff) - gKernelArgs.virtual_allocated_range[0].start = KERNEL_BASE; + gKernelArgs.virtual_allocated_range[0].start = KERNEL_LOAD_BASE; gKernelArgs.virtual_allocated_range[0].size - = sNextVirtualAddress - KERNEL_BASE; + = sNextVirtualAddress - KERNEL_LOAD_BASE; gKernelArgs.num_virtual_allocated_ranges = 1; // sort the address ranges - sort_physical_address_ranges(gKernelArgs.physical_memory_range, + sort_address_ranges(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges); - sort_physical_address_ranges(gKernelArgs.physical_allocated_range, + sort_address_ranges(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges); sort_address_ranges(gKernelArgs.virtual_allocated_range, gKernelArgs.num_virtual_allocated_ranges); @@ -578,24 +627,23 @@ mmu_init_for_kernel(void) dprintf("phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { - dprintf(" base %#018" B_PRIxPHYSADDR ", length %#018" - B_PRIxPHYSADDR "\n", gKernelArgs.physical_memory_range[i].start, + dprintf(" base %#018" B_PRIx64 ", length %#018" B_PRIx64 "\n", + gKernelArgs.physical_memory_range[i].start, gKernelArgs.physical_memory_range[i].size); } dprintf("allocated phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) { - dprintf(" base %#018" B_PRIxPHYSADDR ", length %#018" - B_PRIxPHYSADDR "\n", + dprintf(" base %#018" B_PRIx64 ", length %#018" B_PRIx64 "\n", gKernelArgs.physical_allocated_range[i].start, gKernelArgs.physical_allocated_range[i].size); } dprintf("allocated virt memory ranges:\n"); for (i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { - dprintf(" base %#018" B_PRIxADDR ", length %#018" B_PRIxSIZE - "\n", gKernelArgs.virtual_allocated_range[i].start, - gKernelArgs.virtual_allocated_range[i].size); + dprintf(" base %#018" B_PRIx64 ", length %#018" B_PRIx64 "\n", + gKernelArgs.virtual_allocated_range[i].start, + gKernelArgs.virtual_allocated_range[i].size); } } #endif @@ -607,7 +655,7 @@ mmu_init(void) { TRACE("mmu_init\n"); - gKernelArgs.arch_args.virtual_end = KERNEL_BASE; + gKernelArgs.arch_args.virtual_end = KERNEL_LOAD_BASE; gKernelArgs.physical_allocated_range[0].start = sNextPhysicalAddress; gKernelArgs.physical_allocated_range[0].size = 0; @@ -692,7 +740,7 @@ mmu_init(void) } // sort the ranges - sort_physical_address_ranges(gKernelArgs.physical_memory_range, + sort_address_ranges(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges); // On some machines we get several ranges that contain only a few pages @@ -701,10 +749,10 @@ mmu_init(void) // leave us only with a few larger contiguous ranges (ideally one). for (int32 i = gKernelArgs.num_physical_memory_ranges - 1; i >= 0; i--) { - size_t size = gKernelArgs.physical_memory_range[i].size; + uint64 size = gKernelArgs.physical_memory_range[i].size; if (size < 64 * 1024) { - addr_t start = gKernelArgs.physical_memory_range[i].start; - remove_physical_address_range(gKernelArgs.physical_memory_range, + uint64 start = gKernelArgs.physical_memory_range[i].start; + remove_address_range(gKernelArgs.physical_memory_range, &gKernelArgs.num_physical_memory_ranges, MAX_PHYSICAL_MEMORY_RANGE, start, size); } diff --git a/src/system/boot/platform/bios_ia32/mmu.h b/src/system/boot/platform/bios_ia32/mmu.h index fc197e98c8..9c59677094 100644 --- a/src/system/boot/platform/bios_ia32/mmu.h +++ b/src/system/boot/platform/bios_ia32/mmu.h @@ -20,9 +20,15 @@ extern void mmu_init(void); extern void mmu_init_for_kernel(void); extern addr_t mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 flags); extern void *mmu_allocate(void *virtualAddress, size_t size); +extern void *mmu_allocate_page(addr_t *_physicalAddress); extern bool mmu_allocate_physical(addr_t base, size_t size); extern void mmu_free(void *virtualAddress, size_t size); +// Used by the long mode switch code +extern size_t mmu_get_virtual_usage(); +extern bool mmu_get_virtual_mapping(addr_t virtualAddress, + addr_t *_physicalAddress); + #ifdef __cplusplus } #endif diff --git a/src/system/boot/platform/bios_ia32/smp.cpp b/src/system/boot/platform/bios_ia32/smp.cpp index 8d8c868141..e3abb4f6a6 100644 --- a/src/system/boot/platform/bios_ia32/smp.cpp +++ b/src/system/boot/platform/bios_ia32/smp.cpp @@ -20,8 +20,10 @@ #include #include #include +#include #include #include +#include #include "mmu.h" #include "acpi.h" @@ -36,10 +38,6 @@ # define TRACE(x) ; #endif -struct gdt_idt_descr { - uint16 a; - uint32 *b; -} _PACKED; static struct scan_spots_struct smp_scan_spots[] = { { 0x9fc00, 0xa0000, 0xa0000 - 0x9fc00 }, @@ -53,36 +51,17 @@ extern "C" void smp_trampoline(void); extern "C" void smp_trampoline_end(void); -static int smp_get_current_cpu(void); - - static uint32 apic_read(uint32 offset) { - return *(volatile uint32 *)((uint32)gKernelArgs.arch_args.apic + offset); + return *(volatile uint32 *)((addr_t)(void *)gKernelArgs.arch_args.apic + offset); } static void apic_write(uint32 offset, uint32 data) { - *(volatile uint32 *)((uint32)gKernelArgs.arch_args.apic + offset) = data; -} - - -static int -smp_get_current_cpu(void) -{ - if (gKernelArgs.arch_args.apic == NULL) - return 0; - - uint8 apicID = apic_read(APIC_ID) >> 24; - for (uint32 i = 0; i < gKernelArgs.num_cpus; i++) { - if (gKernelArgs.arch_args.cpu_apic_id[i] == apicID) - return i; - } - - return 0; + *(volatile uint32 *)((addr_t)(void *)gKernelArgs.arch_args.apic + offset) = data; } @@ -340,53 +319,6 @@ smp_do_acpi_config(void) } -/*! Target function of the trampoline code. - The trampoline code should have the pgdir and a gdt set up for us, - along with us being on the final stack for this processor. We need - to set up the local APIC and load the global idt and gdt. When we're - done, we'll jump into the kernel with the cpu number as an argument. -*/ -static int -smp_cpu_ready(void) -{ - uint32 curr_cpu = smp_get_current_cpu(); - struct gdt_idt_descr idt_descr; - struct gdt_idt_descr gdt_descr; - - //TRACE(("smp_cpu_ready: entry cpu %ld\n", curr_cpu)); - - // Important. Make sure supervisor threads can fault on read only pages... - asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1)); - asm("cld"); - asm("fninit"); - - // Set up the final idt - idt_descr.a = IDT_LIMIT - 1; - idt_descr.b = (uint32 *)gKernelArgs.arch_args.vir_idt; - - asm("lidt %0;" - : : "m" (idt_descr)); - - // Set up the final gdt - gdt_descr.a = GDT_LIMIT - 1; - gdt_descr.b = (uint32 *)gKernelArgs.arch_args.vir_gdt; - - asm("lgdt %0;" - : : "m" (gdt_descr)); - - asm("pushl %0; " // push the cpu number - "pushl %1; " // kernel args - "pushl $0x0;" // dummy retval for call to main - "pushl %2; " // this is the start address - "ret; " // jump. - : : "g" (curr_cpu), "g" (&gKernelArgs), - "g" (gKernelArgs.kernel_image.elf_header.e_entry)); - - // no where to return to - return 0; -} - - static void calculate_apic_timer_conversion_factor(void) { @@ -425,6 +357,22 @@ calculate_apic_timer_conversion_factor(void) // #pragma mark - +int +smp_get_current_cpu(void) +{ + if (gKernelArgs.arch_args.apic == NULL) + return 0; + + uint8 apicID = apic_read(APIC_ID) >> 24; + for (uint32 i = 0; i < gKernelArgs.num_cpus; i++) { + if (gKernelArgs.arch_args.cpu_apic_id[i] == apicID) + return i; + } + + return 0; +} + + void smp_init_other_cpus(void) { @@ -450,10 +398,10 @@ smp_init_other_cpus(void) (void *)gKernelArgs.arch_args.ioapic_phys)); // map in the apic - gKernelArgs.arch_args.apic = (uint32 *)mmu_map_physical_memory( + gKernelArgs.arch_args.apic = (void *)mmu_map_physical_memory( gKernelArgs.arch_args.apic_phys, B_PAGE_SIZE, kDefaultPageFlags); - TRACE(("smp: apic (mapped) = %p\n", gKernelArgs.arch_args.apic)); + TRACE(("smp: apic (mapped) = %p\n", (void *)gKernelArgs.arch_args.apic)); // calculate how fast the apic timer is calculate_apic_timer_conversion_factor(); @@ -472,7 +420,7 @@ smp_init_other_cpus(void) void -smp_boot_other_cpus(void) +smp_boot_other_cpus(void (*entryFunc)(void)) { if (gKernelArgs.num_cpus < 2) return; @@ -512,7 +460,7 @@ smp_boot_other_cpus(void) tempStack = (finalStack + (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE) / sizeof(uint32)) - 1; - *tempStack = (uint32)&smp_cpu_ready; + *tempStack = (uint32)entryFunc; // set the trampoline stack up tempStack = (uint32 *)(trampolineStack + B_PAGE_SIZE - 4); @@ -521,15 +469,20 @@ smp_boot_other_cpus(void) + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE - sizeof(uint32); tempStack--; // page dir - *tempStack = gKernelArgs.arch_args.phys_pgdir; + *tempStack = x86_read_cr3() & 0xfffff000; // put a gdt descriptor at the bottom of the stack *((uint16 *)trampolineStack) = 0x18 - 1; // LIMIT *((uint32 *)(trampolineStack + 2)) = trampolineStack + 8; - // put the gdt at the bottom - memcpy(&((uint32 *)trampolineStack)[2], - (void *)gKernelArgs.arch_args.vir_gdt, 6 * 4); + // construct a temporary gdt at the bottom + segment_descriptor* tempGDT + = (segment_descriptor*)&((uint32 *)trampolineStack)[2]; + clear_segment_descriptor(&tempGDT[0]); + set_segment_descriptor(&tempGDT[1], 0, 0xffffffff, DT_CODE_READABLE, + DPL_KERNEL); + set_segment_descriptor(&tempGDT[2], 0, 0xffffffff, DT_DATA_WRITEABLE, + DPL_KERNEL); /* clear apic errors */ if (gKernelArgs.arch_args.cpu_apic_version[i] & 0xf0) { diff --git a/src/system/boot/platform/bios_ia32/smp.h b/src/system/boot/platform/bios_ia32/smp.h index bf942a0925..4acda1622d 100644 --- a/src/system/boot/platform/bios_ia32/smp.h +++ b/src/system/boot/platform/bios_ia32/smp.h @@ -19,7 +19,9 @@ extern "C" { extern void smp_init(void); extern void smp_init_other_cpus(void); -extern void smp_boot_other_cpus(void); +extern void smp_boot_other_cpus(void (*entryFunc)(void)); + +extern int smp_get_current_cpu(void); #ifdef __cplusplus } diff --git a/src/system/boot/platform/bios_ia32/start.cpp b/src/system/boot/platform/bios_ia32/start.cpp index 6af13dd6da..2cc72123fb 100644 --- a/src/system/boot/platform/bios_ia32/start.cpp +++ b/src/system/boot/platform/bios_ia32/start.cpp @@ -22,6 +22,7 @@ #include "hpet.h" #include "interrupts.h" #include "keyboard.h" +#include "long.h" #include "mmu.h" #include "multiboot.h" #include "serial.h" @@ -72,9 +73,64 @@ platform_boot_options(void) } +/*! Target function of the SMP trampoline code. + The trampoline code should have the pgdir and a gdt set up for us, + along with us being on the final stack for this processor. We need + to set up the local APIC and load the global idt and gdt. When we're + done, we'll jump into the kernel with the cpu number as an argument. +*/ +static void +smp_start_kernel(void) +{ + uint32 curr_cpu = smp_get_current_cpu(); + struct gdt_idt_descr idt_descr; + struct gdt_idt_descr gdt_descr; + + //TRACE(("smp_cpu_ready: entry cpu %ld\n", curr_cpu)); + + preloaded_elf32_image *image = static_cast( + gKernelArgs.kernel_image.Pointer()); + + // Important. Make sure supervisor threads can fault on read only pages... + asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1)); + asm("cld"); + asm("fninit"); + + // Set up the final idt + idt_descr.limit = IDT_LIMIT - 1; + idt_descr.base = (uint32 *)(addr_t)gKernelArgs.arch_args.vir_idt; + + asm("lidt %0;" + : : "m" (idt_descr)); + + // Set up the final gdt + gdt_descr.limit = GDT_LIMIT - 1; + gdt_descr.base = (uint32 *)gKernelArgs.arch_args.vir_gdt; + + asm("lgdt %0;" + : : "m" (gdt_descr)); + + asm("pushl %0; " // push the cpu number + "pushl %1; " // kernel args + "pushl $0x0;" // dummy retval for call to main + "pushl %2; " // this is the start address + "ret; " // jump. + : : "g" (curr_cpu), "g" (&gKernelArgs), + "g" (image->elf_header.e_entry)); + + panic("kernel returned!\n"); +} + + extern "C" void platform_start_kernel(void) { + // 64-bit kernel entry is all handled in long.cpp + if (gKernelArgs.kernel_image->elf_class == ELFCLASS64) { + long_start_kernel(); + return; + } + static struct kernel_args *args = &gKernelArgs; // something goes wrong when we pass &gKernelArgs directly // to the assembler inline below - might be a bug in GCC @@ -82,6 +138,9 @@ platform_start_kernel(void) addr_t stackTop = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; + preloaded_elf32_image *image = static_cast( + gKernelArgs.kernel_image.Pointer()); + smp_init_other_cpus(); debug_cleanup(); mmu_init_for_kernel(); @@ -89,10 +148,9 @@ platform_start_kernel(void) // We're about to enter the kernel -- disable console output. stdout = NULL; - smp_boot_other_cpus(); + smp_boot_other_cpus(smp_start_kernel); - dprintf("kernel entry at %lx\n", - gKernelArgs.kernel_image.elf_header.e_entry); + dprintf("kernel entry at %lx\n", image->elf_header.e_entry); asm("movl %0, %%eax; " // move stack out of way "movl %%eax, %%esp; " @@ -102,7 +160,7 @@ platform_start_kernel(void) "pushl $0x0;" // dummy retval for call to main "pushl %1; " // this is the start address "ret; " // jump. - : : "g" (args), "g" (gKernelArgs.kernel_image.elf_header.e_entry)); + : : "g" (args), "g" (image->elf_header.e_entry)); panic("kernel returned!\n"); } diff --git a/src/system/boot/platform/cfe/Jamfile b/src/system/boot/platform/cfe/Jamfile index 8114492e79..7f54c77414 100644 --- a/src/system/boot/platform/cfe/Jamfile +++ b/src/system/boot/platform/cfe/Jamfile @@ -6,7 +6,7 @@ UsePrivateHeaders [ FDirName graphics common ] ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; -KernelMergeObject boot_platform_cfe.o : +BootMergeObject boot_platform_cfe.o : console.cpp debug.cpp devices.cpp diff --git a/src/system/boot/platform/cfe/arch/ppc/Jamfile b/src/system/boot/platform/cfe/arch/ppc/Jamfile index 14cc7e7567..5bace2e838 100644 --- a/src/system/boot/platform/cfe/arch/ppc/Jamfile +++ b/src/system/boot/platform/cfe/arch/ppc/Jamfile @@ -2,12 +2,12 @@ SubDir HAIKU_TOP src system boot platform cfe arch ppc ; SubDirHdrs $(HAIKU_TOP) src system boot platform $(TARGET_BOOT_PLATFORM) ; UsePrivateSystemHeaders ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] +UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; SubDirC++Flags -fno-rtti ; -KernelStaticLibrary boot_platform_cfe_ppc : +BootStaticLibrary boot_platform_cfe_ppc : arch_mmu.cpp arch_cpu_asm.S arch_start_kernel.S @@ -16,4 +16,4 @@ KernelStaticLibrary boot_platform_cfe_ppc : ; SEARCH on [ FGristFiles arch_cpu_asm.S arch_mmu.cpp ] - = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ; diff --git a/src/system/boot/platform/cfe/arch/ppc/mmu.cpp b/src/system/boot/platform/cfe/arch/ppc/mmu.cpp index b06114fc68..68c709ee74 100644 --- a/src/system/boot/platform/cfe/arch/ppc/mmu.cpp +++ b/src/system/boot/platform/cfe/arch/ppc/mmu.cpp @@ -88,7 +88,7 @@ find_physical_memory_ranges(size_t &total) static bool is_virtual_allocated(void *address, size_t size) { - addr_t foundBase; + uint64 foundBase; return !get_free_address_range(gKernelArgs.virtual_allocated_range, gKernelArgs.num_virtual_allocated_ranges, (addr_t)address, size, &foundBase) || foundBase != (addr_t)address; @@ -98,9 +98,8 @@ is_virtual_allocated(void *address, size_t size) static bool is_physical_allocated(void *address, size_t size) { - phys_addr_t foundBase; - return !get_free_physical_address_range( - gKernelArgs.physical_allocated_range, + uint64 foundBase; + return !get_free_address_range(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges, (addr_t)address, size, &foundBase) || foundBase != (addr_t)address; } @@ -109,7 +108,7 @@ is_physical_allocated(void *address, size_t size) static bool is_physical_memory(void *address, size_t size) { - return is_physical_address_range_covered(gKernelArgs.physical_memory_range, + return is_address_range_covered(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges, (addr_t)address, size); } @@ -243,7 +242,7 @@ find_physical_memory_range(size_t size) { for (uint32 i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { if (gKernelArgs.physical_memory_range[i].size > size) - return (void *)gKernelArgs.physical_memory_range[i].start; + return (void *)(addr_t)gKernelArgs.physical_memory_range[i].start; } return PHYSINVAL; } @@ -262,8 +261,9 @@ find_free_physical_range(size_t size) } for (uint32 i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) { - void *address = (void *)(gKernelArgs.physical_allocated_range[i].start - + gKernelArgs.physical_allocated_range[i].size); + void *address + = (void *)(addr_t)(gKernelArgs.physical_allocated_range[i].start + + gKernelArgs.physical_allocated_range[i].size); if (!is_physical_allocated(address, size) && is_physical_memory(address, size)) return address; @@ -281,8 +281,9 @@ find_free_virtual_range(void *base, size_t size) void *firstFound = NULL; void *firstBaseFound = NULL; for (uint32 i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { - void *address = (void *)(gKernelArgs.virtual_allocated_range[i].start - + gKernelArgs.virtual_allocated_range[i].size); + void *address + = (void *)(addr_t)(gKernelArgs.virtual_allocated_range[i].start + + gKernelArgs.virtual_allocated_range[i].size); if (!is_virtual_allocated(address, size)) { if (!base) return address; diff --git a/src/system/boot/platform/cfe/devices.cpp b/src/system/boot/platform/cfe/devices.cpp index 46a20ce82e..13e7e6c0f1 100644 --- a/src/system/boot/platform/cfe/devices.cpp +++ b/src/system/boot/platform/cfe/devices.cpp @@ -130,8 +130,8 @@ platform_register_boot_device(Node *device) disk.device_type = UNKNOWN_DEVICE; disk.device.unknown.size = device->Size(); - gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, - &disk, sizeof(disk_identifier)); + gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, &disk, + sizeof(disk_identifier)); return B_OK; } diff --git a/src/system/boot/platform/cfe/start.cpp b/src/system/boot/platform/cfe/start.cpp index 64309c2807..b9a8dafb82 100644 --- a/src/system/boot/platform/cfe/start.cpp +++ b/src/system/boot/platform/cfe/start.cpp @@ -60,7 +60,10 @@ clear_bss(void) extern "C" void platform_start_kernel(void) { - addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry; + preloaded_elf32_image* image = static_cast( + gKernelArgs.kernel_image.Pointer()); + + addr_t kernelEntry = image->elf_header.e_entry; addr_t stackTop = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; diff --git a/src/system/boot/platform/generic/Jamfile b/src/system/boot/platform/generic/Jamfile index 0ca49679b0..fad4f47ad2 100644 --- a/src/system/boot/platform/generic/Jamfile +++ b/src/system/boot/platform/generic/Jamfile @@ -5,7 +5,7 @@ UsePrivateKernelHeaders ; SubDirC++Flags -D_BOOT_MODE -fno-rtti ; -KernelStaticLibrary boot_platform_generic : +BootStaticLibrary boot_platform_generic : text_menu.cpp video_blit.cpp video_splash.cpp diff --git a/src/system/boot/platform/generic/video_splash.cpp b/src/system/boot/platform/generic/video_splash.cpp index 8d3cb49a8e..5d1c41166a 100644 --- a/src/system/boot/platform/generic/video_splash.cpp +++ b/src/system/boot/platform/generic/video_splash.cpp @@ -151,7 +151,7 @@ video_display_splash(addr_t frameBuffer) uncompress(kSplashIcons8BitCompressedImage, sizeof(kSplashIcons8BitCompressedImage), gKernelArgs.boot_splash, uncompressedSize); - lowerHalfIconImage = gKernelArgs.boot_splash + lowerHalfIconImage = (uint8 *)gKernelArgs.boot_splash + (kSplashIconsWidth * iconsHalfHeight); break; default: // 24bits is assumed here @@ -164,7 +164,7 @@ video_display_splash(addr_t frameBuffer) uncompress(kSplashIcons24BitCompressedImage, sizeof(kSplashIcons24BitCompressedImage), gKernelArgs.boot_splash, uncompressedSize); - lowerHalfIconImage = gKernelArgs.boot_splash + lowerHalfIconImage = (uint8 *)gKernelArgs.boot_splash + (kSplashIconsWidth * iconsHalfHeight) * 3; break; } diff --git a/src/system/boot/platform/openfirmware/Jamfile b/src/system/boot/platform/openfirmware/Jamfile index 227df039bf..43f2f2c765 100644 --- a/src/system/boot/platform/openfirmware/Jamfile +++ b/src/system/boot/platform/openfirmware/Jamfile @@ -6,7 +6,7 @@ UsePrivateHeaders [ FDirName graphics common ] ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; -KernelMergeObject boot_platform_openfirmware.o : +BootMergeObject boot_platform_openfirmware.o : console.cpp debug.cpp devices.cpp diff --git a/src/system/boot/platform/openfirmware/arch/ppc/Jamfile b/src/system/boot/platform/openfirmware/arch/ppc/Jamfile index 651d61c6b5..cb053f478f 100644 --- a/src/system/boot/platform/openfirmware/arch/ppc/Jamfile +++ b/src/system/boot/platform/openfirmware/arch/ppc/Jamfile @@ -2,12 +2,12 @@ SubDir HAIKU_TOP src system boot platform openfirmware arch ppc ; SubDirHdrs $(HAIKU_TOP) src system boot platform $(TARGET_BOOT_PLATFORM) ; UsePrivateSystemHeaders ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] +UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; SubDirC++Flags -fno-rtti ; -KernelStaticLibrary boot_platform_openfirmware_ppc : +BootStaticLibrary boot_platform_openfirmware_ppc : arch_mmu.cpp arch_cpu_asm.S arch_start_kernel.S @@ -16,4 +16,4 @@ KernelStaticLibrary boot_platform_openfirmware_ppc : ; SEARCH on [ FGristFiles arch_cpu_asm.S arch_mmu.cpp ] - = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ; diff --git a/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp b/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp index 0d3e0d2810..a89fec7f53 100644 --- a/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp +++ b/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp @@ -170,7 +170,7 @@ find_physical_memory_ranges(size_t &total) static bool is_virtual_allocated(void *address, size_t size) { - addr_t foundBase; + uint64 foundBase; return !get_free_address_range(gKernelArgs.virtual_allocated_range, gKernelArgs.num_virtual_allocated_ranges, (addr_t)address, size, &foundBase) || foundBase != (addr_t)address; @@ -180,9 +180,8 @@ is_virtual_allocated(void *address, size_t size) static bool is_physical_allocated(void *address, size_t size) { - phys_addr_t foundBase; - return !get_free_physical_address_range( - gKernelArgs.physical_allocated_range, + uint64 foundBase; + return !get_free_address_range(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges, (addr_t)address, size, &foundBase) || foundBase != (addr_t)address; } @@ -191,7 +190,7 @@ is_physical_allocated(void *address, size_t size) static bool is_physical_memory(void *address, size_t size) { - return is_physical_address_range_covered(gKernelArgs.physical_memory_range, + return is_address_range_covered(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges, (addr_t)address, size); } @@ -424,7 +423,7 @@ find_physical_memory_range(size_t size) { for (uint32 i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { if (gKernelArgs.physical_memory_range[i].size > size) - return (void *)gKernelArgs.physical_memory_range[i].start; + return (void *)(addr_t)gKernelArgs.physical_memory_range[i].start; } return PHYSINVAL; } @@ -443,8 +442,9 @@ find_free_physical_range(size_t size) } for (uint32 i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) { - void *address = (void *)(gKernelArgs.physical_allocated_range[i].start - + gKernelArgs.physical_allocated_range[i].size); + void *address + = (void *)(addr_t)(gKernelArgs.physical_allocated_range[i].start + + gKernelArgs.physical_allocated_range[i].size); if (!is_physical_allocated(address, size) && is_physical_memory(address, size)) return address; @@ -462,8 +462,9 @@ find_free_virtual_range(void *base, size_t size) void *firstFound = NULL; void *firstBaseFound = NULL; for (uint32 i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { - void *address = (void *)(gKernelArgs.virtual_allocated_range[i].start - + gKernelArgs.virtual_allocated_range[i].size); + void *address + = (void *)(addr_t)(gKernelArgs.virtual_allocated_range[i].start + + gKernelArgs.virtual_allocated_range[i].size); if (!is_virtual_allocated(address, size)) { if (!base) return address; diff --git a/src/system/boot/platform/openfirmware/devices.cpp b/src/system/boot/platform/openfirmware/devices.cpp index 03b00bfe4f..b58e30fe05 100644 --- a/src/system/boot/platform/openfirmware/devices.cpp +++ b/src/system/boot/platform/openfirmware/devices.cpp @@ -233,8 +233,8 @@ platform_register_boot_device(Node *device) disk.device_type = UNKNOWN_DEVICE; disk.device.unknown.size = device->Size(); - gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, - &disk, sizeof(disk_identifier)); + gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, &disk, + sizeof(disk_identifier)); return B_OK; } diff --git a/src/system/boot/platform/openfirmware/start.cpp b/src/system/boot/platform/openfirmware/start.cpp index e297900d5f..0d983e8292 100644 --- a/src/system/boot/platform/openfirmware/start.cpp +++ b/src/system/boot/platform/openfirmware/start.cpp @@ -95,7 +95,10 @@ determine_machine(void) extern "C" void platform_start_kernel(void) { - addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry; + preloaded_elf32_image* image = static_cast( + gKernelArgs.kernel_image.Pointer()); + + addr_t kernelEntry = image->elf_header.e_entry; addr_t stackTop = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; diff --git a/src/system/boot/platform/pxe_ia32/Jamfile b/src/system/boot/platform/pxe_ia32/Jamfile index 73c75ebe35..7adb3072ec 100644 --- a/src/system/boot/platform/pxe_ia32/Jamfile +++ b/src/system/boot/platform/pxe_ia32/Jamfile @@ -37,6 +37,8 @@ local bios_ia32_src = apm.cpp interrupts.cpp interrupts_asm.S + long.cpp + long_asm.S ; local bios_ia32_edid_src = @@ -45,7 +47,7 @@ local bios_ia32_edid_src = ; -KernelMergeObject boot_platform_pxe_ia32.o : +BootMergeObject boot_platform_pxe_ia32.o : pxe_stage2.S smp_trampoline.S pxe_bios.S diff --git a/src/system/boot/platform/pxe_ia32/devices.cpp b/src/system/boot/platform/pxe_ia32/devices.cpp index 7b2f9ac4e3..6dd064fc78 100644 --- a/src/system/boot/platform/pxe_ia32/devices.cpp +++ b/src/system/boot/platform/pxe_ia32/devices.cpp @@ -152,15 +152,14 @@ platform_register_boot_device(Node *device) rootPath = fileNameEnd + 1; } - KMessage& bootVolume = gKernelArgs.boot_volume; - if (bootVolume.SetInt32(BOOT_METHOD, BOOT_METHOD_NET) != B_OK - || bootVolume.AddInt64("client MAC", + if (gBootVolume.SetInt32(BOOT_METHOD, BOOT_METHOD_NET) != B_OK + || gBootVolume.AddInt64("client MAC", sTFTP.MACAddress().ToUInt64()) != B_OK - || bootVolume.AddInt32("client IP", sTFTP.IPAddress()) != B_OK - || bootVolume.AddInt32("server IP", sTFTP.ServerIPAddress()) != B_OK - || bootVolume.AddInt32("server port", sTFTP.ServerPort()) != B_OK + || gBootVolume.AddInt32("client IP", sTFTP.IPAddress()) != B_OK + || gBootVolume.AddInt32("server IP", sTFTP.ServerIPAddress()) != B_OK + || gBootVolume.AddInt32("server port", sTFTP.ServerPort()) != B_OK || (sTFTP.RootPath() - && bootVolume.AddString("net root path", rootPath) + && gBootVolume.AddString("net root path", rootPath) != B_OK)) { return B_NO_MEMORY; } diff --git a/src/system/boot/platform/raspberrypi_arm/Jamfile b/src/system/boot/platform/raspberrypi_arm/Jamfile index d7c41f9ccc..034ecea576 100644 --- a/src/system/boot/platform/raspberrypi_arm/Jamfile +++ b/src/system/boot/platform/raspberrypi_arm/Jamfile @@ -8,7 +8,7 @@ UsePrivateHeaders [ FDirName graphics common ] ; UsePrivateHeaders [ FDirName graphics vesa ] ; UsePrivateHeaders [ FDirName storage ] ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOARD) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ; { local defines = _BOOT_MODE ; @@ -20,7 +20,7 @@ UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOAR SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; -KernelMergeObject boot_platform_raspberrypi_arm.o : +BootMergeObject boot_platform_raspberrypi_arm.o : entry.S start.c console.cpp diff --git a/src/system/boot/platform/routerboard_mipsel/Jamfile b/src/system/boot/platform/routerboard_mipsel/Jamfile index 94f292ddd6..979e6fd6c4 100644 --- a/src/system/boot/platform/routerboard_mipsel/Jamfile +++ b/src/system/boot/platform/routerboard_mipsel/Jamfile @@ -23,7 +23,7 @@ local genericPlatformSources = # video_splash.cpp ; -KernelMergeObject boot_platform_routerboard_mipsel.o : +BootMergeObject boot_platform_routerboard_mipsel.o : console.cpp cpu.cpp debug.c diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index a2cea4405b..9230ba9a18 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -2,7 +2,7 @@ SubDir HAIKU_TOP src system boot platform u-boot ; SubDirHdrs $(HAIKU_TOP) headers private kernel boot platform $(TARGET_BOOT_PLATFORM) ; -SubDirHdrs $(HAIKU_TOP) src system boot arch $(TARGET_ARCH) ; +SubDirHdrs $(HAIKU_TOP) src system boot arch $(TARGET_KERNEL_ARCH) ; UsePrivateHeaders [ FDirName kernel disk_device_manager ] ; UsePrivateHeaders [ FDirName graphics common ] ; @@ -12,7 +12,7 @@ UsePrivateHeaders [ FDirName kernel arch generic ] ; # TODO: move this to arch/arm ! -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOARD) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ; { local defines = _BOOT_MODE ; @@ -40,7 +40,7 @@ local uImageFakeOS = "netbsd" ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; # First build the non arch dependent parts -KernelMergeObject boot_platform_u-boot_common.o : +BootMergeObject boot_platform_u-boot_common.o : start.cpp debug.cpp console.cpp @@ -61,7 +61,7 @@ KernelMergeObject boot_platform_u-boot_common.o : : boot_platform_generic.a ; -KernelMergeObject boot_platform_u-boot.o : +BootMergeObject boot_platform_u-boot.o : : : # must come first to have _start_* at correct locations boot_platform_u-boot_$(TARGET_ARCH).o diff --git a/src/system/boot/platform/u-boot/arch/arm/Jamfile b/src/system/boot/platform/u-boot/arch/arm/Jamfile index 508788c563..d5221acf74 100644 --- a/src/system/boot/platform/u-boot/arch/arm/Jamfile +++ b/src/system/boot/platform/u-boot/arch/arm/Jamfile @@ -2,17 +2,17 @@ SubDir HAIKU_TOP src system boot platform u-boot arch arm ; SubDirHdrs $(HAIKU_TOP) src system boot platform $(TARGET_BOOT_PLATFORM) ; UsePrivateSystemHeaders ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] +UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOARD) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ; SubDirC++Flags -fno-rtti ; -KernelMergeObject boot_platform_u-boot_arm.o : +BootMergeObject boot_platform_u-boot_arm.o : # must come first to have _start_* at correct locations shell.S : -fno-pic ; #SEARCH on [ FGristFiles arch_cpu_asm.S ] -# = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; +# = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ; diff --git a/src/system/boot/platform/u-boot/arch/ppc/Jamfile b/src/system/boot/platform/u-boot/arch/ppc/Jamfile index 0f5b0f5a56..54f465975e 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/Jamfile +++ b/src/system/boot/platform/u-boot/arch/ppc/Jamfile @@ -2,13 +2,13 @@ SubDir HAIKU_TOP src system boot platform u-boot arch ppc ; SubDirHdrs $(HAIKU_TOP) src system boot platform $(TARGET_BOOT_PLATFORM) ; UsePrivateSystemHeaders ; -UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] +UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOARD) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ; SubDirC++Flags -fno-rtti ; -KernelMergeObject boot_platform_u-boot_ppc.o : +BootMergeObject boot_platform_u-boot_ppc.o : # must come first to have _start_* at correct locations shell.S @@ -21,4 +21,4 @@ KernelMergeObject boot_platform_u-boot_ppc.o : ; SEARCH on [ FGristFiles arch_cpu_asm.S ] - = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ; + = [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ; diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 3ee80eec8a..074e434f07 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -98,7 +98,10 @@ abort(void) extern "C" void platform_start_kernel(void) { - addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry; + preloaded_elf32_image *image = static_cast( + gKernelArgs.kernel_image.Pointer()); + + addr_t kernelEntry = image->elf_header.e_entry; addr_t stackTop = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; @@ -107,8 +110,7 @@ platform_start_kernel(void) mmu_init_for_kernel(); // smp_boot_other_cpus(); - dprintf("kernel entry at %lx\n", - gKernelArgs.kernel_image.elf_header.e_entry); + dprintf("kernel entry at %lx\n", kernelEntry); status_t error = arch_start_kernel(&gKernelArgs, kernelEntry, stackTop); diff --git a/src/system/glue/arch/x86_64/Jamfile b/src/system/glue/arch/x86_64/Jamfile new file mode 100644 index 0000000000..4d43342366 --- /dev/null +++ b/src/system/glue/arch/x86_64/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src system glue arch x86_64 ; + +KernelObjects + crti.S + crtn.S + ; + diff --git a/src/system/glue/arch/x86_64/crti.S b/src/system/glue/arch/x86_64/crti.S new file mode 100644 index 0000000000..3ef8e5f8df --- /dev/null +++ b/src/system/glue/arch/x86_64/crti.S @@ -0,0 +1,43 @@ +/* + * Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + + +/** This file contains the first part of the ".init" and ".fini" sections in + * the ELF executable. + * The functions defined here will be called during initialization/termination + * of the loaded executable/library. The ".init" and ".fini" sections are + * stacked together like this: + * + * crti.S entry point + * call to _init_before/_term_before + * crtbegin.S GCC specific: constructors/destructors are called, ... + * crtend.S + * crtn.S call to _init_after/_term_after + * exit + */ + + +.section .init +FUNCTION(_init): + push %rbp + movq %rsp, %rbp + + // Preserve image ID for call to __haiku_init_after. + push %rdi + + call __haiku_init_before + // crtbegin.o stuff comes here + +.section .fini +FUNCTION(_fini): + push %rbp + movq %rsp, %rbp + push %rdi + call __haiku_term_before + // crtend.o stuff comes here diff --git a/src/system/glue/arch/x86_64/crtn.S b/src/system/glue/arch/x86_64/crtn.S new file mode 100644 index 0000000000..8ed6433843 --- /dev/null +++ b/src/system/glue/arch/x86_64/crtn.S @@ -0,0 +1,27 @@ +/* + * Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +/** This file contains the final part of the ".init" and ".fini" sections in + * the ELF executable. It is tightly connected to crti.S. + * Have a look at crti.S to find a description of what happens here. + */ + + +.section .init + // The image ID is preserved on the stack. + pop %rdi + call __haiku_init_after + movq %rbp, %rsp + pop %rbp + ret + +.section .fini + pop %rdi + call __haiku_term_after + movq %rbp, %rsp + pop %rbp + ret diff --git a/src/system/kernel/Jamfile b/src/system/kernel/Jamfile index 04b3719298..568a113482 100644 --- a/src/system/kernel/Jamfile +++ b/src/system/kernel/Jamfile @@ -114,7 +114,7 @@ KernelLd kernel_$(TARGET_ARCH) : kernel_util.o kernel_vm.o - kernel_arch_$(TARGET_ARCH).o + kernel_arch_$(TARGET_KERNEL_ARCH).o kernel_platform_$(TARGET_BOOT_PLATFORM).o linkhack.so @@ -126,7 +126,7 @@ KernelLd kernel_$(TARGET_ARCH) : kernel_lib_posix_arch_$(TARGET_ARCH).o kernel_misc.o - $(HAIKU_STATIC_LIBSUPC++) + $(HAIKU_KERNEL_LIBSUPC++) : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/kernel.ld : -Bdynamic -export-dynamic -dynamic-linker /foo/bar @@ -134,37 +134,47 @@ KernelLd kernel_$(TARGET_ARCH) : : ; -KernelLd kernel.so : - kernel_cache.o - kernel_core.o - kernel_debug.o - kernel_device_manager.o - kernel_disk_device_manager.o - kernel_fs.o - kernel_messaging.o - kernel_posix.o - kernel_slab.o - kernel_util.o - kernel_vm.o +if $(HAIKU_ARCH) = x86_64 { + # Cannot relink everything as a shared object on x86_64 as shared library + # code is required to be position-independent. Instead create a copy of the + # executable kernel image and change the ELF header type to DYN. A bit of + # a hack, but avoids having to recompile a PIC copy of the kernel code. + # kernel.so is only used when linking modules to provide symbol information, + # this is sufficient for that purpose. + KernelSo kernel.so : kernel_$(TARGET_ARCH) ; +} else { + KernelLd kernel.so : + kernel_cache.o + kernel_core.o + kernel_debug.o + kernel_device_manager.o + kernel_disk_device_manager.o + kernel_fs.o + kernel_messaging.o + kernel_posix.o + kernel_slab.o + kernel_util.o + kernel_vm.o - kernel_arch_$(TARGET_ARCH).o - kernel_platform_$(TARGET_BOOT_PLATFORM).o + kernel_arch_$(TARGET_KERNEL_ARCH).o + kernel_platform_$(TARGET_BOOT_PLATFORM).o - linkhack.so + linkhack.so - # kernel libroot parts - kernel_os_main.o - kernel_os_arch_$(TARGET_ARCH).o - kernel_lib_posix.o - kernel_lib_posix_arch_$(TARGET_ARCH).o - kernel_misc.o + # kernel libroot parts + kernel_os_main.o + kernel_os_arch_$(TARGET_ARCH).o + kernel_lib_posix.o + kernel_lib_posix_arch_$(TARGET_ARCH).o + kernel_misc.o - $(HAIKU_STATIC_LIBSUPC++) + $(HAIKU_KERNEL_LIBSUPC++) - : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/kernel.ld - : -Bdynamic -shared -export-dynamic -dynamic-linker /foo/bar - $(TARGET_KERNEL_PIC_LINKFLAGS) -; + : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/kernel.ld + : -Bdynamic -shared -export-dynamic -dynamic-linker /foo/bar + $(TARGET_KERNEL_PIC_LINKFLAGS) + ; +} NotFile kernel ; Depends kernel : kernel_$(TARGET_ARCH) ; diff --git a/src/system/kernel/arch/Jamfile b/src/system/kernel/arch/Jamfile index f93fb20fd0..9a7dbb5696 100644 --- a/src/system/kernel/arch/Jamfile +++ b/src/system/kernel/arch/Jamfile @@ -1,3 +1,3 @@ SubDir HAIKU_TOP src system kernel arch ; -SubInclude HAIKU_TOP src system kernel arch $(TARGET_ARCH) ; +SubInclude HAIKU_TOP src system kernel arch $(TARGET_KERNEL_ARCH) ; diff --git a/src/system/kernel/arch/arm/Jamfile b/src/system/kernel/arch/arm/Jamfile index 68124ed9b9..25e4f8a42c 100644 --- a/src/system/kernel/arch/arm/Jamfile +++ b/src/system/kernel/arch/arm/Jamfile @@ -2,7 +2,7 @@ SubDir HAIKU_TOP src system kernel arch arm ; SubDirHdrs $(SUBDIR) $(DOTDOT) generic ; UsePrivateKernelHeaders ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOARD) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) paging ] ; diff --git a/src/system/kernel/arch/arm/arch_elf.cpp b/src/system/kernel/arch/arm/arch_elf.cpp index a64d0fae5a..62fc17efd5 100644 --- a/src/system/kernel/arch/arm/arch_elf.cpp +++ b/src/system/kernel/arch/arm/arch_elf.cpp @@ -164,7 +164,7 @@ is_in_image(struct elf_image_info *image, addr_t address) #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_image *image, +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, struct Elf32_Rel *rel, int relLength) #else int @@ -308,7 +308,7 @@ write_8_check(addr_t P, Elf32_Word value) #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rela(struct preloaded_image *image, +boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, struct Elf32_Rela *rel, int rel_len) #else int diff --git a/src/system/kernel/arch/arm/paging/ARMVMTranslationMap.cpp b/src/system/kernel/arch/arm/paging/ARMVMTranslationMap.cpp index ca5b73777a..1f94eba8ee 100644 --- a/src/system/kernel/arch/arm/paging/ARMVMTranslationMap.cpp +++ b/src/system/kernel/arch/arm/paging/ARMVMTranslationMap.cpp @@ -128,7 +128,7 @@ ARMVMTranslationMap::Flush() if (fIsKernelMap) { smp_send_broadcast_ici(SMP_MSG_INVALIDATE_PAGE_LIST, - (uint32)fInvalidPages, fInvalidPagesCount, 0, NULL, + (addr_t)fInvalidPages, fInvalidPagesCount, 0, NULL, SMP_MSG_FLAG_SYNC); } else { int cpu = smp_get_current_cpu(); @@ -136,7 +136,7 @@ ARMVMTranslationMap::Flush() & ~((uint32)1 << cpu); if (cpuMask != 0) { smp_send_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST, - (uint32)fInvalidPages, fInvalidPagesCount, 0, NULL, + (addr_t)fInvalidPages, fInvalidPagesCount, 0, NULL, SMP_MSG_FLAG_SYNC); } } diff --git a/src/system/kernel/arch/m68k/arch_elf.cpp b/src/system/kernel/arch/m68k/arch_elf.cpp index 7c96746802..2251f030dd 100644 --- a/src/system/kernel/arch/m68k/arch_elf.cpp +++ b/src/system/kernel/arch/m68k/arch_elf.cpp @@ -76,7 +76,7 @@ static const char *kRelocations[] = { #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_image *image, +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, struct Elf32_Rel *rel, int rel_len) #else int @@ -137,7 +137,7 @@ write_8_check(addr_t P, Elf32_Word value) #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rela(struct preloaded_image *image, +boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, struct Elf32_Rela *rel, int rel_len) #else int diff --git a/src/system/kernel/arch/m68k/paging/M68KVMTranslationMap.cpp b/src/system/kernel/arch/m68k/paging/M68KVMTranslationMap.cpp index 8efa64aa3d..47fc0b274f 100644 --- a/src/system/kernel/arch/m68k/paging/M68KVMTranslationMap.cpp +++ b/src/system/kernel/arch/m68k/paging/M68KVMTranslationMap.cpp @@ -128,7 +128,7 @@ M68KVMTranslationMap::Flush() if (fIsKernelMap) { smp_send_broadcast_ici(SMP_MSG_INVALIDATE_PAGE_LIST, - (uint32)fInvalidPages, fInvalidPagesCount, 0, NULL, + (addr_t)fInvalidPages, fInvalidPagesCount, 0, NULL, SMP_MSG_FLAG_SYNC); } else { int cpu = smp_get_current_cpu(); @@ -136,7 +136,7 @@ M68KVMTranslationMap::Flush() & ~((uint32)1 << cpu); if (cpuMask != 0) { smp_send_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST, - (uint32)fInvalidPages, fInvalidPagesCount, 0, NULL, + (addr_t)fInvalidPages, fInvalidPagesCount, 0, NULL, SMP_MSG_FLAG_SYNC); } } diff --git a/src/system/kernel/arch/mipsel/arch_elf.cpp b/src/system/kernel/arch/mipsel/arch_elf.cpp index 6339b99c0d..f44206cd22 100644 --- a/src/system/kernel/arch/mipsel/arch_elf.cpp +++ b/src/system/kernel/arch/mipsel/arch_elf.cpp @@ -22,7 +22,7 @@ #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_image *image, +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, struct Elf32_Rel *rel, int rel_len) #else int @@ -83,7 +83,7 @@ write_8_check(addr_t P, Elf32_Word value) #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rela(struct preloaded_image *image, +boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, struct Elf32_Rela *rel, int rel_len) #else int diff --git a/src/system/kernel/arch/ppc/arch_elf.cpp b/src/system/kernel/arch/ppc/arch_elf.cpp index 2cd675a793..75f6728f5b 100644 --- a/src/system/kernel/arch/ppc/arch_elf.cpp +++ b/src/system/kernel/arch/ppc/arch_elf.cpp @@ -21,7 +21,7 @@ #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_image *image, +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, struct Elf32_Rel *rel, int rel_len) #else int @@ -115,7 +115,7 @@ ha(Elf32_Word value) #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rela(struct preloaded_image *image, +boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, struct Elf32_Rela *rel, int rel_len) #else int diff --git a/src/system/kernel/arch/x86/apm.cpp b/src/system/kernel/arch/x86/32/apm.cpp similarity index 100% rename from src/system/kernel/arch/x86/apm.cpp rename to src/system/kernel/arch/x86/32/apm.cpp diff --git a/src/system/kernel/arch/x86/arch_x86.S b/src/system/kernel/arch/x86/32/arch.S similarity index 80% rename from src/system/kernel/arch/x86/arch_x86.S rename to src/system/kernel/arch/x86/32/arch.S index 1ebcae0e82..97eb069a40 100644 --- a/src/system/kernel/arch/x86/arch_x86.S +++ b/src/system/kernel/arch/x86/32/arch.S @@ -19,98 +19,63 @@ .text -/*! \fn void arch_cpu_user_TLB_invalidate() - Invalidates the TLB. Must be called with interrupts disabled. -*/ -FUNCTION(arch_cpu_user_TLB_invalidate): - movl %cr3, %eax - movl %eax, %cr3 - ret -FUNCTION_END(arch_cpu_user_TLB_invalidate) - -/* void i386_fnsave(void *fpu_state); */ -FUNCTION(i386_fnsave): +/* void x86_fnsave(void *fpu_state); */ +FUNCTION(x86_fnsave): movl 4(%esp), %eax fnsave (%eax) ret -FUNCTION_END(i386_fnsave) +FUNCTION_END(x86_fnsave) -/* void i386_fxsave(void *fpu_state); */ -FUNCTION(i386_fxsave): +/* void x86_fxsave(void *fpu_state); */ +FUNCTION(x86_fxsave): movl 4(%esp), %eax fxsave (%eax) ret -FUNCTION_END(i386_fxsave) +FUNCTION_END(x86_fxsave) -/* void i386_frstor(const void *fpu_state); */ -FUNCTION(i386_frstor): +/* void x86_frstor(const void *fpu_state); */ +FUNCTION(x86_frstor): movl 4(%esp), %eax frstor (%eax) ret -FUNCTION_END(i386_frstor) +FUNCTION_END(x86_frstor) -/* void i386_fxrstor(const void *fpu_state); */ -FUNCTION(i386_fxrstor): +/* void x86_fxrstor(const void *fpu_state); */ +FUNCTION(x86_fxrstor): movl 4(%esp), %eax fxrstor (%eax) ret -FUNCTION_END(i386_fxrstor) +FUNCTION_END(x86_fxrstor) -/* void i386_noop_swap(void *old_fpu_state, const void *new_fpu_state); */ -FUNCTION(i386_noop_swap): +/* void x86_noop_swap(void *old_fpu_state, const void *new_fpu_state); */ +FUNCTION(x86_noop_swap): nop ret -FUNCTION_END(i386_noop_swap) +FUNCTION_END(x86_noop_swap) -/* void i386_fsave_swap(void *old_fpu_state, const void *new_fpu_state); */ -FUNCTION(i386_fnsave_swap): +/* void x86_fnsave_swap(void *old_fpu_state, const void *new_fpu_state); */ +FUNCTION(x86_fnsave_swap): movl 4(%esp),%eax fnsave (%eax) movl 8(%esp),%eax frstor (%eax) ret -FUNCTION_END(i386_fnsave_swap) +FUNCTION_END(x86_fnsave_swap) -/* void i386_fxsave_swap(void *old_fpu_state, const void *new_fpu_state); */ -FUNCTION(i386_fxsave_swap): +/* void x86_fxsave_swap(void *old_fpu_state, const void *new_fpu_state); */ +FUNCTION(x86_fxsave_swap): movl 4(%esp),%eax fxsave (%eax) movl 8(%esp),%eax fxrstor (%eax) ret -FUNCTION_END(i386_fxsave_swap) +FUNCTION_END(x86_fxsave_swap) -/* uint32 x86_read_ebp(); */ -FUNCTION(x86_read_ebp): +/* uint32 x86_get_stack_frame(); */ +FUNCTION(x86_get_stack_frame): movl %ebp, %eax ret -FUNCTION_END(x86_read_ebp) - -/* uint32 x86_read_cr0(); */ -FUNCTION(x86_read_cr0): - movl %cr0, %eax - ret -FUNCTION_END(x86_read_cr0) - -/* void x86_write_cr0(uint32 value); */ -FUNCTION(x86_write_cr0): - movl 4(%esp), %eax - movl %eax, %cr0 - ret -FUNCTION_END(x86_write_cr0) - -/* uint32 x86_read_cr4(); */ -FUNCTION(x86_read_cr4): - movl %cr4, %eax - ret -FUNCTION_END(x86_read_cr4) - -/* void x86_write_cr4(uint32 value); */ -FUNCTION(x86_write_cr4): - movl 4(%esp), %eax - movl %eax, %cr4 - ret -FUNCTION_END(x86_write_cr4) +FUNCTION_END(x86_get_stack_frame) /* uint64 x86_read_msr(uint32 register); */ FUNCTION(x86_read_msr): @@ -168,12 +133,12 @@ null_idt_descr: .word 0 .word 0,0 -FUNCTION(reboot): +FUNCTION(x86_reboot): lidt null_idt_descr int $0 done: jmp done -FUNCTION_END(reboot) +FUNCTION_END(x86_reboot) /* status_t arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */ diff --git a/src/system/kernel/arch/x86/bios.cpp b/src/system/kernel/arch/x86/32/bios.cpp similarity index 100% rename from src/system/kernel/arch/x86/bios.cpp rename to src/system/kernel/arch/x86/32/bios.cpp diff --git a/src/system/kernel/arch/x86/cpuid.S b/src/system/kernel/arch/x86/32/cpuid.S similarity index 100% rename from src/system/kernel/arch/x86/cpuid.S rename to src/system/kernel/arch/x86/32/cpuid.S diff --git a/src/system/kernel/arch/x86/32/descriptors.cpp b/src/system/kernel/arch/x86/32/descriptors.cpp new file mode 100644 index 0000000000..b5bde1d65c --- /dev/null +++ b/src/system/kernel/arch/x86/32/descriptors.cpp @@ -0,0 +1,593 @@ +/* + * Copyright 2008-2011, Michael Lotz, mmlr@mlotz.ch. + * Copyright 2010, Clemens Zeidler, haiku@clemens-zeidler.de. + * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "interrupts.h" + + +static interrupt_descriptor* sIDTs[B_MAX_CPU_COUNT]; + +// table with functions handling respective interrupts +typedef void interrupt_handler_function(struct iframe* frame); + +static const uint32 kInterruptHandlerTableSize = 256; +interrupt_handler_function* gInterruptHandlerTable[kInterruptHandlerTableSize]; + +segment_descriptor* gGDT; + + +/*! Initializes a descriptor in an IDT. +*/ +static void +set_gate(interrupt_descriptor *gate_addr, addr_t addr, int type, int dpl) +{ + unsigned int gate1; // first byte of gate desc + unsigned int gate2; // second byte of gate desc + + gate1 = (KERNEL_CODE_SEG << 16) | (0x0000ffff & addr); + gate2 = (0xffff0000 & addr) | 0x8000 | (dpl << 13) | (type << 8); + + gate_addr->a = gate1; + gate_addr->b = gate2; +} + + +/*! Initializes the descriptor for interrupt vector \a n in the IDT of the + specified CPU to an interrupt-gate descriptor with the given procedure + address. + For CPUs other than the boot CPU it must not be called before + arch_int_init_post_vm(). +*/ +static void +set_interrupt_gate(int32 cpu, int n, void (*addr)()) +{ + set_gate(&sIDTs[cpu][n], (addr_t)addr, 14, DPL_KERNEL); +} + + +/*! Initializes the descriptor for interrupt vector \a n in the IDT of the + specified CPU to an trap-gate descriptor with the given procedure address. + For CPUs other than the boot CPU it must not be called before + arch_int_init_post_vm(). +*/ +static void +set_trap_gate(int32 cpu, int n, void (*addr)()) +{ + set_gate(&sIDTs[cpu][n], (unsigned int)addr, 15, DPL_USER); +} + + +/*! Initializes the descriptor for interrupt vector \a n in the IDT of CPU + \a cpu to a task-gate descripter referring to the TSS segment identified + by TSS segment selector \a segment. + For CPUs other than the boot CPU it must not be called before + arch_int_init_post_vm() (arch_cpu_init_post_vm() is fine). +*/ +static void +set_task_gate(int32 cpu, int32 n, int32 segment) +{ + sIDTs[cpu][n].a = (segment << 16); + sIDTs[cpu][n].b = 0x8000 | (0 << 13) | (0x5 << 8); // present, dpl 0, type 5 +} + + +static void +load_tss(int cpu) +{ + short seg = (TSS_SEGMENT(cpu) << 3) | DPL_KERNEL; + asm("ltr %%ax" : : "a" (seg)); +} + + +// #pragma mark - Double fault handling + + +void +x86_double_fault_exception(struct iframe* frame) +{ + int cpu = x86_double_fault_get_cpu(); + + // The double fault iframe contains no useful information (as + // per Intel's architecture spec). Thus we simply save the + // information from the (unhandlable) exception which caused the + // double in our iframe. This will result even in useful stack + // traces. Only problem is that we trust that at least the + // TSS is still accessible. + struct tss *tss = &gCPU[cpu].arch.tss; + + frame->cs = tss->cs; + frame->es = tss->es; + frame->ds = tss->ds; + frame->fs = tss->fs; + frame->gs = tss->gs; + frame->ip = tss->eip; + frame->bp = tss->ebp; + frame->sp = tss->esp; + frame->ax = tss->eax; + frame->bx = tss->ebx; + frame->cx = tss->ecx; + frame->dx = tss->edx; + frame->si = tss->esi; + frame->di = tss->edi; + frame->flags = tss->eflags; + + // Use a special handler for page faults which avoids the triple fault + // pitfalls. + set_interrupt_gate(cpu, 14, &trap14_double_fault); + + debug_double_fault(cpu); +} + + +void +x86_page_fault_exception_double_fault(struct iframe* frame) +{ + addr_t cr2 = x86_read_cr2(); + + // Only if this CPU has a fault handler, we're allowed to be here. + cpu_ent& cpu = gCPU[x86_double_fault_get_cpu()]; + addr_t faultHandler = cpu.fault_handler; + if (faultHandler != 0) { + debug_set_page_fault_info(cr2, frame->ip, + (frame->error_code & 0x2) != 0 ? DEBUG_PAGE_FAULT_WRITE : 0); + frame->ip = faultHandler; + frame->bp = cpu.fault_handler_stack_pointer; + return; + } + + // No fault handler. This is bad. Since we originally came from a double + // fault, we don't try to reenter the kernel debugger. Instead we just + // print the info we've got and enter an infinite loop. + kprintf("Page fault in double fault debugger without fault handler! " + "Touching address %p from eip %p. Entering infinite loop...\n", + (void*)cr2, (void*)frame->ip); + + while (true); +} + + +static void +init_double_fault(int cpuNum) +{ + // set up the double fault TSS + struct tss* tss = &gCPU[cpuNum].arch.double_fault_tss; + + memset(tss, 0, sizeof(struct tss)); + size_t stackSize; + tss->sp0 = (addr_t)x86_get_double_fault_stack(cpuNum, &stackSize); + tss->sp0 += stackSize; + tss->ss0 = KERNEL_DATA_SEG; + tss->cr3 = x86_read_cr3(); + // copy the current cr3 to the double fault cr3 + tss->eip = (uint32)&double_fault; + tss->es = KERNEL_DATA_SEG; + tss->cs = KERNEL_CODE_SEG; + tss->ss = KERNEL_DATA_SEG; + tss->esp = tss->sp0; + tss->ds = KERNEL_DATA_SEG; + tss->fs = KERNEL_DATA_SEG; + tss->gs = KERNEL_DATA_SEG; + tss->ldt_seg_selector = 0; + tss->io_map_base = sizeof(struct tss); + + // add TSS descriptor for this new TSS + uint16 tssSegmentDescriptorIndex = DOUBLE_FAULT_TSS_BASE_SEGMENT + cpuNum; + set_tss_descriptor(&gGDT[tssSegmentDescriptorIndex], + (addr_t)tss, sizeof(struct tss)); + + set_task_gate(cpuNum, 8, tssSegmentDescriptorIndex << 3); +} + + +// #pragma mark - + + +void +x86_descriptors_init(kernel_args* args) +{ + uint32 i; + interrupt_handler_function** table; + + // Get the GDT and boot CPU IDT set up by the boot loader. + gGDT = (segment_descriptor*)args->arch_args.vir_gdt; + sIDTs[0] = (interrupt_descriptor *)(addr_t)args->arch_args.vir_idt; + + set_interrupt_gate(0, 0, &trap0); + set_interrupt_gate(0, 1, &trap1); + set_interrupt_gate(0, 2, &trap2); + set_trap_gate(0, 3, &trap3); + set_interrupt_gate(0, 4, &trap4); + set_interrupt_gate(0, 5, &trap5); + set_interrupt_gate(0, 6, &trap6); + set_interrupt_gate(0, 7, &trap7); + // trap8 (double fault) is set in init_double_fault(). + set_interrupt_gate(0, 9, &trap9); + set_interrupt_gate(0, 10, &trap10); + set_interrupt_gate(0, 11, &trap11); + set_interrupt_gate(0, 12, &trap12); + set_interrupt_gate(0, 13, &trap13); + set_interrupt_gate(0, 14, &trap14); +// set_interrupt_gate(0, 15, &trap15); + set_interrupt_gate(0, 16, &trap16); + set_interrupt_gate(0, 17, &trap17); + set_interrupt_gate(0, 18, &trap18); + set_interrupt_gate(0, 19, &trap19); + + // legacy or ioapic interrupts + set_interrupt_gate(0, 32, &trap32); + set_interrupt_gate(0, 33, &trap33); + set_interrupt_gate(0, 34, &trap34); + set_interrupt_gate(0, 35, &trap35); + set_interrupt_gate(0, 36, &trap36); + set_interrupt_gate(0, 37, &trap37); + set_interrupt_gate(0, 38, &trap38); + set_interrupt_gate(0, 39, &trap39); + set_interrupt_gate(0, 40, &trap40); + set_interrupt_gate(0, 41, &trap41); + set_interrupt_gate(0, 42, &trap42); + set_interrupt_gate(0, 43, &trap43); + set_interrupt_gate(0, 44, &trap44); + set_interrupt_gate(0, 45, &trap45); + set_interrupt_gate(0, 46, &trap46); + set_interrupt_gate(0, 47, &trap47); + + // additional ioapic interrupts + set_interrupt_gate(0, 48, &trap48); + set_interrupt_gate(0, 49, &trap49); + set_interrupt_gate(0, 50, &trap50); + set_interrupt_gate(0, 51, &trap51); + set_interrupt_gate(0, 52, &trap52); + set_interrupt_gate(0, 53, &trap53); + set_interrupt_gate(0, 54, &trap54); + set_interrupt_gate(0, 55, &trap55); + + // configurable msi or msi-x interrupts + set_interrupt_gate(0, 56, &trap56); + set_interrupt_gate(0, 57, &trap57); + set_interrupt_gate(0, 58, &trap58); + set_interrupt_gate(0, 59, &trap59); + set_interrupt_gate(0, 60, &trap60); + set_interrupt_gate(0, 61, &trap61); + set_interrupt_gate(0, 62, &trap62); + set_interrupt_gate(0, 63, &trap63); + set_interrupt_gate(0, 64, &trap64); + set_interrupt_gate(0, 65, &trap65); + set_interrupt_gate(0, 66, &trap66); + set_interrupt_gate(0, 67, &trap67); + set_interrupt_gate(0, 68, &trap68); + set_interrupt_gate(0, 69, &trap69); + set_interrupt_gate(0, 70, &trap70); + set_interrupt_gate(0, 71, &trap71); + set_interrupt_gate(0, 72, &trap72); + set_interrupt_gate(0, 73, &trap73); + set_interrupt_gate(0, 74, &trap74); + set_interrupt_gate(0, 75, &trap75); + set_interrupt_gate(0, 76, &trap76); + set_interrupt_gate(0, 77, &trap77); + set_interrupt_gate(0, 78, &trap78); + set_interrupt_gate(0, 79, &trap79); + set_interrupt_gate(0, 80, &trap80); + set_interrupt_gate(0, 81, &trap81); + set_interrupt_gate(0, 82, &trap82); + set_interrupt_gate(0, 83, &trap83); + set_interrupt_gate(0, 84, &trap84); + set_interrupt_gate(0, 85, &trap85); + set_interrupt_gate(0, 86, &trap86); + set_interrupt_gate(0, 87, &trap87); + set_interrupt_gate(0, 88, &trap88); + set_interrupt_gate(0, 89, &trap89); + set_interrupt_gate(0, 90, &trap90); + set_interrupt_gate(0, 91, &trap91); + set_interrupt_gate(0, 92, &trap92); + set_interrupt_gate(0, 93, &trap93); + set_interrupt_gate(0, 94, &trap94); + set_interrupt_gate(0, 95, &trap95); + set_interrupt_gate(0, 96, &trap96); + set_interrupt_gate(0, 97, &trap97); + + set_trap_gate(0, 98, &trap98); // for performance testing only + set_trap_gate(0, 99, &trap99); // syscall interrupt + + reserve_io_interrupt_vectors(2, 98); + + // configurable msi or msi-x interrupts + set_interrupt_gate(0, 100, &trap100); + set_interrupt_gate(0, 101, &trap101); + set_interrupt_gate(0, 102, &trap102); + set_interrupt_gate(0, 103, &trap103); + set_interrupt_gate(0, 104, &trap104); + set_interrupt_gate(0, 105, &trap105); + set_interrupt_gate(0, 106, &trap106); + set_interrupt_gate(0, 107, &trap107); + set_interrupt_gate(0, 108, &trap108); + set_interrupt_gate(0, 109, &trap109); + set_interrupt_gate(0, 110, &trap110); + set_interrupt_gate(0, 111, &trap111); + set_interrupt_gate(0, 112, &trap112); + set_interrupt_gate(0, 113, &trap113); + set_interrupt_gate(0, 114, &trap114); + set_interrupt_gate(0, 115, &trap115); + set_interrupt_gate(0, 116, &trap116); + set_interrupt_gate(0, 117, &trap117); + set_interrupt_gate(0, 118, &trap118); + set_interrupt_gate(0, 119, &trap119); + set_interrupt_gate(0, 120, &trap120); + set_interrupt_gate(0, 121, &trap121); + set_interrupt_gate(0, 122, &trap122); + set_interrupt_gate(0, 123, &trap123); + set_interrupt_gate(0, 124, &trap124); + set_interrupt_gate(0, 125, &trap125); + set_interrupt_gate(0, 126, &trap126); + set_interrupt_gate(0, 127, &trap127); + set_interrupt_gate(0, 128, &trap128); + set_interrupt_gate(0, 129, &trap129); + set_interrupt_gate(0, 130, &trap130); + set_interrupt_gate(0, 131, &trap131); + set_interrupt_gate(0, 132, &trap132); + set_interrupt_gate(0, 133, &trap133); + set_interrupt_gate(0, 134, &trap134); + set_interrupt_gate(0, 135, &trap135); + set_interrupt_gate(0, 136, &trap136); + set_interrupt_gate(0, 137, &trap137); + set_interrupt_gate(0, 138, &trap138); + set_interrupt_gate(0, 139, &trap139); + set_interrupt_gate(0, 140, &trap140); + set_interrupt_gate(0, 141, &trap141); + set_interrupt_gate(0, 142, &trap142); + set_interrupt_gate(0, 143, &trap143); + set_interrupt_gate(0, 144, &trap144); + set_interrupt_gate(0, 145, &trap145); + set_interrupt_gate(0, 146, &trap146); + set_interrupt_gate(0, 147, &trap147); + set_interrupt_gate(0, 148, &trap148); + set_interrupt_gate(0, 149, &trap149); + set_interrupt_gate(0, 150, &trap150); + set_interrupt_gate(0, 151, &trap151); + set_interrupt_gate(0, 152, &trap152); + set_interrupt_gate(0, 153, &trap153); + set_interrupt_gate(0, 154, &trap154); + set_interrupt_gate(0, 155, &trap155); + set_interrupt_gate(0, 156, &trap156); + set_interrupt_gate(0, 157, &trap157); + set_interrupt_gate(0, 158, &trap158); + set_interrupt_gate(0, 159, &trap159); + set_interrupt_gate(0, 160, &trap160); + set_interrupt_gate(0, 161, &trap161); + set_interrupt_gate(0, 162, &trap162); + set_interrupt_gate(0, 163, &trap163); + set_interrupt_gate(0, 164, &trap164); + set_interrupt_gate(0, 165, &trap165); + set_interrupt_gate(0, 166, &trap166); + set_interrupt_gate(0, 167, &trap167); + set_interrupt_gate(0, 168, &trap168); + set_interrupt_gate(0, 169, &trap169); + set_interrupt_gate(0, 170, &trap170); + set_interrupt_gate(0, 171, &trap171); + set_interrupt_gate(0, 172, &trap172); + set_interrupt_gate(0, 173, &trap173); + set_interrupt_gate(0, 174, &trap174); + set_interrupt_gate(0, 175, &trap175); + set_interrupt_gate(0, 176, &trap176); + set_interrupt_gate(0, 177, &trap177); + set_interrupt_gate(0, 178, &trap178); + set_interrupt_gate(0, 179, &trap179); + set_interrupt_gate(0, 180, &trap180); + set_interrupt_gate(0, 181, &trap181); + set_interrupt_gate(0, 182, &trap182); + set_interrupt_gate(0, 183, &trap183); + set_interrupt_gate(0, 184, &trap184); + set_interrupt_gate(0, 185, &trap185); + set_interrupt_gate(0, 186, &trap186); + set_interrupt_gate(0, 187, &trap187); + set_interrupt_gate(0, 188, &trap188); + set_interrupt_gate(0, 189, &trap189); + set_interrupt_gate(0, 190, &trap190); + set_interrupt_gate(0, 191, &trap191); + set_interrupt_gate(0, 192, &trap192); + set_interrupt_gate(0, 193, &trap193); + set_interrupt_gate(0, 194, &trap194); + set_interrupt_gate(0, 195, &trap195); + set_interrupt_gate(0, 196, &trap196); + set_interrupt_gate(0, 197, &trap197); + set_interrupt_gate(0, 198, &trap198); + set_interrupt_gate(0, 199, &trap199); + set_interrupt_gate(0, 200, &trap200); + set_interrupt_gate(0, 201, &trap201); + set_interrupt_gate(0, 202, &trap202); + set_interrupt_gate(0, 203, &trap203); + set_interrupt_gate(0, 204, &trap204); + set_interrupt_gate(0, 205, &trap205); + set_interrupt_gate(0, 206, &trap206); + set_interrupt_gate(0, 207, &trap207); + set_interrupt_gate(0, 208, &trap208); + set_interrupt_gate(0, 209, &trap209); + set_interrupt_gate(0, 210, &trap210); + set_interrupt_gate(0, 211, &trap211); + set_interrupt_gate(0, 212, &trap212); + set_interrupt_gate(0, 213, &trap213); + set_interrupt_gate(0, 214, &trap214); + set_interrupt_gate(0, 215, &trap215); + set_interrupt_gate(0, 216, &trap216); + set_interrupt_gate(0, 217, &trap217); + set_interrupt_gate(0, 218, &trap218); + set_interrupt_gate(0, 219, &trap219); + set_interrupt_gate(0, 220, &trap220); + set_interrupt_gate(0, 221, &trap221); + set_interrupt_gate(0, 222, &trap222); + set_interrupt_gate(0, 223, &trap223); + set_interrupt_gate(0, 224, &trap224); + set_interrupt_gate(0, 225, &trap225); + set_interrupt_gate(0, 226, &trap226); + set_interrupt_gate(0, 227, &trap227); + set_interrupt_gate(0, 228, &trap228); + set_interrupt_gate(0, 229, &trap229); + set_interrupt_gate(0, 230, &trap230); + set_interrupt_gate(0, 231, &trap231); + set_interrupt_gate(0, 232, &trap232); + set_interrupt_gate(0, 233, &trap233); + set_interrupt_gate(0, 234, &trap234); + set_interrupt_gate(0, 235, &trap235); + set_interrupt_gate(0, 236, &trap236); + set_interrupt_gate(0, 237, &trap237); + set_interrupt_gate(0, 238, &trap238); + set_interrupt_gate(0, 239, &trap239); + set_interrupt_gate(0, 240, &trap240); + set_interrupt_gate(0, 241, &trap241); + set_interrupt_gate(0, 242, &trap242); + set_interrupt_gate(0, 243, &trap243); + set_interrupt_gate(0, 244, &trap244); + set_interrupt_gate(0, 245, &trap245); + set_interrupt_gate(0, 246, &trap246); + set_interrupt_gate(0, 247, &trap247); + set_interrupt_gate(0, 248, &trap248); + set_interrupt_gate(0, 249, &trap249); + set_interrupt_gate(0, 250, &trap250); + + // smp / apic local interrupts + set_interrupt_gate(0, 251, &trap251); + set_interrupt_gate(0, 252, &trap252); + set_interrupt_gate(0, 253, &trap253); + set_interrupt_gate(0, 254, &trap254); + set_interrupt_gate(0, 255, &trap255); + + // init interrupt handler table + table = gInterruptHandlerTable; + + // defaults + for (i = 0; i < ARCH_INTERRUPT_BASE; i++) + table[i] = x86_invalid_exception; + for (i = ARCH_INTERRUPT_BASE; i < kInterruptHandlerTableSize; i++) + table[i] = x86_hardware_interrupt; + + table[0] = x86_unexpected_exception; // Divide Error Exception (#DE) + table[1] = x86_handle_debug_exception; // Debug Exception (#DB) + table[2] = x86_fatal_exception; // NMI Interrupt + table[3] = x86_handle_breakpoint_exception; // Breakpoint Exception (#BP) + table[4] = x86_unexpected_exception; // Overflow Exception (#OF) + table[5] = x86_unexpected_exception; // BOUND Range Exceeded Exception (#BR) + table[6] = x86_unexpected_exception; // Invalid Opcode Exception (#UD) + table[7] = x86_fatal_exception; // Device Not Available Exception (#NM) + table[8] = x86_double_fault_exception; // Double Fault Exception (#DF) + table[9] = x86_fatal_exception; // Coprocessor Segment Overrun + table[10] = x86_fatal_exception; // Invalid TSS Exception (#TS) + table[11] = x86_fatal_exception; // Segment Not Present (#NP) + table[12] = x86_fatal_exception; // Stack Fault Exception (#SS) + table[13] = x86_unexpected_exception; // General Protection Exception (#GP) + table[14] = x86_page_fault_exception; // Page-Fault Exception (#PF) + table[16] = x86_unexpected_exception; // x87 FPU Floating-Point Error (#MF) + table[17] = x86_unexpected_exception; // Alignment Check Exception (#AC) + table[18] = x86_fatal_exception; // Machine-Check Exception (#MC) + table[19] = x86_unexpected_exception; // SIMD Floating-Point Exception (#XF) +} + + +void +x86_descriptors_init_percpu(kernel_args* args, int cpu) +{ + // load the TSS for this cpu + // note the main cpu gets initialized in x86_descriptors_init_post_vm() + if (cpu != 0) { + load_tss(cpu); + + // set the IDT + struct { + uint16 limit; + void* address; + } _PACKED descriptor = { + 256 * 8 - 1, // 256 descriptors, 8 bytes each (-1 for "limit") + sIDTs[cpu] + }; + + asm volatile("lidt %0" : : "m"(descriptor)); + } +} + + +status_t +x86_descriptors_init_post_vm(kernel_args* args) +{ + uint32 i; + + // account for the segment descriptors + create_area("gdt", (void **)&gGDT, B_EXACT_ADDRESS, B_PAGE_SIZE, + B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + + // create IDT area for the boot CPU + area_id area = create_area("idt", (void**)&sIDTs[0], B_EXACT_ADDRESS, + B_PAGE_SIZE, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + if (area < B_OK) + return area; + + // create IDTs for the off-boot CPU + size_t idtSize = 256 * 8; + // 256 8 bytes-sized descriptors + if (args->num_cpus > 0) { + size_t areaSize = ROUNDUP(args->num_cpus * idtSize, B_PAGE_SIZE); + interrupt_descriptor* idt; + virtual_address_restrictions virtualRestrictions = {}; + virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; + physical_address_restrictions physicalRestrictions = {}; + area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, + &virtualRestrictions, &physicalRestrictions, (void**)&idt); + if (area < 0) + return area; + + for (i = 1; i < args->num_cpus; i++) { + sIDTs[i] = idt; + memcpy(idt, sIDTs[0], idtSize); + idt += 256; + // The CPU's IDTR will be set in arch_cpu_init_percpu(). + } + } + + // setup task-state segments + for (i = 0; i < args->num_cpus; i++) { + // initialize the regular and double fault tss stored in the per-cpu + // structure + memset(&gCPU[i].arch.tss, 0, sizeof(struct tss)); + gCPU[i].arch.tss.ss0 = KERNEL_DATA_SEG; + gCPU[i].arch.tss.io_map_base = sizeof(struct tss); + + // add TSS descriptor for this new TSS + set_tss_descriptor(&gGDT[TSS_SEGMENT(i)], (addr_t)&gCPU[i].arch.tss, + sizeof(struct tss)); + + // initialize the double fault tss + init_double_fault(i); + } + + // set the current hardware task on cpu 0 + load_tss(0); + + // setup TLS descriptors (one for every CPU) + + for (i = 0; i < args->num_cpus; i++) { + set_segment_descriptor(&gGDT[TLS_BASE_SEGMENT + i], 0, TLS_SIZE, + DT_DATA_WRITEABLE, DPL_USER); + } + + return B_OK; +} diff --git a/src/system/kernel/arch/x86/arch_interrupts.S b/src/system/kernel/arch/x86/32/interrupts.S similarity index 88% rename from src/system/kernel/arch/x86/arch_interrupts.S rename to src/system/kernel/arch/x86/32/interrupts.S index aa4dfe16ac..5fde6b901e 100644 --- a/src/system/kernel/arch/x86/arch_interrupts.S +++ b/src/system/kernel/arch/x86/32/interrupts.S @@ -138,7 +138,7 @@ subl $80, %esp; \ \ /* get the address of the syscall parameters */ \ - movl IFRAME_user_esp(%ebp), %esi; \ + movl IFRAME_user_sp(%ebp), %esi; \ addl $4, %esi; \ cmp $KERNEL_BASE, %esi; /* must not be a kernel address */ \ jae bad_syscall_params; \ @@ -516,8 +516,6 @@ STATIC_FUNCTION(int_bottom): // exception. orl $0x10000, IFRAME_flags(%ebp); - testl $0x20000, IFRAME_flags(%ebp) // VM86 mode - jnz int_bottom_vm86 cmp $USER_CODE_SEG, IFRAME_cs(%ebp) // user mode je int_bottom_user @@ -583,36 +581,6 @@ STATIC_FUNCTION(int_bottom_user): FUNCTION_END(int_bottom_user) -STATIC_FUNCTION(int_bottom_vm86): - movl $KERNEL_DATA_SEG,%eax - cld - movl %eax,%ds - movl %eax,%es - - // update the thread's user time - movl %dr3, %edi // thread pointer - cli - UPDATE_THREAD_USER_TIME() - - // leave interrupts disabled -- the handler will enable them, if - // necessary - - pushl %ebp - movl IFRAME_vector(%ebp), %eax - call *gInterruptHandlerTable(, %eax, 4) - - cli // disable interrupts - - // update the thread's kernel time and return - UPDATE_THREAD_KERNEL_TIME() - - // the above will reset the in_kernel flag to 0, but we actually stay - movb $1, THREAD_in_kernel(%edi); - - POP_IFRAME_AND_RETURN() -FUNCTION_END(int_bottom_vm86) - - // test interrupt handler for performance measurements .align 16 FUNCTION(trap98): @@ -673,8 +641,8 @@ STATIC_FUNCTION(handle_syscall): // overwrite the values of %eax and %edx on the stack (the syscall return // value) - movl %edx, IFRAME_edx(%ebp) - movl %eax, IFRAME_eax(%ebp) + movl %edx, IFRAME_dx(%ebp) + movl %eax, IFRAME_ax(%ebp) TRACE_POST_SYSCALL() @@ -725,8 +693,8 @@ FUNCTION_END(handle_syscall) jz 1f pushl -8(%ebp) // syscall start time pushl -12(%ebp) - movl IFRAME_edx(%ebp), %edx // syscall return value - movl IFRAME_eax(%ebp), %eax + movl IFRAME_dx(%ebp), %edx // syscall return value + movl IFRAME_ax(%ebp), %eax push %edx push %eax lea 16(%esp), %eax // syscall parameters @@ -856,80 +824,3 @@ FUNCTION(x86_return_to_userland): UPDATE_THREAD_KERNEL_TIME() POP_IFRAME_AND_RETURN() FUNCTION_END(x86_return_to_userland) - - -/* status_t x86_vm86_enter(struct vm86_iframe *frame) */ -FUNCTION(x86_vm86_enter): - // save critical registers - pushf - pushl %edi - pushl %esi - pushl %ebp - pushl %ebx - push %gs - push %fs - - // get pointers - movl 32(%esp), %esi // vm86 iframe - pushl %esi // ... store iframe addr for x86_vm86_return - movl %dr3, %edi // Thread* - - // make sure eflags are in right shape - movl VM86_IFRAME_flags(%esi), %eax - andl $0x200CD5, %eax // leave ID,OF,DF,SF,ZF,AF,PF,CF flags - orl $0x20202, %eax // set VM and IF flags (+10b) - movl %eax, VM86_IFRAME_flags(%esi) - - // update kernel_stack_top and tss.esp0 - pushl THREAD_kernel_stack_top(%edi) - movl %esp, THREAD_kernel_stack_top(%edi) - pushl %esp - call i386_set_tss_and_kstack - - // go to vm86 mode - cli - UPDATE_THREAD_KERNEL_TIME() - lea 20(%esi), %esp - popa - addl $16, %esp - iret -FUNCTION_END(x86_vm86_enter) - - -/* void x86_vm86_return(struct vm86_iframe *frame, status_t retval) */ -FUNCTION(x86_vm86_return): - // set stack to where x86_vm86_enter was left - movl 8(%esp), %ebx - movl 4(%esp), %esi - cli - movl %esi, %esp - addl $VM86_IFRAME_sizeof, %esp - - // save old iframe - popl %eax // old kernel stack top - popl %edi - movl $(VM86_IFRAME_sizeof >> 2), %ecx - cld - rep movsl - - // adjust kernel_stack_top and tss.esp0 - movl %dr3, %edi - movl %eax, THREAD_kernel_stack_top(%edi) - pushl %eax - call i386_set_tss_and_kstack - addl $4, %esp - - // restore registers - movl %ebx, %eax - - // we skip %fs, as this contains the CPU dependent TLS segment - addl $4, %esp; - - pop %gs - popl %ebx - popl %ebp - popl %esi - popl %edi - popf - ret -FUNCTION_END(x86_vm86_return) diff --git a/src/system/kernel/arch/x86/interrupts.h b/src/system/kernel/arch/x86/32/interrupts.h similarity index 96% rename from src/system/kernel/arch/x86/interrupts.h rename to src/system/kernel/arch/x86/32/interrupts.h index f81f1c6101..fc1efb0d1c 100644 --- a/src/system/kernel/arch/x86/interrupts.h +++ b/src/system/kernel/arch/x86/32/interrupts.h @@ -13,6 +13,10 @@ extern "C" { #endif + +struct iframe; + + void trap0();void trap1();void trap2();void trap3();void trap4();void trap5(); void trap6();void trap7();void trap9();void trap10();void trap11(); void trap12();void trap13();void trap14();void trap16();void trap17(); @@ -73,6 +77,10 @@ void trap250(); void trap251();void trap252();void trap253();void trap254();void trap255(); +void x86_double_fault_exception(struct iframe* frame); +void x86_page_fault_exception_double_fault(struct iframe* frame); + + #ifdef __cplusplus } #endif diff --git a/src/system/kernel/arch/x86/x86_signals.cpp b/src/system/kernel/arch/x86/32/signals.cpp similarity index 100% rename from src/system/kernel/arch/x86/x86_signals.cpp rename to src/system/kernel/arch/x86/32/signals.cpp diff --git a/src/system/kernel/arch/x86/x86_signals_asm.S b/src/system/kernel/arch/x86/32/signals_asm.S similarity index 100% rename from src/system/kernel/arch/x86/x86_signals_asm.S rename to src/system/kernel/arch/x86/32/signals_asm.S diff --git a/src/system/kernel/arch/x86/x86_syscalls.cpp b/src/system/kernel/arch/x86/32/syscalls.cpp similarity index 84% rename from src/system/kernel/arch/x86/x86_syscalls.cpp rename to src/system/kernel/arch/x86/32/syscalls.cpp index bd14bb0faf..f0c9b7c1a0 100644 --- a/src/system/kernel/arch/x86/x86_syscalls.cpp +++ b/src/system/kernel/arch/x86/32/syscalls.cpp @@ -18,10 +18,10 @@ // user syscall assembly stubs -extern "C" void _user_syscall_int(void); -extern unsigned int _user_syscall_int_end; -extern "C" void _user_syscall_sysenter(void); -extern unsigned int _user_syscall_sysenter_end; +extern "C" void x86_user_syscall_int(void); +extern unsigned int x86_user_syscall_int_end; +extern "C" void x86_user_syscall_sysenter(void); +extern unsigned int x86_user_syscall_sysenter_end; // sysenter handler extern "C" void x86_sysenter(); @@ -76,10 +76,10 @@ init_amd_syscall_registers(void* dummy, int cpuNum) void -x86_initialize_commpage_syscall(void) +x86_initialize_syscall(void) { - void* syscallCode = (void *)&_user_syscall_int; - void* syscallCodeEnd = &_user_syscall_int_end; + void* syscallCode = (void *)&x86_user_syscall_int; + void* syscallCodeEnd = &x86_user_syscall_int_end; // check syscall if (all_cpus_have_feature(FEATURE_COMMON, IA32_FEATURE_SEP) @@ -89,8 +89,8 @@ x86_initialize_commpage_syscall(void) dprintf("initialize_commpage_syscall(): sysenter/sysexit supported\n"); // the code to be used in userland - syscallCode = (void *)&_user_syscall_sysenter; - syscallCodeEnd = &_user_syscall_sysenter_end; + syscallCode = (void *)&x86_user_syscall_sysenter; + syscallCodeEnd = &x86_user_syscall_sysenter_end; // tell all CPUs to init their sysenter/sysexit related registers call_all_cpus_sync(&init_intel_syscall_registers, NULL); diff --git a/src/system/kernel/arch/x86/syscall.S b/src/system/kernel/arch/x86/32/syscalls_asm.S similarity index 68% rename from src/system/kernel/arch/x86/syscall.S rename to src/system/kernel/arch/x86/32/syscalls_asm.S index b4400caa3e..ef8b1e50c7 100644 --- a/src/system/kernel/arch/x86/syscall.S +++ b/src/system/kernel/arch/x86/32/syscalls_asm.S @@ -11,21 +11,21 @@ /* user space half of the syscall mechanism, to be copied into the commpage */ // int 99 fallback -FUNCTION(_user_syscall_int): +FUNCTION(x86_user_syscall_int): int $99 ret -FUNCTION_END(_user_syscall_int) -SYMBOL(_user_syscall_int_end): +FUNCTION_END(x86_user_syscall_int) +SYMBOL(x86_user_syscall_int_end): // Intel sysenter/sysexit -FUNCTION(_user_syscall_sysenter): +FUNCTION(x86_user_syscall_sysenter): // sysexit forces us to trash edx (-> eip) and ecx (-> esp), but they are // scratch registers anyway. We use ecx right away to store esp. movl %esp, %ecx sysenter ret -FUNCTION_END(_user_syscall_sysenter) -SYMBOL(_user_syscall_sysenter_end): +FUNCTION_END(x86_user_syscall_sysenter) +SYMBOL(x86_user_syscall_sysenter_end): diff --git a/src/system/kernel/arch/x86/32/thread.cpp b/src/system/kernel/arch/x86/32/thread.cpp new file mode 100644 index 0000000000..5878aacced --- /dev/null +++ b/src/system/kernel/arch/x86/32/thread.cpp @@ -0,0 +1,390 @@ +/* + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "paging/X86PagingStructures.h" +#include "paging/X86VMTranslationMap.h" +#include "x86_signals.h" + + +//#define TRACE_ARCH_THREAD +#ifdef TRACE_ARCH_THREAD +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +#ifdef SYSCALL_TRACING + +namespace SyscallTracing { + +class RestartSyscall : public AbstractTraceEntry { + public: + RestartSyscall() + { + Initialized(); + } + + virtual void AddDump(TraceOutput& out) + { + out.Print("syscall restart"); + } +}; + +} + +# define TSYSCALL(x) new(std::nothrow) SyscallTracing::x + +#else +# define TSYSCALL(x) +#endif // SYSCALL_TRACING + + +// from arch_cpu.cpp +extern bool gHasSSE; +extern segment_descriptor* gGDT; + +static struct arch_thread sInitialState _ALIGNED(16); + // the fpu_state must be aligned on a 16 byte boundary, so that fxsave can use it + + +static inline void +set_fs_register(uint32 segment) +{ + asm("movl %0,%%fs" :: "r" (segment)); +} + + +void +x86_restart_syscall(struct iframe* frame) +{ + Thread* thread = thread_get_current_thread(); + + atomic_and(&thread->flags, ~THREAD_FLAGS_RESTART_SYSCALL); + atomic_or(&thread->flags, THREAD_FLAGS_SYSCALL_RESTARTED); + + frame->ax = frame->orig_eax; + frame->dx = frame->orig_edx; + frame->ip -= 2; + // undoes the "int $99"/"sysenter"/"syscall" instruction + // (so that it'll be executed again) + + TSYSCALL(RestartSyscall()); +} + + +void +x86_set_tls_context(Thread *thread) +{ + int entry = smp_get_current_cpu() + TLS_BASE_SEGMENT; + + set_segment_descriptor_base(&gGDT[entry], thread->user_local_storage); + set_fs_register((entry << 3) | DPL_USER); +} + + +static uint8* +get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action) +{ + // use the alternate signal stack if we should and can + if (thread->signal_stack_enabled + && (action->sa_flags & SA_ONSTACK) != 0 + && (frame->user_sp < thread->signal_stack_base + || frame->user_sp >= thread->signal_stack_base + + thread->signal_stack_size)) { + return (uint8*)(thread->signal_stack_base + thread->signal_stack_size); + } + + return (uint8*)frame->user_sp; +} + + +// #pragma mark - + + +status_t +arch_thread_init(struct kernel_args *args) +{ + // save one global valid FPU state; it will be copied in the arch dependent + // part of each new thread + + asm volatile ("clts; fninit; fnclex;"); + if (gHasSSE) + x86_fxsave(sInitialState.fpu_state); + else + x86_fnsave(sInitialState.fpu_state); + + return B_OK; +} + + +status_t +arch_thread_init_thread_struct(Thread *thread) +{ + // set up an initial state (stack & fpu) + memcpy(&thread->arch_info, &sInitialState, sizeof(struct arch_thread)); + return B_OK; +} + + +/*! Prepares the given thread's kernel stack for executing its entry function. + + \param thread The thread. + \param stack The usable bottom of the thread's kernel stack. + \param stackTop The usable top of the thread's kernel stack. + \param function The entry function the thread shall execute. + \param data Pointer to be passed to the entry function. +*/ +void +arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop, + void (*function)(void*), const void* data) +{ + addr_t* stackTop = (addr_t*)_stackTop; + + TRACE(("arch_thread_init_kthread_stack: stack top %p, function %p, data: " + "%p\n", stackTop, function, data)); + + // push the function argument, a pointer to the data + *--stackTop = (addr_t)data; + + // push a dummy return address for the function + *--stackTop = 0; + + // push the function address -- that's the return address used after the + // context switch + *--stackTop = (addr_t)function; + + // simulate pushad as done by x86_context_switch() + for (int i = 0; i < 8; i++) + *--stackTop = 0; + + // save the stack position + thread->arch_info.current_stack.esp = stackTop; + thread->arch_info.current_stack.ss = (addr_t*)KERNEL_DATA_SEG; +} + + +void +arch_thread_dump_info(void *info) +{ + struct arch_thread *at = (struct arch_thread *)info; + + kprintf("\tesp: %p\n", at->current_stack.esp); + kprintf("\tss: %p\n", at->current_stack.ss); + kprintf("\tfpu_state at %p\n", at->fpu_state); +} + + +/*! Sets up initial thread context and enters user space +*/ +status_t +arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, + void* args2) +{ + addr_t stackTop = thread->user_stack_base + thread->user_stack_size; + uint32 codeSize = (addr_t)x86_end_userspace_thread_exit + - (addr_t)x86_userspace_thread_exit; + uint32 args[3]; + + TRACE(("arch_thread_enter_userspace: entry 0x%lx, args %p %p, " + "ustack_top 0x%lx\n", entry, args1, args2, stackTop)); + + // copy the little stub that calls exit_thread() when the thread entry + // function returns, as well as the arguments of the entry function + stackTop -= codeSize; + + if (user_memcpy((void *)stackTop, (const void *)&x86_userspace_thread_exit, codeSize) < B_OK) + return B_BAD_ADDRESS; + + args[0] = stackTop; + args[1] = (uint32)args1; + args[2] = (uint32)args2; + stackTop -= sizeof(args); + + if (user_memcpy((void *)stackTop, args, sizeof(args)) < B_OK) + return B_BAD_ADDRESS; + + // prepare the user iframe + iframe frame = {}; + frame.type = IFRAME_TYPE_SYSCALL; + frame.gs = USER_DATA_SEG; + // frame.fs not used, we call x86_set_tls_context() on context switch + frame.es = USER_DATA_SEG; + frame.ds = USER_DATA_SEG; + frame.ip = entry; + frame.cs = USER_CODE_SEG; + frame.flags = X86_EFLAGS_RESERVED1 | X86_EFLAGS_INTERRUPT + | (3 << X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT); + frame.user_sp = stackTop; + frame.user_ss = USER_DATA_SEG; + + // return to userland + x86_initial_return_to_userland(thread, &frame); + + return B_OK; + // never gets here +} + + +/*! Sets up the user iframe for invoking a signal handler. + + The function fills in the remaining fields of the given \a signalFrameData, + copies it to the thread's userland stack (the one on which the signal shall + be handled), and sets up the user iframe so that when returning to userland + a wrapper function is executed that calls the user-defined signal handler. + When the signal handler returns, the wrapper function shall call the + "restore signal frame" syscall with the (possibly modified) signal frame + data. + + The following fields of the \a signalFrameData structure still need to be + filled in: + - \c context.uc_stack: The stack currently used by the thread. + - \c context.uc_mcontext: The current userland state of the registers. + - \c syscall_restart_return_value: Architecture specific use. On x86 the + value of eax and edx which are overwritten by the syscall return value. + + Furthermore the function needs to set \c thread->user_signal_context to the + userland pointer to the \c ucontext_t on the user stack. + + \param thread The current thread. + \param action The signal action specified for the signal to be handled. + \param signalFrameData A partially initialized structure of all the data + that need to be copied to userland. + \return \c B_OK on success, another error code, if something goes wrong. +*/ +status_t +arch_setup_signal_frame(Thread* thread, struct sigaction* action, + struct signal_frame_data* signalFrameData) +{ + struct iframe *frame = x86_get_current_iframe(); + if (!IFRAME_IS_USER(frame)) { + panic("arch_setup_signal_frame(): No user iframe!"); + return B_BAD_VALUE; + } + + // In case of a BeOS compatible handler map SIGBUS to SIGSEGV, since they + // had the same signal number. + if ((action->sa_flags & SA_BEOS_COMPATIBLE_HANDLER) != 0 + && signalFrameData->info.si_signo == SIGBUS) { + signalFrameData->info.si_signo = SIGSEGV; + } + + // store the register state in signalFrameData->context.uc_mcontext + signalFrameData->context.uc_mcontext.eip = frame->ip; + signalFrameData->context.uc_mcontext.eflags = frame->flags; + signalFrameData->context.uc_mcontext.eax = frame->ax; + signalFrameData->context.uc_mcontext.ecx = frame->cx; + signalFrameData->context.uc_mcontext.edx = frame->dx; + signalFrameData->context.uc_mcontext.ebp = frame->bp; + signalFrameData->context.uc_mcontext.esp = frame->user_sp; + signalFrameData->context.uc_mcontext.edi = frame->di; + signalFrameData->context.uc_mcontext.esi = frame->si; + signalFrameData->context.uc_mcontext.ebx = frame->bx; + x86_fnsave((void *)(&signalFrameData->context.uc_mcontext.xregs)); + + // Fill in signalFrameData->context.uc_stack + signal_get_user_stack(frame->user_sp, &signalFrameData->context.uc_stack); + + // store orig_eax/orig_edx in syscall_restart_return_value + signalFrameData->syscall_restart_return_value + = (uint64)frame->orig_edx << 32 | frame->orig_eax; + + // get the stack to use -- that's either the current one or a special signal + // stack + uint8* userStack = get_signal_stack(thread, frame, action); + + // copy the signal frame data onto the stack + userStack -= sizeof(*signalFrameData); + signal_frame_data* userSignalFrameData = (signal_frame_data*)userStack; + if (user_memcpy(userSignalFrameData, signalFrameData, + sizeof(*signalFrameData)) != B_OK) { + return B_BAD_ADDRESS; + } + + // prepare the user stack frame for a function call to the signal handler + // wrapper function + uint32 stackFrame[2] = { + frame->ip, // return address + (addr_t)userSignalFrameData, // parameter: pointer to signal frame data + }; + + userStack -= sizeof(stackFrame); + if (user_memcpy(userStack, stackFrame, sizeof(stackFrame)) != B_OK) + return B_BAD_ADDRESS; + + // Update Thread::user_signal_context, now that everything seems to have + // gone fine. + thread->user_signal_context = &userSignalFrameData->context; + + // Adjust the iframe's esp and eip, so that the thread will continue with + // the prepared stack, executing the signal handler wrapper function. + frame->user_sp = (addr_t)userStack; + frame->ip = x86_get_user_signal_handler_wrapper( + (action->sa_flags & SA_BEOS_COMPATIBLE_HANDLER) != 0); + + return B_OK; +} + + +int64 +arch_restore_signal_frame(struct signal_frame_data* signalFrameData) +{ + struct iframe* frame = x86_get_current_iframe(); + + TRACE(("### arch_restore_signal_frame: entry\n")); + + frame->orig_eax = (uint32)signalFrameData->syscall_restart_return_value; + frame->orig_edx + = (uint32)(signalFrameData->syscall_restart_return_value >> 32); + + frame->ip = signalFrameData->context.uc_mcontext.eip; + frame->flags = (frame->flags & ~(uint32)X86_EFLAGS_USER_FLAGS) + | (signalFrameData->context.uc_mcontext.eflags & X86_EFLAGS_USER_FLAGS); + frame->ax = signalFrameData->context.uc_mcontext.eax; + frame->cx = signalFrameData->context.uc_mcontext.ecx; + frame->dx = signalFrameData->context.uc_mcontext.edx; + frame->bp = signalFrameData->context.uc_mcontext.ebp; + frame->user_sp = signalFrameData->context.uc_mcontext.esp; + frame->di = signalFrameData->context.uc_mcontext.edi; + frame->si = signalFrameData->context.uc_mcontext.esi; + frame->bx = signalFrameData->context.uc_mcontext.ebx; + + x86_frstor((void*)(&signalFrameData->context.uc_mcontext.xregs)); + + TRACE(("### arch_restore_signal_frame: exit\n")); + + return (int64)frame->ax | ((int64)frame->dx << 32); +} + + +void +arch_syscall_64_bit_return_value(void) +{ + Thread* thread = thread_get_current_thread(); + atomic_or(&thread->flags, THREAD_FLAGS_64_BIT_SYSCALL_RETURN); +} diff --git a/src/system/kernel/arch/x86/64/arch.S b/src/system/kernel/arch/x86/64/arch.S new file mode 100644 index 0000000000..cbaeec86cd --- /dev/null +++ b/src/system/kernel/arch/x86/64/arch.S @@ -0,0 +1,321 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Copyright 2002, Michael Noisternig. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include + +#include "asm_offsets.h" +#include "syscall_numbers.h" + + +.text + + +/* void x86_fxsave(void* fpuState); */ +FUNCTION(x86_fxsave): + fxsave (%rdi) + ret +FUNCTION_END(x86_fxsave) + + +/* void x86_fxrstor(const void* fpuState); */ +FUNCTION(x86_fxrstor): + fxrstor (%rdi) + ret +FUNCTION_END(x86_fxrstor) + + +/* void x86_noop_swap(void *oldFpuState, const void *newFpuState); */ +FUNCTION(x86_noop_swap): + nop + ret +FUNCTION_END(x86_noop_swap) + + +/* void x86_fxsave_swap(void* oldFpuState, const void* newFpuState); */ +FUNCTION(x86_fxsave_swap): + fxsave (%rdi) + fxrstor (%rsi) + ret +FUNCTION_END(x86_fxsave_swap) + + +/* addr_t x86_get_stack_frame(); */ +FUNCTION(x86_get_stack_frame): + mov %rbp, %rax + ret +FUNCTION_END(x86_get_stack_frame) + + +/* uint64 x86_read_msr(uint32 register); */ +FUNCTION(x86_read_msr): + mov %edi, %ecx + rdmsr + shl $32, %rdx + mov %eax, %eax + or %rdx, %rax + ret +FUNCTION_END(x86_read_msr) + + +/* void x86_write_msr(uint32 register, uint64 value); */ +FUNCTION(x86_write_msr): + mov %rsi, %rdx + mov %esi, %eax + mov %edi, %ecx + shr $32, %rdx + wrmsr + ret +FUNCTION_END(x86_write_msr) + + +/* void x86_64_thread_entry(); */ +FUNCTION(x86_64_thread_entry): + movq %r15, %rdi + jmp *%r14 +FUNCTION_END(x86_64_thread_entry) + + +/* void x86_context_switch(struct arch_thread* oldState, + struct arch_thread* newState); */ +FUNCTION(x86_context_switch): + // Just need to save callee-save registers: RBP, RBX, R12-15. + push %r15 + push %r14 + push %r13 + push %r12 + push %rbp + push %rbx + + // Swap the stack pointers. + movq %rsp, ARCH_THREAD_current_stack(%rdi) + movq ARCH_THREAD_current_stack(%rsi), %rsp + + // Restore callee-save registers. + pop %rbx + pop %rbp + pop %r12 + pop %r13 + pop %r14 + pop %r15 + + ret +FUNCTION_END(x86_context_switch) + + +/* void x86_swap_pgdir(uint64 newPageDir); */ +FUNCTION(x86_swap_pgdir): + movq %rdi, %cr3 + ret +FUNCTION_END(x86_swap_pgdir) + + +/* thread exit stub - copied to the userspace stack in arch_thread_enter_uspace() */ +.align 8 +FUNCTION(x86_userspace_thread_exit): + movq %rax, %rdi + movq $SYSCALL_EXIT_THREAD, %rax + syscall +.align 8 +FUNCTION_END(x86_userspace_thread_exit) +SYMBOL(x86_end_userspace_thread_exit): + + +null_idt_descr: + .word 0 + .quad 0 + +FUNCTION(x86_reboot): + lidt null_idt_descr + int $0 +done: + jmp done +FUNCTION_END(x86_reboot) + + +/* status_t arch_cpu_user_memcpy(void* to, const void* from, size_t size, + addr_t* faultHandler) */ +FUNCTION(arch_cpu_user_memcpy): + // faultHandler -> r8, size -> rcx. + movq %rcx, %r8 + movq %rdx, %rcx + + // Set the fault handler, preserve old in rax. + movq (%r8), %rax + movq $.L_user_memcpy_error, (%r8) + + // Move by quadwords. + cld + movq %rcx, %r9 + shrq $3, %rcx + rep + movsq + + // Move any remaining data by bytes. + movq %r9, %rcx + andq $7, %rcx + rep + movsb + + // Restore the old fault handler and return. + movq %rax, (%r8) + xorl %eax, %eax + ret + +.L_user_memcpy_error: + // Restore the old fault handler. Return a generic error, the wrapper + // routine will deal with it. + movq %rax, (%r8) + movl $-1, %eax + ret +FUNCTION_END(arch_cpu_user_memcpy) + + +/* status_t arch_cpu_user_memset(void* to, char c, size_t count, + addr_t* faultHandler) */ +FUNCTION(arch_cpu_user_memset): + // c -> al, faultHandler -> r8, size -> rcx. + movw %si, %ax + movq %rcx, %r8 + movq %rdx, %rcx + + // Set the fault handler, preserve old in rdx. + movq (%r8), %rdx + movq $.L_user_memset_error, (%r8) + + rep + stosb + + // Restore the old fault handler and return. + movq %rdx, (%r8) + xorl %eax, %eax + ret + +.L_user_memset_error: + // Restore the old fault handler. Return a generic error, the wrapper + // routine will deal with it. + movq %rdx, (%r8) + movl $-1, %eax + ret +FUNCTION_END(arch_cpu_user_memset) + + +/* ssize_t arch_cpu_user_strlcpy(void* to, const void* from, size_t size, + addr_t* faultHandler) */ +FUNCTION(arch_cpu_user_strlcpy): + // faultHandler -> r8, size -> rcx, source -> r9 (original value needed to + // calculate return value). + movq %rcx, %r8 + movq %rdx, %rcx + movq %rsi, %r9 + + // Set the fault handler, preserve old in rax. + movq (%r8), %rax + movq $.L_user_strlcpy_error, (%r8) + + // Check for 0 length. + cmp $0, %rcx + je .L_user_strlcpy_source_count + + // Copy at most count - 1 bytes. + dec %rcx + + // If count is now 0, skip straight to null terminating as our loop will + // otherwise overflow. + jnz .L_user_strlcpy_copy_begin + movb $0, (%rdi) + jmp .L_user_strlcpy_source_count + +.L_user_strlcpy_copy_begin: + cld +.L_user_strlcpy_copy_loop: + // Move data by bytes. + lodsb + stosb + test %al, %al + jz .L_user_strlcpy_source_done + loop .L_user_strlcpy_copy_loop + + // Null terminate string. + movb $0, (%rdi) + dec %rsi + +.L_user_strlcpy_source_count: + // Count remaining bytes in src + not %rcx + xor %al, %al + repnz + scasb + +.L_user_strlcpy_source_done: + // Restore the old fault handler + movq %rax, (%r8) + + // Calculate total string length and return. + movq %rsi, %rax + subq %r9, %rax + dec %rax + ret + +.L_user_strlcpy_error: + // Restore the old fault handler. Return a generic error, the wrapper + // routine will deal with it. + movq %rax, (%r8) + movq $-1, %rax + ret +FUNCTION_END(arch_cpu_user_strlcpy) + + +/*! \fn void arch_debug_call_with_fault_handler(cpu_ent* cpu, + jmp_buf jumpBuffer, void (*function)(void*), void* parameter) + + Called by debug_call_with_fault_handler() to do the dirty work of setting + the fault handler and calling the function. If the function causes a page + fault, the arch_debug_call_with_fault_handler() calls longjmp() with the + given \a jumpBuffer. Otherwise it returns normally. + + debug_call_with_fault_handler() has already saved the CPU's fault_handler + and fault_handler_stack_pointer and will reset them later, so + arch_debug_call_with_fault_handler() doesn't need to care about it. + + \param cpu The \c cpu_ent for the current CPU. + \param jumpBuffer Buffer to be used for longjmp(). + \param function The function to be called. + \param parameter The parameter to be passed to the function to be called. +*/ +FUNCTION(arch_debug_call_with_fault_handler): + push %rbp + movq %rsp, %rbp + + // Preserve the jump buffer address for the fault return. + push %rsi + + // Set fault handler address, and fault handler stack pointer address. We + // don't need to save the previous values, since that's done by the caller. + movq $.L_debug_call_fault_handler, CPU_ENT_fault_handler(%rdi) + movq %rbp, CPU_ENT_fault_handler_stack_pointer(%rdi) + + // Call the function. + movq %rcx, %rdi + call *%rdx + + // Regular return. + movq %rbp, %rsp + pop %rbp + ret + +.L_debug_call_fault_handler: + // Fault -- return via longjmp(jumpBuffer, 1) + movq %rbp, %rsp + movq -8(%rsp), %rdi + movq $1, %rsi + call longjmp +FUNCTION_END(arch_debug_call_with_fault_handler) diff --git a/src/system/kernel/arch/x86/64/cpuid.S b/src/system/kernel/arch/x86/64/cpuid.S new file mode 100644 index 0000000000..8e6b07cd6b --- /dev/null +++ b/src/system/kernel/arch/x86/64/cpuid.S @@ -0,0 +1,45 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + + +.text + + +/* status_t get_current_cpuid(cpuid_info* info, uint32 eaxRegister) */ +FUNCTION(get_current_cpuid): + push %rbx + movl %esi, %eax + cpuid + movl %eax, 0(%rdi) + movl %ebx, 4(%rdi) + movl %edx, 8(%rdi) + movl %ecx, 12(%rdi) + xorl %eax, %eax + // B_OK + pop %rbx + ret +FUNCTION_END(get_current_cpuid) + + +/* uint32 get_eflags(void) */ +FUNCTION(get_eflags): + // The top 32 bits of RFLAGS are reserved, we can ignore them. + pushf + pop %rax + mov %eax, %eax + ret +FUNCTION_END(get_eflags) + + +/* void set_eflags(uint32 val) */ +FUNCTION(set_eflags): + mov %edi, %edi + push %rdi + popf + ret +FUNCTION_END(set_eflags) diff --git a/src/system/kernel/arch/x86/64/descriptors.cpp b/src/system/kernel/arch/x86/64/descriptors.cpp new file mode 100644 index 0000000000..955f96c1e4 --- /dev/null +++ b/src/system/kernel/arch/x86/64/descriptors.cpp @@ -0,0 +1,172 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include +#include +#include +#include + +#include +#include + + +typedef void interrupt_handler_function(iframe* frame); + + +static segment_descriptor* sGDT; +static interrupt_descriptor* sIDT; + +static const uint32 kInterruptHandlerTableSize = 256; +interrupt_handler_function* gInterruptHandlerTable[kInterruptHandlerTableSize]; + +extern uint8 isr_array[kInterruptHandlerTableSize][16]; + + +static void +load_tss(int cpu) +{ + uint16 seg = (TSS_SEGMENT(cpu) << 3) | DPL_KERNEL; + asm volatile("ltr %%ax" :: "a" (seg)); +} + + +// #pragma mark - Exception handlers + + +static void +x86_64_general_protection_fault(iframe* frame) +{ + if (debug_debugger_running()) { + // Handle GPFs if there is a debugger fault handler installed, for + // non-canonical address accesses. + cpu_ent* cpu = &gCPU[smp_get_current_cpu()]; + if (cpu->fault_handler != 0) { + debug_set_page_fault_info(0, frame->ip, DEBUG_PAGE_FAULT_NO_INFO); + frame->ip = cpu->fault_handler; + frame->bp = cpu->fault_handler_stack_pointer; + return; + } + } + + x86_unexpected_exception(frame); +} + + +// #pragma mark - + + +void +x86_descriptors_init(kernel_args* args) +{ + // The boot loader sets up a GDT and allocates an empty IDT for us. + sGDT = (segment_descriptor*)args->arch_args.vir_gdt; + sIDT = (interrupt_descriptor*)args->arch_args.vir_idt; + + // Fill out the IDT, pointing each entry to the corresponding entry in the + // ISR array created in arch_interrupts.S (see there to see how this works). + for(uint32 i = 0; i < kInterruptHandlerTableSize; i++) { + // x86_64 removes task gates, therefore we cannot use a separate TSS + // for the double fault exception. However, instead it adds a new stack + // switching mechanism, the IST. The IST is a table of stack addresses + // in the TSS. If the IST field of an interrupt descriptor is non-zero, + // the CPU will switch to the stack specified by that IST entry when + // handling that interrupt. So, we use IST entry 1 to store the double + // fault stack address (set up in x86_descriptors_init_post_vm()). + uint32 ist = (i == 8) ? 1 : 0; + + // Breakpoint exception can be raised from userland. + uint32 dpl = (i == 3) ? DPL_USER : DPL_KERNEL; + + set_interrupt_descriptor(&sIDT[i], (addr_t)&isr_array[i], + GATE_INTERRUPT, KERNEL_CODE_SEG, dpl, ist); + } + + // Initialize the interrupt handler table. + interrupt_handler_function** table = gInterruptHandlerTable; + for (uint32 i = 0; i < ARCH_INTERRUPT_BASE; i++) + table[i] = x86_invalid_exception; + for (uint32 i = ARCH_INTERRUPT_BASE; i < kInterruptHandlerTableSize; i++) + table[i] = x86_hardware_interrupt; + + table[0] = x86_unexpected_exception; // Divide Error Exception (#DE) + table[1] = x86_handle_debug_exception; // Debug Exception (#DB) + table[2] = x86_fatal_exception; // NMI Interrupt + table[3] = x86_handle_breakpoint_exception; // Breakpoint Exception (#BP) + table[4] = x86_unexpected_exception; // Overflow Exception (#OF) + table[5] = x86_unexpected_exception; // BOUND Range Exceeded Exception (#BR) + table[6] = x86_unexpected_exception; // Invalid Opcode Exception (#UD) + table[7] = x86_fatal_exception; // Device Not Available Exception (#NM) + table[8] = x86_fatal_exception; // Double Fault Exception (#DF) + table[9] = x86_fatal_exception; // Coprocessor Segment Overrun + table[10] = x86_fatal_exception; // Invalid TSS Exception (#TS) + table[11] = x86_fatal_exception; // Segment Not Present (#NP) + table[12] = x86_fatal_exception; // Stack Fault Exception (#SS) + table[13] = x86_64_general_protection_fault; // General Protection Exception (#GP) + table[14] = x86_page_fault_exception; // Page-Fault Exception (#PF) + table[16] = x86_unexpected_exception; // x87 FPU Floating-Point Error (#MF) + table[17] = x86_unexpected_exception; // Alignment Check Exception (#AC) + table[18] = x86_fatal_exception; // Machine-Check Exception (#MC) + table[19] = x86_unexpected_exception; // SIMD Floating-Point Exception (#XF) +} + + +void +x86_descriptors_init_percpu(kernel_args* args, int cpu) +{ + // Load the IDT. + gdt_idt_descr idtr = { + 256 * sizeof(interrupt_descriptor) - 1, + (addr_t)sIDT + }; + asm volatile("lidt %0" :: "m" (idtr)); + + // Load the TSS for non-boot CPUs (boot CPU gets done below). + if (cpu != 0) { + load_tss(cpu); + } +} + + +status_t +x86_descriptors_init_post_vm(kernel_args* args) +{ + area_id area; + + // Create an area for the GDT. + area = create_area("gdt", (void**)&sGDT, B_EXACT_ADDRESS, B_PAGE_SIZE, + B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + if (area < B_OK) + return area; + + // Same for the IDT. + area = create_area("idt", (void**)&sIDT, B_EXACT_ADDRESS, B_PAGE_SIZE, + B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + if (area < B_OK) + return area; + + for (uint32 i = 0; i < args->num_cpus; i++) { + // Set up the task state segment. + memset(&gCPU[i].arch.tss, 0, sizeof(struct tss)); + gCPU[i].arch.tss.io_map_base = sizeof(struct tss); + + // Set up the descriptor for this TSS. + set_tss_descriptor(&sGDT[TSS_SEGMENT(i)], (addr_t)&gCPU[i].arch.tss, + sizeof(struct tss)); + + // Set up the double fault IST entry (see x86_descriptors_init()). + struct tss* tss = &gCPU[i].arch.tss; + size_t stackSize; + tss->ist1 = (addr_t)x86_get_double_fault_stack(i, &stackSize); + tss->ist1 += stackSize; + } + + // Load the TSS for the boot CPU. + load_tss(0); + + return B_OK; +} diff --git a/src/system/kernel/arch/x86/64/interrupts.S b/src/system/kernel/arch/x86/64/interrupts.S new file mode 100644 index 0000000000..b5157e1344 --- /dev/null +++ b/src/system/kernel/arch/x86/64/interrupts.S @@ -0,0 +1,547 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include +#include +#include + +#include "asm_offsets.h" +#include "syscall_numbers.h" +#include "syscall_table.h" + + +// Push the remainder of the interrupt frame onto the stack. +#define PUSH_IFRAME_BOTTOM(iframeType) \ + push %rax; /* orig_rax */ \ + push %rax; \ + push %rbx; \ + push %rcx; \ + push %rdx; \ + push %rdi; \ + push %rsi; \ + push %rbp; \ + push %r8; \ + push %r9; \ + push %r10; \ + push %r11; \ + push %r12; \ + push %r13; \ + push %r14; \ + push %r15; \ + push $iframeType; + +// Restore the interrupt frame. +#define RESTORE_IFRAME() \ + add $8, %rsp; \ + pop %r15; \ + pop %r14; \ + pop %r13; \ + pop %r12; \ + pop %r11; \ + pop %r10; \ + pop %r9; \ + pop %r8; \ + pop %rbp; \ + pop %rsi; \ + pop %rdi; \ + pop %rdx; \ + pop %rcx; \ + pop %rbx; \ + pop %rax; \ + addq $24, %rsp; + + +// The macros below require R12 to contain the current thread pointer. R12 is +// callee-save so will be preserved through all function calls and only needs +// to be obtained once. R13 is used to store the system call start time, will +// also be preserved. + +#define LOCK_THREAD_TIME() \ + leaq THREAD_time_lock(%r12), %rdi; \ + call acquire_spinlock; + +#define UNLOCK_THREAD_TIME() \ + leaq THREAD_time_lock(%r12), %rdi; \ + call release_spinlock; \ + +#define UPDATE_THREAD_USER_TIME() \ + LOCK_THREAD_TIME() \ + \ + call system_time; \ + \ + /* Preserve system_time for post syscall debug */ \ + movq %rax, %r13; \ + \ + /* thread->user_time += now - thread->last_time; */ \ + subq THREAD_last_time(%r12), %rax; \ + addq %rax, THREAD_user_time(%r12); \ + \ + /* thread->last_time = now; */ \ + movq %r13, THREAD_last_time(%r12); \ + \ + /* thread->in_kernel = true; */ \ + movb $1, THREAD_in_kernel(%r12); \ + \ + UNLOCK_THREAD_TIME() + +#define UPDATE_THREAD_KERNEL_TIME() \ + LOCK_THREAD_TIME() \ + \ + call system_time; \ + movq %rax, %r13; \ + \ + /* thread->kernel_time += now - thread->last_time; */ \ + subq THREAD_last_time(%r12), %rax; \ + addq %rax, THREAD_kernel_time(%r12); \ + \ + /* thread->last_time = now; */ \ + movq %r13, THREAD_last_time(%r12); \ + \ + /* thread->in_kernel = false; */ \ + movb $0, THREAD_in_kernel(%r12); \ + \ + UNLOCK_THREAD_TIME() + +#define STOP_USER_DEBUGGING() \ + testl $(THREAD_FLAGS_BREAKPOINTS_INSTALLED \ + | THREAD_FLAGS_SINGLE_STEP), THREAD_flags(%r12); \ + jz 1f; \ + call x86_exit_user_debug_at_kernel_entry; \ + 1: + + +// The following code defines the interrupt service routines for all 256 +// interrupts. It creates a block of handlers, each 16 bytes, that the IDT +// initialization code just loops through. + +// Interrupt with no error code, pushes a 0 error code. +#define DEFINE_ISR(nr) \ + .align 16; \ + push $0; \ + push $nr; \ + jmp int_bottom; + +// Interrupt with an error code. +#define DEFINE_ISR_E(nr) \ + .align 16; \ + push $nr; \ + jmp int_bottom; + +// Array of interrupt service routines. +.align 16 +SYMBOL(isr_array): + // Exceptions (0-19) and reserved interrupts (20-31). + DEFINE_ISR(0) + DEFINE_ISR(1) + DEFINE_ISR(2) + DEFINE_ISR(3) + DEFINE_ISR(4) + DEFINE_ISR(5) + DEFINE_ISR(6) + DEFINE_ISR(7) + DEFINE_ISR_E(8) + DEFINE_ISR(9) + DEFINE_ISR_E(10) + DEFINE_ISR_E(11) + DEFINE_ISR_E(12) + DEFINE_ISR_E(13) + DEFINE_ISR_E(14) + DEFINE_ISR(15) + DEFINE_ISR(16) + DEFINE_ISR_E(17) + DEFINE_ISR(18) + DEFINE_ISR(19) + DEFINE_ISR(20) + DEFINE_ISR(21) + DEFINE_ISR(22) + DEFINE_ISR(23) + DEFINE_ISR(24) + DEFINE_ISR(25) + DEFINE_ISR(26) + DEFINE_ISR(27) + DEFINE_ISR(28) + DEFINE_ISR(29) + DEFINE_ISR(30) + DEFINE_ISR(31) + + // User-defined ISRs (32-255) - none take an error code. + .Lintr = 32 + .rept 224 + DEFINE_ISR(.Lintr) + .Lintr = .Lintr+1 + .endr + + +// Common interrupt handling code. +STATIC_FUNCTION(int_bottom): + // Coming from user-mode requires special handling. + testl $3, 24(%rsp) + jnz int_bottom_user + + // Push the rest of the interrupt frame to the stack. + PUSH_IFRAME_BOTTOM(IFRAME_TYPE_OTHER) + + cld + + // Frame pointer is the iframe. + movq %rsp, %rbp + + // Set the RF (resume flag) in RFLAGS. This prevents an instruction + // breakpoint on the instruction we're returning to to trigger a debug + // exception. + orq $X86_EFLAGS_RESUME, IFRAME_flags(%rbp) + + // Call the interrupt handler. + movq %rsp, %rdi + movq IFRAME_vector(%rsp), %rax + call *gInterruptHandlerTable(, %rax, 8) + + // Restore the saved registers. + RESTORE_IFRAME() + + iretq +FUNCTION_END(int_bottom) + + +// Handler for an interrupt that occurred in user-mode. +STATIC_FUNCTION(int_bottom_user): + // Load the kerrnel GS segment base. + swapgs + + // Push the rest of the interrupt frame to the stack. + PUSH_IFRAME_BOTTOM(IFRAME_TYPE_OTHER) + + cld + + // Frame pointer is the iframe. + movq %rsp, %rbp + + // Set the RF (resume flag) in RFLAGS. This prevents an instruction + // breakpoint on the instruction we're returning to to trigger a debug + // exception. + orq $X86_EFLAGS_RESUME, IFRAME_flags(%rbp) + + // Get thread pointer. + movq %gs:0, %r12 + + STOP_USER_DEBUGGING() + UPDATE_THREAD_USER_TIME() + + // Call the interrupt handler. + movq %rsp, %rdi + movq IFRAME_vector(%rsp), %rax + call *gInterruptHandlerTable(, %rax, 8) + + // If there are no signals pending or we're not debugging, we can avoid + // most of the work here, just need to update the kernel time. + testl $(THREAD_FLAGS_DEBUGGER_INSTALLED | THREAD_FLAGS_SIGNALS_PENDING \ + | THREAD_FLAGS_DEBUG_THREAD | THREAD_FLAGS_BREAKPOINTS_DEFINED) \ + , THREAD_flags(%r12) + jnz .Lkernel_exit_work + + cli + + UPDATE_THREAD_KERNEL_TIME() + + // Restore the saved registers. + RESTORE_IFRAME() + + // Restore the previous GS base and return. + swapgs + iretq + +.Lkernel_exit_work: + // Slow path for return to userland. + + // Do we need to handle signals? + testl $(THREAD_FLAGS_SIGNALS_PENDING | THREAD_FLAGS_DEBUG_THREAD) \ + , THREAD_flags(%r12) + jnz .Lkernel_exit_handle_signals + cli + call thread_at_kernel_exit_no_signals + +.Lkernel_exit_work_done: + // Install breakpoints, if defined. + testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12) + jz 1f + movq %rbp, %rdi + call x86_init_user_debug_at_kernel_exit +1: + // Restore the saved registers. + RESTORE_IFRAME() + + // Restore the previous GS base and return. + swapgs + iretq + +.Lkernel_exit_handle_signals: + // thread_at_kernel_exit requires interrupts to be enabled, it will disable + // them after. + sti + call thread_at_kernel_exit + jmp .Lkernel_exit_work_done +FUNCTION_END(int_bottom_user) + + +// SYSCALL entry point. +FUNCTION(x86_64_syscall_entry): + // Upon entry, RSP still points at the user stack. Load the kernel GS + // segment base address, which points at the current thread's arch_thread + // structure. This contains our kernel stack pointer and a temporary + // scratch space to store the user stack pointer in before we can push it + // to the stack. + swapgs + movq %rsp, %gs:ARCH_THREAD_user_rsp + movq %gs:ARCH_THREAD_syscall_rsp, %rsp + + // Set up an iframe on the stack (R11 = saved RFLAGS, RCX = saved RIP). + push $USER_DATA_SEG // ss + push %gs:ARCH_THREAD_user_rsp // rsp + push %r11 // flags + push $USER_CODE_SEG // cs + push %rcx // ip + push $0 // error_code + push $0 // vector + PUSH_IFRAME_BOTTOM(IFRAME_TYPE_SYSCALL) + + cld + + // Frame pointer is the iframe. + movq %rsp, %rbp + + // Preserve call number (R14 is callee-save), get thread pointer. + movq %rax, %r14 + movq %gs:0, %r12 + + STOP_USER_DEBUGGING() + UPDATE_THREAD_USER_TIME() + + // No longer need interrupts disabled. + sti + + // Check whether the syscall number is valid. + cmpq $SYSCALL_COUNT, %r14 + jae .Lsyscall_return + + // Get the system call table entry. Note I'm hardcoding the shift because + // sizeof(syscall_info) is 16 and scale factors of 16 aren't supported, + // so can't just do leaq kSyscallInfos(, %rax, SYSCALL_INFO_sizeof). + movq %r14, %rax + shlq $4, %rax + leaq kSyscallInfos(, %rax, 1), %rax + + // Check the number of call arguments, greater than 6 (6 * 8 = 48) requires + // a stack copy. + movq SYSCALL_INFO_parameter_size(%rax), %rcx + cmpq $48, %rcx + ja .Lsyscall_stack_args + +.Lperform_syscall: + testl $THREAD_FLAGS_DEBUGGER_INSTALLED, THREAD_flags(%r12) + jnz .Lpre_syscall_debug + +.Lpre_syscall_debug_done: + // Restore the arguments from the iframe. UPDATE_THREAD_USER_TIME() makes + // 2 function calls which means they may have been overwritten. Note that + // argument 4 is in R10 on the frame rather than RCX as RCX is used by + // SYSCALL. + movq IFRAME_di(%rbp), %rdi + movq IFRAME_si(%rbp), %rsi + movq IFRAME_dx(%rbp), %rdx + movq IFRAME_r10(%rbp), %rcx + movq IFRAME_r8(%rbp), %r8 + movq IFRAME_r9(%rbp), %r9 + + // TODO: pre-syscall tracing + + // Call the function and save its return value. + call *SYSCALL_INFO_function(%rax) + movq %rax, IFRAME_ax(%rbp) + + // TODO: post-syscall tracing + + // Restore the original stack pointer and return. + movq %rbp, %rsp + +.Lsyscall_return: + // Clear the restarted flag. + testl $THREAD_FLAGS_SYSCALL_RESTARTED, THREAD_flags(%r12) + jz 2f +1: + movl THREAD_flags(%r12), %eax + movl %eax, %edx + andl $~THREAD_FLAGS_SYSCALL_RESTARTED, %edx + lock + cmpxchgl %edx, THREAD_flags(%r12) + jnz 1b +2: + testl $(THREAD_FLAGS_DEBUGGER_INSTALLED | THREAD_FLAGS_SIGNALS_PENDING \ + | THREAD_FLAGS_DEBUG_THREAD | THREAD_FLAGS_BREAKPOINTS_DEFINED \ + | THREAD_FLAGS_RESTART_SYSCALL) \ + , THREAD_flags(%r12) + jnz .Lpost_syscall_work + + cli + + UPDATE_THREAD_KERNEL_TIME() + + // If we've just restored a signal frame, use the IRET path. + cmpq $SYSCALL_RESTORE_SIGNAL_FRAME, %r14 + je .Liret + + // Restore the iframe and RCX/R11 for SYSRET. + RESTORE_IFRAME() + pop %rcx + addq $8, %rsp + pop %r11 + pop %rsp + + // Restore previous GS base and return. + swapgs + sysretq + +.Lpre_syscall_debug: + // user_debug_pre_syscall expects a pointer to a block of arguments, need + // to push the register arguments onto the stack. + push IFRAME_r9(%rbp) + push IFRAME_r8(%rbp) + push IFRAME_r10(%rbp) + push IFRAME_dx(%rbp) + push IFRAME_si(%rbp) + push IFRAME_di(%rbp) + movq %r14, %rdi // syscall number + movq %rsp, %rsi + push %rax + call user_debug_pre_syscall + pop %rax + addq $48, %rsp + jmp .Lpre_syscall_debug_done + +.Lpost_syscall_work: + testl $THREAD_FLAGS_DEBUGGER_INSTALLED, THREAD_flags(%r12) + jz 1f + + // Post-syscall debugging. Same as above, need a block of arguments. + push IFRAME_r9(%rbp) + push IFRAME_r8(%rbp) + push IFRAME_r10(%rbp) + push IFRAME_dx(%rbp) + push IFRAME_si(%rbp) + push IFRAME_di(%rbp) + movq %r14, %rdi // syscall number + movq %rsp, %rsi + movq IFRAME_ax(%rbp), %rdx // return value + movq %r13, %rcx // start time, preserved earlier + call user_debug_post_syscall + addq $48, %rsp +1: + // Do we need to handle signals? + testl $(THREAD_FLAGS_SIGNALS_PENDING | THREAD_FLAGS_DEBUG_THREAD) \ + , THREAD_flags(%r12) + jnz .Lpost_syscall_handle_signals + cli + call thread_at_kernel_exit_no_signals + +.Lpost_syscall_work_done: + // Handle syscall restarting. + testl $THREAD_FLAGS_RESTART_SYSCALL, THREAD_flags(%r12) + jz 1f + movq %rsp, %rdi + call x86_restart_syscall +1: + // Install breakpoints, if defined. + testl $THREAD_FLAGS_BREAKPOINTS_DEFINED, THREAD_flags(%r12) + jz .Liret + movq %rbp, %rdi + call x86_init_user_debug_at_kernel_exit + + // On this return path it is possible that the frame has been modified, + // for example to execute a signal handler. In this case it is safer to + // return via IRET. + +.Liret: + // Restore the saved registers. + RESTORE_IFRAME() + + // Restore the previous GS base and return. + swapgs + iretq + +.Lpost_syscall_handle_signals: + call thread_at_kernel_exit + jmp .Lpost_syscall_work_done + +.Lsyscall_stack_args: + // Some arguments are on the stack, work out what we need to copy. 6 + // arguments (48 bytes) are already in registers. + // RAX = syscall table entry address, RCX = argument size. + subq $48, %rcx + + // Get the address to copy from. + movq IFRAME_user_sp(%rbp), %rsi + addq $8, %rsi + movabs $(USER_BASE + USER_SIZE), %rdx + cmp %rdx, %rsi + jae .Lbad_syscall_args + + // Make space on the stack. + subq %rcx, %rsp + movq %rsp, %rdi + + // Set a fault handler. + movq $.Lbad_syscall_args, THREAD_fault_handler(%r12) + + // Copy them by quadwords. + shrq $3, %rcx + rep + movsq + movq $0, THREAD_fault_handler(%r12) + + // Perform the call. + jmp .Lperform_syscall + +.Lbad_syscall_args: + movq $0, THREAD_fault_handler(%r12) + movq %rbp, %rsp + jmp .Lsyscall_return +FUNCTION_END(x86_64_syscall_entry) + + +/*! \fn void x86_return_to_userland(iframe* frame) + \brief Returns to the userland environment given by \a frame. + + Before returning to userland all potentially necessary kernel exit work is + done. + + \a frame must point to a location somewhere on the caller's stack (e.g. a + local variable). + The function must be called with interrupts disabled. + + \param frame The iframe defining the userland environment. +*/ +FUNCTION(x86_return_to_userland): + movq %rdi, %rbp + movq %rbp, %rsp + + // Perform kernel exit work. + movq %gs:0, %r12 + testl $(THREAD_FLAGS_DEBUGGER_INSTALLED | THREAD_FLAGS_SIGNALS_PENDING \ + | THREAD_FLAGS_DEBUG_THREAD | THREAD_FLAGS_BREAKPOINTS_DEFINED) \ + , THREAD_flags(%r12) + jnz .Lkernel_exit_work + + // update the thread's kernel time and return + UPDATE_THREAD_KERNEL_TIME() + + // Restore the frame and return. + RESTORE_IFRAME() + swapgs + iretq +FUNCTION_END(x86_return_to_userland) diff --git a/src/system/kernel/arch/x86/64/signals.cpp b/src/system/kernel/arch/x86/64/signals.cpp new file mode 100644 index 0000000000..947e76fbb7 --- /dev/null +++ b/src/system/kernel/arch/x86/64/signals.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include "x86_signals.h" + +#include + +#include + +#include +#include +#include +#include + + +extern "C" void x86_64_user_signal_handler(void); +extern int x86_64_user_signal_handler_end; + + +void +x86_initialize_commpage_signal_handler() +{ + void* handlerCode = (void*)&x86_64_user_signal_handler; + void* handlerCodeEnd = &x86_64_user_signal_handler_end; + + // Copy the signal handler code to the commpage. + size_t len = (size_t)((addr_t)handlerCodeEnd - (addr_t)handlerCode); + fill_commpage_entry(COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, handlerCode, len); + + // Add symbol to the commpage image. + image_id image = get_commpage_image(); + elf_add_memory_image_symbol(image, "commpage_signal_handler", + ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER], + len, B_SYMBOL_TYPE_TEXT); +} + diff --git a/src/system/kernel/arch/x86/64/signals_asm.S b/src/system/kernel/arch/x86/64/signals_asm.S new file mode 100644 index 0000000000..5d85022707 --- /dev/null +++ b/src/system/kernel/arch/x86/64/signals_asm.S @@ -0,0 +1,56 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include "asm_offsets.h" +#include "syscall_numbers.h" + + +.text + + +// Userspace signal handler wrapper, copied to the commpage. +FUNCTION(x86_64_user_signal_handler): + push %rbp + movq %rsp, %rbp + + // RDI points to the signal_frame_data structure, however we'll overwrite + // that with the function arguments, so move it somewhere else. We can use + // callee-save registers here without preserving them because the old value + // will be restored when the frame is restored. + movq %rdi, %r12 + + // Check the handler type. + cmpb $0, SIGNAL_FRAME_DATA_siginfo_handler(%r12) + jne .Lsiginfo_handler + +.Lsimple_handler: + // Fetch other arguments (user data, vregs). + movq SIGNAL_FRAME_DATA_user_data(%r12), %rsi + leaq SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%r12), %rdx + +.Lcall_handler: + // Get the handler address and the signal number first argument. + movq SIGNAL_FRAME_DATA_handler(%r12), %rax + movl SIGNAL_FRAME_DATA_info + SIGINFO_T_si_signo(%r12), %edi + + // Call the handler. + callq *%rax + + // Perform the restore_signal_frame() syscall, should not return. + movq $SYSCALL_RESTORE_SIGNAL_FRAME, %rax + movq %r12, %rdi + syscall + +.Lsiginfo_handler: + // Fetch other arguments (info pointer, context, user data). + leaq SIGNAL_FRAME_DATA_info(%r12), %rsi + leaq SIGNAL_FRAME_DATA_context(%r12), %rdx + movq SIGNAL_FRAME_DATA_user_data(%r12), %rcx + jmp .Lcall_handler +FUNCTION_END(x86_64_user_signal_handler) +SYMBOL(x86_64_user_signal_handler_end): diff --git a/src/system/kernel/arch/x86/64/syscalls.cpp b/src/system/kernel/arch/x86/64/syscalls.cpp new file mode 100644 index 0000000000..20bf44ef4e --- /dev/null +++ b/src/system/kernel/arch/x86/64/syscalls.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include "x86_syscalls.h" + +#include + +#include +#include + + +// SYSCALL handler (in interrupts.S). +extern "C" void x86_64_syscall_entry(void); + + +static void +init_syscall_registers(void* dummy, int cpuNum) +{ + // Enable SYSCALL (EFER.SCE = 1). + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) | (1 << 0)); + + // Flags to clear upon entry. Want interrupts disabled and the direction + // flag cleared. + x86_write_msr(IA32_MSR_FMASK, X86_EFLAGS_INTERRUPT | X86_EFLAGS_DIRECTION); + + // Entry point address. + x86_write_msr(IA32_MSR_LSTAR, (addr_t)x86_64_syscall_entry); + + // Segments that will be set upon entry and return. This is very strange + // and requires a specific ordering of segments in the GDT. Upon entry: + // - CS is set to IA32_STAR[47:32] + // - SS is set to IA32_STAR[47:32] + 8 + // Upon return: + // - CS is set to IA32_STAR[63:48] + 16 + // - SS is set to IA32_STAR[63:48] + 8 + // From this we get: + // - Entry CS = KERNEL_CODE_SEG + // - Entry SS = KERNEL_CODE_SEG + 8 = KERNEL_DATA_SEG + // - Return CS = KERNEL_DATA_SEG + 16 = USER_CODE_SEG + // - Return SS = KERNEL_DATA_SEG + 8 = USER_DATA_SEG + x86_write_msr(IA32_MSR_STAR, ((uint64)(KERNEL_DATA_SEG | 3) << 48) + | ((uint64)KERNEL_CODE_SEG << 32)); +} + + +// #pragma mark - + + +void +x86_initialize_syscall(void) +{ + // SYSCALL/SYSRET are always available on x86_64 so we just use them, no + // need to use the commpage. Tell all CPUs to initialize the SYSCALL MSRs. + call_all_cpus_sync(&init_syscall_registers, NULL); +} diff --git a/src/system/kernel/arch/x86/64/thread.cpp b/src/system/kernel/arch/x86/64/thread.cpp new file mode 100644 index 0000000000..03797773ea --- /dev/null +++ b/src/system/kernel/arch/x86/64/thread.cpp @@ -0,0 +1,389 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "paging/X86PagingStructures.h" +#include "paging/X86VMTranslationMap.h" + + +//#define TRACE_ARCH_THREAD +#ifdef TRACE_ARCH_THREAD +# define TRACE(x...) dprintf(x) +#else +# define TRACE(x...) ; +#endif + + +#ifdef SYSCALL_TRACING + +namespace SyscallTracing { + +class RestartSyscall : public AbstractTraceEntry { + public: + RestartSyscall() + { + Initialized(); + } + + virtual void AddDump(TraceOutput& out) + { + out.Print("syscall restart"); + } +}; + +} + +# define TSYSCALL(x) new(std::nothrow) SyscallTracing::x + +#else +# define TSYSCALL(x) +#endif // SYSCALL_TRACING + + +extern "C" void x86_64_thread_entry(); + +// Initial thread saved state. +static arch_thread sInitialState; + + +void +x86_restart_syscall(iframe* frame) +{ + Thread* thread = thread_get_current_thread(); + + atomic_and(&thread->flags, ~THREAD_FLAGS_RESTART_SYSCALL); + atomic_or(&thread->flags, THREAD_FLAGS_SYSCALL_RESTARTED); + + // Get back the original system call number and modify the frame to + // re-execute the syscall instruction. + frame->ax = frame->orig_rax; + frame->ip -= 2; + + TSYSCALL(RestartSyscall()); +} + + +void +x86_set_tls_context(Thread* thread) +{ + // Set FS segment base address to the TLS segment. + x86_write_msr(IA32_MSR_FS_BASE, thread->user_local_storage); +} + + +static uint8* +get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action) +{ + // Use the alternate signal stack if we should and can. + if (thread->signal_stack_enabled + && (action->sa_flags & SA_ONSTACK) != 0 + && (frame->user_sp < thread->signal_stack_base + || frame->user_sp >= thread->signal_stack_base + + thread->signal_stack_size)) { + return (uint8*)(thread->signal_stack_base + thread->signal_stack_size); + } + + // We are going to use the stack that we are already on. We must not touch + // the red zone (128 byte area below the stack pointer, reserved for use + // by functions to store temporary data and guaranteed not to be modified + // by signal handlers). + return (uint8*)(frame->user_sp - 128); +} + + +// #pragma mark - + + +status_t +arch_thread_init(kernel_args* args) +{ + // Save one global valid FPU state; it will be copied in the arch dependent + // part of each new thread. + asm volatile ("clts; fninit; fnclex;"); + x86_fxsave(sInitialState.fpu_state); + + return B_OK; +} + + +status_t +arch_thread_init_thread_struct(Thread* thread) +{ + // Copy the initial saved FPU state to the new thread. + memcpy(&thread->arch_info, &sInitialState, sizeof(arch_thread)); + + // Initialise the current thread pointer. + thread->arch_info.thread = thread; + + return B_OK; +} + + +/*! Prepares the given thread's kernel stack for executing its entry function. + + \param thread The thread. + \param stack The usable bottom of the thread's kernel stack. + \param stackTop The usable top of the thread's kernel stack. + \param function The entry function the thread shall execute. + \param data Pointer to be passed to the entry function. +*/ +void +arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop, + void (*function)(void*), const void* data) +{ + addr_t* stackTop = (addr_t*)_stackTop; + + TRACE("arch_thread_init_kthread_stack: stack top %p, function %p, data: " + "%p\n", _stackTop, function, data); + + // Save the stack top for system call entry. + thread->arch_info.syscall_rsp = (uint64*)thread->kernel_stack_top; + + // x86_64 uses registers for argument passing, first argument in RDI, + // however we don't save RDI on every context switch (there is no need + // for us to: it is not callee-save, and only contains the first argument + // to x86_context_switch). However, this presents a problem since we + // cannot store the argument for the entry function here. Therefore, we + // save the function address in R14 and the argument in R15 (which are + // restored), and then set up the stack to initially call a wrapper + // function which passes the argument correctly. + + *--stackTop = 0; // Dummy return address. + *--stackTop = (addr_t)x86_64_thread_entry; // Wrapper function. + *--stackTop = (addr_t)data; // R15: argument. + *--stackTop = (addr_t)function; // R14: entry function. + *--stackTop = 0; // R13. + *--stackTop = 0; // R12. + *--stackTop = 0; // RBP. + *--stackTop = 0; // RBX. + + // Save the stack position. + thread->arch_info.current_stack = stackTop; +} + + +void +arch_thread_dump_info(void* info) +{ + arch_thread* thread = (arch_thread*)info; + + kprintf("\trsp: %p\n", thread->current_stack); + kprintf("\tsyscall_rsp: %p\n", thread->syscall_rsp); + kprintf("\tuser_rsp: %p\n", thread->user_rsp); + kprintf("\tfpu_state at %p\n", thread->fpu_state); +} + + +/*! Sets up initial thread context and enters user space +*/ +status_t +arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, + void* args2) +{ + addr_t stackTop = thread->user_stack_base + thread->user_stack_size; + + TRACE("arch_thread_enter_userspace: entry %#lx, args %p %p, " + "stackTop %#lx\n", entry, args1, args2, stackTop); + + // Copy the little stub that calls exit_thread() when the thread entry + // function returns. + // TODO: This will become a problem later if we want to support execute + // disable, the stack shouldn't really be executable. + size_t codeSize = (addr_t)x86_end_userspace_thread_exit + - (addr_t)x86_userspace_thread_exit; + stackTop -= codeSize; + if (user_memcpy((void*)stackTop, (const void*)&x86_userspace_thread_exit, + codeSize) != B_OK) + return B_BAD_ADDRESS; + + // Copy the address of the stub to the top of the stack to act as the + // return address. + addr_t codeAddr = stackTop; + stackTop -= sizeof(codeAddr); + if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr)) + != B_OK) + return B_BAD_ADDRESS; + + // Prepare the user iframe. + iframe frame = {}; + frame.type = IFRAME_TYPE_SYSCALL; + frame.si = (uint64)args2; + frame.di = (uint64)args1; + frame.ip = entry; + frame.cs = USER_CODE_SEG; + frame.flags = X86_EFLAGS_RESERVED1 | X86_EFLAGS_INTERRUPT + | (3 << X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT); + frame.sp = stackTop; + frame.ss = USER_DATA_SEG; + + // Return to userland. Never returns. + x86_initial_return_to_userland(thread, &frame); + + return B_OK; +} + + +/*! Sets up the user iframe for invoking a signal handler. + + The function fills in the remaining fields of the given \a signalFrameData, + copies it to the thread's userland stack (the one on which the signal shall + be handled), and sets up the user iframe so that when returning to userland + a wrapper function is executed that calls the user-defined signal handler. + When the signal handler returns, the wrapper function shall call the + "restore signal frame" syscall with the (possibly modified) signal frame + data. + + The following fields of the \a signalFrameData structure still need to be + filled in: + - \c context.uc_stack: The stack currently used by the thread. + - \c context.uc_mcontext: The current userland state of the registers. + - \c syscall_restart_return_value: Architecture specific use. On x86_64 the + value of rax which is overwritten by the syscall return value. + + Furthermore the function needs to set \c thread->user_signal_context to the + userland pointer to the \c ucontext_t on the user stack. + + \param thread The current thread. + \param action The signal action specified for the signal to be handled. + \param signalFrameData A partially initialized structure of all the data + that need to be copied to userland. + \return \c B_OK on success, another error code, if something goes wrong. +*/ +status_t +arch_setup_signal_frame(Thread* thread, struct sigaction* action, + struct signal_frame_data* signalFrameData) +{ + iframe* frame = x86_get_current_iframe(); + if (!IFRAME_IS_USER(frame)) { + panic("arch_setup_signal_frame(): No user iframe!"); + return B_BAD_VALUE; + } + + // Store the register state. + signalFrameData->context.uc_mcontext.rax = frame->ax; + signalFrameData->context.uc_mcontext.rbx = frame->bx; + signalFrameData->context.uc_mcontext.rcx = frame->cx; + signalFrameData->context.uc_mcontext.rdx = frame->dx; + signalFrameData->context.uc_mcontext.rdi = frame->di; + signalFrameData->context.uc_mcontext.rsi = frame->si; + signalFrameData->context.uc_mcontext.rbp = frame->bp; + signalFrameData->context.uc_mcontext.r8 = frame->r8; + signalFrameData->context.uc_mcontext.r9 = frame->r9; + signalFrameData->context.uc_mcontext.r10 = frame->r10; + signalFrameData->context.uc_mcontext.r11 = frame->r11; + signalFrameData->context.uc_mcontext.r12 = frame->r12; + signalFrameData->context.uc_mcontext.r13 = frame->r13; + signalFrameData->context.uc_mcontext.r14 = frame->r14; + signalFrameData->context.uc_mcontext.r15 = frame->r15; + signalFrameData->context.uc_mcontext.rsp = frame->user_sp; + signalFrameData->context.uc_mcontext.rip = frame->ip; + signalFrameData->context.uc_mcontext.rflags = frame->flags; + + // Store the FPU state. There appears to be a bug in GCC where the aligned + // attribute on a structure is being ignored when the structure is allocated + // on the stack, so even if the fpu_state struct has aligned(16) it may not + // get aligned correctly. Instead, use the current thread's FPU save area + // and then memcpy() to the frame structure. + x86_fxsave(thread->arch_info.fpu_state); + memcpy((void*)&signalFrameData->context.uc_mcontext.fpu, + thread->arch_info.fpu_state, + sizeof(signalFrameData->context.uc_mcontext.fpu)); + + // Fill in signalFrameData->context.uc_stack. + signal_get_user_stack(frame->user_sp, &signalFrameData->context.uc_stack); + + // Store syscall_restart_return_value. + signalFrameData->syscall_restart_return_value = frame->orig_rax; + + // Get the stack to use and copy the frame data to it. + uint8* userStack = get_signal_stack(thread, frame, action); + + userStack -= sizeof(*signalFrameData); + signal_frame_data* userSignalFrameData = (signal_frame_data*)userStack; + + if (user_memcpy(userSignalFrameData, signalFrameData, + sizeof(*signalFrameData)) != B_OK) { + return B_BAD_ADDRESS; + } + + // Copy a return address to the stack so that backtraces will be correct. + userStack -= sizeof(frame->ip); + if (user_memcpy(userStack, &frame->ip, sizeof(frame->ip)) != B_OK) + return B_BAD_ADDRESS; + + // Update Thread::user_signal_context, now that everything seems to have + // gone fine. + thread->user_signal_context = &userSignalFrameData->context; + + // Set up the iframe to execute the signal handler wrapper on our prepared + // stack. First argument points to the frame data. + frame->user_sp = (addr_t)userStack; + frame->ip = ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER]; + frame->di = (addr_t)userSignalFrameData; + + return B_OK; +} + + +int64 +arch_restore_signal_frame(struct signal_frame_data* signalFrameData) +{ + iframe* frame = x86_get_current_iframe(); + + frame->orig_rax = signalFrameData->syscall_restart_return_value; + frame->ax = signalFrameData->context.uc_mcontext.rax; + frame->bx = signalFrameData->context.uc_mcontext.rbx; + frame->cx = signalFrameData->context.uc_mcontext.rcx; + frame->dx = signalFrameData->context.uc_mcontext.rdx; + frame->di = signalFrameData->context.uc_mcontext.rdi; + frame->si = signalFrameData->context.uc_mcontext.rsi; + frame->bp = signalFrameData->context.uc_mcontext.rbp; + frame->r8 = signalFrameData->context.uc_mcontext.r8; + frame->r9 = signalFrameData->context.uc_mcontext.r9; + frame->r10 = signalFrameData->context.uc_mcontext.r10; + frame->r11 = signalFrameData->context.uc_mcontext.r11; + frame->r12 = signalFrameData->context.uc_mcontext.r12; + frame->r13 = signalFrameData->context.uc_mcontext.r13; + frame->r14 = signalFrameData->context.uc_mcontext.r14; + frame->r15 = signalFrameData->context.uc_mcontext.r15; + frame->user_sp = signalFrameData->context.uc_mcontext.rsp; + frame->ip = signalFrameData->context.uc_mcontext.rip; + frame->flags = (frame->flags & ~(uint64)X86_EFLAGS_USER_FLAGS) + | (signalFrameData->context.uc_mcontext.rflags & X86_EFLAGS_USER_FLAGS); + + // Same as above, alignment may not be correct. Copy to thread and restore + // from there. + Thread* thread = thread_get_current_thread(); + memcpy(thread->arch_info.fpu_state, + (void*)&signalFrameData->context.uc_mcontext.fpu, + sizeof(thread->arch_info.fpu_state)); + x86_fxrstor(thread->arch_info.fpu_state); + + // The syscall return code overwrites frame->ax with the return value of + // the syscall, need to return it here to ensure the correct value is + // restored. + return frame->ax; +} diff --git a/src/system/kernel/arch/x86/Jamfile b/src/system/kernel/arch/x86/Jamfile index 17d82e4f2d..d9ac20fe79 100644 --- a/src/system/kernel/arch/x86/Jamfile +++ b/src/system/kernel/arch/x86/Jamfile @@ -12,65 +12,101 @@ UsePrivateKernelHeaders ; UsePrivateHeaders shared ; SEARCH_SOURCE += [ FDirName $(SUBDIR) paging ] ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) paging 32bit ] ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) paging pae ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) timers ] ; +local archSpecificSources ; +if $(TARGET_ARCH) = x86_64 { + SEARCH_SOURCE += [ FDirName $(SUBDIR) 64 ] ; + SEARCH_SOURCE += [ FDirName $(SUBDIR) paging 64bit ] ; -KernelMergeObject kernel_arch_x86.o : - arch_commpage.cpp + archSpecificSources = + arch.S + cpuid.S + descriptors.cpp + interrupts.S + signals.cpp + signals_asm.S + syscalls.cpp + thread.cpp + + # paging + x86_physical_page_mapper_mapped.cpp + + # paging/64bit + X86PagingMethod64Bit.cpp + X86PagingStructures64Bit.cpp + X86VMTranslationMap64Bit.cpp + ; +} else { + SEARCH_SOURCE += [ FDirName $(SUBDIR) 32 ] ; + SEARCH_SOURCE += [ FDirName $(SUBDIR) paging 32bit ] ; + SEARCH_SOURCE += [ FDirName $(SUBDIR) paging pae ] ; + + archSpecificSources = + apm.cpp + arch.S + bios.cpp + cpuid.S + descriptors.cpp + interrupts.S + signals.cpp + signals_asm.S + syscalls.cpp + syscalls_asm.S + thread.cpp + + # paging + x86_physical_page_mapper_large_memory.cpp + + # paging/32bit + X86PagingMethod32Bit.cpp + X86PagingStructures32Bit.cpp + X86VMTranslationMap32Bit.cpp + + # paging/pae + X86PagingMethodPAE.cpp + X86PagingStructuresPAE.cpp + X86VMTranslationMapPAE.cpp + ; +} + +local archGenericSources = arch_cpu.cpp + arch_commpage.cpp arch_debug.cpp arch_debug_console.cpp arch_elf.cpp arch_int.cpp arch_platform.cpp -# arch_selector.cpp arch_real_time_clock.cpp arch_smp.cpp + arch_system_info.cpp arch_thread.cpp arch_timer.cpp + arch_user_debugger.cpp arch_vm.cpp arch_vm_translation_map.cpp - arch_x86.S - arch_interrupts.S - arch_system_info.cpp - arch_user_debugger.cpp apic.cpp - apm.cpp - bios.cpp - cpuid.S ioapic.cpp irq_routing_table.cpp msi.cpp pic.cpp - syscall.S - vm86.cpp - x86_signals.cpp - x86_signals_asm.S - x86_syscalls.cpp # paging x86_physical_page_mapper.cpp - x86_physical_page_mapper_large_memory.cpp X86PagingMethod.cpp X86PagingStructures.cpp X86VMTranslationMap.cpp - # paging/32bit - X86PagingMethod32Bit.cpp - X86PagingStructures32Bit.cpp - X86VMTranslationMap32Bit.cpp - - # paging/pae - X86PagingMethodPAE.cpp - X86PagingStructuresPAE.cpp - X86VMTranslationMapPAE.cpp - # timers x86_apic.cpp x86_hpet.cpp x86_pit.cpp +; + +KernelMergeObject kernel_arch_x86.o : + $(archSpecificSources) + $(archGenericSources) : $(TARGET_KERNEL_PIC_CCFLAGS) ; @@ -78,8 +114,7 @@ KernelMergeObject kernel_arch_x86.o : CreateAsmStructOffsetsHeader asm_offsets.h : asm_offsets.cpp ; # We need to specify the dependency on the generated syscalls file explicitly. -Includes [ FGristFiles arch_interrupts.S arch_x86.S x86_signals.cpp - x86_signals_asm.S ] +Includes [ FGristFiles interrupts.S arch.S signals.cpp signals_asm.S ] : syscall_numbers.h ; -Includes [ FGristFiles arch_interrupts.S ] +Includes [ FGristFiles interrupts.S ] : syscall_table.h ; diff --git a/src/system/kernel/arch/x86/apic.cpp b/src/system/kernel/arch/x86/apic.cpp index 2c83935402..70f662cbde 100644 --- a/src/system/kernel/arch/x86/apic.cpp +++ b/src/system/kernel/arch/x86/apic.cpp @@ -88,8 +88,9 @@ apic_init(kernel_args *args) status_t apic_per_cpu_init(kernel_args *args, int32 cpu) { - dprintf("setting up apic for CPU %ld: apic id %lu, version %lu\n", cpu, - apic_local_id(), apic_read(APIC_VERSION)); + dprintf("setting up apic for CPU %" B_PRId32 ": apic id %" B_PRIu32 ", " + "version %" B_PRIu32 "\n", cpu, apic_local_id(), + apic_read(APIC_VERSION)); /* set spurious interrupt vector to 0xff */ uint32 config = apic_read(APIC_SPURIOUS_INTR_VECTOR) & 0xffffff00; diff --git a/src/system/kernel/arch/x86/arch_commpage.cpp b/src/system/kernel/arch/x86/arch_commpage.cpp index 8b9cc0bdb6..ccb142f3c2 100644 --- a/src/system/kernel/arch/x86/arch_commpage.cpp +++ b/src/system/kernel/arch/x86/arch_commpage.cpp @@ -22,7 +22,7 @@ status_t arch_commpage_init_post_cpus(void) { // select the optimum syscall mechanism and patch the commpage - x86_initialize_commpage_syscall(); + x86_initialize_syscall(); // initialize the signal handler code in the commpage x86_initialize_commpage_signal_handler(); diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index d5e4c71d40..155ed9753c 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -1,10 +1,10 @@ /* * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the NewOS License. - * */ @@ -21,17 +21,14 @@ #include #include #include -#include #include #include #include #include #include -#include #include -#include "interrupts.h" #include "paging/X86PagingStructures.h" #include "paging/X86VMTranslationMap.h" @@ -94,11 +91,11 @@ struct set_mtrrs_parameter { }; -extern "C" void reboot(void); - // from arch_x86.S +extern "C" void x86_reboot(void); + // from arch.S -void (*gX86SwapFPUFunc)(void *oldState, const void *newState); void (*gCpuIdleFunc)(void); +void (*gX86SwapFPUFunc)(void* oldState, const void* newState) = x86_noop_swap; bool gHasSSE = false; static uint32 sCpuRendezvous; @@ -106,13 +103,11 @@ static uint32 sCpuRendezvous2; static uint32 sCpuRendezvous3; static vint32 sTSCSyncRendezvous; -segment_descriptor *gGDT = NULL; - /* Some specials for the double fault handler */ static uint8* sDoubleFaultStacks; static const size_t kDoubleFaultStackSize = 4096; // size per CPU -static x86_cpu_module_info *sCpuModule; +static x86_cpu_module_info* sCpuModule; extern "C" void memcpy_generic(void* dest, const void* source, size_t count); @@ -187,10 +182,10 @@ enable_caches() static void -set_mtrr(void *_parameter, int cpu) +set_mtrr(void* _parameter, int cpu) { - struct set_mtrr_parameter *parameter - = (struct set_mtrr_parameter *)_parameter; + struct set_mtrr_parameter* parameter + = (struct set_mtrr_parameter*)_parameter; // wait until all CPUs have arrived here smp_cpu_rendezvous(&sCpuRendezvous, cpu); @@ -244,7 +239,7 @@ set_mtrrs(void* _parameter, int cpu) static void -init_mtrrs(void *_unused, int cpu) +init_mtrrs(void* _unused, int cpu) { // wait until all CPUs have arrived here smp_cpu_rendezvous(&sCpuRendezvous, cpu); @@ -293,7 +288,7 @@ x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type) status_t -x86_get_mtrr(uint32 index, uint64 *_base, uint64 *_length, uint8 *_type) +x86_get_mtrr(uint32 index, uint64* _base, uint64* _length, uint8* _type) { // the MTRRs are identical on all CPUs, so it doesn't matter // on which CPU this runs @@ -320,10 +315,12 @@ x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos, uint32 count) void x86_init_fpu(void) { + // All x86_64 CPUs support SSE, don't need to bother checking for it. +#ifndef __x86_64__ if (!x86_check_feature(IA32_FEATURE_FPU, FEATURE_COMMON)) { // No FPU... time to install one in your 386? dprintf("%s: Warning: CPU has no reported FPU.\n", __func__); - gX86SwapFPUFunc = i386_noop_swap; + gX86SwapFPUFunc = x86_noop_swap; return; } @@ -332,65 +329,25 @@ x86_init_fpu(void) dprintf("%s: CPU has no SSE... just enabling FPU.\n", __func__); // we don't have proper SSE support, just enable FPU x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU)); - gX86SwapFPUFunc = i386_fnsave_swap; + gX86SwapFPUFunc = x86_fnsave_swap; return; } +#endif + dprintf("%s: CPU has SSE... enabling FXSR and XMM.\n", __func__); // enable OS support for SSE x86_write_cr4(x86_read_cr4() | CR4_OS_FXSR | CR4_OS_XMM_EXCEPTION); x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU)); - gX86SwapFPUFunc = i386_fxsave_swap; + gX86SwapFPUFunc = x86_fxsave_swap; gHasSSE = true; } -static void -load_tss(int cpu) -{ - short seg = ((TSS_BASE_SEGMENT + cpu) << 3) | DPL_KERNEL; - asm("movw %0, %%ax;" - "ltr %%ax;" : : "r" (seg) : "eax"); -} - - -static void -init_double_fault(int cpuNum) -{ - // set up the double fault TSS - struct tss *tss = &gCPU[cpuNum].arch.double_fault_tss; - - memset(tss, 0, sizeof(struct tss)); - size_t stackSize; - tss->sp0 = (uint32)x86_get_double_fault_stack(cpuNum, &stackSize); - tss->sp0 += stackSize; - tss->ss0 = KERNEL_DATA_SEG; - read_cr3(tss->cr3); - // copy the current cr3 to the double fault cr3 - tss->eip = (uint32)&double_fault; - tss->es = KERNEL_DATA_SEG; - tss->cs = KERNEL_CODE_SEG; - tss->ss = KERNEL_DATA_SEG; - tss->esp = tss->sp0; - tss->ds = KERNEL_DATA_SEG; - tss->fs = KERNEL_DATA_SEG; - tss->gs = KERNEL_DATA_SEG; - tss->ldt_seg_selector = 0; - tss->io_map_base = sizeof(struct tss); - - // add TSS descriptor for this new TSS - uint16 tssSegmentDescriptorIndex = DOUBLE_FAULT_TSS_BASE_SEGMENT + cpuNum; - set_tss_descriptor(&gGDT[tssSegmentDescriptorIndex], - (addr_t)tss, sizeof(struct tss)); - - x86_set_task_gate(cpuNum, 8, tssSegmentDescriptorIndex << 3); -} - - #if DUMP_FEATURE_STRING static void -dump_feature_string(int currentCPU, cpu_ent *cpu) +dump_feature_string(int currentCPU, cpu_ent* cpu) { char features[384]; features[0] = 0; @@ -549,10 +506,10 @@ dump_feature_string(int currentCPU, cpu_ent *cpu) #endif // DUMP_FEATURE_STRING -static int +static void detect_cpu(int currentCPU) { - cpu_ent *cpu = get_cpu_struct(); + cpu_ent* cpu = get_cpu_struct(); char vendorString[17]; cpuid_info cpuid; @@ -659,15 +616,13 @@ detect_cpu(int currentCPU) #if DUMP_FEATURE_STRING dump_feature_string(currentCPU, cpu); #endif - - return 0; } bool x86_check_feature(uint32 feature, enum x86_feature_type type) { - cpu_ent *cpu = get_cpu_struct(); + cpu_ent* cpu = get_cpu_struct(); #if 0 int i; @@ -695,8 +650,8 @@ x86_get_double_fault_stack(int32 cpu, size_t* _size) int32 x86_double_fault_get_cpu(void) { - uint32 stack = x86_read_ebp(); - return (stack - (uint32)sDoubleFaultStacks) / kDoubleFaultStackSize; + addr_t stack = x86_get_stack_frame(); + return (stack - (addr_t)sDoubleFaultStacks) / kDoubleFaultStackSize; } @@ -704,11 +659,8 @@ x86_double_fault_get_cpu(void) status_t -arch_cpu_preboot_init_percpu(kernel_args *args, int cpu) +arch_cpu_preboot_init_percpu(kernel_args* args, int cpu) { - // A simple nop FPU call until x86_init_fpu - gX86SwapFPUFunc = i386_noop_swap; - // On SMP system we want to synchronize the CPUs' TSCs, so system_time() // will return consistent values. if (smp_get_num_cpus() > 1) { @@ -755,7 +707,7 @@ amdc1e_noarat_idle(void) static bool detect_amdc1e_noarat() { - cpu_ent *cpu = get_cpu_struct(); + cpu_ent* cpu = get_cpu_struct(); if (cpu->arch.vendor != VENDOR_AMD) return false; @@ -770,27 +722,13 @@ detect_amdc1e_noarat() status_t -arch_cpu_init_percpu(kernel_args *args, int cpu) +arch_cpu_init_percpu(kernel_args* args, int cpu) { + // Load descriptor tables for this CPU. + x86_descriptors_init_percpu(args, cpu); + detect_cpu(cpu); - // load the TSS for this cpu - // note the main cpu gets initialized in arch_cpu_init_post_vm() - if (cpu != 0) { - load_tss(cpu); - - // set the IDT - struct { - uint16 limit; - void* address; - } _PACKED descriptor = { - 256 * 8 - 1, // 256 descriptors, 8 bytes each (-1 for "limit") - x86_get_idt(cpu) - }; - - asm volatile("lidt %0" : : "m"(descriptor)); - } - if (!gCpuIdleFunc) { if (detect_amdc1e_noarat()) gCpuIdleFunc = amdc1e_noarat_idle; @@ -807,18 +745,25 @@ arch_cpu_init_percpu(kernel_args *args, int cpu) } } - return 0; + return B_OK; } status_t -arch_cpu_init(kernel_args *args) +arch_cpu_init(kernel_args* args) { // init the TSC -> system_time() conversion factors uint32 conversionFactor = args->arch_args.system_time_cv_factor; uint64 conversionFactorNsecs = (uint64)conversionFactor * 1000; +#ifdef __x86_64__ + // The x86_64 system_time() implementation uses 64-bit multiplication and + // therefore shifting is not necessary for low frequencies (it's also not + // too likely that there'll be any x86_64 CPUs clocked under 1GHz). + __x86_setup_system_time((uint64)conversionFactor << 32, + conversionFactorNsecs); +#else if (conversionFactorNsecs >> 32 != 0) { // the TSC frequency is < 1 GHz, which forces us to shift the factor __x86_setup_system_time(conversionFactor, conversionFactorNsecs >> 16, @@ -827,25 +772,20 @@ arch_cpu_init(kernel_args *args) // the TSC frequency is >= 1 GHz __x86_setup_system_time(conversionFactor, conversionFactorNsecs, false); } +#endif + + // Initialize descriptor tables. + x86_descriptors_init(args); return B_OK; } status_t -arch_cpu_init_post_vm(kernel_args *args) +arch_cpu_init_post_vm(kernel_args* args) { uint32 i; - // account for the segment descriptors - gGDT = (segment_descriptor *)args->arch_args.vir_gdt; - create_area("gdt", (void **)&gGDT, B_EXACT_ADDRESS, B_PAGE_SIZE, - B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); - - // currently taken out of the build, because it's not yet used (and assumes - // (a fixed number of used GDT entries) - //i386_selector_init(gGDT); // pass the new gdt - // allocate an area for the double fault stacks virtual_address_restrictions virtualRestrictions = {}; virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; @@ -856,40 +796,19 @@ arch_cpu_init_post_vm(kernel_args *args) &virtualRestrictions, &physicalRestrictions, (void**)&sDoubleFaultStacks); + // More descriptor table setup. + x86_descriptors_init_post_vm(args); + X86PagingStructures* kernelPagingStructures = static_cast( VMAddressSpace::Kernel()->TranslationMap())->PagingStructures(); - // setup task-state segments + // Set active translation map on each CPU. for (i = 0; i < args->num_cpus; i++) { - // initialize the regular and double fault tss stored in the per-cpu - // structure - memset(&gCPU[i].arch.tss, 0, sizeof(struct tss)); - gCPU[i].arch.tss.ss0 = KERNEL_DATA_SEG; - gCPU[i].arch.tss.io_map_base = sizeof(struct tss); - - // add TSS descriptor for this new TSS - set_tss_descriptor(&gGDT[TSS_BASE_SEGMENT + i], - (addr_t)&gCPU[i].arch.tss, sizeof(struct tss)); - - // initialize the double fault tss - init_double_fault(i); - - // init active translation map gCPU[i].arch.active_paging_structures = kernelPagingStructures; kernelPagingStructures->AddReference(); } - // set the current hardware task on cpu 0 - load_tss(0); - - // setup TLS descriptors (one for every CPU) - - for (i = 0; i < args->num_cpus; i++) { - set_segment_descriptor(&gGDT[TLS_BASE_SEGMENT + i], 0, TLS_SIZE, - DT_DATA_WRITEABLE, DPL_USER); - } - if (!apic_available()) x86_init_fpu(); // else fpu gets set up in smp code @@ -899,18 +818,18 @@ arch_cpu_init_post_vm(kernel_args *args) status_t -arch_cpu_init_post_modules(kernel_args *args) +arch_cpu_init_post_modules(kernel_args* args) { // initialize CPU module - void *cookie = open_module_list("cpu"); + void* cookie = open_module_list("cpu"); while (true) { char name[B_FILE_NAME_LENGTH]; size_t nameLength = sizeof(name); if (read_next_module_name(cookie, name, &nameLength) != B_OK - || get_module(name, (module_info **)&sCpuModule) == B_OK) + || get_module(name, (module_info**)&sCpuModule) == B_OK) break; } @@ -964,9 +883,9 @@ arch_cpu_init_post_modules(kernel_args *args) void -i386_set_tss_and_kstack(addr_t kstack) +arch_cpu_user_TLB_invalidate(void) { - get_cpu_struct()->arch.tss.sp0 = kstack; + x86_write_cr3(x86_read_cr3()); } @@ -1015,8 +934,13 @@ arch_cpu_shutdown(bool rebootSystem) if (acpi_shutdown(rebootSystem) == B_OK) return B_OK; - if (!rebootSystem) + if (!rebootSystem) { +#ifndef __x86_64__ return apm_shutdown(); +#else + return B_NOT_SUPPORTED; +#endif + } cpu_status state = disable_interrupts(); @@ -1027,7 +951,7 @@ arch_cpu_shutdown(bool rebootSystem) snooze(500000); // if that didn't help, try it this way - reboot(); + x86_reboot(); restore_interrupts(state); return B_ERROR; @@ -1042,7 +966,7 @@ arch_cpu_idle(void) void -arch_cpu_sync_icache(void *address, size_t length) +arch_cpu_sync_icache(void* address, size_t length) { // instruction cache is always consistent on x86 } @@ -1051,15 +975,23 @@ arch_cpu_sync_icache(void *address, size_t length) void arch_cpu_memory_read_barrier(void) { +#ifdef __x86_64__ + asm volatile("lfence" : : : "memory"); +#else asm volatile ("lock;" : : : "memory"); asm volatile ("addl $0, 0(%%esp);" : : : "memory"); +#endif } void arch_cpu_memory_write_barrier(void) { +#ifdef __x86_64__ + asm volatile("sfence" : : : "memory"); +#else asm volatile ("lock;" : : : "memory"); asm volatile ("addl $0, 0(%%esp);" : : : "memory"); +#endif } diff --git a/src/system/kernel/arch/x86/arch_debug.cpp b/src/system/kernel/arch/x86/arch_debug.cpp index 1cd4dad7db..ce61320f30 100644 --- a/src/system/kernel/arch/x86/arch_debug.cpp +++ b/src/system/kernel/arch/x86/arch_debug.cpp @@ -1,6 +1,7 @@ /* * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Distributed under the terms of the MIT License. * * Copyright 2001, Travis Geiselbrecht. All rights reserved. @@ -28,31 +29,29 @@ #include #include -#include - struct stack_frame { - struct stack_frame *previous; - addr_t return_address; + stack_frame* previous; + addr_t return_address; }; #define NUM_PREVIOUS_LOCATIONS 32 static bool -already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 ebp) +already_visited(addr_t* visited, int32* _last, int32* _num, addr_t bp) { int32 last = *_last; int32 num = *_num; int32 i; for (i = 0; i < num; i++) { - if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) % NUM_PREVIOUS_LOCATIONS] == ebp) + if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) % NUM_PREVIOUS_LOCATIONS] == bp) return true; } *_last = last = (last + 1) % NUM_PREVIOUS_LOCATIONS; - visited[last] = ebp; + visited[last] = bp; if (num < NUM_PREVIOUS_LOCATIONS) *_num = num + 1; @@ -64,14 +63,14 @@ already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 ebp) /*! Safe to be called only from outside the debugger. */ static status_t -get_next_frame_no_debugger(addr_t ebp, addr_t *_next, addr_t *_eip) +get_next_frame_no_debugger(addr_t bp, addr_t* _next, addr_t* _ip) { // TODO: Do this more efficiently in assembly. stack_frame frame; - if (user_memcpy(&frame, (void*)ebp, sizeof(frame)) != B_OK) + if (user_memcpy(&frame, (void*)bp, sizeof(frame)) != B_OK) return B_BAD_ADDRESS; - *_eip = frame.return_address; + *_ip = frame.return_address; *_next = (addr_t)frame.previous; return B_OK; @@ -81,13 +80,13 @@ get_next_frame_no_debugger(addr_t ebp, addr_t *_next, addr_t *_eip) /*! Safe to be called only from inside the debugger. */ static status_t -get_next_frame_debugger(addr_t ebp, addr_t *_next, addr_t *_eip) +get_next_frame_debugger(addr_t bp, addr_t* _next, addr_t* _ip) { stack_frame frame; - if (debug_memcpy(B_CURRENT_TEAM, &frame, (void*)ebp, sizeof(frame)) != B_OK) + if (debug_memcpy(B_CURRENT_TEAM, &frame, (void*)bp, sizeof(frame)) != B_OK) return B_BAD_ADDRESS; - *_eip = frame.return_address; + *_ip = frame.return_address; *_next = (addr_t)frame.previous; return B_OK; @@ -95,8 +94,8 @@ get_next_frame_debugger(addr_t ebp, addr_t *_next, addr_t *_eip) static status_t -lookup_symbol(Thread* thread, addr_t address, addr_t *_baseAddress, - const char **_symbolName, const char **_imageName, bool *_exactMatch) +lookup_symbol(Thread* thread, addr_t address, addr_t* _baseAddress, + const char** _symbolName, const char** _imageName, bool* _exactMatch) { status_t status = B_ENTRY_NOT_FOUND; @@ -120,6 +119,9 @@ lookup_symbol(Thread* thread, addr_t address, addr_t *_baseAddress, } +#ifndef __x86_64__ + + static void set_debug_argument_variable(int32 index, uint64 value) { @@ -307,51 +309,104 @@ print_demangled_call(const char* image, const char* symbol, addr_t args, } +#else // __x86_64__ + + +static status_t +print_demangled_call(const char* image, const char* symbol, addr_t args, + bool noObjectMethod, bool addDebugVariables) +{ + // Since x86_64 uses registers rather than the stack for the first 6 + // arguments we cannot use the same method as x86 to read the function + // arguments. Maybe we need DWARF support in the kernel debugger. For now + // just print out the function signature without the argument values. + + static const size_t kBufferSize = 256; + char* buffer = (char*)debug_malloc(kBufferSize); + if (buffer == NULL) + return B_NO_MEMORY; + + bool isObjectMethod; + const char* name = debug_demangle_symbol(symbol, buffer, kBufferSize, + &isObjectMethod); + if (name == NULL) { + debug_free(buffer); + return B_ERROR; + } + + kprintf("<%s> %s(", image, name); + + size_t length; + int32 type, i = 0; + uint32 cookie = 0; + while (debug_get_next_demangled_argument(&cookie, symbol, buffer, + kBufferSize, &type, &length) == B_OK) { + if (i++ > 0) + kprintf(", "); + + if (buffer[0]) + kprintf("%s", buffer); + else + kprintf("???"); + } + + debug_free(buffer); + + kprintf(")"); + return B_OK; +} + + +#endif // __x86_64__ + + static void -print_stack_frame(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp, +print_stack_frame(Thread* thread, addr_t ip, addr_t bp, addr_t nextBp, int32 callIndex, bool demangle) { - const char *symbol, *image; + const char* symbol; + const char* image; addr_t baseAddress; bool exactMatch; status_t status; addr_t diff; - diff = nextEbp - ebp; + diff = nextBp - bp; - // kernel space/user space switch - if (diff & 0x80000000) + // MSB set = kernel space/user space switch + if (diff & ~((addr_t)-1 >> 1)) diff = 0; - status = lookup_symbol(thread, eip, &baseAddress, &symbol, &image, + status = lookup_symbol(thread, ip, &baseAddress, &symbol, &image, &exactMatch); - kprintf("%2ld %08lx (+%4ld) %08lx ", callIndex, ebp, diff, eip); + kprintf("%2" B_PRId32 " %0*lx (+%4ld) %0*lx ", callIndex, + B_PRINTF_POINTER_WIDTH, bp, diff, B_PRINTF_POINTER_WIDTH, ip); if (status == B_OK) { if (exactMatch && demangle) { - status = print_demangled_call(image, symbol, nextEbp + 8, false, - false); + status = print_demangled_call(image, symbol, + nextBp + sizeof(stack_frame), false, false); } if (!exactMatch || !demangle || status != B_OK) { if (symbol != NULL) { - kprintf("<%s>:%s%s", image, symbol, + kprintf("<%s> %s%s", image, symbol, exactMatch ? "" : " (nearest)"); } else - kprintf("<%s@%p>:unknown", image, (void *)baseAddress); + kprintf("<%s@%p> ", image, (void*)baseAddress); } - kprintf(" + 0x%04lx\n", eip - baseAddress); + kprintf(" + %#04lx\n", ip - baseAddress); } else { VMArea *area = NULL; if (thread != NULL && thread->team != NULL && thread->team->address_space != NULL) { - area = thread->team->address_space->LookupArea(eip); + area = thread->team->address_space->LookupArea(ip); } if (area != NULL) { - kprintf("%ld:%s@%p + %#lx\n", area->id, area->name, - (void*)area->Base(), eip - area->Base()); + kprintf("%" B_PRId32 ":%s@%p + %#lx\n", area->id, area->name, + (void*)area->Base(), ip - area->Base()); } else kprintf("\n"); } @@ -359,50 +414,70 @@ print_stack_frame(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp, static void -print_iframe(struct iframe *frame) +print_iframe(iframe* frame) { bool isUser = IFRAME_IS_USER(frame); - kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", frame, - isUser ? (uint32*)(frame + 1) : &frame->user_esp); - kprintf(" eax 0x%-9lx ebx 0x%-9lx ecx 0x%-9lx edx 0x%lx\n", - frame->eax, frame->ebx, frame->ecx, frame->edx); - kprintf(" esi 0x%-9lx edi 0x%-9lx ebp 0x%-9lx esp 0x%lx\n", - frame->esi, frame->edi, frame->ebp, frame->esp); - kprintf(" eip 0x%-9lx eflags 0x%-9lx", frame->eip, frame->flags); +#ifdef __x86_64__ + kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", frame, + frame + 1); + + kprintf(" rax %#-18lx rbx %#-18lx rcx %#lx\n", frame->ax, + frame->bx, frame->cx); + kprintf(" rdx %#-18lx rsi %#-18lx rdi %#lx\n", frame->dx, + frame->si, frame->di); + kprintf(" rbp %#-18lx r8 %#-18lx r9 %#lx\n", frame->bp, + frame->r8, frame->r9); + kprintf(" r10 %#-18lx r11 %#-18lx r12 %#lx\n", frame->r10, + frame->r11, frame->r12); + kprintf(" r13 %#-18lx r14 %#-18lx r15 %#lx\n", frame->r13, + frame->r14, frame->r15); + kprintf(" rip %#-18lx rsp %#-18lx rflags %#lx\n", frame->ip, + frame->sp, frame->flags); +#else + kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", frame, + isUser ? (void*)(frame + 1) : (void*)&frame->user_sp); + + kprintf(" eax %#-10lx ebx %#-10lx ecx %#-10lx edx %#lx\n", + frame->ax, frame->bx, frame->cx, frame->dx); + kprintf(" esi %#-10lx edi %#-10lx ebp %#-10lx esp %#lx\n", + frame->si, frame->di, frame->bp, frame->sp); + kprintf(" eip %#-10lx eflags %#-10lx", frame->ip, frame->flags); if (isUser) { // from user space - kprintf("user esp 0x%lx", frame->user_esp); + kprintf("user esp %#lx", frame->user_sp); } kprintf("\n"); - kprintf(" vector: 0x%lx, error code: 0x%lx\n", frame->vector, +#endif + + kprintf(" vector: %#lx, error code: %#lx\n", frame->vector, frame->error_code); } static bool -setup_for_thread(char *arg, Thread **_thread, uint32 *_ebp, - uint32 *_oldPageDirectory) +setup_for_thread(char* arg, Thread** _thread, addr_t* _bp, + phys_addr_t* _oldPageDirectory) { - Thread *thread = NULL; + Thread* thread = NULL; if (arg != NULL) { thread_id id = strtoul(arg, NULL, 0); thread = Thread::GetDebug(id); if (thread == NULL) { - kprintf("could not find thread %ld\n", id); + kprintf("could not find thread %" B_PRId32 "\n", id); return false; } if (id != thread_get_current_thread_id()) { // switch to the page directory of the new thread to be // able to follow the stack trace into userland - uint32 newPageDirectory = x86_next_page_directory( + phys_addr_t newPageDirectory = x86_next_page_directory( thread_get_current_thread(), thread); if (newPageDirectory != 0) { - read_cr3(*_oldPageDirectory); - write_cr3(newPageDirectory); + *_oldPageDirectory = x86_read_cr3(); + x86_write_cr3(newPageDirectory); } if (thread->state == B_THREAD_RUNNING) { @@ -413,10 +488,10 @@ setup_for_thread(char *arg, Thread **_thread, uint32 *_ebp, thread->cpu->cpu_num); if (registers == NULL) return false; - *_ebp = registers->ebp; + *_bp = registers->bp; } else { - // read %ebp from the thread's stack stored by a pushad - *_ebp = thread->arch_info.current_stack.esp[2]; + // Read frame pointer from the thread's stack. + *_bp = thread->arch_info.GetFramePointer(); } } else thread = NULL; @@ -469,17 +544,18 @@ is_iframe(Thread* thread, addr_t frame) return false; addr_t previousFrame = *(addr_t*)frame; - return ((previousFrame & ~IFRAME_TYPE_MASK) == 0 && previousFrame != 0); + return ((previousFrame & ~(addr_t)IFRAME_TYPE_MASK) == 0 + && previousFrame != 0); } -static struct iframe * -find_previous_iframe(Thread *thread, addr_t frame) +static iframe* +find_previous_iframe(Thread* thread, addr_t frame) { // iterate backwards through the stack frames, until we hit an iframe while (is_kernel_stack_address(thread, frame)) { if (is_iframe(thread, frame)) - return (struct iframe*)frame; + return (iframe*)frame; frame = *(addr_t*)frame; } @@ -488,100 +564,93 @@ find_previous_iframe(Thread *thread, addr_t frame) } -static struct iframe* -get_previous_iframe(Thread* thread, struct iframe* frame) +static iframe* +get_previous_iframe(Thread* thread, iframe* frame) { if (frame == NULL) return NULL; - return find_previous_iframe(thread, frame->ebp); + return find_previous_iframe(thread, frame->bp); } -static struct iframe* +static iframe* get_current_iframe(Thread* thread) { if (thread == thread_get_current_thread()) - return i386_get_current_iframe(); + return x86_get_current_iframe(); - addr_t ebp = thread->arch_info.current_stack.esp[2]; - // NOTE: This doesn't work, if the thread is running (on another CPU). - return find_previous_iframe(thread, ebp); + // NOTE: This doesn't work, if the thread is running (on another CPU). + return find_previous_iframe(thread, thread->arch_info.GetFramePointer()); } -uint32* +#define CHECK_DEBUG_VARIABLE(_name, _member, _settable) \ + if (strcmp(variableName, _name) == 0) { \ + settable = _settable; \ + return &_member; \ + } + + +static size_t* find_debug_variable(const char* variableName, bool& settable) { - struct iframe* frame = get_current_iframe(debug_get_debugged_thread()); + iframe* frame = get_current_iframe(debug_get_debugged_thread()); if (frame == NULL) return NULL; - settable = false; - - if (strcmp(variableName, "gs") == 0) { - return &frame->gs; - } else if (strcmp(variableName, "fs") == 0) { - return &frame->fs; - } else if (strcmp(variableName, "es") == 0) { - return &frame->es; - } else if (strcmp(variableName, "ds") == 0) { - return &frame->ds; - } else if (strcmp(variableName, "cs") == 0) { - return &frame->cs; - } else if (strcmp(variableName, "edi") == 0) { - settable = true; - return &frame->edi; - } else if (strcmp(variableName, "esi") == 0) { - settable = true; - return &frame->esi; - } else if (strcmp(variableName, "ebp") == 0) { - settable = true; - return &frame->ebp; - } else if (strcmp(variableName, "esp") == 0) { - settable = true; - return &frame->esp; - } else if (strcmp(variableName, "ebx") == 0) { - settable = true; - return &frame->ebx; - } else if (strcmp(variableName, "edx") == 0) { - settable = true; - return &frame->edx; - } else if (strcmp(variableName, "ecx") == 0) { - settable = true; - return &frame->ecx; - } else if (strcmp(variableName, "eax") == 0) { - settable = true; - return &frame->eax; - } else if (strcmp(variableName, "orig_eax") == 0) { - settable = true; - return &frame->orig_eax; - } else if (strcmp(variableName, "orig_edx") == 0) { - settable = true; - return &frame->orig_edx; - } else if (strcmp(variableName, "eip") == 0) { - settable = true; - return &frame->eip; - } else if (strcmp(variableName, "eflags") == 0) { - settable = true; - return &frame->flags; - } +#ifdef __x86_64__ + CHECK_DEBUG_VARIABLE("cs", frame->cs, false); + CHECK_DEBUG_VARIABLE("ss", frame->ss, false); + CHECK_DEBUG_VARIABLE("r15", frame->r15, true); + CHECK_DEBUG_VARIABLE("r14", frame->r14, true); + CHECK_DEBUG_VARIABLE("r13", frame->r13, true); + CHECK_DEBUG_VARIABLE("r12", frame->r12, true); + CHECK_DEBUG_VARIABLE("r11", frame->r11, true); + CHECK_DEBUG_VARIABLE("r10", frame->r10, true); + CHECK_DEBUG_VARIABLE("r9", frame->r9, true); + CHECK_DEBUG_VARIABLE("r8", frame->r8, true); + CHECK_DEBUG_VARIABLE("rbp", frame->bp, true); + CHECK_DEBUG_VARIABLE("rsi", frame->si, true); + CHECK_DEBUG_VARIABLE("rdi", frame->di, true); + CHECK_DEBUG_VARIABLE("rdx", frame->dx, true); + CHECK_DEBUG_VARIABLE("rcx", frame->cx, true); + CHECK_DEBUG_VARIABLE("rbx", frame->bx, true); + CHECK_DEBUG_VARIABLE("rax", frame->ax, true); + CHECK_DEBUG_VARIABLE("rip", frame->ip, true); + CHECK_DEBUG_VARIABLE("rflags", frame->flags, true); + CHECK_DEBUG_VARIABLE("rsp", frame->sp, true); +#else + CHECK_DEBUG_VARIABLE("gs", frame->gs, false); + CHECK_DEBUG_VARIABLE("fs", frame->fs, false); + CHECK_DEBUG_VARIABLE("es", frame->es, false); + CHECK_DEBUG_VARIABLE("ds", frame->ds, false); + CHECK_DEBUG_VARIABLE("cs", frame->cs, false); + CHECK_DEBUG_VARIABLE("edi", frame->di, true); + CHECK_DEBUG_VARIABLE("esi", frame->si, true); + CHECK_DEBUG_VARIABLE("ebp", frame->bp, true); + CHECK_DEBUG_VARIABLE("esp", frame->sp, true); + CHECK_DEBUG_VARIABLE("ebx", frame->bx, true); + CHECK_DEBUG_VARIABLE("edx", frame->dx, true); + CHECK_DEBUG_VARIABLE("ecx", frame->cx, true); + CHECK_DEBUG_VARIABLE("eax", frame->ax, true); + CHECK_DEBUG_VARIABLE("orig_eax", frame->orig_eax, true); + CHECK_DEBUG_VARIABLE("orig_edx", frame->orig_edx, true); + CHECK_DEBUG_VARIABLE("eip", frame->ip, true); + CHECK_DEBUG_VARIABLE("eflags", frame->flags, true); if (IFRAME_IS_USER(frame)) { - if (strcmp(variableName, "user_esp") == 0) { - settable = true; - return &frame->user_esp; - } else if (strcmp(variableName, "user_ss") == 0) { - return &frame->user_ss; - } + CHECK_DEBUG_VARIABLE("user_esp", frame->user_sp, true); + CHECK_DEBUG_VARIABLE("user_ss", frame->user_ss, false); } +#endif return NULL; } static int -stack_trace(int argc, char **argv) +stack_trace(int argc, char** argv) { static const char* usage = "usage: %s [-d] [ ]\n" "Prints a stack trace for the current, respectively the specified\n" @@ -602,80 +671,82 @@ stack_trace(int argc, char **argv) return 0; } - uint32 previousLocations[NUM_PREVIOUS_LOCATIONS]; - Thread *thread = NULL; - uint32 oldPageDirectory = 0; - uint32 ebp = x86_read_ebp(); + addr_t previousLocations[NUM_PREVIOUS_LOCATIONS]; + Thread* thread = NULL; + phys_addr_t oldPageDirectory = 0; + addr_t bp = x86_get_stack_frame(); int32 num = 0, last = 0; if (!setup_for_thread(argc == threadIndex + 1 ? argv[threadIndex] : NULL, - &thread, &ebp, &oldPageDirectory)) + &thread, &bp, &oldPageDirectory)) return 0; DebuggedThreadSetter threadSetter(thread); if (thread != NULL) { - kprintf("stack trace for thread %ld \"%s\"\n", thread->id, + kprintf("stack trace for thread %" B_PRId32 " \"%s\"\n", thread->id, thread->name); kprintf(" kernel stack: %p to %p\n", - (void *)thread->kernel_stack_base, - (void *)(thread->kernel_stack_top)); + (void*)thread->kernel_stack_base, + (void*)(thread->kernel_stack_top)); if (thread->user_stack_base != 0) { kprintf(" user stack: %p to %p\n", - (void *)thread->user_stack_base, - (void *)(thread->user_stack_base + thread->user_stack_size)); + (void*)thread->user_stack_base, + (void*)(thread->user_stack_base + thread->user_stack_size)); } } - kprintf("frame caller :function + offset\n"); + kprintf("%-*s %-*s :function + offset\n", + B_PRINTF_POINTER_WIDTH, "frame", B_PRINTF_POINTER_WIDTH, "caller"); bool onKernelStack = true; for (int32 callIndex = 0;; callIndex++) { onKernelStack = onKernelStack - && is_kernel_stack_address(thread, ebp); + && is_kernel_stack_address(thread, bp); - if (onKernelStack && is_iframe(thread, ebp)) { - struct iframe *frame = (struct iframe *)ebp; + if (onKernelStack && is_iframe(thread, bp)) { + iframe* frame = (iframe*)bp; print_iframe(frame); - print_stack_frame(thread, frame->eip, ebp, frame->ebp, callIndex, + print_stack_frame(thread, frame->ip, bp, frame->bp, callIndex, demangle); - ebp = frame->ebp; + bp = frame->bp; } else { - addr_t eip, nextEbp; + addr_t ip, nextBp; - if (get_next_frame_debugger(ebp, &nextEbp, &eip) != B_OK) { - kprintf("%08lx -- read fault\n", ebp); + if (get_next_frame_debugger(bp, &nextBp, &ip) != B_OK) { + kprintf("%0*lx -- read fault\n", B_PRINTF_POINTER_WIDTH, bp); break; } - if (eip == 0 || ebp == 0) + if (ip == 0 || bp == 0) break; - print_stack_frame(thread, eip, ebp, nextEbp, callIndex, demangle); - ebp = nextEbp; + print_stack_frame(thread, ip, bp, nextBp, callIndex, demangle); + bp = nextBp; } - if (already_visited(previousLocations, &last, &num, ebp)) { - kprintf("circular stack frame: %p!\n", (void *)ebp); + if (already_visited(previousLocations, &last, &num, bp)) { + kprintf("circular stack frame: %p!\n", (void*)bp); break; } - if (ebp == 0) + if (bp == 0) break; } if (oldPageDirectory != 0) { // switch back to the previous page directory to no cause any troubles - write_cr3(oldPageDirectory); + x86_write_cr3(oldPageDirectory); } return 0; } +#ifndef __x86_64__ static void print_call(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp, int32 argCount) @@ -758,8 +829,8 @@ show_call(int argc, char **argv) } Thread *thread = NULL; - uint32 oldPageDirectory = 0; - addr_t ebp = x86_read_ebp(); + phys_addr_t oldPageDirectory = 0; + addr_t ebp = x86_get_stack_frame(); int32 argCount = 0; if (argc >= 2 && argv[argc - 1][0] == '-') { @@ -803,9 +874,9 @@ show_call(int argc, char **argv) struct iframe *frame = (struct iframe *)ebp; if (index == callIndex) - print_call(thread, frame->eip, ebp, frame->ebp, argCount); + print_call(thread, frame->ip, ebp, frame->bp, argCount); - ebp = frame->ebp; + ebp = frame->bp; } else { addr_t eip, nextEbp; @@ -829,15 +900,16 @@ show_call(int argc, char **argv) if (oldPageDirectory != 0) { // switch back to the previous page directory to not cause any troubles - write_cr3(oldPageDirectory); + x86_write_cr3(oldPageDirectory); } return 0; } +#endif static int -dump_iframes(int argc, char **argv) +dump_iframes(int argc, char** argv) { static const char* usage = "usage: %s [ ]\n" "Prints the iframe stack for the current, respectively the specified\n" @@ -849,7 +921,7 @@ dump_iframes(int argc, char **argv) return 0; } - Thread *thread = NULL; + Thread* thread = NULL; if (argc < 2) { thread = thread_get_current_thread(); @@ -857,7 +929,7 @@ dump_iframes(int argc, char **argv) thread_id id = strtoul(argv[1], NULL, 0); thread = Thread::GetDebug(id); if (thread == NULL) { - kprintf("could not find thread %ld\n", id); + kprintf("could not find thread %" B_PRId32 "\n", id); return 0; } } else if (argc > 2) { @@ -865,12 +937,14 @@ dump_iframes(int argc, char **argv) return 0; } - if (thread != NULL) - kprintf("iframes for thread %ld \"%s\"\n", thread->id, thread->name); + if (thread != NULL) { + kprintf("iframes for thread %" B_PRId32 " \"%s\"\n", thread->id, + thread->name); + } DebuggedThreadSetter threadSetter(thread); - struct iframe* frame = find_previous_iframe(thread, x86_read_ebp()); + iframe* frame = find_previous_iframe(thread, x86_get_stack_frame()); while (frame != NULL) { print_iframe(frame); frame = get_previous_iframe(thread, frame); @@ -881,17 +955,17 @@ dump_iframes(int argc, char **argv) static bool -is_calling(Thread *thread, addr_t eip, const char *pattern, - addr_t start, addr_t end) +is_calling(Thread* thread, addr_t ip, const char* pattern, addr_t start, + addr_t end) { if (pattern == NULL) - return eip >= start && eip < end; + return ip >= start && ip < end; - if (!IS_KERNEL_ADDRESS(eip)) + if (!IS_KERNEL_ADDRESS(ip)) return false; - const char *symbol; - if (lookup_symbol(thread, eip, NULL, &symbol, NULL, NULL) != B_OK) + const char* symbol; + if (lookup_symbol(thread, ip, NULL, &symbol, NULL, NULL) != B_OK) return false; return strstr(symbol, pattern); @@ -932,14 +1006,14 @@ cmd_in_context(int argc, char** argv) } // switch the page directory, if necessary - uint32 oldPageDirectory = 0; + phys_addr_t oldPageDirectory = 0; if (thread != thread_get_current_thread()) { - uint32 newPageDirectory = x86_next_page_directory( + phys_addr_t newPageDirectory = x86_next_page_directory( thread_get_current_thread(), thread); if (newPageDirectory != 0) { - read_cr3(oldPageDirectory); - write_cr3(newPageDirectory); + oldPageDirectory = x86_read_cr3(); + x86_write_cr3(newPageDirectory); } } @@ -951,7 +1025,7 @@ cmd_in_context(int argc, char** argv) // reset the page directory if (oldPageDirectory) - write_cr3(oldPageDirectory); + x86_write_cr3(oldPageDirectory); return 0; } @@ -961,11 +1035,11 @@ cmd_in_context(int argc, char** argv) void -arch_debug_save_registers(struct arch_debug_registers* registers) +arch_debug_save_registers(arch_debug_registers* registers) { // get the caller's frame pointer - stack_frame* frame = (stack_frame*)x86_read_ebp(); - registers->ebp = (addr_t)frame->previous; + stack_frame* frame = (stack_frame*)x86_get_stack_frame(); + registers->bp = (addr_t)frame->previous; } @@ -977,14 +1051,14 @@ arch_debug_stack_trace(void) bool -arch_debug_contains_call(Thread *thread, const char *symbol, - addr_t start, addr_t end) +arch_debug_contains_call(Thread* thread, const char* symbol, addr_t start, + addr_t end) { DebuggedThreadSetter threadSetter(thread); - addr_t ebp; + addr_t bp; if (thread == thread_get_current_thread()) - ebp = x86_read_ebp(); + bp = x86_get_stack_frame(); else { if (thread->state == B_THREAD_RUNNING) { // The thread is currently running on another CPU. @@ -994,38 +1068,38 @@ arch_debug_contains_call(Thread *thread, const char *symbol, thread->cpu->cpu_num); if (registers == NULL) return false; - ebp = registers->ebp; + bp = registers->bp; } else { // thread not running - ebp = thread->arch_info.current_stack.esp[2]; + bp = thread->arch_info.GetFramePointer(); } } for (;;) { - if (!is_kernel_stack_address(thread, ebp)) + if (!is_kernel_stack_address(thread, bp)) break; - if (is_iframe(thread, ebp)) { - struct iframe *frame = (struct iframe *)ebp; + if (is_iframe(thread, bp)) { + iframe* frame = (iframe*)bp; - if (is_calling(thread, frame->eip, symbol, start, end)) + if (is_calling(thread, frame->ip, symbol, start, end)) return true; - ebp = frame->ebp; + bp = frame->bp; } else { - addr_t eip, nextEbp; + addr_t ip, nextBp; - if (get_next_frame_no_debugger(ebp, &nextEbp, &eip) != B_OK - || eip == 0 || ebp == 0) + if (get_next_frame_no_debugger(bp, &nextBp, &ip) != B_OK + || ip == 0 || bp == 0) break; - if (is_calling(thread, eip, symbol, start, end)) + if (is_calling(thread, ip, symbol, start, end)) return true; - ebp = nextEbp; + bp = nextBp; } - if (ebp == 0) + if (bp == 0) break; } @@ -1033,11 +1107,11 @@ arch_debug_contains_call(Thread *thread, const char *symbol, } -void * +void* arch_debug_get_caller(void) { - struct stack_frame *frame = (struct stack_frame *)x86_read_ebp(); - return (void *)frame->previous->return_address; + stack_frame* frame = (stack_frame*)x86_get_stack_frame(); + return (void*)frame->previous->return_address; } @@ -1063,39 +1137,39 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, Thread* thread = thread_get_current_thread(); int32 count = 0; - addr_t ebp = x86_read_ebp(); + addr_t bp = x86_get_stack_frame(); bool onKernelStack = true; - while (ebp != 0 && count < maxCount) { + while (bp != 0 && count < maxCount) { onKernelStack = onKernelStack - && is_kernel_stack_address(thread, ebp); + && is_kernel_stack_address(thread, bp); if (!onKernelStack && (flags & STACK_TRACE_USER) == 0) break; - addr_t eip; - addr_t nextEbp; + addr_t ip; + addr_t nextBp; - if (onKernelStack && is_iframe(thread, ebp)) { - struct iframe *frame = (struct iframe*)ebp; - eip = frame->eip; - nextEbp = frame->ebp; + if (onKernelStack && is_iframe(thread, bp)) { + iframe* frame = (iframe*)bp; + ip = frame->ip; + nextBp = frame->bp; if (skipIframes > 0) { if (--skipIframes == 0) skipFrames = 0; } } else { - if (get_next_frame_no_debugger(ebp, &nextEbp, &eip) != B_OK) + if (get_next_frame_no_debugger(bp, &nextBp, &ip) != B_OK) break; } if (skipFrames <= 0 && ((flags & STACK_TRACE_KERNEL) != 0 || onKernelStack)) { - returnAddresses[count++] = eip; + returnAddresses[count++] = ip; } else skipFrames--; - ebp = nextEbp; + bp = nextBp; } return count; @@ -1111,14 +1185,14 @@ arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, void* arch_debug_get_interrupt_pc(bool* _isSyscall) { - struct iframe* frame = get_current_iframe(debug_get_debugged_thread()); + iframe* frame = get_current_iframe(debug_get_debugged_thread()); if (frame == NULL) return NULL; if (_isSyscall != NULL) - *_isSyscall = frame->vector == 99; + *_isSyscall = frame->type == IFRAME_TYPE_SYSCALL; - return (void*)(addr_t)frame->eip; + return (void*)(addr_t)frame->ip; } @@ -1128,7 +1202,14 @@ arch_debug_get_interrupt_pc(bool* _isSyscall) void arch_debug_unset_current_thread(void) { - write_dr3(NULL); +#ifdef __x86_64__ + // Can't just write 0 to the GS base, that will cause the read from %gs:0 + // to fault. Instead point it at a NULL pointer, %gs:0 will get this value. + static Thread* unsetThread = NULL; + x86_write_msr(IA32_MSR_GS_BASE, (addr_t)&unsetThread); +#else + x86_write_dr3(NULL); +#endif } @@ -1144,14 +1225,14 @@ status_t arch_set_debug_variable(const char* variableName, uint64 value) { bool settable; - uint32* variable = find_debug_variable(variableName, settable); + size_t* variable = find_debug_variable(variableName, settable); if (variable == NULL) return B_ENTRY_NOT_FOUND; if (!settable) return B_NOT_ALLOWED; - *variable = (uint32)value; + *variable = (size_t)value; return B_OK; } @@ -1160,7 +1241,7 @@ status_t arch_get_debug_variable(const char* variableName, uint64* value) { bool settable; - uint32* variable = find_debug_variable(variableName, settable); + size_t* variable = find_debug_variable(variableName, settable); if (variable == NULL) return B_ENTRY_NOT_FOUND; @@ -1169,6 +1250,12 @@ arch_get_debug_variable(const char* variableName, uint64* value) } +struct gdb_register { + int32 type; + int64 value; +}; + + /*! Writes the contents of the CPU registers at some fixed outer stack frame or iframe into the given buffer in the format expected by gdb. @@ -1182,10 +1269,36 @@ arch_get_debug_variable(const char* variableName, uint64* value) ssize_t arch_debug_gdb_get_registers(char* buffer, size_t bufferSize) { - struct iframe* frame = get_current_iframe(debug_get_debugged_thread()); + iframe* frame = get_current_iframe(debug_get_debugged_thread()); if (frame == NULL) return B_NOT_SUPPORTED; +#ifdef __x86_64__ + // For x86_64 the register order is: + // + // rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, + // r8, r9, r10, r11, r12, r13, r14, r15, + // rip, rflags, cs, ss, ds, es, fs, gs + // + // Annoyingly, GDB wants all the registers as 64-bit values, but then + // RFLAGS and the segment registers as 32-bit values, hence the need for + // the type information. + static const int32 kRegisterCount = 24; + gdb_register registers[kRegisterCount] = { + { B_UINT64_TYPE, frame->ax }, { B_UINT64_TYPE, frame->bx }, + { B_UINT64_TYPE, frame->cx }, { B_UINT64_TYPE, frame->dx }, + { B_UINT64_TYPE, frame->si }, { B_UINT64_TYPE, frame->di }, + { B_UINT64_TYPE, frame->bp }, { B_UINT64_TYPE, frame->sp }, + { B_UINT64_TYPE, frame->r8 }, { B_UINT64_TYPE, frame->r9 }, + { B_UINT64_TYPE, frame->r10 }, { B_UINT64_TYPE, frame->r11 }, + { B_UINT64_TYPE, frame->r12 }, { B_UINT64_TYPE, frame->r13 }, + { B_UINT64_TYPE, frame->r14 }, { B_UINT64_TYPE, frame->r15 }, + { B_UINT64_TYPE, frame->ip }, { B_UINT32_TYPE, frame->flags }, + { B_UINT32_TYPE, frame->cs }, { B_UINT32_TYPE, frame->ss }, + { B_UINT32_TYPE, 0 }, { B_UINT32_TYPE, 0 }, + { B_UINT32_TYPE, 0 }, { B_UINT32_TYPE, 0 }, + }; +#else // For x86 the register order is: // // eax, ecx, edx, ebx, @@ -1194,23 +1307,36 @@ arch_debug_gdb_get_registers(char* buffer, size_t bufferSize) // cs, ss, ds, es, fs, gs // // Note that even though the segment descriptors are actually 16 bits wide, - // gdb requires them as 32 bit integers. Note also that for some reason - // gdb wants the register dump in *big endian* format. + // gdb requires them as 32 bit integers. static const int32 kRegisterCount = 16; - uint32 registers[kRegisterCount] = { - frame->eax, frame->ecx, frame->edx, frame->ebx, - frame->esp, frame->ebp, frame->esi, frame->edi, - frame->eip, frame->flags, - frame->cs, frame->ds, frame->ds, frame->es, + gdb_register registers[kRegisterCount] = { + { B_UINT32_TYPE, frame->ax }, { B_UINT32_TYPE, frame->cx }, + { B_UINT32_TYPE, frame->dx }, { B_UINT32_TYPE, frame->bx }, + { B_UINT32_TYPE, frame->sp }, { B_UINT32_TYPE, frame->bp }, + { B_UINT32_TYPE, frame->si }, { B_UINT32_TYPE, frame->di }, + { B_UINT32_TYPE, frame->ip }, { B_UINT32_TYPE, frame->flags }, + { B_UINT32_TYPE, frame->cs }, { B_UINT32_TYPE, frame->ds }, // assume ss == ds - frame->fs, frame->gs + { B_UINT32_TYPE, frame->ds }, { B_UINT32_TYPE, frame->es }, + { B_UINT32_TYPE, frame->fs }, { B_UINT32_TYPE, frame->gs }, }; +#endif const char* const bufferStart = buffer; for (int32 i = 0; i < kRegisterCount; i++) { - int result = snprintf(buffer, bufferSize, "%08" B_PRIx32, - B_HOST_TO_BENDIAN_INT32(registers[i])); + // For some reason gdb wants the register dump in *big endian* format. + int result = 0; + switch (registers[i].type) { + case B_UINT64_TYPE: + result = snprintf(buffer, bufferSize, "%016" B_PRIx64, + B_HOST_TO_BENDIAN_INT64(registers[i].value)); + break; + case B_UINT32_TYPE: + result = snprintf(buffer, bufferSize, "%08" B_PRIx32, + B_HOST_TO_BENDIAN_INT32((uint32)registers[i].value)); + break; + } if (result >= (int)bufferSize) return B_BUFFER_OVERFLOW; @@ -1223,7 +1349,7 @@ arch_debug_gdb_get_registers(char* buffer, size_t bufferSize) status_t -arch_debug_init(kernel_args *args) +arch_debug_init(kernel_args* args) { // at this stage, the debugger command system is alive @@ -1233,7 +1359,9 @@ arch_debug_init(kernel_args *args) "Stack crawl for current thread (or any other)"); add_debugger_command("iframe", &dump_iframes, "Dump iframes for the specified thread"); +#ifndef __x86_64__ add_debugger_command("call", &show_call, "Show call with arguments"); +#endif add_debugger_command_etc("in_context", &cmd_in_context, "Executes a command in the context of a given thread", " ...\n" diff --git a/src/system/kernel/arch/x86/arch_elf.cpp b/src/system/kernel/arch/x86/arch_elf.cpp index 978ee9cb35..111329a3c2 100644 --- a/src/system/kernel/arch/x86/arch_elf.cpp +++ b/src/system/kernel/arch/x86/arch_elf.cpp @@ -25,6 +25,21 @@ #endif +#ifndef _BOOT_MODE +static bool +is_in_image(struct elf_image_info *image, addr_t address) +{ + return (address >= image->text_region.start + && address < image->text_region.start + image->text_region.size) + || (address >= image->data_region.start + && address < image->data_region.start + image->data_region.size); +} +#endif // !_BOOT_MODE + + +#if !defined(__x86_64__) || defined(_BOOT_MODE) + + #ifdef TRACE_ARCH_ELF static const char *kRelocations[] = { "R_386_NONE", @@ -42,21 +57,9 @@ static const char *kRelocations[] = { #endif -#ifndef _BOOT_MODE -static bool -is_in_image(struct elf_image_info *image, addr_t address) -{ - return (address >= image->text_region.start - && address < image->text_region.start + image->text_region.size) - || (address >= image->data_region.start - && address < image->data_region.start + image->data_region.size); -} -#endif // !_BOOT_MODE - - #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rel(struct preloaded_image *image, +boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image, struct Elf32_Rel *rel, int relLength) #else int @@ -167,7 +170,7 @@ arch_elf_relocate_rel(struct elf_image_info *image, #ifdef _BOOT_MODE status_t -boot_arch_elf_relocate_rela(struct preloaded_image *image, +boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image, struct Elf32_Rela *rel, int relLength) #else int @@ -179,3 +182,98 @@ arch_elf_relocate_rela(struct elf_image_info *image, return B_ERROR; } + +#endif // !__x86_64__ || _BOOT_MODE + + +#if defined(__x86_64__) || defined(_BOOT_MODE) + + +#ifdef _BOOT_MODE +status_t +boot_arch_elf_relocate_rel(preloaded_elf64_image* image, Elf64_Rel* rel, + int relLength) +#else +int +arch_elf_relocate_rel(struct elf_image_info *image, + struct elf_image_info *resolveImage, Elf64_Rel *rel, int relLength) +#endif +{ + dprintf("arch_elf_relocate_rel: not supported on x86_64\n"); + return B_ERROR; +} + + +#ifdef _BOOT_MODE +status_t +boot_arch_elf_relocate_rela(preloaded_elf64_image* image, Elf64_Rela* rel, + int relLength) +#else +int +arch_elf_relocate_rela(struct elf_image_info *image, + struct elf_image_info *resolveImage, Elf64_Rela *rel, int relLength) +#endif +{ + for (int i = 0; i < relLength / (int)sizeof(Elf64_Rela); i++) { + int type = ELF64_R_TYPE(rel[i].r_info); + int symIndex = ELF64_R_SYM(rel[i].r_info); + Elf64_Addr symAddr = 0; + + // Resolve the symbol, if any. + if (symIndex != 0) { + Elf64_Sym* symbol = SYMBOL(image, symIndex); + + status_t status; +#ifdef _BOOT_MODE + status = boot_elf_resolve_symbol(image, symbol, &symAddr); +#else + status = elf_resolve_symbol(image, symbol, resolveImage, &symAddr); +#endif + if (status < B_OK) + return status; + } + + // Address of the relocation. + Elf64_Addr relocAddr = image->text_region.delta + rel[i].r_offset; + + // Calculate the relocation value. + Elf64_Addr relocValue; + switch(type) { + case R_X86_64_NONE: + continue; + case R_X86_64_64: + relocValue = symAddr + rel[i].r_addend; + break; + case R_X86_64_PC32: + relocValue = symAddr + rel[i].r_addend - rel[i].r_offset; + break; + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: + relocValue = symAddr + rel[i].r_addend; + break; + case R_X86_64_RELATIVE: + relocValue = image->text_region.delta + rel[i].r_addend; + break; + default: + dprintf("arch_elf_relocate_rela: unhandled relocation type %d\n", + type); + return B_BAD_DATA; + } +#ifdef _BOOT_MODE + boot_elf64_set_relocation(relocAddr, relocValue); +#else + if (!is_in_image(image, relocAddr)) { + dprintf("arch_elf_relocate_rela: invalid offset %#lx\n", + rel[i].r_offset); + return B_BAD_ADDRESS; + } + + *(Elf64_Addr *)relocAddr = relocValue; +#endif + } + + return B_OK; +} + + +#endif // __x86_64__ || _BOOT_MODE diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp index c83b6ae702..75e50a827e 100644 --- a/src/system/kernel/arch/x86/arch_int.cpp +++ b/src/system/kernel/arch/x86/arch_int.cpp @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include #include @@ -23,16 +21,10 @@ #include #include -#include -#include -#include #include #include #include -#include - -#include "interrupts.h" #include @@ -49,8 +41,6 @@ #endif -static const interrupt_controller *sCurrentPIC = NULL; - static const char *kInterruptNames[] = { /* 0 */ "Divide Error Exception", /* 1 */ "Debug Exception", @@ -75,81 +65,268 @@ static const char *kInterruptNames[] = { }; static const int kInterruptNameCount = 20; -#define MAX_ARGS 16 - -typedef struct { - uint32 a, b; -} desc_table; -static desc_table* sIDTs[B_MAX_CPU_COUNT]; - -// table with functions handling respective interrupts -typedef void interrupt_handler_function(struct iframe* frame); - -#define INTERRUPT_HANDLER_TABLE_SIZE 256 -interrupt_handler_function* gInterruptHandlerTable[ - INTERRUPT_HANDLER_TABLE_SIZE]; +static const interrupt_controller* sCurrentPIC = NULL; -/*! Initializes a descriptor in an IDT. -*/ -static void -set_gate(desc_table *gate_addr, addr_t addr, int type, int dpl) +static const char* +exception_name(int number, char* buffer, int32 bufferSize) { - unsigned int gate1; // first byte of gate desc - unsigned int gate2; // second byte of gate desc + if (number >= 0 && number < kInterruptNameCount) + return kInterruptNames[number]; - gate1 = (KERNEL_CODE_SEG << 16) | (0x0000ffff & addr); - gate2 = (0xffff0000 & addr) | 0x8000 | (dpl << 13) | (type << 8); - - gate_addr->a = gate1; - gate_addr->b = gate2; + snprintf(buffer, bufferSize, "exception %d", number); + return buffer; } -/*! Initializes the descriptor for interrupt vector \a n in the IDT of the - specified CPU to an interrupt-gate descriptor with the given procedure - address. - For CPUs other than the boot CPU it must not be called before - arch_int_init_post_vm(). -*/ -static void -set_interrupt_gate(int32 cpu, int n, void (*addr)()) -{ - set_gate(&sIDTs[cpu][n], (addr_t)addr, 14, DPL_KERNEL); -} - - -/*! Initializes the descriptor for interrupt vector \a n in the IDT of the - specified CPU to an trap-gate descriptor with the given procedure address. - For CPUs other than the boot CPU it must not be called before - arch_int_init_post_vm(). -*/ -static void -set_trap_gate(int32 cpu, int n, void (*addr)()) -{ - set_gate(&sIDTs[cpu][n], (unsigned int)addr, 15, DPL_USER); -} - - -/*! Initializes the descriptor for interrupt vector \a n in the IDT of CPU - \a cpu to a task-gate descripter referring to the TSS segment identified - by TSS segment selector \a segment. - For CPUs other than the boot CPU it must not be called before - arch_int_init_post_vm() (arch_cpu_init_post_vm() is fine). -*/ void -x86_set_task_gate(int32 cpu, int32 n, int32 segment) +x86_invalid_exception(iframe* frame) { - sIDTs[cpu][n].a = (segment << 16); - sIDTs[cpu][n].b = 0x8000 | (0 << 13) | (0x5 << 8); // present, dpl 0, type 5 + Thread* thread = thread_get_current_thread(); + char name[32]; + panic("unhandled trap 0x%lx (%s) at ip 0x%lx, thread %" B_PRId32 "!\n", + frame->vector, exception_name(frame->vector, name, sizeof(name)), + frame->ip, thread ? thread->id : -1); } -/*! Returns the virtual IDT address for CPU \a cpu. */ -void* -x86_get_idt(int32 cpu) +void +x86_fatal_exception(iframe* frame) { - return sIDTs[cpu]; + char name[32]; + panic("Fatal exception \"%s\" occurred! Error code: 0x%lx\n", + exception_name(frame->vector, name, sizeof(name)), frame->error_code); +} + + +void +x86_unexpected_exception(iframe* frame) +{ + debug_exception_type type; + uint32 signalNumber; + int32 signalCode; + addr_t signalAddress = 0; + int32 signalError = B_ERROR; + + switch (frame->vector) { + case 0: // Divide Error Exception (#DE) + type = B_DIVIDE_ERROR; + signalNumber = SIGFPE; + signalCode = FPE_INTDIV; + signalAddress = frame->ip; + break; + + case 4: // Overflow Exception (#OF) + type = B_OVERFLOW_EXCEPTION; + signalNumber = SIGFPE; + signalCode = FPE_INTOVF; + signalAddress = frame->ip; + break; + + case 5: // BOUND Range Exceeded Exception (#BR) + type = B_BOUNDS_CHECK_EXCEPTION; + signalNumber = SIGTRAP; + signalCode = SI_USER; + break; + + case 6: // Invalid Opcode Exception (#UD) + type = B_INVALID_OPCODE_EXCEPTION; + signalNumber = SIGILL; + signalCode = ILL_ILLOPC; + signalAddress = frame->ip; + break; + + case 13: // General Protection Exception (#GP) + type = B_GENERAL_PROTECTION_FAULT; + signalNumber = SIGILL; + signalCode = ILL_PRVOPC; // or ILL_PRVREG + signalAddress = frame->ip; + break; + + case 16: // x87 FPU Floating-Point Error (#MF) + type = B_FLOATING_POINT_EXCEPTION; + signalNumber = SIGFPE; + signalCode = FPE_FLTDIV; + // TODO: Determine the correct cause via the FPU status + // register! + signalAddress = frame->ip; + break; + + case 17: // Alignment Check Exception (#AC) + type = B_ALIGNMENT_EXCEPTION; + signalNumber = SIGBUS; + signalCode = BUS_ADRALN; + // TODO: Also get the address (from where?). Since we don't enable + // alignment checking this exception should never happen, though. + signalError = EFAULT; + break; + + case 19: // SIMD Floating-Point Exception (#XF) + type = B_FLOATING_POINT_EXCEPTION; + signalNumber = SIGFPE; + signalCode = FPE_FLTDIV; + // TODO: Determine the correct cause via the MXCSR register! + signalAddress = frame->ip; + break; + + default: + x86_invalid_exception(frame); + return; + } + + if (IFRAME_IS_USER(frame)) { + struct sigaction action; + Thread* thread = thread_get_current_thread(); + + enable_interrupts(); + + // If the thread has a signal handler for the signal, we simply send it + // the signal. Otherwise we notify the user debugger first. + if ((sigaction(signalNumber, NULL, &action) == 0 + && action.sa_handler != SIG_DFL + && action.sa_handler != SIG_IGN) + || user_debug_exception_occurred(type, signalNumber)) { + Signal signal(signalNumber, signalCode, signalError, + thread->team->id); + signal.SetAddress((void*)signalAddress); + send_signal_to_thread(thread, signal, 0); + } + } else { + char name[32]; + panic("Unexpected exception \"%s\" occurred in kernel mode! " + "Error code: 0x%lx\n", + exception_name(frame->vector, name, sizeof(name)), + frame->error_code); + } +} + + +void +x86_hardware_interrupt(struct iframe* frame) +{ + int32 vector = frame->vector - ARCH_INTERRUPT_BASE; + bool levelTriggered = false; + Thread* thread = thread_get_current_thread(); + + if (sCurrentPIC->is_spurious_interrupt(vector)) { + TRACE(("got spurious interrupt at vector %ld\n", vector)); + return; + } + + levelTriggered = sCurrentPIC->is_level_triggered_interrupt(vector); + + if (!levelTriggered) { + // if it's not handled by the current pic then it's an apic generated + // interrupt like local interrupts, msi or ipi. + if (!sCurrentPIC->end_of_interrupt(vector)) + apic_end_of_interrupt(); + } + + int_io_interrupt_handler(vector, levelTriggered); + + if (levelTriggered) { + if (!sCurrentPIC->end_of_interrupt(vector)) + apic_end_of_interrupt(); + } + + cpu_status state = disable_interrupts(); + if (thread->cpu->invoke_scheduler) { + SpinLocker schedulerLocker(gSchedulerLock); + scheduler_reschedule(); + schedulerLocker.Unlock(); + restore_interrupts(state); + } else if (thread->post_interrupt_callback != NULL) { + void (*callback)(void*) = thread->post_interrupt_callback; + void* data = thread->post_interrupt_data; + + thread->post_interrupt_callback = NULL; + thread->post_interrupt_data = NULL; + + restore_interrupts(state); + + callback(data); + } +} + + +void +x86_page_fault_exception(struct iframe* frame) +{ + Thread* thread = thread_get_current_thread(); + addr_t cr2 = x86_read_cr2(); + addr_t newip; + + if (debug_debugger_running()) { + // If this CPU or this thread has a fault handler, we're allowed to be + // here. + if (thread != NULL) { + cpu_ent* cpu = &gCPU[smp_get_current_cpu()]; + if (cpu->fault_handler != 0) { + debug_set_page_fault_info(cr2, frame->ip, + (frame->error_code & 0x2) != 0 + ? DEBUG_PAGE_FAULT_WRITE : 0); + frame->ip = cpu->fault_handler; + frame->bp = cpu->fault_handler_stack_pointer; + return; + } + + if (thread->fault_handler != 0) { + kprintf("ERROR: thread::fault_handler used in kernel " + "debugger!\n"); + debug_set_page_fault_info(cr2, frame->ip, + (frame->error_code & 0x2) != 0 + ? DEBUG_PAGE_FAULT_WRITE : 0); + frame->ip = thread->fault_handler; + return; + } + } + + // otherwise, not really + panic("page fault in debugger without fault handler! Touching " + "address %p from ip %p\n", (void*)cr2, (void*)frame->ip); + return; + } else if ((frame->flags & 0x200) == 0) { + // interrupts disabled + + // If a page fault handler is installed, we're allowed to be here. + // TODO: Now we are generally allowing user_memcpy() with interrupts + // disabled, which in most cases is a bug. We should add some thread + // flag allowing to explicitly indicate that this handling is desired. + if (thread && thread->fault_handler != 0) { + if (frame->ip != thread->fault_handler) { + frame->ip = thread->fault_handler; + return; + } + + // The fault happened at the fault handler address. This is a + // certain infinite loop. + panic("page fault, interrupts disabled, fault handler loop. " + "Touching address %p from ip %p\n", (void*)cr2, + (void*)frame->ip); + } + + // If we are not running the kernel startup the page fault was not + // allowed to happen and we must panic. + panic("page fault, but interrupts were disabled. Touching address " + "%p from ip %p\n", (void*)cr2, (void*)frame->ip); + return; + } else if (thread != NULL && thread->page_faults_allowed < 1) { + panic("page fault not allowed at this place. Touching address " + "%p from ip %p\n", (void*)cr2, (void*)frame->ip); + return; + } + + enable_interrupts(); + + vm_page_fault(cr2, frame->ip, + (frame->error_code & 0x2) != 0, // write access + (frame->error_code & 0x4) != 0, // userland + &newip); + if (newip != 0) { + // the page fault handler wants us to modify the iframe to set the + // IP the cpu will return to this ip + frame->ip = newip; + } } @@ -211,682 +388,22 @@ arch_int_are_interrupts_enabled(void) } -static const char * -exception_name(int number, char *buffer, int32 bufferSize) -{ - if (number >= 0 && number < kInterruptNameCount) - return kInterruptNames[number]; - - snprintf(buffer, bufferSize, "exception %d", number); - return buffer; -} - - -static void -invalid_exception(struct iframe* frame) -{ - Thread* thread = thread_get_current_thread(); - char name[32]; - panic("unhandled trap 0x%lx (%s) at ip 0x%lx, thread %ld!\n", - frame->vector, exception_name(frame->vector, name, sizeof(name)), - frame->eip, thread ? thread->id : -1); -} - - -static void -fatal_exception(struct iframe *frame) -{ - char name[32]; - panic("Fatal exception \"%s\" occurred! Error code: 0x%lx\n", - exception_name(frame->vector, name, sizeof(name)), frame->error_code); -} - - -static void -unexpected_exception(struct iframe* frame) -{ - debug_exception_type type; - uint32 signalNumber; - int32 signalCode; - addr_t signalAddress = 0; - int32 signalError = B_ERROR; - - if (IFRAME_IS_VM86(frame)) { - x86_vm86_return((struct vm86_iframe *)frame, (frame->vector == 13) ? - B_OK : B_ERROR); - // won't get here - } - - switch (frame->vector) { - case 0: // Divide Error Exception (#DE) - type = B_DIVIDE_ERROR; - signalNumber = SIGFPE; - signalCode = FPE_INTDIV; - signalAddress = frame->eip; - break; - - case 4: // Overflow Exception (#OF) - type = B_OVERFLOW_EXCEPTION; - signalNumber = SIGFPE; - signalCode = FPE_INTOVF; - signalAddress = frame->eip; - break; - - case 5: // BOUND Range Exceeded Exception (#BR) - type = B_BOUNDS_CHECK_EXCEPTION; - signalNumber = SIGTRAP; - signalCode = SI_USER; - break; - - case 6: // Invalid Opcode Exception (#UD) - type = B_INVALID_OPCODE_EXCEPTION; - signalNumber = SIGILL; - signalCode = ILL_ILLOPC; - signalAddress = frame->eip; - break; - - case 13: // General Protection Exception (#GP) - type = B_GENERAL_PROTECTION_FAULT; - signalNumber = SIGILL; - signalCode = ILL_PRVOPC; // or ILL_PRVREG - signalAddress = frame->eip; - break; - - case 16: // x87 FPU Floating-Point Error (#MF) - type = B_FLOATING_POINT_EXCEPTION; - signalNumber = SIGFPE; - signalCode = FPE_FLTDIV; - // TODO: Determine the correct cause via the FPU status - // register! - signalAddress = frame->eip; - break; - - case 17: // Alignment Check Exception (#AC) - type = B_ALIGNMENT_EXCEPTION; - signalNumber = SIGBUS; - signalCode = BUS_ADRALN; - // TODO: Also get the address (from where?). Since we don't enable - // alignment checking this exception should never happen, though. - signalError = EFAULT; - break; - - case 19: // SIMD Floating-Point Exception (#XF) - type = B_FLOATING_POINT_EXCEPTION; - signalNumber = SIGFPE; - signalCode = FPE_FLTDIV; - // TODO: Determine the correct cause via the MXCSR register! - signalAddress = frame->eip; - break; - - default: - invalid_exception(frame); - return; - } - - if (IFRAME_IS_USER(frame)) { - struct sigaction action; - Thread* thread = thread_get_current_thread(); - - enable_interrupts(); - - // If the thread has a signal handler for the signal, we simply send it - // the signal. Otherwise we notify the user debugger first. - if ((sigaction(signalNumber, NULL, &action) == 0 - && action.sa_handler != SIG_DFL - && action.sa_handler != SIG_IGN) - || user_debug_exception_occurred(type, signalNumber)) { - Signal signal(signalNumber, signalCode, signalError, - thread->team->id); - signal.SetAddress((void*)signalAddress); - send_signal_to_thread(thread, signal, 0); - } - } else { - char name[32]; - panic("Unexpected exception \"%s\" occurred in kernel mode! " - "Error code: 0x%lx\n", - exception_name(frame->vector, name, sizeof(name)), - frame->error_code); - } -} - - -void -x86_double_fault_exception(struct iframe* frame) -{ - int cpu = x86_double_fault_get_cpu(); - - // The double fault iframe contains no useful information (as - // per Intel's architecture spec). Thus we simply save the - // information from the (unhandlable) exception which caused the - // double in our iframe. This will result even in useful stack - // traces. Only problem is that we trust that at least the - // TSS is still accessible. - struct tss *tss = &gCPU[cpu].arch.tss; - - frame->cs = tss->cs; - frame->es = tss->es; - frame->ds = tss->ds; - frame->fs = tss->fs; - frame->gs = tss->gs; - frame->eip = tss->eip; - frame->ebp = tss->ebp; - frame->esp = tss->esp; - frame->eax = tss->eax; - frame->ebx = tss->ebx; - frame->ecx = tss->ecx; - frame->edx = tss->edx; - frame->esi = tss->esi; - frame->edi = tss->edi; - frame->flags = tss->eflags; - - // Use a special handler for page faults which avoids the triple fault - // pitfalls. - set_interrupt_gate(cpu, 14, &trap14_double_fault); - - debug_double_fault(cpu); -} - - -void -x86_page_fault_exception_double_fault(struct iframe* frame) -{ - uint32 cr2; - asm("movl %%cr2, %0" : "=r" (cr2)); - - // Only if this CPU has a fault handler, we're allowed to be here. - cpu_ent& cpu = gCPU[x86_double_fault_get_cpu()]; - addr_t faultHandler = cpu.fault_handler; - if (faultHandler != 0) { - debug_set_page_fault_info(cr2, frame->eip, - (frame->error_code & 0x2) != 0 ? DEBUG_PAGE_FAULT_WRITE : 0); - frame->eip = faultHandler; - frame->ebp = cpu.fault_handler_stack_pointer; - return; - } - - // No fault handler. This is bad. Since we originally came from a double - // fault, we don't try to reenter the kernel debugger. Instead we just - // print the info we've got and enter an infinite loop. - kprintf("Page fault in double fault debugger without fault handler! " - "Touching address %p from eip %p. Entering infinite loop...\n", - (void*)cr2, (void*)frame->eip); - - while (true); -} - - -static void -page_fault_exception(struct iframe* frame) -{ - Thread *thread = thread_get_current_thread(); - uint32 cr2; - addr_t newip; - - asm("movl %%cr2, %0" : "=r" (cr2)); - - if (debug_debugger_running()) { - // If this CPU or this thread has a fault handler, we're allowed to be - // here. - if (thread != NULL) { - cpu_ent* cpu = &gCPU[smp_get_current_cpu()]; - if (cpu->fault_handler != 0) { - debug_set_page_fault_info(cr2, frame->eip, - (frame->error_code & 0x2) != 0 - ? DEBUG_PAGE_FAULT_WRITE : 0); - frame->eip = cpu->fault_handler; - frame->ebp = cpu->fault_handler_stack_pointer; - return; - } - - if (thread->fault_handler != 0) { - kprintf("ERROR: thread::fault_handler used in kernel " - "debugger!\n"); - debug_set_page_fault_info(cr2, frame->eip, - (frame->error_code & 0x2) != 0 - ? DEBUG_PAGE_FAULT_WRITE : 0); - frame->eip = thread->fault_handler; - return; - } - } - - // otherwise, not really - panic("page fault in debugger without fault handler! Touching " - "address %p from eip %p\n", (void *)cr2, (void *)frame->eip); - return; - } else if ((frame->flags & 0x200) == 0) { - // interrupts disabled - - // If a page fault handler is installed, we're allowed to be here. - // TODO: Now we are generally allowing user_memcpy() with interrupts - // disabled, which in most cases is a bug. We should add some thread - // flag allowing to explicitly indicate that this handling is desired. - if (thread && thread->fault_handler != 0) { - if (frame->eip != thread->fault_handler) { - frame->eip = thread->fault_handler; - return; - } - - // The fault happened at the fault handler address. This is a - // certain infinite loop. - panic("page fault, interrupts disabled, fault handler loop. " - "Touching address %p from eip %p\n", (void*)cr2, - (void*)frame->eip); - } - - // If we are not running the kernel startup the page fault was not - // allowed to happen and we must panic. - panic("page fault, but interrupts were disabled. Touching address " - "%p from eip %p\n", (void *)cr2, (void *)frame->eip); - return; - } else if (thread != NULL && thread->page_faults_allowed < 1) { - panic("page fault not allowed at this place. Touching address " - "%p from eip %p\n", (void *)cr2, (void *)frame->eip); - return; - } - - enable_interrupts(); - - vm_page_fault(cr2, frame->eip, - (frame->error_code & 0x2) != 0, // write access - (frame->error_code & 0x4) != 0, // userland - &newip); - if (newip != 0) { - // the page fault handler wants us to modify the iframe to set the - // IP the cpu will return to to be this ip - frame->eip = newip; - } -} - - -static void -hardware_interrupt(struct iframe* frame) -{ - int32 vector = frame->vector - ARCH_INTERRUPT_BASE; - bool levelTriggered = false; - Thread* thread = thread_get_current_thread(); - - if (sCurrentPIC->is_spurious_interrupt(vector)) { - TRACE(("got spurious interrupt at vector %ld\n", vector)); - return; - } - - levelTriggered = sCurrentPIC->is_level_triggered_interrupt(vector); - - if (!levelTriggered) { - // if it's not handled by the current pic then it's an apic generated - // interrupt like local interrupts, msi or ipi. - if (!sCurrentPIC->end_of_interrupt(vector)) - apic_end_of_interrupt(); - } - - int_io_interrupt_handler(vector, levelTriggered); - - if (levelTriggered) { - if (!sCurrentPIC->end_of_interrupt(vector)) - apic_end_of_interrupt(); - } - - cpu_status state = disable_interrupts(); - if (thread->cpu->invoke_scheduler) { - SpinLocker schedulerLocker(gSchedulerLock); - scheduler_reschedule(); - schedulerLocker.Unlock(); - restore_interrupts(state); - } else if (thread->post_interrupt_callback != NULL) { - void (*callback)(void*) = thread->post_interrupt_callback; - void* data = thread->post_interrupt_data; - - thread->post_interrupt_callback = NULL; - thread->post_interrupt_data = NULL; - - restore_interrupts(state); - - callback(data); - } -} - - status_t -arch_int_init(struct kernel_args *args) +arch_int_init(kernel_args* args) { - int i; - interrupt_handler_function** table; - - // set the global sIDT variable - sIDTs[0] = (desc_table *)args->arch_args.vir_idt; - // setup the standard programmable interrupt controller pic_init(); - - set_interrupt_gate(0, 0, &trap0); - set_interrupt_gate(0, 1, &trap1); - set_interrupt_gate(0, 2, &trap2); - set_trap_gate(0, 3, &trap3); - set_interrupt_gate(0, 4, &trap4); - set_interrupt_gate(0, 5, &trap5); - set_interrupt_gate(0, 6, &trap6); - set_interrupt_gate(0, 7, &trap7); - // trap8 (double fault) is set in arch_cpu.c - set_interrupt_gate(0, 9, &trap9); - set_interrupt_gate(0, 10, &trap10); - set_interrupt_gate(0, 11, &trap11); - set_interrupt_gate(0, 12, &trap12); - set_interrupt_gate(0, 13, &trap13); - set_interrupt_gate(0, 14, &trap14); -// set_interrupt_gate(0, 15, &trap15); - set_interrupt_gate(0, 16, &trap16); - set_interrupt_gate(0, 17, &trap17); - set_interrupt_gate(0, 18, &trap18); - set_interrupt_gate(0, 19, &trap19); - - // legacy or ioapic interrupts - set_interrupt_gate(0, 32, &trap32); - set_interrupt_gate(0, 33, &trap33); - set_interrupt_gate(0, 34, &trap34); - set_interrupt_gate(0, 35, &trap35); - set_interrupt_gate(0, 36, &trap36); - set_interrupt_gate(0, 37, &trap37); - set_interrupt_gate(0, 38, &trap38); - set_interrupt_gate(0, 39, &trap39); - set_interrupt_gate(0, 40, &trap40); - set_interrupt_gate(0, 41, &trap41); - set_interrupt_gate(0, 42, &trap42); - set_interrupt_gate(0, 43, &trap43); - set_interrupt_gate(0, 44, &trap44); - set_interrupt_gate(0, 45, &trap45); - set_interrupt_gate(0, 46, &trap46); - set_interrupt_gate(0, 47, &trap47); - - // additional ioapic interrupts - set_interrupt_gate(0, 48, &trap48); - set_interrupt_gate(0, 49, &trap49); - set_interrupt_gate(0, 50, &trap50); - set_interrupt_gate(0, 51, &trap51); - set_interrupt_gate(0, 52, &trap52); - set_interrupt_gate(0, 53, &trap53); - set_interrupt_gate(0, 54, &trap54); - set_interrupt_gate(0, 55, &trap55); - - // configurable msi or msi-x interrupts - set_interrupt_gate(0, 56, &trap56); - set_interrupt_gate(0, 57, &trap57); - set_interrupt_gate(0, 58, &trap58); - set_interrupt_gate(0, 59, &trap59); - set_interrupt_gate(0, 60, &trap60); - set_interrupt_gate(0, 61, &trap61); - set_interrupt_gate(0, 62, &trap62); - set_interrupt_gate(0, 63, &trap63); - set_interrupt_gate(0, 64, &trap64); - set_interrupt_gate(0, 65, &trap65); - set_interrupt_gate(0, 66, &trap66); - set_interrupt_gate(0, 67, &trap67); - set_interrupt_gate(0, 68, &trap68); - set_interrupt_gate(0, 69, &trap69); - set_interrupt_gate(0, 70, &trap70); - set_interrupt_gate(0, 71, &trap71); - set_interrupt_gate(0, 72, &trap72); - set_interrupt_gate(0, 73, &trap73); - set_interrupt_gate(0, 74, &trap74); - set_interrupt_gate(0, 75, &trap75); - set_interrupt_gate(0, 76, &trap76); - set_interrupt_gate(0, 77, &trap77); - set_interrupt_gate(0, 78, &trap78); - set_interrupt_gate(0, 79, &trap79); - set_interrupt_gate(0, 80, &trap80); - set_interrupt_gate(0, 81, &trap81); - set_interrupt_gate(0, 82, &trap82); - set_interrupt_gate(0, 83, &trap83); - set_interrupt_gate(0, 84, &trap84); - set_interrupt_gate(0, 85, &trap85); - set_interrupt_gate(0, 86, &trap86); - set_interrupt_gate(0, 87, &trap87); - set_interrupt_gate(0, 88, &trap88); - set_interrupt_gate(0, 89, &trap89); - set_interrupt_gate(0, 90, &trap90); - set_interrupt_gate(0, 91, &trap91); - set_interrupt_gate(0, 92, &trap92); - set_interrupt_gate(0, 93, &trap93); - set_interrupt_gate(0, 94, &trap94); - set_interrupt_gate(0, 95, &trap95); - set_interrupt_gate(0, 96, &trap96); - set_interrupt_gate(0, 97, &trap97); - - set_trap_gate(0, 98, &trap98); // for performance testing only - set_trap_gate(0, 99, &trap99); // syscall interrupt - - reserve_io_interrupt_vectors(2, 98); - - // configurable msi or msi-x interrupts - set_interrupt_gate(0, 100, &trap100); - set_interrupt_gate(0, 101, &trap101); - set_interrupt_gate(0, 102, &trap102); - set_interrupt_gate(0, 103, &trap103); - set_interrupt_gate(0, 104, &trap104); - set_interrupt_gate(0, 105, &trap105); - set_interrupt_gate(0, 106, &trap106); - set_interrupt_gate(0, 107, &trap107); - set_interrupt_gate(0, 108, &trap108); - set_interrupt_gate(0, 109, &trap109); - set_interrupt_gate(0, 110, &trap110); - set_interrupt_gate(0, 111, &trap111); - set_interrupt_gate(0, 112, &trap112); - set_interrupt_gate(0, 113, &trap113); - set_interrupt_gate(0, 114, &trap114); - set_interrupt_gate(0, 115, &trap115); - set_interrupt_gate(0, 116, &trap116); - set_interrupt_gate(0, 117, &trap117); - set_interrupt_gate(0, 118, &trap118); - set_interrupt_gate(0, 119, &trap119); - set_interrupt_gate(0, 120, &trap120); - set_interrupt_gate(0, 121, &trap121); - set_interrupt_gate(0, 122, &trap122); - set_interrupt_gate(0, 123, &trap123); - set_interrupt_gate(0, 124, &trap124); - set_interrupt_gate(0, 125, &trap125); - set_interrupt_gate(0, 126, &trap126); - set_interrupt_gate(0, 127, &trap127); - set_interrupt_gate(0, 128, &trap128); - set_interrupt_gate(0, 129, &trap129); - set_interrupt_gate(0, 130, &trap130); - set_interrupt_gate(0, 131, &trap131); - set_interrupt_gate(0, 132, &trap132); - set_interrupt_gate(0, 133, &trap133); - set_interrupt_gate(0, 134, &trap134); - set_interrupt_gate(0, 135, &trap135); - set_interrupt_gate(0, 136, &trap136); - set_interrupt_gate(0, 137, &trap137); - set_interrupt_gate(0, 138, &trap138); - set_interrupt_gate(0, 139, &trap139); - set_interrupt_gate(0, 140, &trap140); - set_interrupt_gate(0, 141, &trap141); - set_interrupt_gate(0, 142, &trap142); - set_interrupt_gate(0, 143, &trap143); - set_interrupt_gate(0, 144, &trap144); - set_interrupt_gate(0, 145, &trap145); - set_interrupt_gate(0, 146, &trap146); - set_interrupt_gate(0, 147, &trap147); - set_interrupt_gate(0, 148, &trap148); - set_interrupt_gate(0, 149, &trap149); - set_interrupt_gate(0, 150, &trap150); - set_interrupt_gate(0, 151, &trap151); - set_interrupt_gate(0, 152, &trap152); - set_interrupt_gate(0, 153, &trap153); - set_interrupt_gate(0, 154, &trap154); - set_interrupt_gate(0, 155, &trap155); - set_interrupt_gate(0, 156, &trap156); - set_interrupt_gate(0, 157, &trap157); - set_interrupt_gate(0, 158, &trap158); - set_interrupt_gate(0, 159, &trap159); - set_interrupt_gate(0, 160, &trap160); - set_interrupt_gate(0, 161, &trap161); - set_interrupt_gate(0, 162, &trap162); - set_interrupt_gate(0, 163, &trap163); - set_interrupt_gate(0, 164, &trap164); - set_interrupt_gate(0, 165, &trap165); - set_interrupt_gate(0, 166, &trap166); - set_interrupt_gate(0, 167, &trap167); - set_interrupt_gate(0, 168, &trap168); - set_interrupt_gate(0, 169, &trap169); - set_interrupt_gate(0, 170, &trap170); - set_interrupt_gate(0, 171, &trap171); - set_interrupt_gate(0, 172, &trap172); - set_interrupt_gate(0, 173, &trap173); - set_interrupt_gate(0, 174, &trap174); - set_interrupt_gate(0, 175, &trap175); - set_interrupt_gate(0, 176, &trap176); - set_interrupt_gate(0, 177, &trap177); - set_interrupt_gate(0, 178, &trap178); - set_interrupt_gate(0, 179, &trap179); - set_interrupt_gate(0, 180, &trap180); - set_interrupt_gate(0, 181, &trap181); - set_interrupt_gate(0, 182, &trap182); - set_interrupt_gate(0, 183, &trap183); - set_interrupt_gate(0, 184, &trap184); - set_interrupt_gate(0, 185, &trap185); - set_interrupt_gate(0, 186, &trap186); - set_interrupt_gate(0, 187, &trap187); - set_interrupt_gate(0, 188, &trap188); - set_interrupt_gate(0, 189, &trap189); - set_interrupt_gate(0, 190, &trap190); - set_interrupt_gate(0, 191, &trap191); - set_interrupt_gate(0, 192, &trap192); - set_interrupt_gate(0, 193, &trap193); - set_interrupt_gate(0, 194, &trap194); - set_interrupt_gate(0, 195, &trap195); - set_interrupt_gate(0, 196, &trap196); - set_interrupt_gate(0, 197, &trap197); - set_interrupt_gate(0, 198, &trap198); - set_interrupt_gate(0, 199, &trap199); - set_interrupt_gate(0, 200, &trap200); - set_interrupt_gate(0, 201, &trap201); - set_interrupt_gate(0, 202, &trap202); - set_interrupt_gate(0, 203, &trap203); - set_interrupt_gate(0, 204, &trap204); - set_interrupt_gate(0, 205, &trap205); - set_interrupt_gate(0, 206, &trap206); - set_interrupt_gate(0, 207, &trap207); - set_interrupt_gate(0, 208, &trap208); - set_interrupt_gate(0, 209, &trap209); - set_interrupt_gate(0, 210, &trap210); - set_interrupt_gate(0, 211, &trap211); - set_interrupt_gate(0, 212, &trap212); - set_interrupt_gate(0, 213, &trap213); - set_interrupt_gate(0, 214, &trap214); - set_interrupt_gate(0, 215, &trap215); - set_interrupt_gate(0, 216, &trap216); - set_interrupt_gate(0, 217, &trap217); - set_interrupt_gate(0, 218, &trap218); - set_interrupt_gate(0, 219, &trap219); - set_interrupt_gate(0, 220, &trap220); - set_interrupt_gate(0, 221, &trap221); - set_interrupt_gate(0, 222, &trap222); - set_interrupt_gate(0, 223, &trap223); - set_interrupt_gate(0, 224, &trap224); - set_interrupt_gate(0, 225, &trap225); - set_interrupt_gate(0, 226, &trap226); - set_interrupt_gate(0, 227, &trap227); - set_interrupt_gate(0, 228, &trap228); - set_interrupt_gate(0, 229, &trap229); - set_interrupt_gate(0, 230, &trap230); - set_interrupt_gate(0, 231, &trap231); - set_interrupt_gate(0, 232, &trap232); - set_interrupt_gate(0, 233, &trap233); - set_interrupt_gate(0, 234, &trap234); - set_interrupt_gate(0, 235, &trap235); - set_interrupt_gate(0, 236, &trap236); - set_interrupt_gate(0, 237, &trap237); - set_interrupt_gate(0, 238, &trap238); - set_interrupt_gate(0, 239, &trap239); - set_interrupt_gate(0, 240, &trap240); - set_interrupt_gate(0, 241, &trap241); - set_interrupt_gate(0, 242, &trap242); - set_interrupt_gate(0, 243, &trap243); - set_interrupt_gate(0, 244, &trap244); - set_interrupt_gate(0, 245, &trap245); - set_interrupt_gate(0, 246, &trap246); - set_interrupt_gate(0, 247, &trap247); - set_interrupt_gate(0, 248, &trap248); - set_interrupt_gate(0, 249, &trap249); - set_interrupt_gate(0, 250, &trap250); - - // smp / apic local interrupts - set_interrupt_gate(0, 251, &trap251); - set_interrupt_gate(0, 252, &trap252); - set_interrupt_gate(0, 253, &trap253); - set_interrupt_gate(0, 254, &trap254); - set_interrupt_gate(0, 255, &trap255); - - // init interrupt handler table - table = gInterruptHandlerTable; - - // defaults - for (i = 0; i < ARCH_INTERRUPT_BASE; i++) - table[i] = invalid_exception; - for (i = ARCH_INTERRUPT_BASE; i < INTERRUPT_HANDLER_TABLE_SIZE; i++) - table[i] = hardware_interrupt; - - table[0] = unexpected_exception; // Divide Error Exception (#DE) - table[1] = x86_handle_debug_exception; // Debug Exception (#DB) - table[2] = fatal_exception; // NMI Interrupt - table[3] = x86_handle_breakpoint_exception; // Breakpoint Exception (#BP) - table[4] = unexpected_exception; // Overflow Exception (#OF) - table[5] = unexpected_exception; // BOUND Range Exceeded Exception (#BR) - table[6] = unexpected_exception; // Invalid Opcode Exception (#UD) - table[7] = fatal_exception; // Device Not Available Exception (#NM) - table[8] = x86_double_fault_exception; // Double Fault Exception (#DF) - table[9] = fatal_exception; // Coprocessor Segment Overrun - table[10] = fatal_exception; // Invalid TSS Exception (#TS) - table[11] = fatal_exception; // Segment Not Present (#NP) - table[12] = fatal_exception; // Stack Fault Exception (#SS) - table[13] = unexpected_exception; // General Protection Exception (#GP) - table[14] = page_fault_exception; // Page-Fault Exception (#PF) - table[16] = unexpected_exception; // x87 FPU Floating-Point Error (#MF) - table[17] = unexpected_exception; // Alignment Check Exception (#AC) - table[18] = fatal_exception; // Machine-Check Exception (#MC) - table[19] = unexpected_exception; // SIMD Floating-Point Exception (#XF) - return B_OK; } status_t -arch_int_init_post_vm(struct kernel_args *args) +arch_int_init_post_vm(kernel_args* args) { // Always init the local apic as it can be used for timers even if we // don't end up using the io apic apic_init(args); - - // create IDT area for the boot CPU - area_id area = create_area("idt", (void**)&sIDTs[0], B_EXACT_ADDRESS, - B_PAGE_SIZE, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); - if (area < 0) - return area; - - // create IDTs for the off-boot CPU - size_t idtSize = 256 * 8; - // 256 8 bytes-sized descriptors - int32 cpuCount = smp_get_num_cpus(); - if (cpuCount > 0) { - size_t areaSize = ROUNDUP(cpuCount * idtSize, B_PAGE_SIZE); - desc_table* idt; - virtual_address_restrictions virtualRestrictions = {}; - virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; - physical_address_restrictions physicalRestrictions = {}; - area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, - &virtualRestrictions, &physicalRestrictions, (void**)&idt); - if (area < 0) - return area; - - for (int32 i = 1; i < cpuCount; i++) { - sIDTs[i] = idt; - memcpy(idt, sIDTs[0], idtSize); - idt += 256; - // The CPU's IDTR will be set in arch_cpu_init_percpu(). - } - } - - return area >= B_OK ? B_OK : area; + return B_OK; } @@ -900,14 +417,14 @@ arch_int_init_io(kernel_args* args) status_t -arch_int_init_post_device_manager(struct kernel_args *args) +arch_int_init_post_device_manager(kernel_args* args) { return B_OK; } void -arch_int_set_interrupt_controller(const interrupt_controller &controller) +arch_int_set_interrupt_controller(const interrupt_controller& controller) { sCurrentPIC = &controller; } diff --git a/src/system/kernel/arch/x86/arch_platform.cpp b/src/system/kernel/arch/x86/arch_platform.cpp index 9dc40abf7d..d967139701 100644 --- a/src/system/kernel/arch/x86/arch_platform.cpp +++ b/src/system/kernel/arch/x86/arch_platform.cpp @@ -29,7 +29,10 @@ arch_platform_init_post_vm(struct kernel_args *args) status_t arch_platform_init_post_thread(struct kernel_args *args) { + // APM is not supported on x86_64. +#ifndef __x86_64__ apm_init(args); +#endif return B_OK; } diff --git a/src/system/kernel/arch/x86/arch_selector.cpp b/src/system/kernel/arch/x86/arch_selector.cpp deleted file mode 100644 index c9ade36f06..0000000000 --- a/src/system/kernel/arch/x86/arch_selector.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* -** Copyright 2002, Michael Noisternig. All rights reserved. -** Distributed under the terms of the NewOS License. -** Distributed under the terms of the MIT License as part of the OpenBeOS project. -*/ -#include -#include -#include -#include - -#include - -#define MAX_SELECTORS (GDT_LIMIT/8) -#define ENTRIES (MAX_SELECTORS/(sizeof(uint32)*8)) - -static uint32 selector_bitmap[ENTRIES] - = { 0x000000ff }; // first 8 selectors reserved - -static selector_type *gdt_table; -static struct gdt_idt_descr descr = { GDT_LIMIT - 1, NULL }; - -void i386_selector_init( void *gdt ) -{ - gdt_table = (selector_type *)gdt; - descr.b = (unsigned int *)gdt_table; -} - -// creates a new selector in the gdt of given type (use SELECTOR macro) -// IN: selector type -// RET: selector that can be directly used for segment registers -// 0 on error -selector_id i386_selector_add( selector_type type ) -{ - static spinlock spinlock; - int state; - uint32 mask; - selector_id id = 0; - unsigned i; - - state = disable_interrupts(); - acquire_spinlock( &spinlock ); - - for ( i = 0; i < ENTRIES; i++ ) - if ( selector_bitmap[i] != 0xffffffff ) { // found free place in there - id = i*sizeof(uint32)*8; - mask = 1; - while ( selector_bitmap[i] & mask ) { - mask <<= 1; - id++; - } - selector_bitmap[i] |= mask; - gdt_table[id] = type; - break; - } - - release_spinlock( &spinlock ); - restore_interrupts( state ); - - if ( id ) { - asm("lgdt %0;" - : : "m" (descr)); - } - - return id*8; -} - -// removes a selector with given id from the gdt -void i386_selector_remove( selector_id id ) -{ - if ( id < 8*8 || id >= MAX_SELECTORS*8 ) - return; - - id /= 8; - gdt_table[id] = 0; - - atomic_and( &selector_bitmap[id/32], ~(1<<(id&31)) ); - - asm("lgdt %0;" - : : "m" (descr)); -} - -// returns the selector type of a given id -selector_type i386_selector_get( selector_id id ) -{ - return gdt_table[id/8]; -} diff --git a/src/system/kernel/arch/x86/arch_smp.cpp b/src/system/kernel/arch/x86/arch_smp.cpp index 0720ae0bc6..b1aedd89f0 100644 --- a/src/system/kernel/arch/x86/arch_smp.cpp +++ b/src/system/kernel/arch/x86/arch_smp.cpp @@ -39,7 +39,7 @@ static uint32 sAPICVersions[B_MAX_CPU_COUNT]; static int32 -i386_ici_interrupt(void *data) +x86_ici_interrupt(void *data) { // genuine inter-cpu interrupt int cpu = smp_get_current_cpu(); @@ -49,10 +49,10 @@ i386_ici_interrupt(void *data) static int32 -i386_spurious_interrupt(void *data) +x86_spurious_interrupt(void *data) { // spurious interrupt - TRACE(("spurious interrupt on cpu %ld\n", smp_get_current_cpu())); + TRACE(("spurious interrupt on cpu %" B_PRId32 "\n", smp_get_current_cpu())); // spurious interrupts must not be acknowledged as it does not expect // a end of interrupt - if we still do it we would loose the next best @@ -62,10 +62,10 @@ i386_spurious_interrupt(void *data) static int32 -i386_smp_error_interrupt(void *data) +x86_smp_error_interrupt(void *data) { // smp error interrupt - TRACE(("smp error interrupt on cpu %ld\n", smp_get_current_cpu())); + TRACE(("smp error interrupt on cpu %" B_PRId32 "\n", smp_get_current_cpu())); return B_HANDLED_INTERRUPT; } @@ -91,9 +91,9 @@ arch_smp_init(kernel_args *args) if (args->num_cpus > 1) { // I/O interrupts start at ARCH_INTERRUPT_BASE, so all interrupts are shifted reserve_io_interrupt_vectors(3, 0xfd - ARCH_INTERRUPT_BASE); - install_io_interrupt_handler(0xfd - ARCH_INTERRUPT_BASE, &i386_ici_interrupt, NULL, B_NO_LOCK_VECTOR); - install_io_interrupt_handler(0xfe - ARCH_INTERRUPT_BASE, &i386_smp_error_interrupt, NULL, B_NO_LOCK_VECTOR); - install_io_interrupt_handler(0xff - ARCH_INTERRUPT_BASE, &i386_spurious_interrupt, NULL, B_NO_LOCK_VECTOR); + install_io_interrupt_handler(0xfd - ARCH_INTERRUPT_BASE, &x86_ici_interrupt, NULL, B_NO_LOCK_VECTOR); + install_io_interrupt_handler(0xfe - ARCH_INTERRUPT_BASE, &x86_smp_error_interrupt, NULL, B_NO_LOCK_VECTOR); + install_io_interrupt_handler(0xff - ARCH_INTERRUPT_BASE, &x86_spurious_interrupt, NULL, B_NO_LOCK_VECTOR); } return B_OK; @@ -104,7 +104,8 @@ status_t arch_smp_per_cpu_init(kernel_args *args, int32 cpu) { // set up the local apic on the current cpu - TRACE(("arch_smp_init_percpu: setting up the apic on cpu %ld\n", cpu)); + TRACE(("arch_smp_init_percpu: setting up the apic on cpu %" B_PRId32 "\n", + cpu)); apic_per_cpu_init(args, cpu); // setup FPU and SSE if supported @@ -154,7 +155,7 @@ arch_smp_send_ici(int32 target_cpu) asm volatile ("pause;"); if (timeout == 0) - panic("arch_smp_send_ici: timeout, target_cpu %ld", target_cpu); + panic("arch_smp_send_ici: timeout, target_cpu %" B_PRId32, target_cpu); restore_interrupts(state); } diff --git a/src/system/kernel/arch/x86/arch_system_info.cpp b/src/system/kernel/arch/x86/arch_system_info.cpp index 3f2eb22ceb..a1423ffaa7 100644 --- a/src/system/kernel/arch/x86/arch_system_info.cpp +++ b/src/system/kernel/arch/x86/arch_system_info.cpp @@ -50,7 +50,7 @@ get_cpuid(cpuid_info *info, uint32 eaxRegister, uint32 forCPU) // that the CPU supports cpuid. if (!get_cpuid_for(info, smp_get_current_cpu(), eaxRegister, forCPU)) { - smp_send_broadcast_ici(SMP_MSG_CALL_FUNCTION, (uint32)info, + smp_send_broadcast_ici(SMP_MSG_CALL_FUNCTION, (addr_t)info, eaxRegister, forCPU, (void *)get_cpuid_for, SMP_MSG_FLAG_SYNC); } @@ -68,7 +68,11 @@ arch_get_system_info(system_info *info, size_t size) // - various cpu_info info->cpu_clock_speed = sCpuClockSpeed; // - bus_clock_speed +#ifdef __x86_64__ + info->platform_type = B_64_BIT_PC_PLATFORM; +#else info->platform_type = B_AT_CLONE_PLATFORM; +#endif // ToDo: clock speeds could be retrieved via SMBIOS/DMI return B_OK; diff --git a/src/system/kernel/arch/x86/arch_thread.cpp b/src/system/kernel/arch/x86/arch_thread.cpp index 93cf26621b..e7b1298a59 100644 --- a/src/system/kernel/arch/x86/arch_thread.cpp +++ b/src/system/kernel/arch/x86/arch_thread.cpp @@ -11,97 +11,37 @@ #include -#include #include #include -#include #include #include #include #include #include #include -#include -#include #include #include #include "paging/X86PagingStructures.h" #include "paging/X86VMTranslationMap.h" -#include "x86_signals.h" #include "x86_syscalls.h" -//#define TRACE_ARCH_THREAD -#ifdef TRACE_ARCH_THREAD -# define TRACE(x) dprintf x -#else -# define TRACE(x) ; -#endif - - -#ifdef SYSCALL_TRACING - -namespace SyscallTracing { - -class RestartSyscall : public AbstractTraceEntry { - public: - RestartSyscall() - { - Initialized(); - } - - virtual void AddDump(TraceOutput& out) - { - out.Print("syscall restart"); - } -}; - -} - -# define TSYSCALL(x) new(std::nothrow) SyscallTracing::x - -#else -# define TSYSCALL(x) -#endif // SYSCALL_TRACING - - // from arch_interrupts.S -extern "C" void i386_stack_init(struct farcall *interrupt_stack_offset); extern "C" void x86_return_to_userland(iframe* frame); -// from arch_cpu.c +// from arch_cpu.cpp extern void (*gX86SwapFPUFunc)(void *oldState, const void *newState); -extern bool gHasSSE; - -static struct arch_thread sInitialState _ALIGNED(16); - // the fpu_state must be aligned on a 16 byte boundary, so that fxsave can use it -status_t -arch_thread_init(struct kernel_args *args) -{ - // save one global valid FPU state; it will be copied in the arch dependent - // part of each new thread - - asm volatile ("clts; fninit; fnclex;"); - if (gHasSSE) - i386_fxsave(sInitialState.fpu_state); - else - i386_fnsave(sInitialState.fpu_state); - - return B_OK; -} - - -static struct iframe * -find_previous_iframe(Thread *thread, addr_t frame) +static struct iframe* +find_previous_iframe(Thread* thread, addr_t frame) { // iterate backwards through the stack frames, until we hit an iframe while (frame >= thread->kernel_stack_base && frame < thread->kernel_stack_top) { addr_t previousFrame = *(addr_t*)frame; - if ((previousFrame & ~IFRAME_TYPE_MASK) == 0) { + if ((previousFrame & ~(addr_t)IFRAME_TYPE_MASK) == 0) { if (previousFrame == 0) return NULL; return (struct iframe*)frame; @@ -120,7 +60,7 @@ get_previous_iframe(struct iframe* frame) if (frame == NULL) return NULL; - return find_previous_iframe(thread_get_current_thread(), frame->ebp); + return find_previous_iframe(thread_get_current_thread(), frame->bp); } @@ -133,39 +73,8 @@ get_previous_iframe(struct iframe* frame) static struct iframe* get_current_iframe(void) { - return find_previous_iframe(thread_get_current_thread(), x86_read_ebp()); -} - - -static inline void -set_fs_register(uint32 segment) -{ - asm("movl %0,%%fs" :: "r" (segment)); -} - - -/*! Returns to the userland environment given by \a frame for a thread not - having been userland before. - - Before returning to userland all potentially necessary kernel exit work is - done. - - \param thread The current thread. - \param frame The iframe defining the userland environment. Must point to a - location somewhere on the caller's stack (e.g. a local variable). -*/ -static void -initial_return_to_userland(Thread* thread, iframe* frame) -{ - // disable interrupts and set up CPU specifics for this thread - disable_interrupts(); - - i386_set_tss_and_kstack(thread->kernel_stack_top); - x86_set_tls_context(thread); - x86_set_syscall_stack(thread->kernel_stack_top); - - // return to userland - x86_return_to_userland(frame); + return find_previous_iframe(thread_get_current_thread(), + x86_get_stack_frame()); } @@ -176,8 +85,8 @@ initial_return_to_userland(Thread* thread, iframe* frame) \return The iframe, or \c NULL, if there is no such iframe (e.g. when the thread is a kernel thread). */ -struct iframe * -i386_get_user_iframe(void) +struct iframe* +x86_get_user_iframe(void) { struct iframe* frame = get_current_iframe(); @@ -191,20 +100,18 @@ i386_get_user_iframe(void) } -/*! \brief Like i386_get_user_iframe(), just for the given thread. +/*! \brief Like x86_get_user_iframe(), just for the given thread. The thread must not be running and the threads spinlock must be held. */ -struct iframe * -i386_get_thread_user_iframe(Thread *thread) +struct iframe* +x86_get_thread_user_iframe(Thread *thread) { if (thread->state == B_THREAD_RUNNING) return NULL; - // read %ebp from the thread's stack stored by a pushad - addr_t ebp = thread->arch_info.current_stack.esp[2]; - // find the user iframe - struct iframe *frame = find_previous_iframe(thread, ebp); + struct iframe* frame = find_previous_iframe(thread, + thread->arch_info.GetFramePointer()); while (frame != NULL) { if (IFRAME_IS_USER(frame)) @@ -216,15 +123,15 @@ i386_get_thread_user_iframe(Thread *thread) } -struct iframe * -i386_get_current_iframe(void) +struct iframe* +x86_get_current_iframe(void) { return get_current_iframe(); } -uint32 -x86_next_page_directory(Thread *from, Thread *to) +phys_addr_t +x86_next_page_directory(Thread* from, Thread* to) { VMAddressSpace* toAddressSpace = to->team->address_space; if (from->team->address_space == toAddressSpace) { @@ -240,47 +147,28 @@ x86_next_page_directory(Thread *from, Thread *to) } +/*! Returns to the userland environment given by \a frame for a thread not + having been userland before. + + Before returning to userland all potentially necessary kernel exit work is + done. + + \param thread The current thread. + \param frame The iframe defining the userland environment. Must point to a + location somewhere on the caller's stack (e.g. a local variable). +*/ void -x86_restart_syscall(struct iframe* frame) +x86_initial_return_to_userland(Thread* thread, iframe* frame) { - Thread* thread = thread_get_current_thread(); + // disable interrupts and set up CPU specifics for this thread + disable_interrupts(); - atomic_and(&thread->flags, ~THREAD_FLAGS_RESTART_SYSCALL); - atomic_or(&thread->flags, THREAD_FLAGS_SYSCALL_RESTARTED); + get_cpu_struct()->arch.tss.sp0 = thread->kernel_stack_top; + x86_set_tls_context(thread); + x86_set_syscall_stack(thread->kernel_stack_top); - frame->eax = frame->orig_eax; - frame->edx = frame->orig_edx; - frame->eip -= 2; - // undoes the "int $99"/"sysenter"/"syscall" instruction - // (so that it'll be executed again) - - TSYSCALL(RestartSyscall()); -} - - -void -x86_set_tls_context(Thread *thread) -{ - int entry = smp_get_current_cpu() + TLS_BASE_SEGMENT; - - set_segment_descriptor_base(&gGDT[entry], thread->user_local_storage); - set_fs_register((entry << 3) | DPL_USER); -} - - -static uint8* -get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action) -{ - // use the alternate signal stack if we should and can - if (thread->signal_stack_enabled - && (action->sa_flags & SA_ONSTACK) != 0 - && (frame->user_esp < thread->signal_stack_base - || frame->user_esp >= thread->signal_stack_base - + thread->signal_stack_size)) { - return (uint8*)(thread->signal_stack_base + thread->signal_stack_size); - } - - return (uint8*)frame->user_esp; + // return to userland + x86_return_to_userland(frame); } @@ -288,68 +176,21 @@ get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action) status_t -arch_team_init_team_struct(Team *p, bool kernel) +arch_team_init_team_struct(Team* p, bool kernel) { return B_OK; } -status_t -arch_thread_init_thread_struct(Thread *thread) -{ - // set up an initial state (stack & fpu) - memcpy(&thread->arch_info, &sInitialState, sizeof(struct arch_thread)); - return B_OK; -} - - -/*! Prepares the given thread's kernel stack for executing its entry function. - - \param thread The thread. - \param stack The usable bottom of the thread's kernel stack. - \param stackTop The usable top of the thread's kernel stack. - \param function The entry function the thread shall execute. - \param data Pointer to be passed to the entry function. +/*! Initializes the user-space TLS local storage pointer in + the thread structure, and the reserved TLS slots. + + Is called from _create_user_thread_kentry(). */ -void -arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop, - void (*function)(void*), const void* data) -{ - addr_t* stackTop = (addr_t*)_stackTop; - - TRACE(("arch_thread_init_kthread_stack: stack top %p, function %p, data: " - "%p\n", stackTop, function, data)); - - // push the function argument, a pointer to the data - *--stackTop = (addr_t)data; - - // push a dummy return address for the function - *--stackTop = 0; - - // push the function address -- that's the return address used after the - // context switch - *--stackTop = (addr_t)function; - - // simulate pushad as done by x86_context_switch() - for (int i = 0; i < 8; i++) - *--stackTop = 0; - - // save the stack position - thread->arch_info.current_stack.esp = stackTop; - thread->arch_info.current_stack.ss = (addr_t*)KERNEL_DATA_SEG; -} - - -/** Initializes the user-space TLS local storage pointer in - * the thread structure, and the reserved TLS slots. - * - * Is called from _create_user_thread_kentry(). - */ - status_t -arch_thread_init_tls(Thread *thread) +arch_thread_init_tls(Thread* thread) { - uint32 tls[TLS_USER_THREAD_SLOT + 1]; + size_t tls[TLS_USER_THREAD_SLOT + 1]; thread->user_local_storage = thread->user_stack_base + thread->user_stack_size; @@ -360,14 +201,16 @@ arch_thread_init_tls(Thread *thread) tls[TLS_THREAD_ID_SLOT] = thread->id; tls[TLS_USER_THREAD_SLOT] = (addr_t)thread->user_thread; - return user_memcpy((void *)thread->user_local_storage, tls, sizeof(tls)); + return user_memcpy((void*)thread->user_local_storage, tls, sizeof(tls)); } void -arch_thread_context_switch(Thread *from, Thread *to) +arch_thread_context_switch(Thread* from, Thread* to) { - i386_set_tss_and_kstack(to->kernel_stack_top); + cpu_ent* cpuData = to->cpu; + + cpuData->arch.tss.sp0 = to->kernel_stack_top; x86_set_syscall_stack(to->kernel_stack_top); // set TLS GDT entry to the current thread - since this action is @@ -375,7 +218,6 @@ arch_thread_context_switch(Thread *from, Thread *to) if (to->user_local_storage != 0) x86_set_tls_context(to); - struct cpu_ent* cpuData = to->cpu; X86PagingStructures* activePagingStructures = cpuData->arch.active_paging_structures; VMAddressSpace* toAddressSpace = to->team->address_space; @@ -396,7 +238,7 @@ arch_thread_context_switch(Thread *from, Thread *to) cpuData->arch.active_paging_structures = toPagingStructures; // set the page directory, if it changes - uint32 newPageDirectory = toPagingStructures->pgdir_phys; + addr_t newPageDirectory = toPagingStructures->pgdir_phys; if (newPageDirectory != activePagingStructures->pgdir_phys) x86_swap_pgdir(newPageDirectory); @@ -409,225 +251,31 @@ arch_thread_context_switch(Thread *from, Thread *to) } -void -arch_thread_dump_info(void *info) -{ - struct arch_thread *at = (struct arch_thread *)info; - - kprintf("\tesp: %p\n", at->current_stack.esp); - kprintf("\tss: %p\n", at->current_stack.ss); - kprintf("\tfpu_state at %p\n", at->fpu_state); -} - - -/*! Sets up initial thread context and enters user space -*/ -status_t -arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1, - void* args2) -{ - addr_t stackTop = thread->user_stack_base + thread->user_stack_size; - uint32 codeSize = (addr_t)x86_end_userspace_thread_exit - - (addr_t)x86_userspace_thread_exit; - uint32 args[3]; - - TRACE(("arch_thread_enter_userspace: entry 0x%lx, args %p %p, " - "ustack_top 0x%lx\n", entry, args1, args2, stackTop)); - - // copy the little stub that calls exit_thread() when the thread entry - // function returns, as well as the arguments of the entry function - stackTop -= codeSize; - - if (user_memcpy((void *)stackTop, (const void *)&x86_userspace_thread_exit, codeSize) < B_OK) - return B_BAD_ADDRESS; - - args[0] = stackTop; - args[1] = (uint32)args1; - args[2] = (uint32)args2; - stackTop -= sizeof(args); - - if (user_memcpy((void *)stackTop, args, sizeof(args)) < B_OK) - return B_BAD_ADDRESS; - - // prepare the user iframe - iframe frame = {}; - frame.type = IFRAME_TYPE_SYSCALL; - frame.gs = USER_DATA_SEG; - // frame.fs not used, we call x86_set_tls_context() on context switch - frame.es = USER_DATA_SEG; - frame.ds = USER_DATA_SEG; - frame.eip = entry; - frame.cs = USER_CODE_SEG; - frame.flags = X86_EFLAGS_RESERVED1 | X86_EFLAGS_INTERRUPT - | (3 << X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT); - frame.user_esp = stackTop; - frame.user_ss = USER_DATA_SEG; - - // return to userland - initial_return_to_userland(thread, &frame); - - return B_OK; - // never gets here -} - - bool arch_on_signal_stack(Thread *thread) { - struct iframe *frame = get_current_iframe(); + struct iframe* frame = get_current_iframe(); - return frame->user_esp >= thread->signal_stack_base - && frame->user_esp < thread->signal_stack_base + return frame->user_sp >= thread->signal_stack_base + && frame->user_sp < thread->signal_stack_base + thread->signal_stack_size; } -/*! Sets up the user iframe for invoking a signal handler. - - The function fills in the remaining fields of the given \a signalFrameData, - copies it to the thread's userland stack (the one on which the signal shall - be handled), and sets up the user iframe so that when returning to userland - a wrapper function is executed that calls the user-defined signal handler. - When the signal handler returns, the wrapper function shall call the - "restore signal frame" syscall with the (possibly modified) signal frame - data. - - The following fields of the \a signalFrameData structure still need to be - filled in: - - \c context.uc_stack: The stack currently used by the thread. - - \c context.uc_mcontext: The current userland state of the registers. - - \c syscall_restart_return_value: Architecture specific use. On x86 the - value of eax and edx which are overwritten by the syscall return value. - - Furthermore the function needs to set \c thread->user_signal_context to the - userland pointer to the \c ucontext_t on the user stack. - - \param thread The current thread. - \param action The signal action specified for the signal to be handled. - \param signalFrameData A partially initialized structure of all the data - that need to be copied to userland. - \return \c B_OK on success, another error code, if something goes wrong. +/*! Saves everything needed to restore the frame in the child fork in the + arch_fork_arg structure to be passed to arch_restore_fork_frame(). + Also makes sure to return the right value. */ -status_t -arch_setup_signal_frame(Thread* thread, struct sigaction* action, - struct signal_frame_data* signalFrameData) -{ - struct iframe *frame = get_current_iframe(); - if (!IFRAME_IS_USER(frame)) { - panic("arch_setup_signal_frame(): No user iframe!"); - return B_BAD_VALUE; - } - - // In case of a BeOS compatible handler map SIGBUS to SIGSEGV, since they - // had the same signal number. - if ((action->sa_flags & SA_BEOS_COMPATIBLE_HANDLER) != 0 - && signalFrameData->info.si_signo == SIGBUS) { - signalFrameData->info.si_signo = SIGSEGV; - } - - // store the register state in signalFrameData->context.uc_mcontext - signalFrameData->context.uc_mcontext.eip = frame->eip; - signalFrameData->context.uc_mcontext.eflags = frame->flags; - signalFrameData->context.uc_mcontext.eax = frame->eax; - signalFrameData->context.uc_mcontext.ecx = frame->ecx; - signalFrameData->context.uc_mcontext.edx = frame->edx; - signalFrameData->context.uc_mcontext.ebp = frame->ebp; - signalFrameData->context.uc_mcontext.esp = frame->user_esp; - signalFrameData->context.uc_mcontext.edi = frame->edi; - signalFrameData->context.uc_mcontext.esi = frame->esi; - signalFrameData->context.uc_mcontext.ebx = frame->ebx; - i386_fnsave((void *)(&signalFrameData->context.uc_mcontext.xregs)); - - // fill in signalFrameData->context.uc_stack - signal_get_user_stack(frame->user_esp, &signalFrameData->context.uc_stack); - - // store orig_eax/orig_edx in syscall_restart_return_value - signalFrameData->syscall_restart_return_value - = (uint64)frame->orig_edx << 32 | frame->orig_eax; - - // get the stack to use -- that's either the current one or a special signal - // stack - uint8* userStack = get_signal_stack(thread, frame, action); - - // copy the signal frame data onto the stack - userStack -= sizeof(*signalFrameData); - signal_frame_data* userSignalFrameData = (signal_frame_data*)userStack; - if (user_memcpy(userSignalFrameData, signalFrameData, - sizeof(*signalFrameData)) != B_OK) { - return B_BAD_ADDRESS; - } - - // prepare the user stack frame for a function call to the signal handler - // wrapper function - uint32 stackFrame[2] = { - frame->eip, // return address - (addr_t)userSignalFrameData, // parameter: pointer to signal frame data - }; - - userStack -= sizeof(stackFrame); - if (user_memcpy(userStack, stackFrame, sizeof(stackFrame)) != B_OK) - return B_BAD_ADDRESS; - - // Update Thread::user_signal_context, now that everything seems to have - // gone fine. - thread->user_signal_context = &userSignalFrameData->context; - - // Adjust the iframe's esp and eip, so that the thread will continue with - // the prepared stack, executing the signal handler wrapper function. - frame->user_esp = (addr_t)userStack; - frame->eip = x86_get_user_signal_handler_wrapper( - (action->sa_flags & SA_BEOS_COMPATIBLE_HANDLER) != 0); - - return B_OK; -} - - -int64 -arch_restore_signal_frame(struct signal_frame_data* signalFrameData) -{ - struct iframe* frame = get_current_iframe(); - - TRACE(("### arch_restore_signal_frame: entry\n")); - - frame->orig_eax = (uint32)signalFrameData->syscall_restart_return_value; - frame->orig_edx - = (uint32)(signalFrameData->syscall_restart_return_value >> 32); - - frame->eip = signalFrameData->context.uc_mcontext.eip; - frame->flags = (frame->flags & ~(uint32)X86_EFLAGS_USER_FLAGS) - | (signalFrameData->context.uc_mcontext.eflags & X86_EFLAGS_USER_FLAGS); - frame->eax = signalFrameData->context.uc_mcontext.eax; - frame->ecx = signalFrameData->context.uc_mcontext.ecx; - frame->edx = signalFrameData->context.uc_mcontext.edx; - frame->ebp = signalFrameData->context.uc_mcontext.ebp; - frame->user_esp = signalFrameData->context.uc_mcontext.esp; - frame->edi = signalFrameData->context.uc_mcontext.edi; - frame->esi = signalFrameData->context.uc_mcontext.esi; - frame->ebx = signalFrameData->context.uc_mcontext.ebx; - - i386_frstor((void*)(&signalFrameData->context.uc_mcontext.xregs)); - - TRACE(("### arch_restore_signal_frame: exit\n")); - - return (int64)frame->eax | ((int64)frame->edx << 32); -} - - -/** Saves everything needed to restore the frame in the child fork in the - * arch_fork_arg structure to be passed to arch_restore_fork_frame(). - * Also makes sure to return the right value. - */ - void -arch_store_fork_frame(struct arch_fork_arg *arg) +arch_store_fork_frame(struct arch_fork_arg* arg) { - struct iframe *frame = get_current_iframe(); + struct iframe* frame = x86_get_current_iframe(); // we need to copy the threads current iframe arg->iframe = *frame; // we also want fork() to return 0 for the child - arg->iframe.eax = 0; + arg->iframe.ax = 0; } @@ -645,13 +293,5 @@ arch_store_fork_frame(struct arch_fork_arg *arg) void arch_restore_fork_frame(struct arch_fork_arg* arg) { - initial_return_to_userland(thread_get_current_thread(), &arg->iframe); -} - - -void -arch_syscall_64_bit_return_value(void) -{ - Thread* thread = thread_get_current_thread(); - atomic_or(&thread->flags, THREAD_FLAGS_64_BIT_SYSCALL_RETURN); + x86_initial_return_to_userland(thread_get_current_thread(), &arg->iframe); } diff --git a/src/system/kernel/arch/x86/arch_timer.cpp b/src/system/kernel/arch/x86/arch_timer.cpp index 3ee378a905..2248afa4fd 100644 --- a/src/system/kernel/arch/x86/arch_timer.cpp +++ b/src/system/kernel/arch/x86/arch_timer.cpp @@ -24,7 +24,6 @@ #include #include -#include "interrupts.h" //#define TRACE_TIMER #ifdef TRACE_TIMER diff --git a/src/system/kernel/arch/x86/arch_user_debugger.cpp b/src/system/kernel/arch/x86/arch_user_debugger.cpp index 3a2673c367..3857c3d06a 100644 --- a/src/system/kernel/arch/x86/arch_user_debugger.cpp +++ b/src/system/kernel/arch/x86/arch_user_debugger.cpp @@ -39,27 +39,27 @@ extern bool gHasSSE; const uint8 kX86SoftwareBreakpoint[1] = { 0xcc }; // maps breakpoint slot index to LEN_i LSB number -static const uint32 sDR7Len[4] = { +static const size_t sDR7Len[4] = { X86_DR7_LEN0_LSB, X86_DR7_LEN1_LSB, X86_DR7_LEN2_LSB, X86_DR7_LEN3_LSB }; // maps breakpoint slot index to R/W_i LSB number -static const uint32 sDR7RW[4] = { +static const size_t sDR7RW[4] = { X86_DR7_RW0_LSB, X86_DR7_RW1_LSB, X86_DR7_RW2_LSB, X86_DR7_RW3_LSB }; // maps breakpoint slot index to L_i bit number -static const uint32 sDR7L[4] = { +static const size_t sDR7L[4] = { X86_DR7_L0, X86_DR7_L1, X86_DR7_L2, X86_DR7_L3 }; // maps breakpoint slot index to G_i bit number -static const uint32 sDR7G[4] = { +static const size_t sDR7G[4] = { X86_DR7_G0, X86_DR7_G1, X86_DR7_G2, X86_DR7_G3 }; // maps breakpoint slot index to B_i bit number -static const uint32 sDR6B[4] = { +static const size_t sDR6B[4] = { X86_DR6_B0, X86_DR6_B1, X86_DR6_B2, X86_DR6_B3 }; @@ -68,50 +68,151 @@ static const uint32 sDR6B[4] = { static bool sQEmuSingleStepHack = false; +#ifdef __x86_64__ + + static void -get_iframe_registers(struct iframe *frame, debug_cpu_state *cpuState) +get_iframe_registers(const iframe* frame, debug_cpu_state* cpuState) +{ + // Get general purpose registers. + cpuState->r15 = frame->r15; + cpuState->r14 = frame->r14; + cpuState->r13 = frame->r13; + cpuState->r12 = frame->r12; + cpuState->r11 = frame->r11; + cpuState->r10 = frame->r10; + cpuState->r9 = frame->r9; + cpuState->r8 = frame->r8; + cpuState->rbp = frame->bp; + cpuState->rsi = frame->si; + cpuState->rdi = frame->di; + cpuState->rdx = frame->dx; + cpuState->rcx = frame->cx; + cpuState->rbx = frame->bx; + cpuState->rax = frame->ax; + cpuState->rip = frame->ip; + cpuState->cs = frame->cs; + cpuState->rflags = frame->flags; + cpuState->rsp = frame->sp; + cpuState->ss = frame->ss; + + // Other segment registers are not saved or changed on interrupts, so + // get their value here. + uint16 seg; + __asm__ volatile ("movw %%ds, %0" : "=r" (seg)); + cpuState->ds = seg; + __asm__ volatile ("movw %%es, %0" : "=r" (seg)); + cpuState->es = seg; + __asm__ volatile ("movw %%fs, %0" : "=r" (seg)); + cpuState->fs = seg; + __asm__ volatile ("movw %%gs, %0" : "=r" (seg)); + cpuState->gs = seg; +} + + +static void +set_iframe_registers(iframe* frame, const debug_cpu_state* cpuState) +{ + frame->r15 = cpuState->r15; + frame->r14 = cpuState->r14; + frame->r13 = cpuState->r13; + frame->r12 = cpuState->r12; + frame->r11 = cpuState->r11; + frame->r10 = cpuState->r10; + frame->r9 = cpuState->r9; + frame->r8 = cpuState->r8; + frame->bp = cpuState->rbp; + frame->si = cpuState->rsi; + frame->di = cpuState->rdi; + frame->dx = cpuState->rdx; + frame->cx = cpuState->rcx; + frame->bx = cpuState->rbx; + frame->ax = cpuState->rax; + frame->ip = cpuState->rip; + frame->flags = (frame->flags & ~X86_EFLAGS_USER_SETTABLE_FLAGS) + | (cpuState->rflags & X86_EFLAGS_USER_SETTABLE_FLAGS); + frame->sp = cpuState->rsp; +} + + +#else // __x86_64__ + + +static void +get_iframe_registers(const iframe* frame, debug_cpu_state* cpuState) { cpuState->gs = frame->gs; cpuState->fs = frame->fs; cpuState->es = frame->es; cpuState->ds = frame->ds; - cpuState->edi = frame->edi; - cpuState->esi = frame->esi; - cpuState->ebp = frame->ebp; - cpuState->esp = frame->esp; - cpuState->ebx = frame->ebx; + cpuState->edi = frame->di; + cpuState->esi = frame->si; + cpuState->ebp = frame->bp; + cpuState->esp = frame->sp; + cpuState->ebx = frame->bx; cpuState->edx = frame->orig_edx; - cpuState->ecx = frame->ecx; + cpuState->ecx = frame->cx; cpuState->eax = frame->orig_eax; cpuState->vector = frame->vector; cpuState->error_code = frame->error_code; - cpuState->eip = frame->eip; + cpuState->eip = frame->ip; cpuState->cs = frame->cs; cpuState->eflags = frame->flags; - cpuState->user_esp = frame->user_esp; + cpuState->user_esp = frame->user_sp; cpuState->user_ss = frame->user_ss; } +static void +set_iframe_registers(iframe* frame, const debug_cpu_state* cpuState) +{ +// frame->gs = cpuState->gs; +// frame->fs = cpuState->fs; +// frame->es = cpuState->es; +// frame->ds = cpuState->ds; + frame->di = cpuState->edi; + frame->si = cpuState->esi; + frame->bp = cpuState->ebp; +// frame->esp = cpuState->esp; + frame->bx = cpuState->ebx; + frame->dx = cpuState->edx; + frame->cx = cpuState->ecx; + frame->ax = cpuState->eax; +// frame->vector = cpuState->vector; +// frame->error_code = cpuState->error_code; + frame->ip = cpuState->eip; +// frame->cs = cpuState->cs; + frame->flags = (frame->flags & ~X86_EFLAGS_USER_SETTABLE_FLAGS) + | (cpuState->eflags & X86_EFLAGS_USER_SETTABLE_FLAGS); + frame->user_sp = cpuState->user_esp; +// frame->user_ss = cpuState->user_ss; +} + + +#endif // __x86_64__ + + static inline void -install_breakpoints(const arch_team_debug_info &teamInfo) +install_breakpoints(const arch_team_debug_info& teamInfo) { // set breakpoints - asm("movl %0, %%dr0" : : "r"(teamInfo.breakpoints[0].address)); - asm("movl %0, %%dr1" : : "r"(teamInfo.breakpoints[1].address)); - asm("movl %0, %%dr2" : : "r"(teamInfo.breakpoints[2].address)); -// asm("movl %0, %%dr3" : : "r"(teamInfo.breakpoints[3].address)); - // DR3 is used to hold the current Thread*. + asm("mov %0, %%dr0" : : "r"(teamInfo.breakpoints[0].address)); + asm("mov %0, %%dr1" : : "r"(teamInfo.breakpoints[1].address)); + asm("mov %0, %%dr2" : : "r"(teamInfo.breakpoints[2].address)); +#ifdef __x86_64__ + asm("mov %0, %%dr3" : : "r"(teamInfo.breakpoints[3].address)); + // DR3 is used to hold the current Thread* on 32. +#endif // enable breakpoints - asm("movl %0, %%dr7" : : "r"(teamInfo.dr7)); + asm("mov %0, %%dr7" : : "r"(teamInfo.dr7)); } static inline void disable_breakpoints() { - asm("movl %0, %%dr7" : : "r"(X86_BREAKPOINTS_DISABLED_DR7)); + asm("mov %0, %%dr7" : : "r"((size_t)X86_BREAKPOINTS_DISABLED_DR7)); } @@ -119,8 +220,8 @@ disable_breakpoints() Interrupts must be disabled and the team debug info lock be held. */ static inline status_t -set_breakpoint(arch_team_debug_info &info, void *address, uint32 type, - uint32 length, bool setGlobalFlag) +set_breakpoint(arch_team_debug_info& info, void* address, size_t type, + size_t length, bool setGlobalFlag) { // check, if there is already a breakpoint at that address bool alreadySet = false; @@ -169,7 +270,7 @@ set_breakpoint(arch_team_debug_info &info, void *address, uint32 type, Interrupts must be disabled and the team debug info lock be held. */ static inline status_t -clear_breakpoint(arch_team_debug_info &info, void *address, bool watchpoint) +clear_breakpoint(arch_team_debug_info& info, void* address, bool watchpoint) { // find the breakpoint int32 slot = -1; @@ -202,12 +303,12 @@ clear_breakpoint(arch_team_debug_info &info, void *address, bool watchpoint) static status_t -set_breakpoint(void *address, uint32 type, uint32 length) +set_breakpoint(void* address, size_t type, size_t length) { if (!address) return B_BAD_VALUE; - Thread *thread = thread_get_current_thread(); + Thread* thread = thread_get_current_thread(); cpu_status state = disable_interrupts(); GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info); @@ -223,12 +324,12 @@ set_breakpoint(void *address, uint32 type, uint32 length) static status_t -clear_breakpoint(void *address, bool watchpoint) +clear_breakpoint(void* address, bool watchpoint) { if (!address) return B_BAD_VALUE; - Thread *thread = thread_get_current_thread(); + Thread* thread = thread_get_current_thread(); cpu_status state = disable_interrupts(); GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info); @@ -260,7 +361,7 @@ install_breakpoints_per_cpu(void* /*cookie*/, int cpu) static status_t -set_kernel_breakpoint(void *address, uint32 type, uint32 length) +set_kernel_breakpoint(void* address, size_t type, size_t length) { if (!address) return B_BAD_VALUE; @@ -284,7 +385,7 @@ set_kernel_breakpoint(void *address, uint32 type, uint32 length) static status_t -clear_kernel_breakpoint(void *address, bool watchpoint) +clear_kernel_breakpoint(void* address, bool watchpoint) { if (!address) return B_BAD_VALUE; @@ -311,7 +412,7 @@ clear_kernel_breakpoint(void *address, bool watchpoint) static inline status_t check_watch_point_parameters(void* address, uint32 type, int32 length, - uint32& archType, uint32& archLength) + size_t& archType, size_t& archLength) { // check type switch (type) { @@ -333,12 +434,12 @@ check_watch_point_parameters(void* address, uint32 type, int32 length, archLength = X86_BREAKPOINT_LENGTH_1; break; case 2: - if ((uint32)address & 0x1) + if ((addr_t)address & 0x1) return B_BAD_WATCHPOINT_ALIGNMENT; archLength = X86_BREAKPOINT_LENGTH_2; break; case 4: - if ((uint32)address & 0x3) + if ((addr_t)address & 0x3) return B_BAD_WATCHPOINT_ALIGNMENT; archLength = X86_BREAKPOINT_LENGTH_4; break; @@ -352,6 +453,7 @@ check_watch_point_parameters(void* address, uint32 type, int32 length, // #pragma mark - kernel debugger commands + #if KERNEL_BREAKPOINTS static int @@ -361,7 +463,7 @@ debugger_breakpoints(int argc, char** argv) arch_team_debug_info& info = kernelTeam->debug_info.arch_info; for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) { - kprintf("breakpoint[%ld] ", i); + kprintf("breakpoint[%" B_PRId32 "] ", i); if (info.breakpoints[i].address != NULL) { kprintf("%p ", info.breakpoints[i].address); @@ -491,7 +593,7 @@ debugger_watchpoint(int argc, char** argv) uint32 type = readWrite ? B_DATA_READ_WRITE_WATCHPOINT : B_DATA_WRITE_WATCHPOINT; - uint32 archType, archLength; + size_t archType, archLength; error = check_watch_point_parameters((void*)address, type, length, archType, archLength); @@ -516,7 +618,7 @@ debugger_single_step(int argc, char** argv) // TODO: Since we need an iframe, this doesn't work when KDL wasn't entered // via an exception. - struct iframe* frame = i386_get_current_iframe(); + iframe* frame = x86_get_current_iframe(); if (frame == NULL) { kprintf("Failed to get the current iframe!\n"); return 0; @@ -535,7 +637,7 @@ debugger_single_step(int argc, char** argv) void -arch_clear_team_debug_info(struct arch_team_debug_info *info) +arch_clear_team_debug_info(arch_team_debug_info* info) { for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) info->breakpoints[i].address = NULL; @@ -545,21 +647,21 @@ arch_clear_team_debug_info(struct arch_team_debug_info *info) void -arch_destroy_team_debug_info(struct arch_team_debug_info *info) +arch_destroy_team_debug_info(arch_team_debug_info* info) { arch_clear_team_debug_info(info); } void -arch_clear_thread_debug_info(struct arch_thread_debug_info *info) +arch_clear_thread_debug_info(arch_thread_debug_info* info) { info->flags = 0; } void -arch_destroy_thread_debug_info(struct arch_thread_debug_info *info) +arch_destroy_thread_debug_info(arch_thread_debug_info* info) { arch_clear_thread_debug_info(info); } @@ -568,7 +670,7 @@ arch_destroy_thread_debug_info(struct arch_thread_debug_info *info) void arch_update_thread_single_step() { - if (struct iframe* frame = i386_get_user_iframe()) { + if (iframe* frame = x86_get_user_iframe()) { Thread* thread = thread_get_current_thread(); // set/clear TF in EFLAGS depending on whether single stepping is @@ -582,9 +684,9 @@ arch_update_thread_single_step() void -arch_set_debug_cpu_state(const debug_cpu_state *cpuState) +arch_set_debug_cpu_state(const debug_cpu_state* cpuState) { - if (struct iframe *frame = i386_get_user_iframe()) { + if (iframe* frame = x86_get_user_iframe()) { // For the floating point state to be correct the calling function must // not use these registers (not even indirectly). if (gHasSSE) { @@ -596,40 +698,22 @@ arch_set_debug_cpu_state(const debug_cpu_state *cpuState) InterruptsLocker locker; memcpy(thread->arch_info.fpu_state, &cpuState->extended_registers, sizeof(cpuState->extended_registers)); - i386_fxrstor(thread->arch_info.fpu_state); + x86_fxrstor(thread->arch_info.fpu_state); +#ifndef __x86_64__ } else { // TODO: Implement! We need to convert the format first. -// i386_frstor(&cpuState->extended_registers); +// x86_frstor(&cpuState->extended_registers); +#endif } - -// frame->gs = cpuState->gs; -// frame->fs = cpuState->fs; -// frame->es = cpuState->es; -// frame->ds = cpuState->ds; - frame->edi = cpuState->edi; - frame->esi = cpuState->esi; - frame->ebp = cpuState->ebp; -// frame->esp = cpuState->esp; - frame->ebx = cpuState->ebx; - frame->edx = cpuState->edx; - frame->ecx = cpuState->ecx; - frame->eax = cpuState->eax; -// frame->vector = cpuState->vector; -// frame->error_code = cpuState->error_code; - frame->eip = cpuState->eip; -// frame->cs = cpuState->cs; - frame->flags = (frame->flags & ~X86_EFLAGS_USER_SETTABLE_FLAGS) - | (cpuState->eflags & X86_EFLAGS_USER_SETTABLE_FLAGS); - frame->user_esp = cpuState->user_esp; -// frame->user_ss = cpuState->user_ss; + set_iframe_registers(frame, cpuState); } } void -arch_get_debug_cpu_state(debug_cpu_state *cpuState) +arch_get_debug_cpu_state(debug_cpu_state* cpuState) { - if (struct iframe *frame = i386_get_user_iframe()) { + if (iframe* frame = x86_get_user_iframe()) { // For the floating point state to be correct the calling function must // not use these registers (not even indirectly). if (gHasSSE) { @@ -638,16 +722,18 @@ arch_get_debug_cpu_state(debug_cpu_state *cpuState) // buffer. We need to disable interrupts to make use of it. Thread* thread = thread_get_current_thread(); InterruptsLocker locker; - i386_fxsave(thread->arch_info.fpu_state); + x86_fxsave(thread->arch_info.fpu_state); // unlike fnsave, fxsave doesn't reinit the FPU state memcpy(&cpuState->extended_registers, thread->arch_info.fpu_state, sizeof(cpuState->extended_registers)); +#ifndef __x86_64__ } else { - i386_fnsave(&cpuState->extended_registers); - i386_frstor(&cpuState->extended_registers); + x86_fnsave(&cpuState->extended_registers); + x86_frstor(&cpuState->extended_registers); // fnsave reinits the FPU state after saving, so we need to // load it again // TODO: Convert to fxsave format! +#endif } get_iframe_registers(frame, cpuState); } @@ -655,7 +741,7 @@ arch_get_debug_cpu_state(debug_cpu_state *cpuState) status_t -arch_set_breakpoint(void *address) +arch_set_breakpoint(void* address) { return set_breakpoint(address, X86_INSTRUCTION_BREAKPOINT, X86_BREAKPOINT_LENGTH_1); @@ -663,16 +749,16 @@ arch_set_breakpoint(void *address) status_t -arch_clear_breakpoint(void *address) +arch_clear_breakpoint(void* address) { return clear_breakpoint(address, false); } status_t -arch_set_watchpoint(void *address, uint32 type, int32 length) +arch_set_watchpoint(void* address, uint32 type, int32 length) { - uint32 archType, archLength; + size_t archType, archLength; status_t error = check_watch_point_parameters(address, type, length, archType, archLength); if (error != B_OK) @@ -683,14 +769,14 @@ arch_set_watchpoint(void *address, uint32 type, int32 length) status_t -arch_clear_watchpoint(void *address) +arch_clear_watchpoint(void* address) { return clear_breakpoint(address, true); } bool -arch_has_breakpoints(struct arch_team_debug_info *info) +arch_has_breakpoints(arch_team_debug_info* info) { // Reading info->dr7 is atomically, so we don't need to lock. The caller // has to ensure, that the info doesn't go away. @@ -701,7 +787,7 @@ arch_has_breakpoints(struct arch_team_debug_info *info) #if KERNEL_BREAKPOINTS status_t -arch_set_kernel_breakpoint(void *address) +arch_set_kernel_breakpoint(void* address) { status_t error = set_kernel_breakpoint(address, X86_INSTRUCTION_BREAKPOINT, X86_BREAKPOINT_LENGTH_1); @@ -716,7 +802,7 @@ arch_set_kernel_breakpoint(void *address) status_t -arch_clear_kernel_breakpoint(void *address) +arch_clear_kernel_breakpoint(void* address) { status_t error = clear_kernel_breakpoint(address, false); @@ -730,9 +816,9 @@ arch_clear_kernel_breakpoint(void *address) status_t -arch_set_kernel_watchpoint(void *address, uint32 type, int32 length) +arch_set_kernel_watchpoint(void* address, uint32 type, int32 length) { - uint32 archType, archLength; + size_t archType, archLength; status_t error = check_watch_point_parameters(address, type, length, archType, archLength); @@ -749,7 +835,7 @@ arch_set_kernel_watchpoint(void *address, uint32 type, int32 length) status_t -arch_clear_kernel_watchpoint(void *address) +arch_clear_kernel_watchpoint(void* address) { status_t error = clear_kernel_breakpoint(address, true); @@ -771,9 +857,9 @@ arch_clear_kernel_watchpoint(void *address) * Interrupts are disabled. \a frame is unused, i.e. can be \c NULL. */ void -x86_init_user_debug_at_kernel_exit(struct iframe *frame) +x86_init_user_debug_at_kernel_exit(iframe* frame) { - Thread *thread = thread_get_current_thread(); + Thread* thread = thread_get_current_thread(); if (!(thread->flags & THREAD_FLAGS_BREAKPOINTS_DEFINED)) return; @@ -800,14 +886,14 @@ x86_init_user_debug_at_kernel_exit(struct iframe *frame) void x86_exit_user_debug_at_kernel_entry() { - Thread *thread = thread_get_current_thread(); + Thread* thread = thread_get_current_thread(); // We need to save the current values of dr6 and dr7 in the CPU structure, // since in case of a debug exception we might overwrite them before // x86_handle_debug_exception() is called. Debug exceptions occur when // hitting a hardware break/watchpoint or when single-stepping. - asm("movl %%dr6, %0" : "=r"(thread->cpu->arch.dr6)); - asm("movl %%dr7, %0" : "=r"(thread->cpu->arch.dr7)); + asm("mov %%dr6, %0" : "=r"(thread->cpu->arch.dr6)); + asm("mov %%dr7, %0" : "=r"(thread->cpu->arch.dr7)); // The remainder needs only be done, when user breakpoints are installed. if (!(thread->flags & THREAD_FLAGS_BREAKPOINTS_INSTALLED)) @@ -833,7 +919,7 @@ x86_exit_user_debug_at_kernel_entry() * Interrupts are disabled and will possibly be enabled by the function. */ void -x86_handle_debug_exception(struct iframe *frame) +x86_handle_debug_exception(iframe* frame) { Thread* thread = thread_get_current_thread(); @@ -842,17 +928,17 @@ x86_handle_debug_exception(struct iframe *frame) // x86_exit_user_debug_at_kernel_entry() has already been invoked and dr6 // and dr7 are stored in the cpu info. Otherwise we need to fetch the // current values from the registers. - uint32 dr6; - uint32 dr7; + size_t dr6; + size_t dr7; if (IFRAME_IS_USER(frame)) { dr6 = thread->cpu->arch.dr6; dr7 = thread->cpu->arch.dr7; } else { - asm("movl %%dr6, %0" : "=r"(dr6)); - asm("movl %%dr7, %0" : "=r"(dr7)); + asm("mov %%dr6, %0" : "=r"(dr6)); + asm("mov %%dr7, %0" : "=r"(dr7)); } - TRACE(("i386_handle_debug_exception(): DR6: %lx, DR7: %lx\n", dr6, dr7)); + TRACE(("x86_handle_debug_exception(): DR6: %lx, DR7: %lx\n", dr6, dr7)); // check, which exception condition applies if (dr6 & X86_DR6_BREAKPOINT_MASK) { @@ -862,7 +948,7 @@ x86_handle_debug_exception(struct iframe *frame) bool watchpoint = true; for (int32 i = 0; i < X86_BREAKPOINT_COUNT; i++) { if (dr6 & (1 << sDR6B[i])) { - uint32 type = (dr7 >> sDR7RW[i]) & 0x3; + size_t type = (dr7 >> sDR7RW[i]) & 0x3; if (type == X86_INSTRUCTION_BREAKPOINT) watchpoint = false; } @@ -885,7 +971,7 @@ x86_handle_debug_exception(struct iframe *frame) // Occurs only, if GD in DR7 is set (which we don't do) and someone // tries to write to the debug registers. if (IFRAME_IS_USER(frame)) { - dprintf("i386_handle_debug_exception(): ignoring spurious general " + dprintf("x86_handle_debug_exception(): ignoring spurious general " "detect exception\n"); enable_interrupts(); @@ -908,7 +994,7 @@ x86_handle_debug_exception(struct iframe *frame) // kernel entry or whether this is genuine kernel single-stepping. bool inKernel = true; if (thread->team != team_get_kernel_team() - && i386_get_user_iframe() == NULL) { + && x86_get_user_iframe() == NULL) { // TODO: This is not yet fully correct, since a newly created // thread that hasn't entered userland yet also has this // property. @@ -948,7 +1034,7 @@ x86_handle_debug_exception(struct iframe *frame) // task switch // Occurs only, if T in EFLAGS is set (which we don't do). if (IFRAME_IS_USER(frame)) { - dprintf("i386_handle_debug_exception(): ignoring spurious task switch " + dprintf("x86_handle_debug_exception(): ignoring spurious task switch " "exception\n"); enable_interrupts(); @@ -956,7 +1042,7 @@ x86_handle_debug_exception(struct iframe *frame) panic("spurious task switch exception in kernel mode"); } else { if (IFRAME_IS_USER(frame)) { - TRACE(("i386_handle_debug_exception(): ignoring spurious debug " + TRACE(("x86_handle_debug_exception(): ignoring spurious debug " "exception (no condition recognized)\n")); enable_interrupts(); @@ -972,12 +1058,12 @@ x86_handle_debug_exception(struct iframe *frame) * Interrupts are disabled and will possibly be enabled by the function. */ void -x86_handle_breakpoint_exception(struct iframe *frame) +x86_handle_breakpoint_exception(iframe* frame) { - TRACE(("i386_handle_breakpoint_exception()\n")); + TRACE(("x86_handle_breakpoint_exception()\n")); // reset eip to the int3 instruction - frame->eip--; + frame->ip--; if (!IFRAME_IS_USER(frame)) { panic("breakpoint exception in kernel mode"); @@ -994,7 +1080,7 @@ void x86_init_user_debug() { // get debug settings - if (void *handle = load_driver_settings("kernel")) { + if (void* handle = load_driver_settings("kernel")) { sQEmuSingleStepHack = get_driver_boolean_parameter(handle, "qemu_single_step_hack", false, false);; diff --git a/src/system/kernel/arch/x86/arch_vm.cpp b/src/system/kernel/arch/x86/arch_vm.cpp index 51715ecadd..0aed76adb7 100644 --- a/src/system/kernel/arch/x86/arch_vm.cpp +++ b/src/system/kernel/arch/x86/arch_vm.cpp @@ -656,7 +656,11 @@ arch_vm_init_post_area(kernel_args *args) return B_NO_MEMORY; } +#ifndef __x86_64__ return bios_init(); +#else + return B_OK; +#endif } @@ -667,8 +671,8 @@ arch_vm_init_end(kernel_args *args) TRACE(("arch_vm_init_endvm: entry\n")); // throw away anything in the kernel_args.pgtable[] that's not yet mapped - vm_free_unused_boot_loader_range(KERNEL_BASE, - args->arch_args.virtual_end - KERNEL_BASE); + vm_free_unused_boot_loader_range(KERNEL_LOAD_BASE, + args->arch_args.virtual_end - KERNEL_LOAD_BASE); return B_OK; } diff --git a/src/system/kernel/arch/x86/arch_vm_translation_map.cpp b/src/system/kernel/arch/x86/arch_vm_translation_map.cpp index aa20762e29..836262365e 100644 --- a/src/system/kernel/arch/x86/arch_vm_translation_map.cpp +++ b/src/system/kernel/arch/x86/arch_vm_translation_map.cpp @@ -12,8 +12,12 @@ #include -#include "paging/32bit/X86PagingMethod32Bit.h" -#include "paging/pae/X86PagingMethodPAE.h" +#ifdef __x86_64__ +# include "paging/64bit/X86PagingMethod64Bit.h" +#else +# include "paging/32bit/X86PagingMethod32Bit.h" +# include "paging/pae/X86PagingMethodPAE.h" +#endif //#define TRACE_VM_TMAP @@ -26,10 +30,14 @@ static union { uint64 align; +#ifdef __x86_64__ + char sixty_four[sizeof(X86PagingMethod64Bit)]; +#else char thirty_two[sizeof(X86PagingMethod32Bit)]; #if B_HAIKU_PHYSICAL_BITS == 64 char pae[sizeof(X86PagingMethodPAE)]; #endif +#endif } sPagingMethodBuffer; @@ -74,7 +82,9 @@ arch_vm_translation_map_init(kernel_args *args, } #endif -#if B_HAIKU_PHYSICAL_BITS == 64 +#ifdef __x86_64__ + gX86PagingMethod = new(&sPagingMethodBuffer) X86PagingMethod64Bit; +#elif B_HAIKU_PHYSICAL_BITS == 64 bool paeAvailable = x86_check_feature(IA32_FEATURE_PAE, FEATURE_COMMON); bool paeNeeded = false; for (uint32 i = 0; i < args->num_physical_memory_ranges; i++) { @@ -144,5 +154,8 @@ bool arch_vm_translation_map_is_kernel_page_accessible(addr_t virtualAddress, uint32 protection) { + if (!gX86PagingMethod) + return true; + return gX86PagingMethod->IsKernelPageAccessible(virtualAddress, protection); } diff --git a/src/system/kernel/arch/x86/asm_offsets.cpp b/src/system/kernel/arch/x86/asm_offsets.cpp index b38f803ae4..88082f90ce 100644 --- a/src/system/kernel/arch/x86/asm_offsets.cpp +++ b/src/system/kernel/arch/x86/asm_offsets.cpp @@ -44,20 +44,31 @@ dummy() DEFINE_OFFSET_MACRO(THREAD, Thread, kernel_stack_top); DEFINE_OFFSET_MACRO(THREAD, Thread, fault_handler); +#ifdef __x86_64__ + // struct arch_thread + DEFINE_OFFSET_MACRO(ARCH_THREAD, arch_thread, syscall_rsp); + DEFINE_OFFSET_MACRO(ARCH_THREAD, arch_thread, user_rsp); + DEFINE_OFFSET_MACRO(ARCH_THREAD, arch_thread, current_stack); +#endif + // struct iframe DEFINE_SIZEOF_MACRO(IFRAME, iframe); DEFINE_OFFSET_MACRO(IFRAME, iframe, cs); - DEFINE_OFFSET_MACRO(IFRAME, iframe, eax); - DEFINE_OFFSET_MACRO(IFRAME, iframe, edx); - DEFINE_OFFSET_MACRO(IFRAME, iframe, orig_eax); + DEFINE_OFFSET_MACRO(IFRAME, iframe, ax); + DEFINE_OFFSET_MACRO(IFRAME, iframe, dx); + DEFINE_OFFSET_MACRO(IFRAME, iframe, di); + DEFINE_OFFSET_MACRO(IFRAME, iframe, si); DEFINE_OFFSET_MACRO(IFRAME, iframe, vector); - DEFINE_OFFSET_MACRO(IFRAME, iframe, eip); + DEFINE_OFFSET_MACRO(IFRAME, iframe, ip); DEFINE_OFFSET_MACRO(IFRAME, iframe, flags); - DEFINE_OFFSET_MACRO(IFRAME, iframe, user_esp); - - // struct vm86_iframe - DEFINE_SIZEOF_MACRO(VM86_IFRAME, vm86_iframe); - DEFINE_OFFSET_MACRO(VM86_IFRAME, vm86_iframe, flags); + DEFINE_OFFSET_MACRO(IFRAME, iframe, user_sp); +#ifdef __x86_64__ + DEFINE_OFFSET_MACRO(IFRAME, iframe, r8); + DEFINE_OFFSET_MACRO(IFRAME, iframe, r9); + DEFINE_OFFSET_MACRO(IFRAME, iframe, r10); +#else + DEFINE_OFFSET_MACRO(IFRAME, iframe, orig_eax); +#endif // struct syscall_info DEFINE_SIZEOF_MACRO(SYSCALL_INFO, syscall_info); @@ -76,6 +87,7 @@ dummy() DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, context); DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, user_data); DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, handler); + DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, siginfo_handler); // struct ucontext_t DEFINE_OFFSET_MACRO(UCONTEXT_T, __ucontext_t, uc_mcontext); diff --git a/src/system/kernel/arch/x86/ioapic.cpp b/src/system/kernel/arch/x86/ioapic.cpp index 6d40b1645b..28d5ba871b 100644 --- a/src/system/kernel/arch/x86/ioapic.cpp +++ b/src/system/kernel/arch/x86/ioapic.cpp @@ -117,8 +117,8 @@ static int32 sSourceOverrides[ISA_INTERRUPT_COUNT]; static void print_ioapic(struct ioapic& ioapic) { - dprintf("io-apic %u has range %u-%u, %u entries, version 0x%08lx, " - "apic-id %u\n", ioapic.number, ioapic.global_interrupt_base, + dprintf("io-apic %u has range %u-%u, %u entries, version 0x%08" B_PRIx32 + ", apic-id %u\n", ioapic.number, ioapic.global_interrupt_base, ioapic.global_interrupt_last, ioapic.max_redirection_entry + 1, ioapic.version, ioapic.apic_id); } @@ -385,7 +385,7 @@ ioapic_initialize_ioapic(struct ioapic& ioapic, uint8 targetAPIC) static int32 ioapic_source_override_handler(void* data) { - int32 vector = (int32)data; + int32 vector = (addr_t)data; bool levelTriggered = ioapic_is_level_triggered_interrupt(vector); return int_io_interrupt_handler(vector, levelTriggered); } @@ -404,9 +404,10 @@ acpi_enumerate_ioapics(acpi_table_madt* madt) case ACPI_MADT_TYPE_IO_APIC: { acpi_madt_io_apic* info = (acpi_madt_io_apic*)apicEntry; - dprintf("found io-apic with address 0x%08lx, global " - "interrupt base %lu, apic-id %u\n", (uint32)info->Address, - (uint32)info->GlobalIrqBase, info->Id); + dprintf("found io-apic with address 0x%08" B_PRIx32 ", global " + "interrupt base %" B_PRIu32 ", apic-id %u\n", + (uint32)info->Address, (uint32)info->GlobalIrqBase, + info->Id); struct ioapic* ioapic = (struct ioapic*)malloc(sizeof(struct ioapic)); @@ -423,8 +424,8 @@ acpi_enumerate_ioapics(acpi_table_madt* madt) ioapic->registers = NULL; ioapic->next = NULL; - dprintf("mapping io-apic %u at physical address %p\n", - ioapic->number, (void*)info->Address); + dprintf("mapping io-apic %u at physical address %#" B_PRIx32 + "\n", ioapic->number, (uint32)info->Address); status_t status = ioapic_map_ioapic(*ioapic, info->Address); if (status != B_OK) { free(ioapic); @@ -446,8 +447,9 @@ acpi_enumerate_ioapics(acpi_table_madt* madt) { acpi_madt_nmi_source* info = (acpi_madt_nmi_source*)apicEntry; - dprintf("found nmi source global irq %lu, flags 0x%04x\n", - (uint32)info->GlobalIrq, (uint16)info->IntiFlags); + dprintf("found nmi source global irq %" B_PRIu32 ", flags " + "0x%04x\n", (uint32)info->GlobalIrq, + (uint16)info->IntiFlags); struct ioapic* ioapic = find_ioapic(info->GlobalIrq); if (ioapic == NULL) { @@ -517,8 +519,8 @@ acpi_configure_source_overrides(acpi_table_madt* madt) acpi_madt_interrupt_override* info = (acpi_madt_interrupt_override*)apicEntry; dprintf("found interrupt override for bus %u, source irq %u, " - "global irq %lu, flags 0x%08lx\n", info->Bus, - info->SourceIrq, (uint32)info->GlobalIrq, + "global irq %" B_PRIu32 ", flags 0x%08" B_PRIx32 "\n", + info->Bus, info->SourceIrq, (uint32)info->GlobalIrq, (uint32)info->IntiFlags); if (info->SourceIrq >= ISA_INTERRUPT_COUNT) { @@ -545,8 +547,9 @@ acpi_configure_source_overrides(acpi_table_madt* madt) { acpi_madt_nmi_source* info = (acpi_madt_nmi_source*)apicEntry; - dprintf("found nmi source global irq %lu, flags 0x%04x\n", - (uint32)info->GlobalIrq, (uint16)info->IntiFlags); + dprintf("found nmi source global irq %" B_PRIu32 ", flags " + "0x%04x\n", (uint32)info->GlobalIrq, + (uint16)info->IntiFlags); struct ioapic* ioapic = find_ioapic(info->GlobalIrq); if (ioapic == NULL) diff --git a/src/system/kernel/arch/x86/irq_routing_table.cpp b/src/system/kernel/arch/x86/irq_routing_table.cpp index 48d386d161..c3637a36b6 100644 --- a/src/system/kernel/arch/x86/irq_routing_table.cpp +++ b/src/system/kernel/arch/x86/irq_routing_table.cpp @@ -66,14 +66,15 @@ print_irq_descriptor(const irq_descriptor& descriptor) static void print_irq_routing_entry(const irq_routing_entry& entry) { - dprintf("address 0x%04llx; pin %u;", entry.device_address, entry.pin); + dprintf("address 0x%04" B_PRIx64 "; pin %u;", entry.device_address, + entry.pin); if (entry.source_index != 0) - dprintf(" GSI %lu;", entry.source_index); + dprintf(" GSI %" B_PRIu32 ";", entry.source_index); else - dprintf(" source %p %lu;", entry.source, entry.source_index); + dprintf(" source %p %" B_PRIu32 ";", entry.source, entry.source_index); - dprintf(" pci %u:%u pin %u func mask %lx; bios irq: %u; gsi %u;" + dprintf(" pci %u:%u pin %u func mask %" B_PRIx32 "; bios irq: %u; gsi %u;" " config 0x%02x\n", entry.pci_bus, entry.pci_device, entry.pin + 1, entry.pci_function_mask, entry.bios_irq, entry.irq, entry.polarity | entry.trigger_mode); @@ -830,8 +831,8 @@ enable_irq_routing(acpi_module_info* acpi, IRQRoutingTable& routingTable) status = update_pci_info_for_entry(pci, irqEntry); if (status != B_OK) { - dprintf("failed to update interrupt_line for PCI %u:%u mask %lx\n", - irqEntry.pci_bus, irqEntry.pci_device, + dprintf("failed to update interrupt_line for PCI %u:%u mask %" + B_PRIx32 "\n", irqEntry.pci_bus, irqEntry.pci_device, irqEntry.pci_function_mask); } } diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp index 9f84057e2d..987f3b4c8d 100644 --- a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp +++ b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp @@ -266,7 +266,7 @@ X86PagingMethod32Bit::Init(kernel_args* args, TRACE("X86PagingMethod32Bit::Init(): entry\n"); // page hole set up in stage2 - fPageHole = (page_table_entry*)args->arch_args.page_hole; + fPageHole = (page_table_entry*)(addr_t)args->arch_args.page_hole; // calculate where the pgdir would be fPageHolePageDir = (page_directory_entry*) (((addr_t)args->arch_args.page_hole) @@ -276,7 +276,7 @@ X86PagingMethod32Bit::Init(kernel_args* args, sizeof(page_directory_entry) * NUM_USER_PGDIR_ENTS); fKernelPhysicalPageDirectory = args->arch_args.phys_pgdir; - fKernelVirtualPageDirectory = (page_directory_entry*) + fKernelVirtualPageDirectory = (page_directory_entry*)(addr_t) args->arch_args.vir_pgdir; #ifdef TRACE_X86_PAGING_METHOD_32_BIT @@ -367,7 +367,7 @@ X86PagingMethod32Bit::CreateTranslationMap(bool kernel, VMTranslationMap** _map) status_t X86PagingMethod32Bit::MapEarly(kernel_args* args, addr_t virtualAddress, phys_addr_t physicalAddress, uint8 attributes, - phys_addr_t (*get_free_page)(kernel_args*)) + page_num_t (*get_free_page)(kernel_args*)) { // XXX horrible back door to map a page quickly regardless of translation // map object, etc. used only during VM setup. @@ -419,9 +419,8 @@ X86PagingMethod32Bit::IsKernelPageAccessible(addr_t virtualAddress, { // We only trust the kernel team's page directory. So switch to it first. // Always set it to make sure the TLBs don't contain obsolete data. - uint32 physicalPageDirectory; - read_cr3(physicalPageDirectory); - write_cr3(fKernelPhysicalPageDirectory); + uint32 physicalPageDirectory = x86_read_cr3(); + x86_write_cr3(fKernelPhysicalPageDirectory); // get the page directory entry for the address page_directory_entry pageDirectoryEntry; @@ -465,7 +464,7 @@ X86PagingMethod32Bit::IsKernelPageAccessible(addr_t virtualAddress, // switch back to the original page directory if (physicalPageDirectory != fKernelPhysicalPageDirectory) - write_cr3(physicalPageDirectory); + x86_write_cr3(physicalPageDirectory); if ((pageTableEntry & X86_PTE_PRESENT) == 0) return false; diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h index 92951f5b39..f781f7df1f 100644 --- a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h +++ b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.h @@ -31,7 +31,7 @@ public: addr_t virtualAddress, phys_addr_t physicalAddress, uint8 attributes, - phys_addr_t (*get_free_page)(kernel_args*)); + page_num_t (*get_free_page)(kernel_args*)); virtual bool IsKernelPageAccessible(addr_t virtualAddress, uint32 protection); diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp index 4b86a85611..3538951466 100644 --- a/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp +++ b/src/system/kernel/arch/x86/paging/32bit/X86PagingStructures32Bit.cpp @@ -100,8 +100,7 @@ X86PagingStructures32Bit::Delete() #if 0 // this sanity check can be enabled when corruption due to // overwriting an active page directory is suspected - uint32 activePageDirectory; - read_cr3(activePageDirectory); + uint32 activePageDirectory = x86_read_cr3(); if (activePageDirectory == pgdir_phys) panic("deleting a still active page directory\n"); #endif diff --git a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp new file mode 100644 index 0000000000..e9dbf30c4b --- /dev/null +++ b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp @@ -0,0 +1,333 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include "paging/64bit/X86PagingMethod64Bit.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "paging/64bit/X86PagingStructures64Bit.h" +#include "paging/64bit/X86VMTranslationMap64Bit.h" +#include "paging/x86_physical_page_mapper.h" +#include "paging/x86_physical_page_mapper_mapped.h" + + +//#define TRACE_X86_PAGING_METHOD_64BIT +#ifdef TRACE_X86_PAGING_METHOD_64BIT +# define TRACE(x...) dprintf(x) +#else +# define TRACE(x...) ; +#endif + + +// #pragma mark - X86PagingMethod64Bit + + +X86PagingMethod64Bit::X86PagingMethod64Bit() + : + fKernelPhysicalPML4(0), + fKernelVirtualPML4(NULL), + fPhysicalPageMapper(NULL), + fKernelPhysicalPageMapper(NULL) +{ +} + + +X86PagingMethod64Bit::~X86PagingMethod64Bit() +{ +} + + +status_t +X86PagingMethod64Bit::Init(kernel_args* args, + VMPhysicalPageMapper** _physicalPageMapper) +{ + fKernelPhysicalPML4 = args->arch_args.phys_pgdir; + fKernelVirtualPML4 = (uint64*)(addr_t)args->arch_args.vir_pgdir; + + // Ensure that the user half of the address space is clear. This removes + // the temporary identity mapping made by the boot loader. + memset(fKernelVirtualPML4, 0, sizeof(uint64) * 256); + arch_cpu_global_TLB_invalidate(); + + // Create the physical page mapper. + mapped_physical_page_ops_init(args, fPhysicalPageMapper, + fKernelPhysicalPageMapper); + + *_physicalPageMapper = fPhysicalPageMapper; + return B_ERROR; +} + + +status_t +X86PagingMethod64Bit::InitPostArea(kernel_args* args) +{ + // Create an area to represent the kernel PML4. + area_id area = create_area("kernel pml4", (void**)&fKernelVirtualPML4, + B_EXACT_ADDRESS, B_PAGE_SIZE, B_ALREADY_WIRED, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + if (area < B_OK) + return area; + + return B_OK; +} + + +status_t +X86PagingMethod64Bit::CreateTranslationMap(bool kernel, VMTranslationMap** _map) +{ + X86VMTranslationMap64Bit* map = new(std::nothrow) X86VMTranslationMap64Bit; + if (map == NULL) + return B_NO_MEMORY; + + status_t error = map->Init(kernel); + if (error != B_OK) { + delete map; + return error; + } + + *_map = map; + return B_OK; +} + + +status_t +X86PagingMethod64Bit::MapEarly(kernel_args* args, addr_t virtualAddress, + phys_addr_t physicalAddress, uint8 attributes, + page_num_t (*get_free_page)(kernel_args*)) +{ + TRACE("X86PagingMethod64Bit::MapEarly(%#" B_PRIxADDR ", %#" B_PRIxPHYSADDR + ", %#" B_PRIx8 ")\n", virtualAddress, physicalAddress, attributes); + + // Get the PDPT. We should be mapping on an existing PDPT at this stage. + uint64* pml4e = &fKernelVirtualPML4[VADDR_TO_PML4E(virtualAddress)]; + ASSERT((*pml4e & X86_64_PML4E_PRESENT) != 0); + uint64* virtualPDPT = (uint64*)fKernelPhysicalPageMapper->GetPageTableAt( + *pml4e & X86_64_PML4E_ADDRESS_MASK); + + // Get the page directory. + uint64* pdpte = &virtualPDPT[VADDR_TO_PDPTE(virtualAddress)]; + uint64* virtualPageDir; + if ((*pdpte & X86_64_PDPTE_PRESENT) == 0) { + phys_addr_t physicalPageDir = get_free_page(args) * B_PAGE_SIZE; + + TRACE("X86PagingMethod64Bit::MapEarly(): creating page directory for va" + " %#" B_PRIxADDR " at %#" B_PRIxPHYSADDR "\n", virtualAddress, + physicalPageDir); + + SetTableEntry(pdpte, (physicalPageDir & X86_64_PDPTE_ADDRESS_MASK) + | X86_64_PDPTE_PRESENT + | X86_64_PDPTE_WRITABLE + | X86_64_PDPTE_USER); + + // Map it and zero it. + virtualPageDir = (uint64*)fKernelPhysicalPageMapper->GetPageTableAt( + physicalPageDir); + memset(virtualPageDir, 0, B_PAGE_SIZE); + } else { + virtualPageDir = (uint64*)fKernelPhysicalPageMapper->GetPageTableAt( + *pdpte & X86_64_PDPTE_ADDRESS_MASK); + } + + // Get the page table. + uint64* pde = &virtualPageDir[VADDR_TO_PDE(virtualAddress)]; + uint64* virtualPageTable; + if ((*pde & X86_64_PDE_PRESENT) == 0) { + phys_addr_t physicalPageTable = get_free_page(args) * B_PAGE_SIZE; + + TRACE("X86PagingMethod64Bit::MapEarly(): creating page table for va" + " %#" B_PRIxADDR " at %#" B_PRIxPHYSADDR "\n", virtualAddress, + physicalPageTable); + + SetTableEntry(pde, (physicalPageTable & X86_64_PDE_ADDRESS_MASK) + | X86_64_PDE_PRESENT + | X86_64_PDE_WRITABLE + | X86_64_PDE_USER); + + // Map it and zero it. + virtualPageTable = (uint64*)fKernelPhysicalPageMapper->GetPageTableAt( + physicalPageTable); + memset(virtualPageTable, 0, B_PAGE_SIZE); + } else { + virtualPageTable = (uint64*)fKernelPhysicalPageMapper->GetPageTableAt( + *pde & X86_64_PDE_ADDRESS_MASK); + } + + // The page table entry must not already be mapped. + uint64* pte = &virtualPageTable[VADDR_TO_PTE(virtualAddress)]; + ASSERT_PRINT( + (*pte & X86_64_PTE_PRESENT) == 0, + "virtual address: %#" B_PRIxADDR ", existing pte: %#" B_PRIx64, + virtualAddress, *pte); + + // Fill in the table entry. + PutPageTableEntryInTable(pte, physicalAddress, attributes, 0, + IS_KERNEL_ADDRESS(virtualAddress)); + + return B_OK; +} + + +bool +X86PagingMethod64Bit::IsKernelPageAccessible(addr_t virtualAddress, + uint32 protection) +{ + return true; +} + + +/*! Traverses down the paging structure hierarchy to find the page table for a + virtual address, allocating new tables if required. +*/ +/*static*/ uint64* +X86PagingMethod64Bit::PageTableForAddress(uint64* virtualPML4, + addr_t virtualAddress, bool isKernel, bool allocateTables, + vm_page_reservation* reservation, + TranslationMapPhysicalPageMapper* pageMapper, int32& mapCount) +{ + TRACE("X86PagingMethod64Bit::PageTableForAddress(%#" B_PRIxADDR ", " + "%d)\n", virtualAddress, allocateTables); + + // Get the PDPT. + uint64* pml4e = &virtualPML4[VADDR_TO_PML4E(virtualAddress)]; + if ((*pml4e & X86_64_PML4E_PRESENT) == 0) { + if (!allocateTables) + return NULL; + + // Allocate a new PDPT. + vm_page* page = vm_page_allocate_page(reservation, + PAGE_STATE_WIRED | VM_PAGE_ALLOC_CLEAR); + + DEBUG_PAGE_ACCESS_END(page); + + phys_addr_t physicalPDPT + = (phys_addr_t)page->physical_page_number * B_PAGE_SIZE; + + TRACE("X86PagingMethod64Bit::PageTableForAddress(): creating PDPT " + "for va %#" B_PRIxADDR " at %#" B_PRIxPHYSADDR "\n", virtualAddress, + physicalPDPT); + + SetTableEntry(pml4e, (physicalPDPT & X86_64_PML4E_ADDRESS_MASK) + | X86_64_PML4E_PRESENT + | X86_64_PML4E_WRITABLE + | X86_64_PML4E_USER); + + mapCount++; + } + + uint64* virtualPDPT = (uint64*)pageMapper->GetPageTableAt( + *pml4e & X86_64_PML4E_ADDRESS_MASK); + + // Get the page directory. + uint64* pdpte = &virtualPDPT[VADDR_TO_PDPTE(virtualAddress)]; + if ((*pdpte & X86_64_PDPTE_PRESENT) == 0) { + if (!allocateTables) + return NULL; + + // Allocate a new page directory. + vm_page* page = vm_page_allocate_page(reservation, + PAGE_STATE_WIRED | VM_PAGE_ALLOC_CLEAR); + + DEBUG_PAGE_ACCESS_END(page); + + phys_addr_t physicalPageDir + = (phys_addr_t)page->physical_page_number * B_PAGE_SIZE; + + TRACE("X86PagingMethod64Bit::PageTableForAddress(): creating page " + "directory for va %#" B_PRIxADDR " at %#" B_PRIxPHYSADDR "\n", + virtualAddress, physicalPageDir); + + SetTableEntry(pdpte, (physicalPageDir & X86_64_PDPTE_ADDRESS_MASK) + | X86_64_PDPTE_PRESENT + | X86_64_PDPTE_WRITABLE + | X86_64_PDPTE_USER); + + mapCount++; + } + + uint64* virtualPageDir = (uint64*)pageMapper->GetPageTableAt( + *pdpte & X86_64_PDPTE_ADDRESS_MASK); + + // Get the page table. + uint64* pde = &virtualPageDir[VADDR_TO_PDE(virtualAddress)]; + if ((*pde & X86_64_PDE_PRESENT) == 0) { + if (!allocateTables) + return NULL; + + // Allocate a new page table. + vm_page* page = vm_page_allocate_page(reservation, + PAGE_STATE_WIRED | VM_PAGE_ALLOC_CLEAR); + + DEBUG_PAGE_ACCESS_END(page); + + phys_addr_t physicalPageTable + = (phys_addr_t)page->physical_page_number * B_PAGE_SIZE; + + TRACE("X86PagingMethod64Bit::PageTableForAddress(): creating page " + "table for va %#" B_PRIxADDR " at %#" B_PRIxPHYSADDR "\n", + virtualAddress, physicalPageTable); + + SetTableEntry(pde, (physicalPageTable & X86_64_PDE_ADDRESS_MASK) + | X86_64_PDE_PRESENT + | X86_64_PDE_WRITABLE + | X86_64_PDE_USER); + + mapCount++; + } + + return (uint64*)pageMapper->GetPageTableAt(*pde & X86_64_PDE_ADDRESS_MASK); +} + + +/*static*/ uint64* +X86PagingMethod64Bit::PageTableEntryForAddress(uint64* virtualPML4, + addr_t virtualAddress, bool isKernel, bool allocateTables, + vm_page_reservation* reservation, + TranslationMapPhysicalPageMapper* pageMapper, int32& mapCount) +{ + uint64* virtualPageTable = PageTableForAddress(virtualPML4, virtualAddress, + isKernel, allocateTables, reservation, pageMapper, mapCount); + if (virtualPageTable == NULL) + return NULL; + + return &virtualPageTable[VADDR_TO_PTE(virtualAddress)]; +} + + +/*static*/ void +X86PagingMethod64Bit::PutPageTableEntryInTable(uint64* entry, + phys_addr_t physicalAddress, uint32 attributes, uint32 memoryType, + bool globalPage) +{ + uint64 page = (physicalAddress & X86_64_PTE_ADDRESS_MASK) + | X86_64_PTE_PRESENT | (globalPage ? X86_64_PTE_GLOBAL : 0) + | MemoryTypeToPageTableEntryFlags(memoryType); + + // if the page is user accessible, it's automatically + // accessible in kernel space, too (but with the same + // protection) + if ((attributes & B_USER_PROTECTION) != 0) { + page |= X86_64_PTE_USER; + if ((attributes & B_WRITE_AREA) != 0) + page |= X86_64_PTE_WRITABLE; + } else if ((attributes & B_KERNEL_WRITE_AREA) != 0) + page |= X86_64_PTE_WRITABLE; + + // put it in the page table + SetTableEntry(entry, page); +} + diff --git a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.h b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.h new file mode 100644 index 0000000000..130e14ddc0 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.h @@ -0,0 +1,168 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_ARCH_X86_PAGING_64BIT_X86_PAGING_METHOD_64BIT_H +#define KERNEL_ARCH_X86_PAGING_64BIT_X86_PAGING_METHOD_64BIT_H + + +#include + +#include +#include + +#include "paging/64bit/paging.h" +#include "paging/X86PagingMethod.h" +#include "paging/X86PagingStructures.h" + + +class TranslationMapPhysicalPageMapper; +class X86PhysicalPageMapper; +struct vm_page_reservation; + + +class X86PagingMethod64Bit : public X86PagingMethod { +public: + X86PagingMethod64Bit(); + virtual ~X86PagingMethod64Bit(); + + virtual status_t Init(kernel_args* args, + VMPhysicalPageMapper** _physicalPageMapper); + virtual status_t InitPostArea(kernel_args* args); + + virtual status_t CreateTranslationMap(bool kernel, + VMTranslationMap** _map); + + virtual status_t MapEarly(kernel_args* args, + addr_t virtualAddress, + phys_addr_t physicalAddress, + uint8 attributes, + page_num_t (*get_free_page)(kernel_args*)); + + virtual bool IsKernelPageAccessible(addr_t virtualAddress, + uint32 protection); + + inline X86PhysicalPageMapper* PhysicalPageMapper() const + { return fPhysicalPageMapper; } + inline TranslationMapPhysicalPageMapper* KernelPhysicalPageMapper() const + { return fKernelPhysicalPageMapper; } + + inline uint64* KernelVirtualPML4() const + { return fKernelVirtualPML4; } + inline phys_addr_t KernelPhysicalPML4() const + { return fKernelPhysicalPML4; } + + static X86PagingMethod64Bit* Method(); + + static uint64* PageTableForAddress(uint64* virtualPML4, + addr_t virtualAddress, bool isKernel, + bool allocateTables, + vm_page_reservation* reservation, + TranslationMapPhysicalPageMapper* + pageMapper, int32& mapCount); + static uint64* PageTableEntryForAddress(uint64* virtualPML4, + addr_t virtualAddress, bool isKernel, + bool allocateTables, + vm_page_reservation* reservation, + TranslationMapPhysicalPageMapper* + pageMapper, int32& mapCount); + + static void PutPageTableEntryInTable( + uint64* entry, phys_addr_t physicalAddress, + uint32 attributes, uint32 memoryType, + bool globalPage); + static uint64 SetTableEntry(uint64* entry, uint64 newEntry); + static uint64 SetTableEntryFlags(uint64* entry, uint64 flags); + static uint64 TestAndSetTableEntry(uint64* entry, + uint64 newEntry, uint64 oldEntry); + static uint64 ClearTableEntry(uint64* entry); + static uint64 ClearTableEntryFlags(uint64* entry, + uint64 flags); + + static uint64 MemoryTypeToPageTableEntryFlags( + uint32 memoryType); + +private: + phys_addr_t fKernelPhysicalPML4; + uint64* fKernelVirtualPML4; + + X86PhysicalPageMapper* fPhysicalPageMapper; + TranslationMapPhysicalPageMapper* fKernelPhysicalPageMapper; +}; + + +/*static*/ inline X86PagingMethod64Bit* +X86PagingMethod64Bit::Method() +{ + return static_cast(gX86PagingMethod); +} + + +/*static*/ inline uint64 +X86PagingMethod64Bit::SetTableEntry(uint64* entry, uint64 newEntry) +{ + return atomic_set64((int64*)entry, newEntry); +} + + +/*static*/ inline uint64 +X86PagingMethod64Bit::SetTableEntryFlags(uint64* entry, uint64 flags) +{ + return atomic_or64((int64*)entry, flags); +} + + +/*static*/ inline uint64 +X86PagingMethod64Bit::TestAndSetTableEntry(uint64* entry, uint64 newEntry, + uint64 oldEntry) +{ + return atomic_test_and_set64((int64*)entry, newEntry, oldEntry); +} + + +/*static*/ inline uint64 +X86PagingMethod64Bit::ClearTableEntry(uint64* entry) +{ + return SetTableEntry(entry, 0); +} + + +/*static*/ inline uint64 +X86PagingMethod64Bit::ClearTableEntryFlags(uint64* entry, uint64 flags) +{ + return atomic_and64((int64*)entry, ~flags); +} + + +/*static*/ inline uint64 +X86PagingMethod64Bit::MemoryTypeToPageTableEntryFlags(uint32 memoryType) +{ + // ATM we only handle the uncacheable and write-through type explicitly. For + // all other types we rely on the MTRRs to be set up correctly. Since we set + // the default memory type to write-back and since the uncacheable type in + // the PTE overrides any MTRR attribute (though, as per the specs, that is + // not recommended for performance reasons), this reduces the work we + // actually *have* to do with the MTRRs to setting the remaining types + // (usually only write-combining for the frame buffer). + switch (memoryType) { + case B_MTR_UC: + return X86_64_PTE_CACHING_DISABLED | X86_64_PTE_WRITE_THROUGH; + + case B_MTR_WC: + // X86_PTE_WRITE_THROUGH would be closer, but the combination with + // MTRR WC is "implementation defined" for Pentium Pro/II. + return 0; + + case B_MTR_WT: + return X86_64_PTE_WRITE_THROUGH; + + case B_MTR_WP: + case B_MTR_WB: + default: + return 0; + } +} + + +#endif // KERNEL_ARCH_X86_PAGING_64BIT_X86_PAGING_METHOD_64BIT_H diff --git a/src/system/kernel/arch/x86/paging/64bit/X86PagingStructures64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86PagingStructures64Bit.cpp new file mode 100644 index 0000000000..aeecb239e7 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/64bit/X86PagingStructures64Bit.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include "paging/64bit/X86PagingStructures64Bit.h" + +#include +#include + +#include + +#include + +#include "paging/64bit/X86PagingMethod64Bit.h" + + +X86PagingStructures64Bit::X86PagingStructures64Bit() + : + fVirtualPML4(NULL) +{ +} + + +X86PagingStructures64Bit::~X86PagingStructures64Bit() +{ + // Free the PML4. + free(fVirtualPML4); +} + + +void +X86PagingStructures64Bit::Init(uint64* virtualPML4, phys_addr_t physicalPML4) +{ + fVirtualPML4 = virtualPML4; + pgdir_phys = physicalPML4; +} + + +void +X86PagingStructures64Bit::Delete() +{ + if (are_interrupts_enabled()) + delete this; + else + deferred_delete(this); +} + diff --git a/src/system/kernel/arch/x86/paging/64bit/X86PagingStructures64Bit.h b/src/system/kernel/arch/x86/paging/64bit/X86PagingStructures64Bit.h new file mode 100644 index 0000000000..e3114d25a6 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/64bit/X86PagingStructures64Bit.h @@ -0,0 +1,30 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_ARCH_X86_PAGING_64BIT_X86_PAGING_STRUCTURES_64BIT_H +#define KERNEL_ARCH_X86_PAGING_64BIT_X86_PAGING_STRUCTURES_64BIT_H + + +#include "paging/64bit/paging.h" +#include "paging/X86PagingStructures.h" + + +struct X86PagingStructures64Bit : X86PagingStructures { + X86PagingStructures64Bit(); + virtual ~X86PagingStructures64Bit(); + + void Init(uint64* virtualPML4, + phys_addr_t physicalPML4); + + virtual void Delete(); + + uint64* VirtualPML4() + { return fVirtualPML4; } + +private: + uint64* fVirtualPML4; +}; + + +#endif // KERNEL_ARCH_X86_PAGING_64BIT_X86_PAGING_STRUCTURES_64BIT_H diff --git a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp new file mode 100644 index 0000000000..70ce26b320 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp @@ -0,0 +1,862 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk + * Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include "paging/64bit/X86VMTranslationMap64Bit.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "paging/64bit/X86PagingMethod64Bit.h" +#include "paging/64bit/X86PagingStructures64Bit.h" +#include "paging/x86_physical_page_mapper.h" + + +//#define TRACE_X86_VM_TRANSLATION_MAP_64BIT +#ifdef TRACE_X86_VM_TRANSLATION_MAP_64BIT +# define TRACE(x...) dprintf(x) +#else +# define TRACE(x...) ; +#endif + + +// #pragma mark - X86VMTranslationMap64Bit + + +X86VMTranslationMap64Bit::X86VMTranslationMap64Bit() + : + fPagingStructures(NULL) +{ +} + + +X86VMTranslationMap64Bit::~X86VMTranslationMap64Bit() +{ + TRACE("X86VMTranslationMap64Bit::~X86VMTranslationMap64Bit()\n"); + + if (fPagingStructures == NULL) + return; + + if (fPageMapper != NULL) { + phys_addr_t address; + vm_page* page; + + // Free all structures in the bottom half of the PML4 (user memory). + uint64* virtualPML4 = fPagingStructures->VirtualPML4(); + for (uint32 i = 0; i < 256; i++) { + if ((virtualPML4[i] & X86_64_PML4E_PRESENT) == 0) + continue; + + uint64* virtualPDPT = (uint64*)fPageMapper->GetPageTableAt( + virtualPML4[i] & X86_64_PML4E_ADDRESS_MASK); + for (uint32 j = 0; j < 512; j++) { + if ((virtualPDPT[j] & X86_64_PDPTE_PRESENT) == 0) + continue; + + uint64* virtualPageDir = (uint64*)fPageMapper->GetPageTableAt( + virtualPDPT[j] & X86_64_PDPTE_ADDRESS_MASK); + for (uint32 k = 0; k < 512; k++) { + if ((virtualPageDir[k] & X86_64_PDE_PRESENT) == 0) + continue; + + address = virtualPageDir[k] & X86_64_PDE_ADDRESS_MASK; + page = vm_lookup_page(address / B_PAGE_SIZE); + if (page == NULL) { + panic("page table %u %u %u on invalid page %#" + B_PRIxPHYSADDR "\n", i, j, k, address); + } + + DEBUG_PAGE_ACCESS_START(page); + vm_page_set_state(page, PAGE_STATE_FREE); + } + + address = virtualPDPT[j] & X86_64_PDPTE_ADDRESS_MASK; + page = vm_lookup_page(address / B_PAGE_SIZE); + if (page == NULL) { + panic("page directory %u %u on invalid page %#" + B_PRIxPHYSADDR "\n", i, j, address); + } + + DEBUG_PAGE_ACCESS_START(page); + vm_page_set_state(page, PAGE_STATE_FREE); + } + + address = virtualPML4[i] & X86_64_PML4E_ADDRESS_MASK; + page = vm_lookup_page(address / B_PAGE_SIZE); + if (page == NULL) { + panic("PDPT %u on invalid page %#" B_PRIxPHYSADDR "\n", i, + address); + } + + DEBUG_PAGE_ACCESS_START(page); + vm_page_set_state(page, PAGE_STATE_FREE); + } + + fPageMapper->Delete(); + } + + fPagingStructures->RemoveReference(); +} + + +status_t +X86VMTranslationMap64Bit::Init(bool kernel) +{ + TRACE("X86VMTranslationMap64Bit::Init()\n"); + + X86VMTranslationMap::Init(kernel); + + fPagingStructures = new(std::nothrow) X86PagingStructures64Bit; + if (fPagingStructures == NULL) + return B_NO_MEMORY; + + X86PagingMethod64Bit* method = X86PagingMethod64Bit::Method(); + + if (kernel) { + // Get the page mapper. + fPageMapper = method->KernelPhysicalPageMapper(); + + // Kernel PML4 is already mapped. + fPagingStructures->Init(method->KernelVirtualPML4(), + method->KernelPhysicalPML4()); + } else { + // Allocate a physical page mapper. + status_t error = method->PhysicalPageMapper() + ->CreateTranslationMapPhysicalPageMapper(&fPageMapper); + if (error != B_OK) + return error; + + // Assuming that only the top 2 PML4 entries are occupied for the + // kernel. + STATIC_ASSERT(KERNEL_PMAP_BASE == 0xffffff0000000000); + STATIC_ASSERT(KERNEL_BASE == 0xffffff8000000000); + + // Allocate and clear the PML4. + uint64* virtualPML4 = (uint64*)memalign(B_PAGE_SIZE, B_PAGE_SIZE); + if (virtualPML4 == NULL) + return B_NO_MEMORY; + memset(virtualPML4, 0, B_PAGE_SIZE); + + // Copy the top 2 PML4 entries. + virtualPML4[510] = method->KernelVirtualPML4()[510]; + virtualPML4[511] = method->KernelVirtualPML4()[511]; + + // Look up the PML4 physical address. + phys_addr_t physicalPML4; + vm_get_page_mapping(VMAddressSpace::KernelID(), (addr_t)virtualPML4, + &physicalPML4); + + // Initialize the paging structures. + fPagingStructures->Init(virtualPML4, physicalPML4); + } + + return B_OK; +} + + +size_t +X86VMTranslationMap64Bit::MaxPagesNeededToMap(addr_t start, addr_t end) const +{ + // If start == 0, the actual base address is not yet known to the caller and + // we shall assume the worst case, which is where the start address is the + // last page covered by a PDPT. + if (start == 0) { + start = k64BitPDPTRange - B_PAGE_SIZE; + end += start; + } + + size_t requiredPDPTs = end / k64BitPDPTRange + 1 + - start / k64BitPDPTRange; + size_t requiredPageDirs = end / k64BitPageDirectoryRange + 1 + - start / k64BitPageDirectoryRange; + size_t requiredPageTables = end / k64BitPageTableRange + 1 + - start / k64BitPageTableRange; + + return requiredPDPTs + requiredPageDirs + requiredPageTables; +} + + +status_t +X86VMTranslationMap64Bit::Map(addr_t virtualAddress, phys_addr_t physicalAddress, + uint32 attributes, uint32 memoryType, vm_page_reservation* reservation) +{ + TRACE("X86VMTranslationMap64Bit::Map(%#" B_PRIxADDR ", %#" B_PRIxPHYSADDR + ")\n", virtualAddress, physicalAddress); + + ThreadCPUPinner pinner(thread_get_current_thread()); + + // Look up the page table for the virtual address, allocating new tables + // if required. Shouldn't fail. + uint64* entry = X86PagingMethod64Bit::PageTableEntryForAddress( + fPagingStructures->VirtualPML4(), virtualAddress, fIsKernelMap, + true, reservation, fPageMapper, fMapCount); + ASSERT(entry != NULL); + + // The entry should not already exist. + ASSERT_PRINT((*entry & X86_64_PTE_PRESENT) == 0, + "virtual address: %#" B_PRIxADDR ", existing pte: %#" B_PRIx64, + virtualAddress, *entry); + + // Fill in the table entry. + X86PagingMethod64Bit::PutPageTableEntryInTable(entry, physicalAddress, + attributes, memoryType, fIsKernelMap); + + // Note: We don't need to invalidate the TLB for this address, as previously + // the entry was not present and the TLB doesn't cache those entries. + + fMapCount++; + + return 0; +} + + +status_t +X86VMTranslationMap64Bit::Unmap(addr_t start, addr_t end) +{ + start = ROUNDDOWN(start, B_PAGE_SIZE); + if (start >= end) + return B_OK; + + TRACE("X86VMTranslationMap64Bit::Unmap(%#" B_PRIxADDR ", %#" B_PRIxADDR + ")\n", start, end); + + ThreadCPUPinner pinner(thread_get_current_thread()); + + do { + uint64* pageTable = X86PagingMethod64Bit::PageTableForAddress( + fPagingStructures->VirtualPML4(), start, fIsKernelMap, false, + NULL, fPageMapper, fMapCount); + if (pageTable == NULL) { + // Move on to the next page table. + start = ROUNDUP(start + 1, k64BitPageTableRange); + continue; + } + + for (uint32 index = start / B_PAGE_SIZE % k64BitTableEntryCount; + index < k64BitTableEntryCount && start < end; + index++, start += B_PAGE_SIZE) { + if ((pageTable[index] & X86_64_PTE_PRESENT) == 0) + continue; + + TRACE("X86VMTranslationMap64Bit::Unmap(): removing page %#" + B_PRIxADDR " (%#" B_PRIxPHYSADDR ")\n", start, + pageTable[index] & X86_64_PTE_ADDRESS_MASK); + + uint64 oldEntry = X86PagingMethod64Bit::ClearTableEntryFlags( + &pageTable[index], X86_64_PTE_PRESENT); + fMapCount--; + + if ((oldEntry & X86_64_PTE_ACCESSED) != 0) { + // Note, that we only need to invalidate the address, if the + // accessed flags was set, since only then the entry could have + // been in any TLB. + InvalidatePage(start); + } + } + } while (start != 0 && start < end); + + return B_OK; +} + + +status_t +X86VMTranslationMap64Bit::DebugMarkRangePresent(addr_t start, addr_t end, + bool markPresent) +{ + start = ROUNDDOWN(start, B_PAGE_SIZE); + if (start >= end) + return B_OK; + + TRACE("X86VMTranslationMap64Bit::DebugMarkRangePresent(%#" B_PRIxADDR + ", %#" B_PRIxADDR ")\n", start, end); + + ThreadCPUPinner pinner(thread_get_current_thread()); + + do { + uint64* pageTable = X86PagingMethod64Bit::PageTableForAddress( + fPagingStructures->VirtualPML4(), start, fIsKernelMap, false, + NULL, fPageMapper, fMapCount); + if (pageTable == NULL) { + // Move on to the next page table. + start = ROUNDUP(start + 1, k64BitPageTableRange); + continue; + } + + for (uint32 index = start / B_PAGE_SIZE % k64BitTableEntryCount; + index < k64BitTableEntryCount && start < end; + index++, start += B_PAGE_SIZE) { + if ((pageTable[index] & X86_64_PTE_PRESENT) == 0) { + if (!markPresent) + continue; + + X86PagingMethod64Bit::SetTableEntryFlags(&pageTable[index], + X86_64_PTE_PRESENT); + } else { + if (markPresent) + continue; + + uint64 oldEntry = X86PagingMethod64Bit::ClearTableEntryFlags( + &pageTable[index], X86_64_PTE_PRESENT); + + if ((oldEntry & X86_64_PTE_ACCESSED) != 0) { + // Note, that we only need to invalidate the address, if the + // accessed flags was set, since only then the entry could + // have been in any TLB. + InvalidatePage(start); + } + } + } + } while (start != 0 && start < end); + + return B_OK; +} + + +status_t +X86VMTranslationMap64Bit::UnmapPage(VMArea* area, addr_t address, + bool updatePageQueue) +{ + ASSERT(address % B_PAGE_SIZE == 0); + + TRACE("X86VMTranslationMap64Bit::UnmapPage(%#" B_PRIxADDR ")\n", address); + + ThreadCPUPinner pinner(thread_get_current_thread()); + + // Look up the page table for the virtual address. + uint64* entry = X86PagingMethod64Bit::PageTableEntryForAddress( + fPagingStructures->VirtualPML4(), address, fIsKernelMap, + false, NULL, fPageMapper, fMapCount); + if (entry == NULL) + return B_ENTRY_NOT_FOUND; + + RecursiveLocker locker(fLock); + + uint64 oldEntry = X86PagingMethod64Bit::ClearTableEntry(entry); + + pinner.Unlock(); + + if ((oldEntry & X86_64_PTE_PRESENT) == 0) + return B_ENTRY_NOT_FOUND; + + fMapCount--; + + if ((oldEntry & X86_64_PTE_ACCESSED) != 0) { + // Note, that we only need to invalidate the address, if the + // accessed flags was set, since only then the entry could have been + // in any TLB. + InvalidatePage(address); + + Flush(); + + // NOTE: Between clearing the page table entry and Flush() other + // processors (actually even this processor with another thread of the + // same team) could still access the page in question via their cached + // entry. We can obviously lose a modified flag in this case, with the + // effect that the page looks unmodified (and might thus be recycled), + // but is actually modified. + // In most cases this is harmless, but for vm_remove_all_page_mappings() + // this is actually a problem. + // Interestingly FreeBSD seems to ignore this problem as well + // (cf. pmap_remove_all()), unless I've missed something. + } + + locker.Detach(); + // PageUnmapped() will unlock for us + + PageUnmapped(area, (oldEntry & X86_64_PTE_ADDRESS_MASK) / B_PAGE_SIZE, + (oldEntry & X86_64_PTE_ACCESSED) != 0, + (oldEntry & X86_64_PTE_DIRTY) != 0, updatePageQueue); + + return B_OK; +} + + +void +X86VMTranslationMap64Bit::UnmapPages(VMArea* area, addr_t base, size_t size, + bool updatePageQueue) +{ + if (size == 0) + return; + + addr_t start = base; + addr_t end = base + size - 1; + + TRACE("X86VMTranslationMap64Bit::UnmapPages(%p, %#" B_PRIxADDR ", %#" + B_PRIxADDR ")\n", area, start, end); + + VMAreaMappings queue; + + RecursiveLocker locker(fLock); + ThreadCPUPinner pinner(thread_get_current_thread()); + + do { + uint64* pageTable = X86PagingMethod64Bit::PageTableForAddress( + fPagingStructures->VirtualPML4(), start, fIsKernelMap, false, + NULL, fPageMapper, fMapCount); + if (pageTable == NULL) { + // Move on to the next page table. + start = ROUNDUP(start + 1, k64BitPageTableRange); + continue; + } + + for (uint32 index = start / B_PAGE_SIZE % k64BitTableEntryCount; + index < k64BitTableEntryCount && start < end; + index++, start += B_PAGE_SIZE) { + uint64 oldEntry = X86PagingMethod64Bit::ClearTableEntry( + &pageTable[index]); + if ((oldEntry & X86_64_PTE_PRESENT) == 0) + continue; + + fMapCount--; + + if ((oldEntry & X86_64_PTE_ACCESSED) != 0) { + // Note, that we only need to invalidate the address, if the + // accessed flags was set, since only then the entry could have + // been in any TLB. + InvalidatePage(start); + } + + if (area->cache_type != CACHE_TYPE_DEVICE) { + // get the page + vm_page* page = vm_lookup_page( + (oldEntry & X86_64_PTE_ADDRESS_MASK) / B_PAGE_SIZE); + ASSERT(page != NULL); + + DEBUG_PAGE_ACCESS_START(page); + + // transfer the accessed/dirty flags to the page + if ((oldEntry & X86_64_PTE_ACCESSED) != 0) + page->accessed = true; + if ((oldEntry & X86_64_PTE_DIRTY) != 0) + page->modified = true; + + // remove the mapping object/decrement the wired_count of the + // page + if (area->wiring == B_NO_LOCK) { + vm_page_mapping* mapping = NULL; + vm_page_mappings::Iterator iterator + = page->mappings.GetIterator(); + while ((mapping = iterator.Next()) != NULL) { + if (mapping->area == area) + break; + } + + ASSERT(mapping != NULL); + + area->mappings.Remove(mapping); + page->mappings.Remove(mapping); + queue.Add(mapping); + } else + page->DecrementWiredCount(); + + if (!page->IsMapped()) { + atomic_add(&gMappedPagesCount, -1); + + if (updatePageQueue) { + if (page->Cache()->temporary) + vm_page_set_state(page, PAGE_STATE_INACTIVE); + else if (page->modified) + vm_page_set_state(page, PAGE_STATE_MODIFIED); + else + vm_page_set_state(page, PAGE_STATE_CACHED); + } + } + + DEBUG_PAGE_ACCESS_END(page); + } + } + + Flush(); + // flush explicitly, since we directly use the lock + } while (start != 0 && start < end); + + // TODO: As in UnmapPage() we can lose page dirty flags here. ATM it's not + // really critical here, as in all cases this method is used, the unmapped + // area range is unmapped for good (resized/cut) and the pages will likely + // be freed. + + locker.Unlock(); + + // free removed mappings + bool isKernelSpace = area->address_space == VMAddressSpace::Kernel(); + uint32 freeFlags = CACHE_DONT_WAIT_FOR_MEMORY + | (isKernelSpace ? CACHE_DONT_LOCK_KERNEL_SPACE : 0); + while (vm_page_mapping* mapping = queue.RemoveHead()) + object_cache_free(gPageMappingsObjectCache, mapping, freeFlags); +} + + +void +X86VMTranslationMap64Bit::UnmapArea(VMArea* area, bool deletingAddressSpace, + bool ignoreTopCachePageFlags) +{ + TRACE("X86VMTranslationMap64Bit::UnmapArea(%p)\n", area); + + if (area->cache_type == CACHE_TYPE_DEVICE || area->wiring != B_NO_LOCK) { + X86VMTranslationMap64Bit::UnmapPages(area, area->Base(), area->Size(), + true); + return; + } + + bool unmapPages = !deletingAddressSpace || !ignoreTopCachePageFlags; + + RecursiveLocker locker(fLock); + ThreadCPUPinner pinner(thread_get_current_thread()); + + VMAreaMappings mappings; + mappings.MoveFrom(&area->mappings); + + for (VMAreaMappings::Iterator it = mappings.GetIterator(); + vm_page_mapping* mapping = it.Next();) { + vm_page* page = mapping->page; + page->mappings.Remove(mapping); + + VMCache* cache = page->Cache(); + + bool pageFullyUnmapped = false; + if (!page->IsMapped()) { + atomic_add(&gMappedPagesCount, -1); + pageFullyUnmapped = true; + } + + if (unmapPages || cache != area->cache) { + addr_t address = area->Base() + + ((page->cache_offset * B_PAGE_SIZE) - area->cache_offset); + + uint64* entry = X86PagingMethod64Bit::PageTableEntryForAddress( + fPagingStructures->VirtualPML4(), address, fIsKernelMap, + false, NULL, fPageMapper, fMapCount); + if (entry == NULL) { + panic("page %p has mapping for area %p (%#" B_PRIxADDR "), but " + "has no page table", page, area, address); + continue; + } + + uint64 oldEntry = X86PagingMethod64Bit::ClearTableEntry(entry); + + if ((oldEntry & X86_64_PTE_PRESENT) == 0) { + panic("page %p has mapping for area %p (%#" B_PRIxADDR "), but " + "has no page table entry", page, area, address); + continue; + } + + // transfer the accessed/dirty flags to the page and invalidate + // the mapping, if necessary + if ((oldEntry & X86_64_PTE_ACCESSED) != 0) { + page->accessed = true; + + if (!deletingAddressSpace) + InvalidatePage(address); + } + + if ((oldEntry & X86_64_PTE_DIRTY) != 0) + page->modified = true; + + if (pageFullyUnmapped) { + DEBUG_PAGE_ACCESS_START(page); + + if (cache->temporary) + vm_page_set_state(page, PAGE_STATE_INACTIVE); + else if (page->modified) + vm_page_set_state(page, PAGE_STATE_MODIFIED); + else + vm_page_set_state(page, PAGE_STATE_CACHED); + + DEBUG_PAGE_ACCESS_END(page); + } + } + + fMapCount--; + } + + Flush(); + // flush explicitely, since we directly use the lock + + locker.Unlock(); + + bool isKernelSpace = area->address_space == VMAddressSpace::Kernel(); + uint32 freeFlags = CACHE_DONT_WAIT_FOR_MEMORY + | (isKernelSpace ? CACHE_DONT_LOCK_KERNEL_SPACE : 0); + while (vm_page_mapping* mapping = mappings.RemoveHead()) + object_cache_free(gPageMappingsObjectCache, mapping, freeFlags); +} + + +status_t +X86VMTranslationMap64Bit::Query(addr_t virtualAddress, + phys_addr_t* _physicalAddress, uint32* _flags) +{ + *_flags = 0; + *_physicalAddress = 0; + + ThreadCPUPinner pinner(thread_get_current_thread()); + + // Look up the page table for the virtual address. + uint64* pte = X86PagingMethod64Bit::PageTableEntryForAddress( + fPagingStructures->VirtualPML4(), virtualAddress, fIsKernelMap, + false, NULL, fPageMapper, fMapCount); + if (pte == NULL) + return B_OK; + + uint64 entry = *pte; + + *_physicalAddress = entry & X86_64_PTE_ADDRESS_MASK; + + // Translate the page state flags. + if ((entry & X86_64_PTE_USER) != 0) { + *_flags |= ((entry & X86_64_PTE_WRITABLE) != 0 ? B_WRITE_AREA : 0) + | B_READ_AREA; + } + + *_flags |= ((entry & X86_64_PTE_WRITABLE) != 0 ? B_KERNEL_WRITE_AREA : 0) + | B_KERNEL_READ_AREA + | ((entry & X86_64_PTE_DIRTY) != 0 ? PAGE_MODIFIED : 0) + | ((entry & X86_64_PTE_ACCESSED) != 0 ? PAGE_ACCESSED : 0) + | ((entry & X86_64_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0); + + TRACE("X86VMTranslationMap64Bit::Query(%#" B_PRIxADDR ") -> %#" + B_PRIxPHYSADDR " %#" B_PRIx32 " (pte: %p %#" B_PRIx64 ")\n", + virtualAddress, *_physicalAddress, *_flags, pte, entry); + + return B_OK; +} + + +status_t +X86VMTranslationMap64Bit::QueryInterrupt(addr_t virtualAddress, + phys_addr_t* _physicalAddress, uint32* _flags) +{ + *_flags = 0; + *_physicalAddress = 0; + + ThreadCPUPinner pinner(thread_get_current_thread()); + + // Look up the page table for the virtual address. + // FIXME: PageTableEntryForAddress uses GetPageTableAt() rather than + // InterruptGetPageTableAt(). This doesn't actually matter since in our + // page mapper both functions are the same, but perhaps this should be + // fixed for correctness. + uint64* pte = X86PagingMethod64Bit::PageTableEntryForAddress( + fPagingStructures->VirtualPML4(), virtualAddress, fIsKernelMap, + false, NULL, fPageMapper, fMapCount); + if (pte == NULL) + return B_OK; + + uint64 entry = *pte; + + *_physicalAddress = entry & X86_64_PTE_ADDRESS_MASK; + + // Translate the page state flags. + if ((entry & X86_64_PTE_USER) != 0) { + *_flags |= ((entry & X86_64_PTE_WRITABLE) != 0 ? B_WRITE_AREA : 0) + | B_READ_AREA; + } + + *_flags |= ((entry & X86_64_PTE_WRITABLE) != 0 ? B_KERNEL_WRITE_AREA : 0) + | B_KERNEL_READ_AREA + | ((entry & X86_64_PTE_DIRTY) != 0 ? PAGE_MODIFIED : 0) + | ((entry & X86_64_PTE_ACCESSED) != 0 ? PAGE_ACCESSED : 0) + | ((entry & X86_64_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0); + + TRACE("X86VMTranslationMap64Bit::QueryInterrupt(%#" B_PRIxADDR ") -> %#" + B_PRIxPHYSADDR ":\n", virtualAddress, *_physicalAddress); + + return B_OK; +} + + +status_t +X86VMTranslationMap64Bit::Protect(addr_t start, addr_t end, uint32 attributes, + uint32 memoryType) +{ + start = ROUNDDOWN(start, B_PAGE_SIZE); + if (start >= end) + return B_OK; + + TRACE("X86VMTranslationMap64Bit::Protect(%#" B_PRIxADDR ", %#" B_PRIxADDR + ", %#" B_PRIx32 ")\n", start, end, attributes); + + // compute protection flags + uint64 newProtectionFlags = 0; + if ((attributes & B_USER_PROTECTION) != 0) { + newProtectionFlags = X86_64_PTE_USER; + if ((attributes & B_WRITE_AREA) != 0) + newProtectionFlags |= X86_64_PTE_WRITABLE; + } else if ((attributes & B_KERNEL_WRITE_AREA) != 0) + newProtectionFlags = X86_64_PTE_WRITABLE; + + ThreadCPUPinner pinner(thread_get_current_thread()); + + do { + uint64* pageTable = X86PagingMethod64Bit::PageTableForAddress( + fPagingStructures->VirtualPML4(), start, fIsKernelMap, false, + NULL, fPageMapper, fMapCount); + if (pageTable == NULL) { + // Move on to the next page table. + start = ROUNDUP(start + 1, k64BitPageTableRange); + continue; + } + + for (uint32 index = start / B_PAGE_SIZE % k64BitTableEntryCount; + index < k64BitTableEntryCount && start < end; + index++, start += B_PAGE_SIZE) { + uint64 entry = pageTable[index]; + if ((entry & X86_64_PTE_PRESENT) == 0) + continue; + + TRACE("X86VMTranslationMap64Bit::Protect(): protect page %#" + B_PRIxADDR "\n", start); + + // set the new protection flags -- we want to do that atomically, + // without changing the accessed or dirty flag + uint64 oldEntry; + while (true) { + oldEntry = X86PagingMethod64Bit::TestAndSetTableEntry( + &pageTable[index], + (entry & ~(X86_64_PTE_PROTECTION_MASK + | X86_64_PTE_MEMORY_TYPE_MASK)) + | newProtectionFlags + | X86PagingMethod64Bit::MemoryTypeToPageTableEntryFlags( + memoryType), + entry); + if (oldEntry == entry) + break; + entry = oldEntry; + } + + if ((oldEntry & X86_64_PTE_ACCESSED) != 0) { + // Note, that we only need to invalidate the address, if the + // accessed flag was set, since only then the entry could have + // been in any TLB. + InvalidatePage(start); + } + } + } while (start != 0 && start < end); + + return B_OK; +} + + +status_t +X86VMTranslationMap64Bit::ClearFlags(addr_t address, uint32 flags) +{ + TRACE("X86VMTranslationMap64Bit::ClearFlags(%#" B_PRIxADDR ", %#" B_PRIx32 + ")\n", address, flags); + + ThreadCPUPinner pinner(thread_get_current_thread()); + + uint64* entry = X86PagingMethod64Bit::PageTableEntryForAddress( + fPagingStructures->VirtualPML4(), address, fIsKernelMap, + false, NULL, fPageMapper, fMapCount); + if (entry == NULL) + return B_OK; + + uint64 flagsToClear = ((flags & PAGE_MODIFIED) ? X86_64_PTE_DIRTY : 0) + | ((flags & PAGE_ACCESSED) ? X86_64_PTE_ACCESSED : 0); + + uint64 oldEntry = X86PagingMethod64Bit::ClearTableEntryFlags(entry, + flagsToClear); + + if ((oldEntry & flagsToClear) != 0) + InvalidatePage(address); + + return B_OK; +} + + +bool +X86VMTranslationMap64Bit::ClearAccessedAndModified(VMArea* area, addr_t address, + bool unmapIfUnaccessed, bool& _modified) +{ + ASSERT(address % B_PAGE_SIZE == 0); + + TRACE("X86VMTranslationMap64Bit::ClearAccessedAndModified(%#" B_PRIxADDR + ")\n", address); + + RecursiveLocker locker(fLock); + ThreadCPUPinner pinner(thread_get_current_thread()); + + uint64* entry = X86PagingMethod64Bit::PageTableEntryForAddress( + fPagingStructures->VirtualPML4(), address, fIsKernelMap, + false, NULL, fPageMapper, fMapCount); + if (entry == NULL) + return false; + + uint64 oldEntry; + + if (unmapIfUnaccessed) { + while (true) { + oldEntry = *entry; + if ((oldEntry & X86_64_PTE_PRESENT) == 0) { + // page mapping not valid + return false; + } + + if (oldEntry & X86_64_PTE_ACCESSED) { + // page was accessed -- just clear the flags + oldEntry = X86PagingMethod64Bit::ClearTableEntryFlags(entry, + X86_64_PTE_ACCESSED | X86_64_PTE_DIRTY); + break; + } + + // page hasn't been accessed -- unmap it + if (X86PagingMethod64Bit::TestAndSetTableEntry(entry, 0, oldEntry) + == oldEntry) { + break; + } + + // something changed -- check again + } + } else { + oldEntry = X86PagingMethod64Bit::ClearTableEntryFlags(entry, + X86_64_PTE_ACCESSED | X86_64_PTE_DIRTY); + } + + pinner.Unlock(); + + _modified = (oldEntry & X86_64_PTE_DIRTY) != 0; + + if ((oldEntry & X86_64_PTE_ACCESSED) != 0) { + // Note, that we only need to invalidate the address, if the + // accessed flags was set, since only then the entry could have been + // in any TLB. + InvalidatePage(address); + Flush(); + + return true; + } + + if (!unmapIfUnaccessed) + return false; + + // We have unmapped the address. Do the "high level" stuff. + + fMapCount--; + + locker.Detach(); + // UnaccessedPageUnmapped() will unlock for us + + UnaccessedPageUnmapped(area, + (oldEntry & X86_64_PTE_ADDRESS_MASK) / B_PAGE_SIZE); + + return false; +} + + +X86PagingStructures* +X86VMTranslationMap64Bit::PagingStructures() const +{ + return fPagingStructures; +} diff --git a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.h b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.h new file mode 100644 index 0000000000..7a9b449a70 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.h @@ -0,0 +1,69 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_ARCH_X86_PAGING_64BIT_X86_VM_TRANSLATION_MAP_64BIT_H +#define KERNEL_ARCH_X86_PAGING_64BIT_X86_VM_TRANSLATION_MAP_64BIT_H + + +#include "paging/X86VMTranslationMap.h" + + +struct X86PagingStructures64Bit; + + +struct X86VMTranslationMap64Bit : X86VMTranslationMap { + X86VMTranslationMap64Bit(); + virtual ~X86VMTranslationMap64Bit(); + + status_t Init(bool kernel); + + virtual size_t MaxPagesNeededToMap(addr_t start, + addr_t end) const; + + virtual status_t Map(addr_t virtualAddress, + phys_addr_t physicalAddress, + uint32 attributes, uint32 memoryType, + vm_page_reservation* reservation); + virtual status_t Unmap(addr_t start, addr_t end); + + virtual status_t DebugMarkRangePresent(addr_t start, addr_t end, + bool markPresent); + + virtual status_t UnmapPage(VMArea* area, addr_t address, + bool updatePageQueue); + virtual void UnmapPages(VMArea* area, addr_t base, + size_t size, bool updatePageQueue); + virtual void UnmapArea(VMArea* area, + bool deletingAddressSpace, + bool ignoreTopCachePageFlags); + + virtual status_t Query(addr_t virtualAddress, + phys_addr_t* _physicalAddress, + uint32* _flags); + virtual status_t QueryInterrupt(addr_t virtualAddress, + phys_addr_t* _physicalAddress, + uint32* _flags); + + virtual status_t Protect(addr_t base, addr_t top, + uint32 attributes, uint32 memoryType); + + virtual status_t ClearFlags(addr_t virtualAddress, + uint32 flags); + + virtual bool ClearAccessedAndModified( + VMArea* area, addr_t address, + bool unmapIfUnaccessed, + bool& _modified); + + virtual X86PagingStructures* PagingStructures() const; + inline X86PagingStructures64Bit* PagingStructures64Bit() const + { return fPagingStructures; } + +private: + X86PagingStructures64Bit* fPagingStructures; +}; + + +#endif // KERNEL_ARCH_X86_PAGING_64BIT_X86_VM_TRANSLATION_MAP_64BIT_H diff --git a/src/system/kernel/arch/x86/paging/64bit/paging.h b/src/system/kernel/arch/x86/paging/64bit/paging.h new file mode 100644 index 0000000000..2cb4fb4b06 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/64bit/paging.h @@ -0,0 +1,80 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_ARCH_X86_PAGING_64BIT_PAGING_H +#define KERNEL_ARCH_X86_PAGING_64BIT_PAGING_H + + +#include + + +// PML4 entry bits. +#define X86_64_PML4E_PRESENT (1LL << 0) +#define X86_64_PML4E_WRITABLE (1LL << 1) +#define X86_64_PML4E_USER (1LL << 2) +#define X86_64_PML4E_WRITE_THROUGH (1LL << 3) +#define X86_64_PML4E_CACHING_DISABLED (1LL << 4) +#define X86_64_PML4E_ACCESSED (1LL << 5) +#define X86_64_PML4E_NOT_EXECUTABLE (1LL << 63) +#define X86_64_PML4E_ADDRESS_MASK 0x000ffffffffff000L + +// PDPT entry bits. +#define X86_64_PDPTE_PRESENT (1LL << 0) +#define X86_64_PDPTE_WRITABLE (1LL << 1) +#define X86_64_PDPTE_USER (1LL << 2) +#define X86_64_PDPTE_WRITE_THROUGH (1LL << 3) +#define X86_64_PDPTE_CACHING_DISABLED (1LL << 4) +#define X86_64_PDPTE_ACCESSED (1LL << 5) +#define X86_64_PDPTE_DIRTY (1LL << 6) +#define X86_64_PDPTE_LARGE_PAGE (1LL << 7) +#define X86_64_PDPTE_GLOBAL (1LL << 8) +#define X86_64_PDPTE_PAT (1LL << 12) +#define X86_64_PDPTE_NOT_EXECUTABLE (1LL << 63) +#define X86_64_PDPTE_ADDRESS_MASK 0x000ffffffffff000L + +// Page directory entry bits. +#define X86_64_PDE_PRESENT (1LL << 0) +#define X86_64_PDE_WRITABLE (1LL << 1) +#define X86_64_PDE_USER (1LL << 2) +#define X86_64_PDE_WRITE_THROUGH (1LL << 3) +#define X86_64_PDE_CACHING_DISABLED (1LL << 4) +#define X86_64_PDE_ACCESSED (1LL << 5) +#define X86_64_PDE_DIRTY (1LL << 6) +#define X86_64_PDE_LARGE_PAGE (1LL << 7) +#define X86_64_PDE_GLOBAL (1LL << 8) +#define X86_64_PDE_PAT (1LL << 12) +#define X86_64_PDE_NOT_EXECUTABLE (1LL << 63) +#define X86_64_PDE_ADDRESS_MASK 0x000ffffffffff000L + +// Page table entry bits. +#define X86_64_PTE_PRESENT (1LL << 0) +#define X86_64_PTE_WRITABLE (1LL << 1) +#define X86_64_PTE_USER (1LL << 2) +#define X86_64_PTE_WRITE_THROUGH (1LL << 3) +#define X86_64_PTE_CACHING_DISABLED (1LL << 4) +#define X86_64_PTE_ACCESSED (1LL << 5) +#define X86_64_PTE_DIRTY (1LL << 6) +#define X86_64_PTE_PAT (1LL << 7) +#define X86_64_PTE_GLOBAL (1LL << 8) +#define X86_64_PTE_NOT_EXECUTABLE (1LL << 63) +#define X86_64_PTE_ADDRESS_MASK 0x000ffffffffff000L +#define X86_64_PTE_PROTECTION_MASK (X86_64_PTE_WRITABLE | X86_64_PTE_USER) +#define X86_64_PTE_MEMORY_TYPE_MASK (X86_64_PTE_WRITE_THROUGH \ + | X86_64_PTE_CACHING_DISABLED) + + +static const size_t k64BitPageTableRange = 0x200000L; +static const size_t k64BitPageDirectoryRange = 0x40000000L; +static const size_t k64BitPDPTRange = 0x8000000000L; + +static const size_t k64BitTableEntryCount = 512; + + +#define VADDR_TO_PML4E(va) (((va) & 0x0000fffffffff000L) / k64BitPDPTRange) +#define VADDR_TO_PDPTE(va) (((va) % k64BitPDPTRange) / k64BitPageDirectoryRange) +#define VADDR_TO_PDE(va) (((va) % k64BitPageDirectoryRange) / k64BitPageTableRange) +#define VADDR_TO_PTE(va) (((va) % k64BitPageTableRange) / B_PAGE_SIZE) + + +#endif // KERNEL_ARCH_X86_PAGING_64BIT_PAGING_H diff --git a/src/system/kernel/arch/x86/paging/X86PagingMethod.h b/src/system/kernel/arch/x86/paging/X86PagingMethod.h index 964f425f92..e80c4c7a14 100644 --- a/src/system/kernel/arch/x86/paging/X86PagingMethod.h +++ b/src/system/kernel/arch/x86/paging/X86PagingMethod.h @@ -8,6 +8,8 @@ #include +#include + struct kernel_args; struct VMPhysicalPageMapper; @@ -30,7 +32,7 @@ public: addr_t virtualAddress, phys_addr_t physicalAddress, uint8 attributes, - phys_addr_t (*get_free_page)(kernel_args*)) + page_num_t (*get_free_page)(kernel_args*)) = 0; virtual bool IsKernelPageAccessible(addr_t virtualAddress, diff --git a/src/system/kernel/arch/x86/paging/X86PagingStructures.h b/src/system/kernel/arch/x86/paging/X86PagingStructures.h index f7cfb6a54c..fe8b9d9a94 100644 --- a/src/system/kernel/arch/x86/paging/X86PagingStructures.h +++ b/src/system/kernel/arch/x86/paging/X86PagingStructures.h @@ -16,7 +16,7 @@ struct X86PagingStructures : DeferredDeletable { - uint32 pgdir_phys; + phys_addr_t pgdir_phys; vint32 ref_count; vint32 active_on_cpus; // mask indicating on which CPUs the map is currently used diff --git a/src/system/kernel/arch/x86/paging/X86VMTranslationMap.cpp b/src/system/kernel/arch/x86/paging/X86VMTranslationMap.cpp index 393ca4eda7..a9768653ef 100644 --- a/src/system/kernel/arch/x86/paging/X86VMTranslationMap.cpp +++ b/src/system/kernel/arch/x86/paging/X86VMTranslationMap.cpp @@ -128,7 +128,7 @@ X86VMTranslationMap::Flush() if (fIsKernelMap) { smp_send_broadcast_ici(SMP_MSG_INVALIDATE_PAGE_LIST, - (uint32)fInvalidPages, fInvalidPagesCount, 0, NULL, + (addr_t)fInvalidPages, fInvalidPagesCount, 0, NULL, SMP_MSG_FLAG_SYNC); } else { int cpu = smp_get_current_cpu(); @@ -136,7 +136,7 @@ X86VMTranslationMap::Flush() & ~((uint32)1 << cpu); if (cpuMask != 0) { smp_send_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST, - (uint32)fInvalidPages, fInvalidPagesCount, 0, NULL, + (addr_t)fInvalidPages, fInvalidPagesCount, 0, NULL, SMP_MSG_FLAG_SYNC); } } diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp index e7001bb7c6..3a3115ff4d 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp +++ b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp @@ -56,7 +56,8 @@ struct X86PagingMethodPAE::ToPAESwitcher { fKernelArgs(args) { // page hole set up in the boot loader - fPageHole = (page_table_entry*)fKernelArgs->arch_args.page_hole; + fPageHole = (page_table_entry*) + (addr_t)fKernelArgs->arch_args.page_hole; // calculate where the page dir would be fPageHolePageDir = (page_directory_entry*) @@ -162,7 +163,7 @@ struct X86PagingMethodPAE::ToPAESwitcher { private: static void _EnablePAE(void* physicalPDPT, int cpu) { - write_cr3((addr_t)physicalPDPT); + x86_write_cr3((addr_t)physicalPDPT); x86_write_cr4(x86_read_cr4() | IA32_CR4_PAE | IA32_CR4_GLOBAL_PAGES); } @@ -628,7 +629,7 @@ X86PagingMethodPAE::CreateTranslationMap(bool kernel, VMTranslationMap** _map) status_t X86PagingMethodPAE::MapEarly(kernel_args* args, addr_t virtualAddress, phys_addr_t physicalAddress, uint8 attributes, - phys_addr_t (*get_free_page)(kernel_args*)) + page_num_t (*get_free_page)(kernel_args*)) { // check to see if a page table exists for this range pae_page_directory_entry* pageDirEntry = PageDirEntryForAddress( @@ -680,9 +681,8 @@ X86PagingMethodPAE::IsKernelPageAccessible(addr_t virtualAddress, // We only trust the kernel team's page directories. So switch to the // kernel PDPT first. Always set it to make sure the TLBs don't contain // obsolete data. - uint32 physicalPDPT; - read_cr3(physicalPDPT); - write_cr3(fKernelPhysicalPageDirPointerTable); + uint32 physicalPDPT = x86_read_cr3(); + x86_write_cr3(fKernelPhysicalPageDirPointerTable); // get the PDPT entry for the address pae_page_directory_pointer_table_entry pdptEntry = 0; @@ -733,7 +733,7 @@ X86PagingMethodPAE::IsKernelPageAccessible(addr_t virtualAddress, // switch back to the original page directory if (physicalPDPT != fKernelPhysicalPageDirPointerTable) - write_cr3(physicalPDPT); + x86_write_cr3(physicalPDPT); if ((pageTableEntry & X86_PAE_PTE_PRESENT) == 0) return false; diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.h b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.h index e1232d05bc..6d6b1ed1ab 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.h +++ b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.h @@ -39,7 +39,7 @@ public: addr_t virtualAddress, phys_addr_t physicalAddress, uint8 attributes, - phys_addr_t (*get_free_page)(kernel_args*)); + page_num_t (*get_free_page)(kernel_args*)); virtual bool IsKernelPageAccessible(addr_t virtualAddress, uint32 protection); diff --git a/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp index 8f086b522d..8d6853689b 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp +++ b/src/system/kernel/arch/x86/paging/pae/X86VMTranslationMapPAE.cpp @@ -697,7 +697,7 @@ X86VMTranslationMapPAE::Query(addr_t virtualAddress, | ((entry & X86_PAE_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0); TRACE("X86VMTranslationMapPAE::Query(%#" B_PRIxADDR ") -> %#" - B_PRIxPHYSADDR ":\n", *_physicalAddress, virtualAddress); + B_PRIxPHYSADDR ":\n", virtualAddress, *_physicalAddress); return B_OK; } @@ -870,7 +870,7 @@ X86VMTranslationMapPAE::ClearAccessedAndModified(VMArea* area, addr_t address, { ASSERT(address % B_PAGE_SIZE == 0); - TRACE("X86VMTranslationMap32Bit::ClearAccessedAndModified(%#" B_PRIxADDR + TRACE("X86VMTranslationMapPAE::ClearAccessedAndModified(%#" B_PRIxADDR ")\n", address); pae_page_directory_entry* pageDirEntry diff --git a/src/system/kernel/arch/x86/paging/x86_physical_page_mapper.h b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper.h index 31e4796066..a29459b9f0 100644 --- a/src/system/kernel/arch/x86/paging/x86_physical_page_mapper.h +++ b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper.h @@ -10,7 +10,6 @@ struct kernel_args; -struct vm_translation_map_ops; class TranslationMapPhysicalPageMapper { diff --git a/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.cpp b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.cpp new file mode 100644 index 0000000000..babdbb87c6 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.cpp @@ -0,0 +1,256 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +/*! Physical page mapper implementation for use where the whole of physical + memory is permanently mapped into the kernel address space. + + This is used on x86_64 where the virtual address space is likely a great + deal larger than the amount of physical memory in the machine, so it can + all be mapped in permanently, which is faster and makes life much easier. +*/ + + +#include "paging/x86_physical_page_mapper_mapped.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include "paging/x86_physical_page_mapper.h" +#include "paging/X86PagingStructures.h" +#include "paging/X86VMTranslationMap.h" + + +// #pragma mark - + + +class MappedTranslationMapPhysicalPageMapper + : public TranslationMapPhysicalPageMapper { +public: + virtual void Delete(); + + virtual void* GetPageTableAt(phys_addr_t physicalAddress); +}; + + +class MappedPhysicalPageMapper : public X86PhysicalPageMapper { +public: + virtual status_t CreateTranslationMapPhysicalPageMapper( + TranslationMapPhysicalPageMapper** _mapper); + + virtual void* InterruptGetPageTableAt( + phys_addr_t physicalAddress); + + virtual status_t GetPage(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle); + virtual status_t PutPage(addr_t virtualAddress, void* handle); + + virtual status_t GetPageCurrentCPU(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle); + virtual status_t PutPageCurrentCPU(addr_t virtualAddress, + void* handle); + + virtual status_t GetPageDebug(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle); + virtual status_t PutPageDebug(addr_t virtualAddress, + void* handle); + + virtual status_t MemsetPhysical(phys_addr_t address, int value, + phys_size_t length); + virtual status_t MemcpyFromPhysical(void* to, phys_addr_t from, + size_t length, bool user); + virtual status_t MemcpyToPhysical(phys_addr_t to, + const void* from, size_t length, bool user); + virtual void MemcpyPhysicalPage(phys_addr_t to, + phys_addr_t from); +}; + + +static MappedPhysicalPageMapper sPhysicalPageMapper; +static MappedTranslationMapPhysicalPageMapper sKernelPageMapper; + + +// #pragma mark - MappedTranslationMapPhysicalPageMapper + + +void +MappedTranslationMapPhysicalPageMapper::Delete() +{ + delete this; +} + + +void* +MappedTranslationMapPhysicalPageMapper::GetPageTableAt( + phys_addr_t physicalAddress) +{ + ASSERT(physicalAddress % B_PAGE_SIZE == 0); + + return (void*)(physicalAddress + KERNEL_PMAP_BASE); +} + + +// #pragma mark - MappedPhysicalPageMapper + + +status_t +MappedPhysicalPageMapper::CreateTranslationMapPhysicalPageMapper( + TranslationMapPhysicalPageMapper** _mapper) +{ + MappedTranslationMapPhysicalPageMapper* mapper + = new(std::nothrow) MappedTranslationMapPhysicalPageMapper; + if (mapper == NULL) + return B_NO_MEMORY; + + *_mapper = mapper; + return B_OK; +} + + +void* +MappedPhysicalPageMapper::InterruptGetPageTableAt( + phys_addr_t physicalAddress) +{ + ASSERT(physicalAddress % B_PAGE_SIZE == 0); + + return (void*)(physicalAddress + KERNEL_PMAP_BASE); +} + + +status_t +MappedPhysicalPageMapper::GetPage(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle) +{ + if (physicalAddress >= KERNEL_PMAP_BASE) + return B_BAD_ADDRESS; + + *virtualAddress = physicalAddress + KERNEL_PMAP_BASE; + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::PutPage(addr_t virtualAddress, void* handle) +{ + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::GetPageCurrentCPU(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle) +{ + if (physicalAddress >= KERNEL_PMAP_BASE) + return B_BAD_ADDRESS; + + *virtualAddress = physicalAddress + KERNEL_PMAP_BASE; + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::PutPageCurrentCPU(addr_t virtualAddress, + void* handle) +{ + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::GetPageDebug(phys_addr_t physicalAddress, + addr_t* virtualAddress, void** handle) +{ + if (physicalAddress >= KERNEL_PMAP_BASE) + return B_BAD_ADDRESS; + + *virtualAddress = physicalAddress + KERNEL_PMAP_BASE; + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::PutPageDebug(addr_t virtualAddress, void* handle) +{ + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::MemsetPhysical(phys_addr_t address, int value, + phys_size_t length) +{ + if (address >= KERNEL_PMAP_SIZE || address + length > KERNEL_PMAP_SIZE) + return B_BAD_ADDRESS; + + memset((void*)(address + KERNEL_PMAP_BASE), value, length); + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::MemcpyFromPhysical(void* to, phys_addr_t _from, + size_t length, bool user) +{ + if (_from >= KERNEL_PMAP_SIZE || _from + length > KERNEL_PMAP_SIZE) + return B_BAD_ADDRESS; + + void* from = (void*)(_from + KERNEL_PMAP_BASE); + + if (user) + return user_memcpy(to, from, length); + else + memcpy(to, from, length); + + return B_OK; +} + + +status_t +MappedPhysicalPageMapper::MemcpyToPhysical(phys_addr_t _to, const void* from, + size_t length, bool user) +{ + if (_to >= KERNEL_PMAP_SIZE || _to + length > KERNEL_PMAP_SIZE) + return B_BAD_ADDRESS; + + void* to = (void*)(_to + KERNEL_PMAP_BASE); + + if (user) + return user_memcpy(to, from, length); + + memcpy(to, from, length); + return B_OK; +} + + +void +MappedPhysicalPageMapper::MemcpyPhysicalPage(phys_addr_t to, + phys_addr_t from) +{ + memcpy((void*)(to + KERNEL_PMAP_BASE), (void*)(from + KERNEL_PMAP_BASE), + B_PAGE_SIZE); +} + + +// #pragma mark - Initialization + + +status_t +mapped_physical_page_ops_init(kernel_args* args, + X86PhysicalPageMapper*& _pageMapper, + TranslationMapPhysicalPageMapper*& _kernelPageMapper) +{ + new(&sPhysicalPageMapper) MappedPhysicalPageMapper; + new(&sKernelPageMapper) MappedTranslationMapPhysicalPageMapper; + + _pageMapper = &sPhysicalPageMapper; + _kernelPageMapper = &sKernelPageMapper; + return B_OK; +} diff --git a/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.h b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.h new file mode 100644 index 0000000000..d0c4390729 --- /dev/null +++ b/src/system/kernel/arch/x86/paging/x86_physical_page_mapper_mapped.h @@ -0,0 +1,24 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_ARCH_X86_PAGING_X86_PHYSICAL_PAGE_MAPPER_MAPPED_H +#define KERNEL_ARCH_X86_PAGING_X86_PHYSICAL_PAGE_MAPPER_MAPPED_H + + +#include + +#include + + +class TranslationMapPhysicalPageMapper; +class X86PhysicalPageMapper; +struct kernel_args; + + +status_t mapped_physical_page_ops_init(kernel_args* args, + X86PhysicalPageMapper*& _pageMapper, + TranslationMapPhysicalPageMapper*& _kernelPageMapper); + + +#endif // KERNEL_ARCH_X86_PAGING_X86_PHYSICAL_PAGE_MAPPER_MAPPED_H diff --git a/src/system/kernel/arch/x86/timers/x86_hpet.cpp b/src/system/kernel/arch/x86/timers/x86_hpet.cpp index d5dfa48693..e25785cd58 100644 --- a/src/system/kernel/arch/x86/timers/x86_hpet.cpp +++ b/src/system/kernel/arch/x86/timers/x86_hpet.cpp @@ -221,7 +221,7 @@ hpet_init(struct kernel_args *args) return B_ERROR; if (sHPETRegs == NULL) { - sHPETRegs = (struct hpet_regs *)args->arch_args.hpet; + sHPETRegs = (struct hpet_regs *)args->arch_args.hpet.Pointer(); if (vm_map_physical_memory(B_SYSTEM_TEAM, "hpet", (void **)&sHPETRegs, B_EXACT_ADDRESS, B_PAGE_SIZE, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, diff --git a/src/system/kernel/arch/x86/vm86.cpp b/src/system/kernel/arch/x86/vm86.cpp deleted file mode 100644 index ebfce515af..0000000000 --- a/src/system/kernel/arch/x86/vm86.cpp +++ /dev/null @@ -1,668 +0,0 @@ -/* - * Copyright 2008 Jan Klötzke - * All rights reserved. Distributed under the terms of the MIT License. - * - * Emulation based on the Linux Real Mode Interface library. - * Copyright (C) 1998 by Josh Vanderhoof - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -//#define TRACE_VM86 -#ifdef TRACE_VM86 -# define TRACE(x...) dprintf("[vm86] " x) -# define TRACE_NP(x...) dprintf(x) -#else -# define TRACE(x...) -# define TRACE_NP(x...) -#endif - -#define CLI 0xfa -#define INB 0xec -#define INBI 0xe4 -#define INSB 0x6c -#define INSW 0x6d -#define INTn 0xcd -#define INW 0xed -#define INWI 0xe5 -#define IRET 0xcf -#define OUTB 0xee -#define OUTBI 0xe6 -#define OUTSB 0x6e -#define OUTSW 0x6f -#define OUTW 0xef -#define OUTWI 0xe7 -#define POPF 0x9d -#define PUSHF 0x9c -#define STI 0xfb - -#define I_FLAG (1u << 9) -#define DIRECTION_FLAG (1u << 10) - -#define CSEG 0x2e -#define SSEG 0x36 -#define DSEG 0x3e -#define ESEG 0x26 -#define FSEG 0x64 -#define GSEG 0x65 - - -static inline uint16 -get_int_seg(int i) -{ - return *(uint16 *)(i * 4 + 2); -} - - -static inline uint16 -get_int_off(int i) -{ - return *(uint16 *)(i * 4); -} - - -static inline void -pushw(struct vm86_iframe *regs, uint16 i) -{ - regs->esp -= 2; - *(uint16 *)(((uint32)regs->ss << 4) + regs->esp) = i; -} - - -static inline void -pushl(struct vm86_iframe *regs, uint32 i) -{ - regs->esp -= 4; - *(uint32 *)(((uint32)regs->ss << 4) + regs->esp) = i; -} - - -static inline uint16 -popw(struct vm86_iframe *regs) -{ - uint16 ret = *(uint16 *)(((uint32)regs->ss << 4) + regs->esp); - regs->esp += 2; - return ret; -} - - -static inline uint32 -popl(struct vm86_iframe *regs) -{ - uint32 ret = *(uint32 *)(((uint32)regs->ss << 4) + regs->esp); - regs->esp += 4; - return ret; -} - - -static void -em_ins(struct vm86_iframe *regs, int size) -{ - unsigned int edx, edi; - - edx = regs->edx & 0xffff; - edi = regs->edi & 0xffff; - edi += (unsigned int)regs->es << 4; - - if (regs->flags & DIRECTION_FLAG) { - if (size == 4) - asm volatile ("std; insl; cld" : "=D" (edi) : "d" (edx), "0" (edi)); - else if (size == 2) - asm volatile ("std; insw; cld" : "=D" (edi) : "d" (edx), "0" (edi)); - else - asm volatile ("std; insb; cld" : "=D" (edi) : "d" (edx), "0" (edi)); - } else { - if (size == 4) - asm volatile ("cld; insl" : "=D" (edi) : "d" (edx), "0" (edi)); - else if (size == 2) - asm volatile ("cld; insw" : "=D" (edi) : "d" (edx), "0" (edi)); - else - asm volatile ("cld; insb" : "=D" (edi) : "d" (edx), "0" (edi)); - } - - edi -= (unsigned int)regs->es << 4; - - regs->edi &= 0xffff0000; - regs->edi |= edi & 0xffff; -} - - -static void -em_rep_ins(struct vm86_iframe *regs, int size) -{ - unsigned int cx; - - cx = regs->ecx & 0xffff; - - while (cx--) - em_ins(regs, size); - - regs->ecx &= 0xffff0000; -} - - -static void -em_outs(struct vm86_iframe *regs, int size, int seg) -{ - unsigned int edx, esi, base; - - edx = regs->edx & 0xffff; - esi = regs->esi & 0xffff; - - switch (seg) { - case CSEG: base = regs->cs; break; - case SSEG: base = regs->ss; break; - case ESEG: base = regs->es; break; - case FSEG: base = regs->fs; break; - case GSEG: base = regs->gs; break; - case DSEG: - default: - base = regs->ds; - break; - } - - esi += base << 4; - - if (regs->flags & DIRECTION_FLAG) { - if (size == 4) { - asm volatile ("std; outsl; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - } else if (size == 2) { - asm volatile ("std; outsw; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - } else { - asm volatile ("std; outsb; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - } - } else { - if (size == 4) - asm volatile ("cld; outsl" : "=S" (esi) : "d" (edx), "0" (esi)); - else if (size == 2) - asm volatile ("cld; outsw" : "=S" (esi) : "d" (edx), "0" (esi)); - else - asm volatile ("cld; outsb" : "=S" (esi) : "d" (edx), "0" (esi)); - } - - esi -= base << 4; - - regs->esi &= 0xffff0000; - regs->esi |= esi & 0xffff; -} - - -static void -em_rep_outs(struct vm86_iframe *regs, int size, int seg) -{ - unsigned int cx; - - cx = regs->ecx & 0xffff; - - while (cx--) - em_outs(regs, size, seg); - - regs->ecx &= 0xffff0000; -} - - -static inline void -em_inb(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("inb %w1, %b0" - : "=a" (regs->eax) - : "d" (port), "0" (regs->eax)); -} - - -static inline void -em_inw(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("inw %w1, %w0" - : "=a" (regs->eax) - : "d" (port), "0" (regs->eax)); -} - - -static inline void -em_inl(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("inl %w1, %0" : "=a" (regs->eax) : "d" (port)); -} - - -static inline void -em_outb(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("outb %b0, %w1" : : "a" (regs->eax), "d" (port)); -} - - -static inline void -em_outw(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("outw %w0, %w1" : : "a" (regs->eax), "d" (port)); -} - - -static inline void -em_outl(struct vm86_iframe *regs, uint32 port) -{ - asm volatile ("outl %0, %w1" : : "a" (regs->eax), "d" (port)); -} - - -static int -emulate(struct vm86_state *state) -{ - unsigned char *instruction; - struct { - unsigned char seg; - unsigned int size : 1; - unsigned int rep : 1; - } prefix = { DSEG, 0, 0 }; - int ret = 0; - - instruction = (unsigned char *)((unsigned int)state->regs.cs << 4); - instruction += state->regs.eip; - - TRACE("emulate: "); - - /* handle prefixes */ - do { - switch (*instruction) { - case 0x66: - TRACE_NP("[SIZE] "); - prefix.size = 1 - prefix.size; - state->regs.eip++; - instruction++; - break; - case 0xf3: - TRACE_NP("REP "); - prefix.rep = 1; - state->regs.eip++; - instruction++; - break; - case CSEG: - case SSEG: - case DSEG: - case ESEG: - case FSEG: - case GSEG: - TRACE_NP("SEG(0x%02x) ", *instruction); - prefix.seg = *instruction; - state->regs.eip++; - instruction++; - break; - case 0xf0: - case 0xf2: - case 0x67: - /* these prefixes are just ignored */ - TRACE_NP("IGN(0x%02x) ", *instruction); - state->regs.eip++; - instruction++; - break; - default: - ret = 1; - } - } while (!ret); - - /* handle actual instruction */ - ret = 0; - switch (*instruction) { - case INSB: - TRACE_NP("INSB"); - if (prefix.rep) - em_rep_ins(&state->regs, 1); - else - em_ins(&state->regs, 1); - state->regs.eip++; - break; - case INSW: - TRACE_NP("INSW"); - if (prefix.rep) { - if (prefix.size) - em_rep_ins(&state->regs, 4); - else - em_rep_ins(&state->regs, 2); - } else { - if (prefix.size) - em_ins(&state->regs, 4); - else - em_ins(&state->regs, 2); - } - state->regs.eip++; - break; - case OUTSB: - TRACE_NP("OUTSB"); - if (prefix.rep) - em_rep_outs(&state->regs, 1, prefix.seg); - else - em_outs(&state->regs, 1, prefix.seg); - state->regs.eip++; - break; - case OUTSW: - TRACE_NP("OUTSW"); - if (prefix.rep) { - if (prefix.size) - em_rep_outs(&state->regs, 4, prefix.seg); - else - em_rep_outs(&state->regs, 2, prefix.seg); - } else { - if (prefix.size) - em_outs(&state->regs, 4, prefix.seg); - else - em_outs(&state->regs, 2, prefix.seg); - } - state->regs.eip++; - break; - case INBI: - em_inb(&state->regs, instruction[1]); - TRACE_NP("IN al(=0x%02lx), 0x%02x", state->regs.eax & 0xff, - instruction[1]); - state->regs.eip += 2; - break; - case INWI: - if (prefix.size) { - em_inl(&state->regs, instruction[1]); - TRACE_NP("IN eax(=0x%08lx), 0x%02x", state->regs.eax, - instruction[1]); - } else { - em_inw(&state->regs, instruction[1]); - TRACE_NP("IN ax(=0x%04lx), 0x%02x", state->regs.eax & 0xffff, - instruction[1]); - } - state->regs.eip += 2; - break; - case INB: - em_inb(&state->regs, state->regs.edx); - TRACE_NP("IN al(=0x%02lx), dx(0x%04lx)", state->regs.edx & 0xff, - state->regs.edx & 0xffff); - state->regs.eip++; - break; - case INW: - if (prefix.size) { - em_inl(&state->regs, state->regs.edx); - TRACE_NP("IN eax(=0x%08lx), dx(0x%04lx)", state->regs.edx, - state->regs.edx & 0xffff); - } else { - em_inw(&state->regs, state->regs.edx); - TRACE_NP("IN ax(=0x%04lx), dx(0x%04lx)", - state->regs.edx & 0xffff, state->regs.edx & 0xffff); - } - state->regs.eip++; - break; - case OUTBI: - em_outb(&state->regs, instruction[1]); - TRACE_NP("OUT 0x%02x, al(0x%02lx)", instruction[1], - state->regs.eax & 0xff); - state->regs.eip += 2; - break; - case OUTWI: - if (prefix.size) { - em_outl(&state->regs, instruction[1]); - TRACE_NP("OUT 0x%02x, eax(0x%08lx)", instruction[1], - state->regs.eax); - } else { - em_outw(&state->regs, instruction[1]); - TRACE_NP("OUT 0x%02x, ax(0x%04lx)", instruction[1], - state->regs.eax & 0xffff); - } - state->regs.eip += 2; - break; - case OUTB: - em_outb(&state->regs, state->regs.edx); - TRACE_NP("OUT dx(0x%04lx), al(0x%02lx)", state->regs.edx & 0xffff, - state->regs.eax & 0xff); - state->regs.eip++; - break; - case OUTW: - if (prefix.size) { - em_outl(&state->regs, state->regs.edx); - TRACE_NP("OUT dx(0x%04lx), eax(0x%08lx)", - state->regs.edx & 0xffff, state->regs.eax); - } else { - em_outw(&state->regs, state->regs.edx); - TRACE_NP("OUT dx(0x%04lx), ax(0x%04lx)", - state->regs.edx & 0xffff, state->regs.eax & 0xffff); - } - state->regs.eip++; - break; - case INTn: - TRACE_NP("INT 0x%02x", instruction[1]); - if (instruction[1] == RETURN_TO_32_INT) { - ret = 1; - } else { - uint16 flags = state->regs.flags; - - /* store real IF */ - flags &= ~I_FLAG; - flags |= (uint16)state->if_flag << 9; - - pushw(&state->regs, flags); - pushw(&state->regs, state->regs.cs); - pushw(&state->regs, state->regs.eip + 2); - - state->regs.cs = get_int_seg(instruction[1]); - state->regs.eip = get_int_off(instruction[1]); - state->if_flag = 0; - } - break; - case IRET: - TRACE_NP("IRET"); - state->regs.eip = popw(&state->regs); - state->regs.cs = popw(&state->regs); - state->regs.flags = popw(&state->regs); - /* restore IF */ - state->if_flag = (state->regs.flags >> 9) & 0x01; - break; - case CLI: - TRACE_NP("CLI"); - state->if_flag = 0; - state->regs.eip++; - break; - case STI: - TRACE_NP("STI"); - state->if_flag = 1; - state->regs.eip++; - break; - case PUSHF: - { - TRACE_NP("PUSHF"); - uint32 flags = state->regs.flags; - - /* store real IF */ - flags &= ~I_FLAG; - flags |= (uint32)state->if_flag << 9; - if (prefix.size) - pushl(&state->regs, flags); - else - pushw(&state->regs, flags); - state->regs.eip++; - break; - } - case POPF: - { - TRACE_NP("POPF"); - if (prefix.size) - state->regs.flags = popl(&state->regs); - else - state->regs.flags = popw(&state->regs); - /* restore IF */ - state->if_flag = (state->regs.flags >> 9) & 0x01; - state->regs.eip++; - break; - } - default: - TRACE_NP("UNK"); - ret = -1; - } - - TRACE_NP("\n"); - return ret; -} - - -static bool -vm86_fault_callback(addr_t address, addr_t faultAddress, bool isWrite) -{ - struct iframe *frame = i386_get_user_iframe(); - - TRACE("Unhandled fault at %#" B_PRIxADDR " touching %#" B_PRIxADDR - "while %s\n", faultAddress, address, isWrite ? "writing" : "reading"); - - // we shouldn't have unhandled page faults in vm86 mode - x86_vm86_return((struct vm86_iframe *)frame, B_BAD_ADDRESS); - - // not reached - return false; -} - - -// #pragma mark - exported interface - - -/*! Prepare the thread to execute BIOS code in virtual 8086 mode. Initializes - the given \a state to default values and maps the BIOS into the teams - address space. The size of the available conventional RAM is given in - \a ramSize in bytes which should be greater or equal to VM86_MIN_RAM_SIZE. -*/ -extern "C" status_t -vm86_prepare(struct vm86_state *state, unsigned int ramSize) -{ - Team *team = thread_get_current_thread()->team; - status_t ret = B_OK; - area_id vectors; - - state->bios_area = B_ERROR; - - // create RAM area - if (ramSize < VM86_MIN_RAM_SIZE) - ramSize = VM86_MIN_RAM_SIZE; - - void *address; - virtual_address_restrictions virtualRestrictions = {}; - virtualRestrictions.address = NULL; - virtualRestrictions.address_specification = B_EXACT_ADDRESS; - physical_address_restrictions physicalRestrictions = {}; - state->ram_area = create_area_etc(team->id, "dos", ramSize, B_NO_LOCK, - B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions, - &physicalRestrictions, &address); - if (state->ram_area < B_OK) { - ret = state->ram_area; - TRACE("Could not create RAM area\n"); - goto error; - } - - // copy int vectors and BIOS data area - vectors = map_physical_memory("int vectors", 0, 0x502, - B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, - &address); - if (vectors < B_OK) { - ret = vectors; - TRACE("Could not copy vectors\n"); - goto error; - } - ret = user_memcpy((void *)0, address, 0x502); - *((uint32 *)0) = 0xdeadbeef; - delete_area(vectors); - if (ret != B_OK) - goto error; - - // map vga/bios area - address = (void *)0xa0000; - state->bios_area = vm_map_physical_memory(team->id, "bios", - &address, B_EXACT_ADDRESS, 0x60000, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, - (addr_t)0xa0000, false); - if (state->bios_area < B_OK) { - ret = state->bios_area; - TRACE("Could not map VGA BIOS.\n"); - goto error; - } - - return B_OK; - -error: - if (state->bios_area > B_OK) - vm_delete_area(team->id, state->bios_area, true); - if (state->ram_area > B_OK) - vm_delete_area(team->id, state->ram_area, true); - return ret; -} - - -/*! Free ressources which were allocated by vm86_prepare(). -*/ -extern "C" void -vm86_cleanup(struct vm86_state *state) -{ - Team *team = thread_get_current_thread()->team; - - if (state->bios_area > B_OK) - vm_delete_area(team->id, state->bios_area, true); - if (state->ram_area > B_OK) - vm_delete_area(team->id, state->ram_area, true); -} - - -/*! Execute a BIOS call of interrupt \a vec. The given \a state must be - initialized by vm86_prepare() before, any registers needed by the BIOS too. - - The function will return B_OK if the BIOS was called successfully, - otherwise an apropriate error code. After the call the registers are - copied back to \a state to reflect the status after the BIOS returned. - - Any buffer which is given to the BIOS function may be allocated starting - from address 0x1000 up to the allocated RAM size (see vm86_prepare()). The - area below 0x1000 is not available because it is used for the interrupt - vector table, BIOS data area and as real mode stack. -*/ -extern "C" status_t -vm86_do_int(struct vm86_state *state, uint8 vec) -{ - int8 *ip; - int emuState = 0; - Thread *thread = thread_get_current_thread(); - status_t ret; - - // prepare environment - state->regs.ss = 0x600 >> 4; - state->regs.esp = (0x1000 - 0x600); - state->regs.cs = get_int_seg(vec); - state->regs.eip = get_int_off(vec); - state->if_flag = 0; - - pushw(&state->regs, state->regs.flags); - pushw(&state->regs, 0x0000); /* CS */ - pushw(&state->regs, 0x0600); /* IP */ - - ip = (int8 *)0x600; - *ip++ = INTn; - *ip++ = RETURN_TO_32_INT; - - // execute interrupt - thread->fault_callback = &vm86_fault_callback; - do { - ret = x86_vm86_enter(&state->regs); - if (ret != B_OK) - break; - emuState = emulate(state); - } while (emuState == 0); - thread->fault_callback = NULL; - - // We might have clobbered %fs, so we need to restore the CPU dependent - // TLS context that we may have overwritten. Note that we can't simply - // restore %fs to its previous value as we might not run on the same CPU - // anymore. - x86_set_tls_context(thread); - - return emuState < 0 ? B_BAD_DATA : ret; -} - diff --git a/src/system/kernel/arch/x86/x86_signals.h b/src/system/kernel/arch/x86/x86_signals.h index 282d4afec1..0e6cb50801 100644 --- a/src/system/kernel/arch/x86/x86_signals.h +++ b/src/system/kernel/arch/x86/x86_signals.h @@ -10,7 +10,9 @@ void x86_initialize_commpage_signal_handler(); +#ifndef __x86_64__ addr_t x86_get_user_signal_handler_wrapper(bool beosHandler); +#endif #endif // _KERNEL_ARCH_X86_SIGNALS_H diff --git a/src/system/kernel/arch/x86/x86_syscalls.h b/src/system/kernel/arch/x86/x86_syscalls.h index db0dd75f33..85ae6d7878 100644 --- a/src/system/kernel/arch/x86/x86_syscalls.h +++ b/src/system/kernel/arch/x86/x86_syscalls.h @@ -9,12 +9,26 @@ #include +void x86_initialize_syscall(); + + +#ifdef __x86_64__ + + +static inline void +x86_set_syscall_stack(addr_t stackTop) +{ + // Nothing to do here, the thread's stack pointer is always accessible + // via the GS segment. +} + + +#else + + extern void (*gX86SetSyscallStack)(addr_t stackTop); -void x86_initialize_commpage_syscall(); - - static inline void x86_set_syscall_stack(addr_t stackTop) { @@ -23,4 +37,6 @@ x86_set_syscall_stack(addr_t stackTop) } +#endif // __x86_64__ + #endif // _KERNEL_ARCH_X86_SYSCALLS_H diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp index 6e60ce1929..ba6f71a87b 100644 --- a/src/system/kernel/cache/block_cache.cpp +++ b/src/system/kernel/cache/block_cache.cpp @@ -304,8 +304,8 @@ public: virtual void AddDump(TraceOutput& out) { - out.Print("block cache %p, %s %Ld, %c%c%c transaction %ld " - "(previous id %ld)\n", fCache, _Action(), fBlockNumber, + out.Print("block cache %p, %s %" B_PRIu64 ", %c%c%c transaction %" B_PRId32 + " (previous id %" B_PRId32 ")\n", fCache, _Action(), fBlockNumber, fIsDirty ? 'd' : '-', fHasOriginal ? 'o' : '-', fHasParent ? 'p' : '-', fTransactionID, fPreviousID); } @@ -402,7 +402,7 @@ public: virtual void AddDump(TraceOutput& out) { - out.Print("block cache %p, error %Ld, %s%s%s", + out.Print("block cache %p, error %" B_PRIu64 ", %s%s%s", fCache, fBlockNumber, fMessage, fStatus != B_OK ? ": " : "", fStatus != B_OK ? strerror(fStatus) : ""); } @@ -444,7 +444,7 @@ public: virtual void AddDump(TraceOutput& out) { - out.Print("block cache %p, block %Ld, data %c%c%c: %s", + out.Print("block cache %p, block %" B_PRIu64 ", data %c%c%c: %s", fCache, fBlockNumber, fCurrent != NULL ? 'c' : '-', fParent != NULL ? 'p' : '-', fOriginal != NULL ? 'o' : '-', fMessage); @@ -470,7 +470,7 @@ public: void DumpBlock(uint32 which, uint32 offset, uint32 size) { if (offset > fSize) { - kprintf("invalid offset (block size %lu)\n", fSize); + kprintf("invalid offset (block size %" B_PRIu32 ")\n", fSize); return; } if (offset + size > fSize) @@ -491,7 +491,7 @@ public: } else return; - kprintf("%s: offset %lu, %lu bytes\n", label, offset, size); + kprintf("%s: offset %" B_PRIu32 ", %" B_PRIu32 " bytes\n", label, offset, size); static const uint32 kBlockSize = 16; data += offset; @@ -499,7 +499,7 @@ public: for (uint32 i = 0; i < size;) { int start = i; - kprintf(" %04lx ", i); + kprintf(" %04" B_PRIx32 " ", i); for (; i < start + kBlockSize; i++) { if (!(i % 4)) kprintf(" "); @@ -573,9 +573,9 @@ public: virtual void AddDump(TraceOutput& out) { - out.Print("block cache %p, %s transaction %p (id %ld)%s" - ", %ld/%ld blocks", fCache, fLabel, fTransaction, fID, - fSub ? " sub" : "", fNumBlocks, fSubNumBlocks); + out.Print("block cache %p, %s transaction %p (id %" B_PRId32 ")%s" + ", %" B_PRId32 "/%" B_PRId32 " blocks", fCache, fLabel, fTransaction, + fID, fSub ? " sub" : "", fNumBlocks, fSubNumBlocks); } private: @@ -605,8 +605,8 @@ public: virtual void AddDump(TraceOutput& out) { - out.Print("block cache %p, detach transaction %p (id %ld)" - "from transaction %p (id %ld)%s", + out.Print("block cache %p, detach transaction %p (id %" B_PRId32 ")" + "from transaction %p (id %" B_PRId32 ")%s", fCache, fNewTransaction, fNewID, fTransaction, fID, fSub ? " sub" : ""); } @@ -653,9 +653,9 @@ public: virtual void AddDump(TraceOutput& out) { out.Print("block cache %p, abort transaction " - "%p (id %ld), blocks", fCache, fTransaction, fID); + "%p (id %" B_PRId32 "), blocks", fCache, fTransaction, fID); for (int32 i = 0; i < fNumBlocks && !out.IsFull(); i++) - out.Print(" %Ld", fBlocks[i]); + out.Print(" %" B_PRIdOFF, fBlocks[i]); } #if KTRACE_PRINTF_STACK_TRACE @@ -1221,7 +1221,7 @@ BlockWriter::_WriteBlock(cached_block* block) { ASSERT(block->busy_writing); - TRACE(("BlockWriter::_WriteBlock(block %Ld)\n", block->block_number)); + TRACE(("BlockWriter::_WriteBlock(block %" B_PRIdOFF ")\n", block->block_number)); TB(Write(fCache, block)); TB2(BlockData(fCache, block, "before write")); @@ -1232,7 +1232,7 @@ BlockWriter::_WriteBlock(cached_block* block) if (written != (ssize_t)blockSize) { TB(Error(fCache, block->block_number, "write failed", written)); - FATAL(("could not write back block %Ld (%s)\n", block->block_number, + FATAL(("could not write back block %" B_PRIdOFF " (%s)\n", block->block_number, strerror(errno))); if (written < 0) return errno; @@ -1274,7 +1274,7 @@ BlockWriter::_BlockDone(cached_block* block, hash_iterator* iterator) // Has the previous transaction been finished with that write? if (--previous->num_blocks == 0) { - TRACE(("cache transaction %ld finished!\n", previous->id)); + TRACE(("cache transaction %" B_PRId32 " finished!\n", previous->id)); T(Action("written", fCache, previous)); notify_transaction_listeners(fCache, previous, @@ -1430,7 +1430,7 @@ block_cache::FreeBlock(cached_block* block) Free(block->current_data); if (block->original_data != NULL || block->parent_data != NULL) { - panic("block_cache::FreeBlock(): %Ld, original %p, parent %p\n", + panic("block_cache::FreeBlock(): %" B_PRIdOFF ", original %p, parent %p\n", block->block_number, block->original_data, block->parent_data); } @@ -1524,7 +1524,7 @@ block_cache::RemoveUnusedBlocks(int32 count, int32 minSecondsOld) continue; TB(Flush(this, block)); - TRACE((" remove block %Ld, last accessed %" B_PRId32 "\n", + TRACE((" remove block %" B_PRIdOFF ", last accessed %" B_PRId32 "\n", block->block_number, block->last_accessed)); // this can only happen if no transactions are used @@ -1578,7 +1578,7 @@ block_cache::DiscardBlock(cached_block* block) void block_cache::_LowMemoryHandler(void* data, uint32 resources, int32 level) { - TRACE(("block_cache: low memory handler called with level %ld\n", level)); + TRACE(("block_cache: low memory handler called with level %" B_PRId32 "\n", level)); // free some blocks according to the low memory state // (if there is enough memory left, we don't free any) @@ -1618,8 +1618,8 @@ block_cache::_LowMemoryHandler(void* data, uint32 resources, int32 level) cache->RemoveUnusedBlocks(free, secondsOld); - TRACE(("block_cache::_LowMemoryHandler(): %p: unused: %lu -> %lu\n", cache, - oldUnused, cache->unused_block_count)); + TRACE(("block_cache::_LowMemoryHandler(): %p: unused: %" B_PRIu32 " -> %" B_PRIu32 "\n", + cache, oldUnused, cache->unused_block_count)); } @@ -1818,7 +1818,7 @@ static void put_cached_block(block_cache* cache, off_t blockNumber) { if (blockNumber < 0 || blockNumber >= cache->max_blocks) { - panic("put_cached_block: invalid block number %lld (max %lld)", + panic("put_cached_block: invalid block number %" B_PRIdOFF " (max %" B_PRIdOFF ")", blockNumber, cache->max_blocks - 1); } @@ -1849,7 +1849,7 @@ get_cached_block(block_cache* cache, off_t blockNumber, bool* _allocated, ASSERT_LOCKED_MUTEX(&cache->lock); if (blockNumber < 0 || blockNumber >= cache->max_blocks) { - panic("get_cached_block: invalid block number %lld (max %lld)", + panic("get_cached_block: invalid block number %" B_PRIdOFF " (max %" B_PRIdOFF ")", blockNumber, cache->max_blocks - 1); return NULL; } @@ -1874,7 +1874,7 @@ retry: } if (block->unused) { - //TRACE(("remove block %Ld from unused\n", blockNumber)); + //TRACE(("remove block %" B_PRIdOFF " from unused\n", blockNumber)); block->unused = false; cache->unused_blocks.Remove(block); cache->unused_block_count--; @@ -1895,7 +1895,7 @@ retry: cache->RemoveBlock(block); TB(Error(cache, blockNumber, "read failed", bytesRead)); - FATAL(("could not read block %Ld: bytesRead: %ld, error: %s\n", + FATAL(("could not read block %" B_PRIdOFF ": bytesRead: %zd, error: %s\n", blockNumber, bytesRead, strerror(errno))); return NULL; } @@ -1922,11 +1922,11 @@ static void* get_writable_cached_block(block_cache* cache, off_t blockNumber, off_t base, off_t length, int32 transactionID, bool cleared) { - TRACE(("get_writable_cached_block(blockNumber = %Ld, transaction = %ld)\n", + TRACE(("get_writable_cached_block(blockNumber = %" B_PRIdOFF ", transaction = %" B_PRId32 ")\n", blockNumber, transactionID)); if (blockNumber < 0 || blockNumber >= cache->max_blocks) { - panic("get_writable_cached_block: invalid block number %lld (max %lld)", + panic("get_writable_cached_block: invalid block number %" B_PRIdOFF " (max %" B_PRIdOFF ")", blockNumber, cache->max_blocks - 1); } @@ -1971,7 +1971,7 @@ get_writable_cached_block(block_cache* cache, off_t blockNumber, off_t base, // TODO: we have to wait here until the other transaction is done. // Maybe we should even panic, since we can't prevent any deadlocks. panic("get_writable_cached_block(): asked to get busy writable block " - "(transaction %ld)\n", block->transaction->id); + "(transaction %" B_PRId32 ")\n", block->transaction->id); put_cached_block(cache, block); return NULL; } @@ -1979,7 +1979,7 @@ get_writable_cached_block(block_cache* cache, off_t blockNumber, off_t base, // get new transaction transaction = lookup_transaction(cache, transactionID); if (transaction == NULL) { - panic("get_writable_cached_block(): invalid transaction %ld!\n", + panic("get_writable_cached_block(): invalid transaction %" B_PRId32 "!\n", transactionID); put_cached_block(cache, block); return NULL; @@ -2070,7 +2070,8 @@ get_writable_cached_block(block_cache* cache, off_t blockNumber, off_t base, static void dump_block(cached_block* block) { - kprintf("%08lx %9Ld %08lx %08lx %08lx %5ld %6ld %c%c%c%c%c%c %08lx %08lx\n", + kprintf("%08lx %9" B_PRIdOFF " %08lx %08lx %08lx %5" B_PRId32 " %6" B_PRId32 + " %c%c%c%c%c%c %08lx %08lx\n", (addr_t)block, block->block_number, (addr_t)block->current_data, (addr_t)block->original_data, (addr_t)block->parent_data, block->ref_count, block->LastAccess(), @@ -2092,8 +2093,8 @@ dump_block_long(cached_block* block) #if BLOCK_CACHE_DEBUG_CHANGED kprintf(" compare data: %p\n", block->compare); #endif - kprintf(" ref_count: %ld\n", block->ref_count); - kprintf(" accessed: %ld\n", block->LastAccess()); + kprintf(" ref_count: %" B_PRId32 "\n", block->ref_count); + kprintf(" accessed: %" B_PRId32 "\n", block->LastAccess()); kprintf(" flags: "); if (block->busy_reading) kprintf(" busy_reading"); @@ -2109,15 +2110,15 @@ dump_block_long(cached_block* block) kprintf(" discard"); kprintf("\n"); if (block->transaction != NULL) { - kprintf(" transaction: %p (%ld)\n", block->transaction, + kprintf(" transaction: %p (%" B_PRId32 ")\n", block->transaction, block->transaction->id); if (block->transaction_next != NULL) { - kprintf(" next in transaction: %Ld\n", + kprintf(" next in transaction: %" B_PRIdOFF "\n", block->transaction_next->block_number); } } if (block->previous_transaction != NULL) { - kprintf(" previous transaction: %p (%ld)\n", + kprintf(" previous transaction: %p (%" B_PRId32 ")\n", block->previous_transaction, block->previous_transaction->id); } @@ -2183,20 +2184,20 @@ dump_cache(int argc, char** argv) if (block != NULL) dump_block_long(block); else - kprintf("block %Ld not found\n", blockNumber); + kprintf("block %" B_PRIdOFF " not found\n", blockNumber); return 0; } kprintf("BLOCK CACHE: %p\n", cache); kprintf(" fd: %d\n", cache->fd); - kprintf(" max_blocks: %Ld\n", cache->max_blocks); - kprintf(" block_size: %lu\n", cache->block_size); - kprintf(" next_transaction_id: %ld\n", cache->next_transaction_id); + kprintf(" max_blocks: %" B_PRIdOFF "\n", cache->max_blocks); + kprintf(" block_size: %zu\n", cache->block_size); + kprintf(" next_transaction_id: %" B_PRId32 "\n", cache->next_transaction_id); kprintf(" buffer_cache: %p\n", cache->buffer_cache); - kprintf(" busy_reading: %lu, %s waiters\n", cache->busy_reading_count, + kprintf(" busy_reading: %" B_PRIu32 ", %s waiters\n", cache->busy_reading_count, cache->busy_reading_waiters ? "has" : "no"); - kprintf(" busy_writing: %lu, %s waiters\n", cache->busy_writing_count, + kprintf(" busy_writing: %" B_PRIu32 ", %s waiters\n", cache->busy_writing_count, cache->busy_writing_waiters ? "has" : "no"); if (!cache->pending_notifications.IsEmpty()) { @@ -2207,7 +2208,7 @@ dump_cache(int argc, char** argv) while (iterator.HasNext()) { cache_notification* notification = iterator.Next(); - kprintf(" %p %5lx %p - %p\n", notification, + kprintf(" %p %5" B_PRIx32 " %p - %p\n", notification, notification->events_pending, notification->hook, notification->data); } @@ -2223,8 +2224,8 @@ dump_cache(int argc, char** argv) cache_transaction* transaction; while ((transaction = (cache_transaction*)hash_next( cache->transaction_hash, &iterator)) != NULL) { - kprintf("%p %5ld %-7s %5ld %5ld %5ld\n", transaction, - transaction->id, transaction->open ? "open" : "closed", + kprintf("%p %5" B_PRId32 " %-7s %5" B_PRId32 " %5" B_PRId32 " %5" B_PRId32 "\n", + transaction, transaction->id, transaction->open ? "open" : "closed", transaction->num_blocks, transaction->main_num_blocks, transaction->sub_num_blocks); } @@ -2256,9 +2257,10 @@ dump_cache(int argc, char** argv) count++; } - kprintf(" %ld blocks total, %ld dirty, %ld discarded, %ld referenced, %ld " - "busy, %" B_PRIu32 " in unused.\n", count, dirty, discarded, referenced, - cache->busy_reading_count, cache->unused_block_count); + kprintf(" %" B_PRIu32 " blocks total, %" B_PRIu32 " dirty, %" B_PRIu32 " discarded" + ", %" B_PRIu32 " referenced, %" B_PRIu32 " busy, %" B_PRIu32 " in unused.\n", + count, dirty, discarded, referenced, cache->busy_reading_count, + cache->unused_block_count); hash_close(cache->hash, &iterator, false); return 0; @@ -2289,20 +2291,20 @@ dump_transaction(int argc, char** argv) int32 id = parse_expression(argv[i + 1]); transaction = lookup_transaction(cache, id); if (transaction == NULL) { - kprintf("No transaction with ID %ld found.\n", id); + kprintf("No transaction with ID %" B_PRId32 " found.\n", id); return 0; } } kprintf("TRANSACTION %p\n", transaction); - kprintf(" id: %ld\n", transaction->id); - kprintf(" num block: %ld\n", transaction->num_blocks); - kprintf(" main num block: %ld\n", transaction->main_num_blocks); - kprintf(" sub num block: %ld\n", transaction->sub_num_blocks); + kprintf(" id: %" B_PRId32 "\n", transaction->id); + kprintf(" num block: %" B_PRId32 "\n", transaction->num_blocks); + kprintf(" main num block: %" B_PRId32 "\n", transaction->main_num_blocks); + kprintf(" sub num block: %" B_PRId32 "\n", transaction->sub_num_blocks); kprintf(" has sub: %d\n", transaction->has_sub_transaction); kprintf(" state: %s\n", transaction->open ? "open" : "closed"); - kprintf(" idle: %Ld secs\n", + kprintf(" idle: %" B_PRId64 " secs\n", (system_time() - transaction->last_used) / 1000000); kprintf(" listeners:\n"); @@ -2311,7 +2313,7 @@ dump_transaction(int argc, char** argv) while (iterator.HasNext()) { cache_listener* listener = iterator.Next(); - kprintf(" %p %5lx %p - %p\n", listener, listener->events_pending, + kprintf(" %p %5" B_PRIx32 " %p - %p\n", listener, listener->events_pending, listener->hook, listener->data); } @@ -2445,7 +2447,7 @@ dump_block_data(int argc, char** argv) if (length > 0 && dump[length - 1] == '\n') length--; - kprintf("%5ld. %.*s\n", index, length, dump); + kprintf("%5" B_PRId32 ". %.*s\n", index, length, dump); if (printStackTrace) { out.Clear(); @@ -2718,7 +2720,7 @@ cache_start_transaction(void* _cache) TransactionLocker locker(cache); if (cache->last_transaction && cache->last_transaction->open) { - panic("last transaction (%ld) still open!\n", + panic("last transaction (%" B_PRId32 ") still open!\n", cache->last_transaction->id); } @@ -2729,7 +2731,7 @@ cache_start_transaction(void* _cache) transaction->id = atomic_add(&cache->next_transaction_id, 1); cache->last_transaction = transaction; - TRACE(("cache_start_transaction(): id %ld started\n", transaction->id)); + TRACE(("cache_start_transaction(): id %" B_PRId32 " started\n", transaction->id)); T(Action("start", cache, transaction)); hash_insert_grow(cache->transaction_hash, transaction); @@ -2744,7 +2746,7 @@ cache_sync_transaction(void* _cache, int32 id) block_cache* cache = (block_cache*)_cache; bool hadBusy; - TRACE(("cache_sync_transaction(id %ld)\n", id)); + TRACE(("cache_sync_transaction(id %" B_PRId32 ")\n", id)); do { TransactionLocker locker(cache); @@ -2799,7 +2801,7 @@ cache_end_transaction(void* _cache, int32 id, block_cache* cache = (block_cache*)_cache; TransactionLocker locker(cache); - TRACE(("cache_end_transaction(id = %ld)\n", id)); + TRACE(("cache_end_transaction(id = %" B_PRId32 ")\n", id)); cache_transaction* transaction = lookup_transaction(cache, id); if (transaction == NULL) { @@ -2865,7 +2867,7 @@ cache_abort_transaction(void* _cache, int32 id) block_cache* cache = (block_cache*)_cache; TransactionLocker locker(cache); - TRACE(("cache_abort_transaction(id = %ld)\n", id)); + TRACE(("cache_abort_transaction(id = %" B_PRId32 ")\n", id)); cache_transaction* transaction = lookup_transaction(cache, id); if (transaction == NULL) { @@ -2884,8 +2886,8 @@ cache_abort_transaction(void* _cache, int32 id) next = block->transaction_next; if (block->original_data != NULL) { - TRACE(("cache_abort_transaction(id = %ld): restored contents of " - "block %Ld\n", transaction->id, block->block_number)); + TRACE(("cache_abort_transaction(id = %" B_PRId32 "): restored contents of " + "block %" B_PRIdOFF "\n", transaction->id, block->block_number)); memcpy(block->current_data, block->original_data, cache->block_size); cache->Free(block->original_data); @@ -2918,7 +2920,7 @@ cache_detach_sub_transaction(void* _cache, int32 id, block_cache* cache = (block_cache*)_cache; TransactionLocker locker(cache); - TRACE(("cache_detach_sub_transaction(id = %ld)\n", id)); + TRACE(("cache_detach_sub_transaction(id = %" B_PRId32 ")\n", id)); cache_transaction* transaction = lookup_transaction(cache, id); if (transaction == NULL) { @@ -3021,7 +3023,7 @@ cache_abort_sub_transaction(void* _cache, int32 id) block_cache* cache = (block_cache*)_cache; TransactionLocker locker(cache); - TRACE(("cache_abort_sub_transaction(id = %ld)\n", id)); + TRACE(("cache_abort_sub_transaction(id = %" B_PRId32 ")\n", id)); cache_transaction* transaction = lookup_transaction(cache, id); if (transaction == NULL) { @@ -3077,9 +3079,9 @@ cache_abort_sub_transaction(void* _cache, int32 id) if (block->parent_data != block->current_data) { // The block has been changed and must be restored - the block // is still dirty and part of the transaction - TRACE(("cache_abort_sub_transaction(id = %ld): restored " - "contents of block %Ld\n", transaction->id, - block->block_number)); + TRACE(("cache_abort_sub_transaction(id = %" B_PRId32 "): " + "restored contents of block %" B_PRIdOFF "\n", + transaction->id, block->block_number)); memcpy(block->current_data, block->parent_data, cache->block_size); cache->Free(block->parent_data); @@ -3106,11 +3108,11 @@ cache_start_sub_transaction(void* _cache, int32 id) block_cache* cache = (block_cache*)_cache; TransactionLocker locker(cache); - TRACE(("cache_start_sub_transaction(id = %ld)\n", id)); + TRACE(("cache_start_sub_transaction(id = %" B_PRId32 ")\n", id)); cache_transaction* transaction = lookup_transaction(cache, id); if (transaction == NULL) { - panic("cache_start_sub_transaction(): invalid transaction ID %ld\n", + panic("cache_start_sub_transaction(): invalid transaction ID %" B_PRId32 "\n", id); return B_BAD_VALUE; } @@ -3406,7 +3408,7 @@ block_cache_sync_etc(void* _cache, off_t blockNumber, size_t numBlocks) // transaction or no transaction only if (blockNumber < 0 || blockNumber >= cache->max_blocks) { - panic("block_cache_sync_etc: invalid block number %Ld (max %Ld)", + panic("block_cache_sync_etc: invalid block number %" B_PRIdOFF " (max %" B_PRIdOFF ")", blockNumber, cache->max_blocks - 1); return B_BAD_VALUE; } @@ -3477,7 +3479,7 @@ block_cache_discard(void* _cache, off_t blockNumber, size_t numBlocks) } else { if (block->transaction != NULL && block->parent_data != NULL && block->parent_data != block->current_data) { - panic("Discarded block %Ld has already been changed in this " + panic("Discarded block %" B_PRIdOFF " has already been changed in this " "transaction!", blockNumber); } @@ -3518,7 +3520,7 @@ block_cache_get_writable_etc(void* _cache, off_t blockNumber, off_t base, block_cache* cache = (block_cache*)_cache; MutexLocker locker(&cache->lock); - TRACE(("block_cache_get_writable_etc(block = %Ld, transaction = %ld)\n", + TRACE(("block_cache_get_writable_etc(block = %" B_PRIdOFF ", transaction = %" B_PRId32 ")\n", blockNumber, transaction)); if (cache->read_only) panic("tried to get writable block on a read-only cache!"); @@ -3542,7 +3544,7 @@ block_cache_get_empty(void* _cache, off_t blockNumber, int32 transaction) block_cache* cache = (block_cache*)_cache; MutexLocker locker(&cache->lock); - TRACE(("block_cache_get_empty(block = %Ld, transaction = %ld)\n", + TRACE(("block_cache_get_empty(block = %" B_PRIdOFF ", transaction = %" B_PRId32 ")\n", blockNumber, transaction)); if (cache->read_only) panic("tried to get empty writable block on a read-only cache!"); diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp index 2825ef1a60..01257d792b 100644 --- a/src/system/kernel/cache/file_cache.cpp +++ b/src/system/kernel/cache/file_cache.cpp @@ -555,7 +555,7 @@ write_to_cache(file_cache_ref* ref, void* cookie, off_t offset, generic_addr_t last = vecs[vecCount - 1].base + vecs[vecCount - 1].length - B_PAGE_SIZE; - if (offset + pageOffset + bufferSize == ref->cache->virtual_end) { + if ((off_t)(offset + pageOffset + bufferSize) == ref->cache->virtual_end) { // the space in the page after this write action needs to be cleaned vm_memset_physical(last + lastPageOffset, 0, B_PAGE_SIZE - lastPageOffset); @@ -724,7 +724,7 @@ cache_io(void* _cacheRef, void* cookie, off_t offset, addr_t buffer, size_t size = *_size; offset -= pageOffset; - if (offset + pageOffset + size > fileSize) { + if ((off_t)(offset + pageOffset + size) > fileSize) { // adapt size to be within the file's offsets size = fileSize - pageOffset - offset; *_size = size; @@ -951,7 +951,7 @@ cache_prefetch_vnode(struct vnode* vnode, off_t offset, size_t size) file_cache_ref* ref = ((VMVnodeCache*)cache)->FileCacheRef(); off_t fileSize = cache->virtual_end; - if (offset + size > fileSize) + if ((off_t)(offset + size) > fileSize) size = fileSize - offset; // "offset" and "size" are always aligned to B_PAGE_SIZE, @@ -1088,7 +1088,7 @@ file_cache_init_post_boot_device(void) if (get_module("file_cache/launch_speedup/v1", (module_info**)&sCacheModule) == B_OK) { - dprintf("** opened launch speedup: %Ld\n", system_time()); + dprintf("** opened launch speedup: %" B_PRId64 "\n", system_time()); } return B_OK; } diff --git a/src/system/kernel/cache/file_map.cpp b/src/system/kernel/cache/file_map.cpp index a80f51a921..0e79bb5670 100644 --- a/src/system/kernel/cache/file_map.cpp +++ b/src/system/kernel/cache/file_map.cpp @@ -419,10 +419,10 @@ FileMap::Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count, *_count = 0; return B_OK; } - if (offset + size > fSize) { + if ((off_t)(offset + size) > fSize) { if (align > 1) { off_t alignedSize = (fSize + align - 1) & ~(off_t)(align - 1); - if (offset + size >= alignedSize) + if ((off_t)(offset + size) >= alignedSize) padLastVec = alignedSize - fSize; } size = fSize - offset; @@ -448,7 +448,7 @@ FileMap::Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count, vecs[0].offset = -1; vecs[0].length = fileExtent->disk.length - offset; - if (vecs[0].length >= size) { + if (vecs[0].length >= (off_t)size) { vecs[0].length = size + padLastVec; *_count = 1; return B_OK; @@ -464,7 +464,7 @@ FileMap::Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count, vecs[vecIndex++] = fileExtent->disk; - if (size <= fileExtent->disk.length) { + if ((off_t)size <= fileExtent->disk.length) { vecs[vecIndex - 1].length = size + padLastVec; break; } @@ -506,7 +506,7 @@ dump_file_map(int argc, char** argv) } kprintf("FileMap %p\n", map); - kprintf(" size %Ld\n", map->Size()); + kprintf(" size %" B_PRIdOFF "\n", map->Size()); kprintf(" count %lu\n", map->Count()); if (!printExtents) @@ -515,8 +515,9 @@ dump_file_map(int argc, char** argv) for (uint32 i = 0; i < map->Count(); i++) { file_extent* extent = map->ExtentAt(i); - kprintf(" [%lu] offset %Ld, disk offset %Ld, length %Ld\n", - i, extent->offset, extent->disk.offset, extent->disk.length); + kprintf(" [%" B_PRIu32 "] offset %" B_PRIdOFF ", disk offset %" + B_PRIdOFF ", length %" B_PRIdOFF "\n", i, extent->offset, + extent->disk.offset, extent->disk.length); } return 0; @@ -562,9 +563,10 @@ dump_file_map_stats(int argc, char** argv) count++; } - kprintf("%ld file maps (%ld empty), %Ld file bytes in total, %Ld bytes " - "cached, %lu extents\n", count, emptyCount, size, mapSize, extents); - kprintf("average %lu extents per map for %Ld bytes.\n", + kprintf("%" B_PRId32 " file maps (%" B_PRIu32 " empty), %" B_PRIdOFF " file" + " bytes in total, %" B_PRIdOFF " bytes cached, %" B_PRIu32 " extents\n", + count, emptyCount, size, mapSize, extents); + kprintf("average %" B_PRIu32 " extents per map for %" B_PRIdOFF " bytes.\n", extents / (count - emptyCount), mapSize / (count - emptyCount)); return 0; diff --git a/src/system/kernel/commpage.cpp b/src/system/kernel/commpage.cpp index aab641905a..4419bfd6cf 100644 --- a/src/system/kernel/commpage.cpp +++ b/src/system/kernel/commpage.cpp @@ -32,7 +32,8 @@ allocate_commpage_entry(int entry, size_t size) sFreeCommPageSpace = ALIGN_ENTRY((addr_t)sFreeCommPageSpace + size); sCommPageAddress[entry] = (addr_t)sUserCommPageAddress + ((addr_t)space - (addr_t)sCommPageAddress); -dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size, (void*)sCommPageAddress[entry]); + dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size, + (void*)sCommPageAddress[entry]); return space; } diff --git a/src/system/kernel/condition_variable.cpp b/src/system/kernel/condition_variable.cpp index ef0dcd28d0..47215606b1 100644 --- a/src/system/kernel/condition_variable.cpp +++ b/src/system/kernel/condition_variable.cpp @@ -315,7 +315,7 @@ ConditionVariable::Dump() const for (EntryList::ConstIterator it = fEntries.GetIterator(); ConditionVariableEntry* entry = it.Next();) { - kprintf(" %ld", entry->fThread->id); + kprintf(" %" B_PRId32, entry->fThread->id); } kprintf("\n"); } @@ -330,7 +330,7 @@ ConditionVariable::_Notify(bool all, bool schedulerLocked, status_t result) if (!fEntries.IsEmpty()) { if (result > B_OK) { - panic("tried to notify with invalid result %ld\n", result); + panic("tried to notify with invalid result %" B_PRId32 "\n", result); result = B_ERROR; } diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index 89e0b3b584..df7e2efa74 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -264,7 +264,7 @@ insert_chars_into_line(char* buffer, int32& position, int32& length, // reposition cursor, if necessary if (position < length) - kprintf("\x1b[%ldD", length - position); + kprintf("\x1b[%" B_PRId32 "D", length - position); } @@ -296,7 +296,7 @@ remove_char_from_line(char* buffer, int32& position, int32& length) kputchar(' '); // reposition the cursor - kprintf("\x1b[%ldD", length - position + 1); + kprintf("\x1b[%" B_PRId32 "D", length - position + 1); } @@ -439,7 +439,7 @@ public: if (reprintLine) { kprintf("%s%.*s", kKDLPrompt, (int)length, buffer); if (position < length) - kprintf("\x1b[%ldD", length - position); + kprintf("\x1b[%" B_PRId32 "D", length - position); } } }; @@ -488,7 +488,7 @@ read_line(char* buffer, int32 maxLength, kputchar(' '); // reposition cursor - kprintf("\x1b[%ldD", length - position); + kprintf("\x1b[%" B_PRId32 "D", length - position); length = position; } @@ -566,7 +566,7 @@ read_line(char* buffer, int32 maxLength, // swap the current line with something from the history if (position > 0) - kprintf("\x1b[%ldD", position); // move to beginning of line + kprintf("\x1b[%" B_PRId32 "D", position); // move to beginning of line strcpy(buffer, sLineBuffer[historyLine]); length = position = strlen(buffer); @@ -608,7 +608,7 @@ read_line(char* buffer, int32 maxLength, length = strlen(buffer); kprintf("%s\x1b[K", buffer + position); // print the line and clear the rest - kprintf("\x1b[%ldD", length - position); + kprintf("\x1b[%" B_PRId32 "D", length - position); // reposition cursor currentHistoryLine = historyLine; @@ -617,7 +617,7 @@ read_line(char* buffer, int32 maxLength, case 'H': // home { if (position > 0) { - kprintf("\x1b[%ldD", position); + kprintf("\x1b[%" B_PRId32 "D", position); position = 0; } break; @@ -625,7 +625,7 @@ read_line(char* buffer, int32 maxLength, case 'F': // end { if (position < length) { - kprintf("\x1b[%ldC", length - position); + kprintf("\x1b[%" B_PRId32 "C", length - position); position = length; } break; @@ -825,10 +825,10 @@ kernel_debugger_loop(const char* messagePrefix, const char* message, Thread* thread = thread_get_current_thread(); if (thread == NULL) { - kprintf("Running on CPU %ld\n", sDebuggerOnCPU); + kprintf("Running on CPU %" B_PRId32 "\n", sDebuggerOnCPU); } else if (!debug_is_kernel_memory_accessible((addr_t)thread, sizeof(Thread), B_KERNEL_READ_AREA)) { - kprintf("Running on CPU %ld\n", sDebuggerOnCPU); + kprintf("Running on CPU %" B_PRId32 "\n", sDebuggerOnCPU); kprintf("Current thread pointer is %p, which is an address we " "can't read from.\n", thread); arch_debug_unset_current_thread(); @@ -836,8 +836,8 @@ kernel_debugger_loop(const char* messagePrefix, const char* message, set_debug_variable("_thread", (uint64)(addr_t)thread); set_debug_variable("_threadID", thread->id); - kprintf("Thread %ld \"%.64s\" running on CPU %ld\n", thread->id, - thread->name, sDebuggerOnCPU); + kprintf("Thread %" B_PRId32 " \"%.64s\" running on CPU %" B_PRId32 "\n", + thread->id, thread->name, sDebuggerOnCPU); if (thread->cpu != gCPU + cpu) { kprintf("The thread's CPU pointer is %p, but should be %p.\n", @@ -1159,7 +1159,7 @@ cmd_switch_cpu(int argc, char** argv) } if (argc == 1) { - kprintf("running on CPU %ld\n", smp_get_current_cpu()); + kprintf("running on CPU %" B_PRId32 "\n", smp_get_current_cpu()); return 0; } @@ -1170,7 +1170,7 @@ cmd_switch_cpu(int argc, char** argv) } if (newCPU == smp_get_current_cpu()) { - kprintf("already running on CPU %ld\n", newCPU); + kprintf("already running on CPU %" B_PRId32 "\n", newCPU); return 0; } @@ -1384,7 +1384,7 @@ syslog_init_post_vm(struct kernel_args* args) } } else { // create an area for the debug syslog buffer - void* base = (void*)ROUNDDOWN((addr_t)args->debug_output, B_PAGE_SIZE); + void* base = (void*)ROUNDDOWN((addr_t)(void *)args->debug_output, B_PAGE_SIZE); size_t size = ROUNDUP(args->debug_size, B_PAGE_SIZE); area_id area = create_area("syslog debug", &base, B_EXACT_ADDRESS, size, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); @@ -1401,15 +1401,17 @@ syslog_init_post_vm(struct kernel_args* args) sSyslogMessage->ident[0] = '\0'; //strcpy(sSyslogMessage->ident, "KERNEL"); - if (args->debug_output != NULL) - syslog_write((const char*)args->debug_output, args->debug_size, false); + if (args->debug_output != NULL) { + syslog_write((const char*)args->debug_output.Pointer(), + args->debug_size, false); + } char revisionBuffer[64]; length = snprintf(revisionBuffer, sizeof(revisionBuffer), "Welcome to syslog debug output!\nHaiku revision: %s\n", get_haiku_revision()); syslog_write(revisionBuffer, - std::min(length, (ssize_t)sizeof(revisionBuffer) - 1), false); + std::min(length, (int32)sizeof(revisionBuffer) - 1), false); add_debugger_command_etc("syslog", &cmd_dump_syslog, "Dumps the syslog buffer.", @@ -1522,7 +1524,7 @@ flush_pending_repeats(bool notifySyslog) if (sMessageRepeatCount > 1) { static char temp[40]; size_t length = snprintf(temp, sizeof(temp), - "Last message repeated %ld times.\n", sMessageRepeatCount); + "Last message repeated %" B_PRId32 " times.\n", sMessageRepeatCount); length = std::min(length, sizeof(temp) - 1); if (sSerialDebugEnabled) @@ -2064,7 +2066,8 @@ panic(const char* format, ...) cpu_status state = disable_interrupts(); - kernel_debugger_internal("PANIC: ", format, args, smp_get_current_cpu()); + kernel_debugger_internal("PANIC: ", format, args, + thread_get_current_thread() ? smp_get_current_cpu() : 0); restore_interrupts(state); diff --git a/src/system/kernel/debug/debug_builtin_commands.cpp b/src/system/kernel/debug/debug_builtin_commands.cpp index bb0fe2857a..3648e9794f 100644 --- a/src/system/kernel/debug/debug_builtin_commands.cpp +++ b/src/system/kernel/debug/debug_builtin_commands.cpp @@ -91,7 +91,7 @@ cmd_expr(int argc, char **argv) uint64 result; if (evaluate_debug_expression(argv[1], &result, false)) { - kprintf("%llu (0x%llx)\n", result, result); + kprintf("%" B_PRIu64 " (0x%" B_PRIx64 ")\n", result, result); set_debug_variable("_", result); } @@ -108,7 +108,7 @@ cmd_error(int argc, char **argv) } int32 error = parse_expression(argv[1]); - kprintf("error 0x%lx: %s\n", error, strerror(error)); + kprintf("error 0x%" B_PRIx32 ": %s\n", error, strerror(error)); return 0; } @@ -291,8 +291,8 @@ cmd_wc(int argc, char** argv) const char* line = argv[1]; if (line == NULL) { // last run -- print results - kprintf("%10lld %10lld %10lld\n", userData->lines, userData->words, - userData->chars); + kprintf("%10" B_PRIu64 " %10" B_PRIu64 " %10" B_PRIu64 "\n", + userData->lines, userData->words, userData->chars); return 0; } diff --git a/src/system/kernel/debug/debug_parser.cpp b/src/system/kernel/debug/debug_parser.cpp index 08cdee8d45..2a0398ce57 100644 --- a/src/system/kernel/debug/debug_parser.cpp +++ b/src/system/kernel/debug/debug_parser.cpp @@ -130,8 +130,8 @@ parse_exception(const char* message, int32 position) { if (sNextJumpBufferIndex == 0) { kprintf_unfiltered("parse_exception(): No jump buffer!\n"); - kprintf_unfiltered("exception: \"%s\", position: %lu\n", message, - position); + kprintf_unfiltered("exception: \"%s\", position: %" B_PRId32 "\n", + message, position); return; } @@ -845,7 +845,7 @@ ExpressionParser::_ParseArgument(int& argc, char** argv) fTokenizer.SetCommandMode(true); _EatToken(TOKEN_CLOSING_PARENTHESIS); - snprintf(sTempBuffer, sizeof(sTempBuffer), "%llu", value); + snprintf(sTempBuffer, sizeof(sTempBuffer), "%" B_PRIu64, value); _AddArgument(argc, argv, sTempBuffer); return true; } @@ -857,7 +857,7 @@ ExpressionParser::_ParseArgument(int& argc, char** argv) uint64 value = _ParseCommandPipe(returnValue); _EatToken(TOKEN_CLOSING_BRACKET); - snprintf(sTempBuffer, sizeof(sTempBuffer), "%llu", value); + snprintf(sTempBuffer, sizeof(sTempBuffer), "%" B_PRIu64, value); _AddArgument(argc, argv, sTempBuffer); return true; } @@ -1050,7 +1050,7 @@ ExpressionParser::_ParseDereference(void** _address, uint32* _size) if (size != 1 && size != 2 && size != 4 && size != 8) { snprintf(sTempBuffer, sizeof(sTempBuffer), - "invalid size (%llu) for unary * operator", size); + "invalid size (%" B_PRIu64 ") for unary * operator", size); parse_exception(sTempBuffer, position); } diff --git a/src/system/kernel/debug/debug_variables.cpp b/src/system/kernel/debug/debug_variables.cpp index fe8c0dbc84..92ae27c820 100644 --- a/src/system/kernel/debug/debug_variables.cpp +++ b/src/system/kernel/debug/debug_variables.cpp @@ -226,8 +226,8 @@ cmd_variables(int argc, char **argv) for (int i = 0; i < kVariableCount; i++) { Variable& variable = sVariables[i]; if (variable.IsUsed()) { - kprintf("%16s: %llu (0x%llx)\n", variable.name, variable.value, - variable.value); + kprintf("%16s: %" B_PRIu64 " (0x%" B_PRIx64 ")\n", variable.name, + variable.value, variable.value); } } @@ -235,8 +235,8 @@ cmd_variables(int argc, char **argv) for (int i = 0; i < kTemporaryVariableCount; i++) { Variable& variable = sTemporaryVariables[i]; if (variable.IsUsed()) { - kprintf("%16s: %llu (0x%llx)\n", variable.name, variable.value, - variable.value); + kprintf("%16s: %" B_PRIu64 " (0x%" B_PRIx64 ")\n", variable.name, + variable.value, variable.value); } } diff --git a/src/system/kernel/debug/gdb.cpp b/src/system/kernel/debug/gdb.cpp index 81ba8a0be5..3711683027 100644 --- a/src/system/kernel/debug/gdb.cpp +++ b/src/system/kernel/debug/gdb.cpp @@ -252,8 +252,8 @@ gdb_parse_command(void) case 'm': { char* ptr; - unsigned address; - unsigned len; + addr_t address; + size_t len; // The 'm' command has the form mAAA,LLL // where AAA is the address and LLL is the diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp index b9ecd1618c..02b55c7ef3 100644 --- a/src/system/kernel/debug/tracing.cpp +++ b/src/system/kernel/debug/tracing.cpp @@ -822,10 +822,11 @@ AbstractTraceEntry::Dump(TraceOutput& out) ? fTime - out.LastEntryTime() : fTime; - if (out.Flags() & TRACE_OUTPUT_TEAM_ID) - out.Print("[%6ld:%6ld] %10Ld: ", fThread, fTeam, time); - else - out.Print("[%6ld] %10Ld: ", fThread, time); + if (out.Flags() & TRACE_OUTPUT_TEAM_ID) { + out.Print("[%6" B_PRId32 ":%6" B_PRId32 "] %10" B_PRId64 ": ", fThread, + fTeam, time); + } else + out.Print("[%6" B_PRId32 "] %10" B_PRId64 ": ", fThread, time); AddDump(out); @@ -1011,7 +1012,7 @@ public: { // TODO: this is *very* slow char buffer[64]; - snprintf(buffer, sizeof(buffer), "%Ld", fValue); + snprintf(buffer, sizeof(buffer), "%" B_PRId64, fValue); return strstr(out.DumpEntry(entry), buffer) != NULL; } }; @@ -1022,7 +1023,7 @@ public: { // TODO: this is *very* slow char buffer[64]; - snprintf(buffer, sizeof(buffer), "%Lx", fValue); + snprintf(buffer, sizeof(buffer), "%" B_PRIx64, fValue); return strstr(out.DumpEntry(entry), buffer) != NULL; } }; diff --git a/src/system/kernel/debug/user_debugger.cpp b/src/system/kernel/debug/user_debugger.cpp index 1f0e1ce26c..a3f1915878 100644 --- a/src/system/kernel/debug/user_debugger.cpp +++ b/src/system/kernel/debug/user_debugger.cpp @@ -77,8 +77,9 @@ static status_t debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize, bool dontWait) { - TRACE(("debugger_write(): thread: %ld, team %ld, port: %ld, code: %lx, message: %p, " - "size: %lu, dontWait: %d\n", thread_get_current_thread()->id, + TRACE(("debugger_write(): thread: %" B_PRId32 ", team %" B_PRId32 ", " + "port: %" B_PRId32 ", code: %" B_PRIx32 ", message: %p, size: %lu, " + "dontWait: %d\n", thread_get_current_thread()->id, thread_get_current_thread()->team->id, port, code, buffer, bufferSize, dontWait)); @@ -94,7 +95,7 @@ debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize, error = acquire_sem_etc(writeLock, 1, dontWait ? (uint32)B_RELATIVE_TIMEOUT : (uint32)B_KILL_CAN_INTERRUPT, 0); if (error != B_OK) { - TRACE(("debugger_write() done1: %lx\n", error)); + TRACE(("debugger_write() done1: %" B_PRIx32 "\n", error)); return error; } @@ -119,7 +120,7 @@ debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize, // release the write lock release_sem(writeLock); - TRACE(("debugger_write() done: %lx\n", error)); + TRACE(("debugger_write() done: %" B_PRIx32 "\n", error)); return error; } @@ -529,8 +530,9 @@ thread_hit_debug_event_internal(debug_debugger_message event, restart = false; Thread *thread = thread_get_current_thread(); - TRACE(("thread_hit_debug_event(): thread: %ld, event: %lu, message: %p, " - "size: %ld\n", thread->id, (uint32)event, message, size)); + TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", event: %" B_PRIu32 + ", message: %p, size: %" B_PRId32 "\n", thread->id, (uint32)event, + message, size)); // check, if there's a debug port already bool setPort = !(atomic_get(&thread->debug_info.flags) @@ -540,7 +542,7 @@ thread_hit_debug_event_internal(debug_debugger_message event, port_id port = -1; if (setPort) { char nameBuffer[128]; - snprintf(nameBuffer, sizeof(nameBuffer), "nub to thread %ld", + snprintf(nameBuffer, sizeof(nameBuffer), "nub to thread %" B_PRId32, thread->id); port = create_port(1, nameBuffer); @@ -567,8 +569,8 @@ thread_hit_debug_event_internal(debug_debugger_message event, = (thread->team->debug_info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED); if (thread->id == thread->team->debug_info.nub_thread) { // Ugh, we're the nub thread. We shouldn't be here. - TRACE(("thread_hit_debug_event(): Misdirected nub thread: %ld\n", - thread->id)); + TRACE(("thread_hit_debug_event(): Misdirected nub thread: %" B_PRId32 + "\n", thread->id)); error = B_ERROR; } else if (debuggerInstalled || !requireDebugger) { @@ -614,8 +616,8 @@ thread_hit_debug_event_internal(debug_debugger_message event, delete_port(deletePort); if (error != B_OK) { - TRACE(("thread_hit_debug_event() error: thread: %ld, error: %lx\n", - thread->id, error)); + TRACE(("thread_hit_debug_event() error: thread: %" B_PRId32 ", error: " + "%" B_PRIx32 "\n", thread->id, error)); return error; } @@ -627,8 +629,9 @@ thread_hit_debug_event_internal(debug_debugger_message event, origin->team = thread->team->id; origin->nub_port = nubPort; - TRACE(("thread_hit_debug_event(): thread: %ld, sending message to " - "debugger port %ld\n", thread->id, debuggerPort)); + TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", sending " + "message to debugger port %" B_PRId32 "\n", thread->id, + debuggerPort)); error = debugger_write(debuggerPort, event, message, size, false); } @@ -648,15 +651,15 @@ thread_hit_debug_event_internal(debug_debugger_message event, if (commandMessageSize < 0) { error = commandMessageSize; - TRACE(("thread_hit_debug_event(): thread: %ld, failed " - "to receive message from port %ld: %lx\n", + TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", failed " + "to receive message from port %" B_PRId32 ": %" B_PRIx32 "\n", thread->id, port, error)); break; } switch (command) { case B_DEBUGGED_THREAD_MESSAGE_CONTINUE: - TRACE(("thread_hit_debug_event(): thread: %ld: " + TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ": " "B_DEBUGGED_THREAD_MESSAGE_CONTINUE\n", thread->id)); result = commandMessage.continue_thread.handle_event; @@ -667,7 +670,7 @@ thread_hit_debug_event_internal(debug_debugger_message event, case B_DEBUGGED_THREAD_SET_CPU_STATE: { - TRACE(("thread_hit_debug_event(): thread: %ld: " + TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ": " "B_DEBUGGED_THREAD_SET_CPU_STATE\n", thread->id)); arch_set_debug_cpu_state( @@ -720,9 +723,9 @@ thread_hit_debug_event_internal(debug_debugger_message event, } } } else { - TRACE(("thread_hit_debug_event(): thread: %ld, failed to send " - "message to debugger port %ld: %lx\n", thread->id, - debuggerPort, error)); + TRACE(("thread_hit_debug_event(): thread: %" B_PRId32 ", failed to send " + "message to debugger port %" B_PRId32 ": %" B_PRIx32 "\n", + thread->id, debuggerPort, error)); } // update the thread debug info @@ -811,7 +814,7 @@ thread_hit_serious_debug_event(debug_debugger_message event, if (error != B_OK) { Thread *thread = thread_get_current_thread(); dprintf("thread_hit_serious_debug_event(): Failed to install debugger: " - "thread: %ld: %s\n", thread->id, strerror(error)); + "thread: %" B_PRId32 ": %s\n", thread->id, strerror(error)); return error; } @@ -993,8 +996,8 @@ void user_debug_team_deleted(team_id teamID, port_id debuggerPort) { if (debuggerPort >= 0) { - TRACE(("user_debug_team_deleted(team: %ld, debugger port: %ld)\n", - teamID, debuggerPort)); + TRACE(("user_debug_team_deleted(team: %" B_PRId32 ", debugger port: " + "%" B_PRId32 ")\n", teamID, debuggerPort)); debug_team_deleted message; message.origin.thread = -1; @@ -1541,7 +1544,8 @@ broadcast_debugged_thread_message(Thread *nubThread, int32 code, code, message, size); if (error != B_OK) { TRACE(("broadcast_debugged_thread_message(): Failed to send " - "message to thread %ld: %lx\n", thread->id, error)); + "message to thread %" B_PRId32 ": %" B_PRIx32 "\n", + thread->id, error)); } } } @@ -1551,8 +1555,8 @@ broadcast_debugged_thread_message(Thread *nubThread, int32 code, static void nub_thread_cleanup(Thread *nubThread) { - TRACE(("nub_thread_cleanup(%ld): debugger port: %ld\n", nubThread->id, - nubThread->team->debug_info.debugger_port)); + TRACE(("nub_thread_cleanup(%" B_PRId32 "): debugger port: %" B_PRId32 "\n", + nubThread->id, nubThread->team->debug_info.debugger_port)); ConditionVariable debugChangeCondition; prepare_debugger_change(nubThread->team, debugChangeCondition); @@ -1654,8 +1658,8 @@ debug_nub_thread(void *) RELEASE_TEAM_DEBUG_INFO_LOCK(nubThread->team->debug_info); restore_interrupts(state); - TRACE(("debug_nub_thread() thread: %ld, team %ld, nub port: %ld\n", - nubThread->id, nubThread->team->id, port)); + TRACE(("debug_nub_thread() thread: %" B_PRId32 ", team %" B_PRId32 ", nub " + "port: %" B_PRId32 "\n", nubThread->id, nubThread->team->id, port)); // notify all threads that a debugger has been installed broadcast_debugged_thread_message(nubThread, @@ -1674,8 +1678,8 @@ debug_nub_thread(void *) // thread, we need to update that. nub_thread_cleanup(nubThread); - TRACE(("nub thread %ld: terminating: %lx\n", nubThread->id, - messageSize)); + TRACE(("nub thread %" B_PRId32 ": terminating: %lx\n", + nubThread->id, messageSize)); return messageSize; } @@ -1719,10 +1723,10 @@ debug_nub_thread(void *) } reply.read_memory.error = result; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_READ_MEMORY: " - "reply port: %ld, address: %p, size: %ld, result: %lx, " - "read: %ld\n", nubThread->id, replyPort, address, size, - result, bytesRead)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_READ_MEMORY: " + "reply port: %" B_PRId32 ", address: %p, size: %" B_PRId32 + ", result: %" B_PRIx32 ", read: %ld\n", nubThread->id, + replyPort, address, size, result, bytesRead)); // send only as much data as necessary reply.read_memory.size = bytesRead; @@ -1755,10 +1759,10 @@ debug_nub_thread(void *) } reply.write_memory.error = result; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_WRITE_MEMORY: " - "reply port: %ld, address: %p, size: %ld, result: %lx, " - "written: %ld\n", nubThread->id, replyPort, address, size, - result, bytesWritten)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_WRITE_MEMORY: " + "reply port: %" B_PRId32 ", address: %p, size: %" B_PRId32 + ", result: %" B_PRIx32 ", written: %ld\n", nubThread->id, + replyPort, address, size, result, bytesWritten)); reply.write_memory.size = bytesWritten; sendReply = true; @@ -1772,8 +1776,8 @@ debug_nub_thread(void *) int32 flags = message.set_team_flags.flags & B_TEAM_DEBUG_USER_FLAG_MASK; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_TEAM_FLAGS: " - "flags: %lx\n", nubThread->id, flags)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_TEAM_FLAGS" + ": flags: %" B_PRIx32 "\n", nubThread->id, flags)); Team *team = thread_get_current_thread()->team; @@ -1797,9 +1801,9 @@ debug_nub_thread(void *) int32 flags = message.set_thread_flags.flags & B_THREAD_DEBUG_USER_FLAG_MASK; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_THREAD_FLAGS: " - "thread: %ld, flags: %lx\n", nubThread->id, threadID, - flags)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_THREAD_FLAGS" + ": thread: %" B_PRId32 ", flags: %" B_PRIx32 "\n", + nubThread->id, threadID, flags)); // set the flags Thread* thread = Thread::GetAndLock(threadID); @@ -1831,9 +1835,10 @@ debug_nub_thread(void *) handleEvent = message.continue_thread.handle_event; singleStep = message.continue_thread.single_step; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CONTINUE_THREAD: " - "thread: %ld, handle event: %lu, single step: %d\n", - nubThread->id, threadID, handleEvent, singleStep)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CONTINUE_THREAD" + ": thread: %" B_PRId32 ", handle event: %" B_PRIu32 ", " + "single step: %d\n", nubThread->id, threadID, handleEvent, + singleStep)); // find the thread and get its debug port port_id threadDebugPort = -1; @@ -1861,8 +1866,8 @@ debug_nub_thread(void *) const debug_cpu_state &cpuState = message.set_cpu_state.cpu_state; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_CPU_STATE: " - "thread: %ld\n", nubThread->id, threadID)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_CPU_STATE" + ": thread: %" B_PRId32 "\n", nubThread->id, threadID)); // find the thread and get its debug port port_id threadDebugPort = -1; @@ -1888,8 +1893,8 @@ debug_nub_thread(void *) thread_id threadID = message.get_cpu_state.thread; replyPort = message.get_cpu_state.reply_port; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_CPU_STATE: " - "thread: %ld\n", nubThread->id, threadID)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_CPU_STATE" + ": thread: %" B_PRId32 "\n", nubThread->id, threadID)); // find the thread and get its debug port port_id threadDebugPort = -1; @@ -1921,8 +1926,8 @@ debug_nub_thread(void *) replyPort = message.set_breakpoint.reply_port; void *address = message.set_breakpoint.address; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_BREAKPOINT: " - "address: %p\n", nubThread->id, address)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_BREAKPOINT" + ": address: %p\n", nubThread->id, address)); // check the address status_t result = B_OK; @@ -1951,8 +1956,8 @@ debug_nub_thread(void *) // get the parameters void *address = message.clear_breakpoint.address; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CLEAR_BREAKPOINT: " - "address: %p\n", nubThread->id, address)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CLEAR_BREAKPOINT" + ": address: %p\n", nubThread->id, address)); // check the address status_t result = B_OK; @@ -1979,9 +1984,9 @@ debug_nub_thread(void *) uint32 type = message.set_watchpoint.type; int32 length = message.set_watchpoint.length; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_WATCHPOINT: " - "address: %p, type: %lu, length: %ld\n", nubThread->id, - address, type, length)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_WATCHPOINT" + ": address: %p, type: %" B_PRIu32 ", length: %" B_PRId32 "\n", + nubThread->id, address, type, length)); // check the address and size status_t result = B_OK; @@ -2014,8 +2019,8 @@ debug_nub_thread(void *) // get the parameters void *address = message.clear_watchpoint.address; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CLEAR_WATCHPOINT: " - "address: %p\n", nubThread->id, address)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_CLEAR_WATCHPOINT" + ": address: %p\n", nubThread->id, address)); // check the address status_t result = B_OK; @@ -2043,10 +2048,11 @@ debug_nub_thread(void *) uint32 ignoreOp = message.set_signal_masks.ignore_op; uint32 ignoreOnceOp = message.set_signal_masks.ignore_once_op; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_SIGNAL_MASKS: " - "thread: %ld, ignore: %llx (op: %lu), ignore once: %llx " - "(op: %lu)\n", nubThread->id, threadID, ignore, - ignoreOp, ignoreOnce, ignoreOnceOp)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_SIGNAL_MASKS" + ": thread: %" B_PRId32 ", ignore: %" B_PRIx64 " (op: %" + B_PRIu32 "), ignore once: %" B_PRIx64 " (op: %" B_PRIu32 + ")\n", nubThread->id, threadID, ignore, ignoreOp, + ignoreOnce, ignoreOnceOp)); // set the masks Thread* thread = Thread::GetAndLock(threadID); @@ -2114,10 +2120,11 @@ debug_nub_thread(void *) } else result = B_BAD_THREAD_ID; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_SIGNAL_MASKS: " - "reply port: %ld, thread: %ld, ignore: %llx, " - "ignore once: %llx, result: %lx\n", nubThread->id, - replyPort, threadID, ignore, ignoreOnce, result)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_SIGNAL_MASKS" + ": reply port: %" B_PRId32 ", thread: %" B_PRId32 ", " + "ignore: %" B_PRIx64 ", ignore once: %" B_PRIx64 ", result: " + "%" B_PRIx32 "\n", nubThread->id, replyPort, threadID, + ignore, ignoreOnce, result)); // prepare the message reply.get_signal_masks.error = result; @@ -2134,9 +2141,9 @@ debug_nub_thread(void *) int signal = message.set_signal_handler.signal; struct sigaction &handler = message.set_signal_handler.handler; - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER: " - "signal: %d, handler: %p\n", nubThread->id, - signal, handler.sa_handler)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER" + ": signal: %d, handler: %p\n", nubThread->id, signal, + handler.sa_handler)); // set the handler sigaction(signal, &handler, NULL); @@ -2157,9 +2164,9 @@ debug_nub_thread(void *) result = errno; } - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER: " - "reply port: %ld, signal: %d, handler: %p\n", nubThread->id, - replyPort, signal, + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER" + ": reply port: %" B_PRId32 ", signal: %d, handler: %p\n", + nubThread->id, replyPort, signal, reply.get_signal_handler.handler.sa_handler)); // prepare the message @@ -2171,8 +2178,8 @@ debug_nub_thread(void *) case B_DEBUG_MESSAGE_PREPARE_HANDOVER: { - TRACE(("nub thread %ld: B_DEBUG_MESSAGE_PREPARE_HANDOVER\n", - nubThread->id)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_MESSAGE_PREPARE_HANDOVER" + "\n", nubThread->id)); Team *team = nubThread->team; @@ -2228,9 +2235,9 @@ debug_nub_thread(void *) B_DEBUG_MIN_PROFILE_INTERVAL); status_t result = B_OK; - TRACE(("nub thread %ld: B_DEBUG_START_PROFILER: " - "thread: %ld, sample area: %ld\n", nubThread->id, threadID, - sampleArea)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_START_PROFILER: " + "thread: %" B_PRId32 ", sample area: %" B_PRId32 "\n", + nubThread->id, threadID, sampleArea)); if (stackDepth < 1) stackDepth = 1; @@ -2331,8 +2338,8 @@ debug_nub_thread(void *) replyPort = message.stop_profiler.reply_port; status_t result = B_OK; - TRACE(("nub thread %ld: B_DEBUG_STOP_PROFILER: " - "thread: %ld\n", nubThread->id, threadID)); + TRACE(("nub thread %" B_PRId32 ": B_DEBUG_STOP_PROFILER: " + "thread: %" B_PRId32 "\n", nubThread->id, threadID)); area_id sampleArea = -1; addr_t* samples = NULL; @@ -2407,8 +2414,9 @@ debug_nub_thread(void *) if (error != B_OK) { // The debugger port is either not longer existing or we got // interrupted by a kill signal. In either case we terminate. - TRACE(("nub thread %ld: failed to send reply to port %ld: %s\n", - nubThread->id, replyPort, strerror(error))); + TRACE(("nub thread %" B_PRId32 ": failed to send reply to port " + "%" B_PRId32 ": %s\n", nubThread->id, replyPort, + strerror(error))); nub_thread_cleanup(nubThread); return error; @@ -2470,8 +2478,9 @@ static port_id install_team_debugger(team_id teamID, port_id debuggerPort, thread_id causingThread, bool useDefault, bool dontReplace) { - TRACE(("install_team_debugger(team: %ld, port: %ld, default: %d, " - "dontReplace: %d)\n", teamID, debuggerPort, useDefault, dontReplace)); + TRACE(("install_team_debugger(team: %" B_PRId32 ", port: %" B_PRId32 ", " + "default: %d, dontReplace: %d)\n", teamID, debuggerPort, useDefault, + dontReplace)); if (useDefault) debuggerPort = atomic_get(&sDefaultDebuggerPort); @@ -2481,7 +2490,7 @@ install_team_debugger(team_id teamID, port_id debuggerPort, status_t error = get_port_info(debuggerPort, &debuggerPortInfo); if (error != B_OK) { TRACE(("install_team_debugger(): Failed to get debugger port info: " - "%lx\n", error)); + "%" B_PRIx32 "\n", error)); return error; } team_id debuggerTeam = debuggerPortInfo.team; @@ -2490,7 +2499,8 @@ install_team_debugger(team_id teamID, port_id debuggerPort, // debugged team. if (debuggerTeam == team_get_kernel_team_id() || debuggerTeam == teamID) { TRACE(("install_team_debugger(): Can't debug kernel or debugger team. " - "debugger: %ld, debugged: %ld\n", debuggerTeam, teamID)); + "debugger: %" B_PRId32 ", debugged: %" B_PRId32 "\n", debuggerTeam, + teamID)); return B_NOT_ALLOWED; } @@ -2618,13 +2628,14 @@ install_team_debugger(team_id teamID, port_id debuggerPort, } TRACE(("install_team_debugger() done: handed over to debugger: team: " - "%ld, port: %ld\n", debuggerTeam, debuggerPort)); + "%" B_PRId32 ", port: %" B_PRId32 "\n", debuggerTeam, + debuggerPort)); return result; } if (done || error != B_OK) { - TRACE(("install_team_debugger() done1: %ld\n", + TRACE(("install_team_debugger() done1: %" B_PRId32 "\n", (error == B_OK ? result : error))); finish_debugger_change(team); return (error == B_OK ? result : error); @@ -2632,14 +2643,14 @@ install_team_debugger(team_id teamID, port_id debuggerPort, // create the debugger write lock semaphore char nameBuffer[B_OS_NAME_LENGTH]; - snprintf(nameBuffer, sizeof(nameBuffer), "team %ld debugger port write", - teamID); + snprintf(nameBuffer, sizeof(nameBuffer), "team %" B_PRId32 " debugger port " + "write", teamID); sem_id debuggerWriteLock = create_sem(1, nameBuffer); if (debuggerWriteLock < 0) error = debuggerWriteLock; // create the nub port - snprintf(nameBuffer, sizeof(nameBuffer), "team %ld debug", teamID); + snprintf(nameBuffer, sizeof(nameBuffer), "team %" B_PRId32 " debug", teamID); if (error == B_OK) { nubPort = create_port(1, nameBuffer); if (nubPort < 0) @@ -2666,7 +2677,8 @@ install_team_debugger(team_id teamID, port_id debuggerPort, // spawn the nub thread thread_id nubThread = -1; if (error == B_OK) { - snprintf(nameBuffer, sizeof(nameBuffer), "team %ld debug task", teamID); + snprintf(nameBuffer, sizeof(nameBuffer), "team %" B_PRId32 " debug task", + teamID); nubThread = spawn_kernel_thread_etc(debug_nub_thread, nameBuffer, B_NORMAL_PRIORITY, NULL, teamID); if (nubThread < 0) @@ -2707,7 +2719,7 @@ install_team_debugger(team_id teamID, port_id debuggerPort, delete breakpointManager; } - TRACE(("install_team_debugger() done2: %ld\n", + TRACE(("install_team_debugger() done2: %" B_PRId32 "\n", (error == B_OK ? result : error))); return (error == B_OK ? result : error); } @@ -2758,7 +2770,8 @@ _user_disable_debugger(int state) { Team *team = thread_get_current_thread()->team; - TRACE(("_user_disable_debugger(%d): team: %ld\n", state, team->id)); + TRACE(("_user_disable_debugger(%d): team: %" B_PRId32 "\n", state, + team->id)); cpu_status cpuState = disable_interrupts(); GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info); @@ -2852,7 +2865,8 @@ _user_remove_team_debugger(team_id teamID) status_t _user_debug_thread(thread_id threadID) { - TRACE(("[%ld] _user_debug_thread(%ld)\n", find_thread(NULL), threadID)); + TRACE(("[%" B_PRId32 "] _user_debug_thread(%" B_PRId32 ")\n", + find_thread(NULL), threadID)); // get the thread Thread* thread = Thread::GetAndLock(threadID); diff --git a/src/system/kernel/device_manager/FileDevice.cpp b/src/system/kernel/device_manager/FileDevice.cpp index 0f76dae5f4..3522db5249 100644 --- a/src/system/kernel/device_manager/FileDevice.cpp +++ b/src/system/kernel/device_manager/FileDevice.cpp @@ -232,7 +232,7 @@ FileDevice::Control(void* _cookie, int32 op, void* buffer, size_t length) switch (op) { case B_GET_DEVICE_SIZE: return set_ioctl_result( - fFileSize > ~(size_t)0 ? ~(size_t)0 : (size_t)fFileSize, + (uint64)fFileSize > (uint64)(~(size_t)0) ? ~(size_t)0 : (size_t)fFileSize, buffer, length); case B_SET_BLOCKING_IO: diff --git a/src/system/kernel/device_manager/IOCache.cpp b/src/system/kernel/device_manager/IOCache.cpp index 2617cf18d4..a65e515d28 100644 --- a/src/system/kernel/device_manager/IOCache.cpp +++ b/src/system/kernel/device_manager/IOCache.cpp @@ -243,7 +243,7 @@ IOCache::_DoRequest(IORequest* request, generic_size_t& _bytesTransferred) off_t lineOffset = (offset >> fLineSizeShift) << fLineSizeShift; // intersection of request and cache line - off_t cacheLineEnd = std::min(lineOffset + fLineSize, fDeviceCapacity); + off_t cacheLineEnd = std::min(lineOffset + (off_t)fLineSize, fDeviceCapacity); size_t requestLineLength = std::min(cacheLineEnd - offset, (off_t)length); diff --git a/src/system/kernel/device_manager/IORequest.cpp b/src/system/kernel/device_manager/IORequest.cpp index e470103346..c573ac1b97 100644 --- a/src/system/kernel/device_manager/IORequest.cpp +++ b/src/system/kernel/device_manager/IORequest.cpp @@ -664,8 +664,8 @@ IOOperation::Dump() const kprintf(" parent: %p\n", fParent); kprintf(" status: %s\n", strerror(fStatus)); kprintf(" dma buffer: %p\n", fDMABuffer); - kprintf(" offset: %-8Ld (original: %Ld)\n", fOffset, - fOriginalOffset); + kprintf(" offset: %-8" B_PRIdOFF " (original: %" B_PRIdOFF ")\n", + fOffset, fOriginalOffset); kprintf(" length: %-8" B_PRIuGENADDR " (original: %" B_PRIuGENADDR ")\n", fLength, fOriginalLength); kprintf(" transferred: %" B_PRIuGENADDR "\n", fTransferredBytes); @@ -1162,8 +1162,8 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn) uint8* buffer = (uint8*)_buffer; if (offset < fOffset || offset + (off_t)size > fOffset + (off_t)fLength) { - panic("IORequest::_CopyData(): invalid range: (%lld, %lu)", offset, - size); + panic("IORequest::_CopyData(): invalid range: (%" B_PRIdOFF ", %lu)", + offset, size); return B_BAD_VALUE; } @@ -1281,19 +1281,19 @@ IORequest::Dump() const kprintf(" status: %s\n", strerror(fStatus)); kprintf(" mutex: %p\n", &fLock); kprintf(" IOBuffer: %p\n", fBuffer); - kprintf(" offset: %Ld\n", fOffset); + kprintf(" offset: %" B_PRIdOFF "\n", fOffset); kprintf(" length: %" B_PRIuGENADDR "\n", fLength); kprintf(" transfer size: %" B_PRIuGENADDR "\n", fTransferSize); kprintf(" relative offset: %" B_PRIuGENADDR "\n", fRelativeParentOffset); - kprintf(" pending children: %ld\n", fPendingChildren); - kprintf(" flags: %#lx\n", fFlags); - kprintf(" team: %ld\n", fTeam); - kprintf(" thread: %ld\n", fThread); + kprintf(" pending children: %" B_PRId32 "\n", fPendingChildren); + kprintf(" flags: %#" B_PRIx32 "\n", fFlags); + kprintf(" team: %" B_PRId32 "\n", fTeam); + kprintf(" thread: %" B_PRId32 "\n", fThread); kprintf(" r/w: %s\n", fIsWrite ? "write" : "read"); kprintf(" partial transfer: %s\n", fPartialTransfer ? "yes" : "no"); kprintf(" finished cvar: %p\n", &fFinishedCondition); kprintf(" iteration:\n"); - kprintf(" vec index: %lu\n", fVecIndex); + kprintf(" vec index: %" B_PRIu32 "\n", fVecIndex); kprintf(" vec offset: %" B_PRIuGENADDR "\n", fVecOffset); kprintf(" remaining bytes: %" B_PRIuGENADDR "\n", fRemainingBytes); kprintf(" callbacks:\n"); diff --git a/src/system/kernel/device_manager/IOSchedulerSimple.cpp b/src/system/kernel/device_manager/IOSchedulerSimple.cpp index 07bd88a06f..34e62ba583 100644 --- a/src/system/kernel/device_manager/IOSchedulerSimple.cpp +++ b/src/system/kernel/device_manager/IOSchedulerSimple.cpp @@ -38,9 +38,9 @@ void IORequestOwner::Dump() const { kprintf("IORequestOwner at %p\n", this); - kprintf(" team: %ld\n", team); - kprintf(" thread: %ld\n", thread); - kprintf(" priority: %ld\n", priority); + kprintf(" team: %" B_PRId32 "\n", team); + kprintf(" thread: %" B_PRId32 "\n", thread); + kprintf(" priority: %" B_PRId32 "\n", priority); kprintf(" requests:"); for (IORequestList::ConstIterator it = requests.GetIterator(); @@ -654,7 +654,7 @@ IOSchedulerSimple::_Scheduler() if (request == NULL) { resourcesAvailable = false; if (operationCount == 0) -panic("no more requests for owner %p (thread %ld)", owner, owner->thread); +panic("no more requests for owner %p (thread %" B_PRId32 ")", owner, owner->thread); break; } diff --git a/src/system/kernel/device_manager/devfs.cpp b/src/system/kernel/device_manager/devfs.cpp index ba3a113a4a..159fe39739 100644 --- a/src/system/kernel/device_manager/devfs.cpp +++ b/src/system/kernel/device_manager/devfs.cpp @@ -803,19 +803,19 @@ dump_node(int argc, char** argv) } kprintf("DEVFS NODE: %p\n", vnode); - kprintf(" id: %Ld\n", vnode->id); + kprintf(" id: %" B_PRIdINO "\n", vnode->id); kprintf(" name: \"%s\"\n", vnode->name); kprintf(" type: %x\n", vnode->stream.type); kprintf(" parent: %p\n", vnode->parent); kprintf(" dir next: %p\n", vnode->dir_next); if (S_ISDIR(vnode->stream.type)) { - kprintf(" dir scanned: %ld\n", vnode->stream.u.dir.scanned); + kprintf(" dir scanned: %" B_PRId32 "\n", vnode->stream.u.dir.scanned); kprintf(" contents:\n"); devfs_vnode* children = vnode->stream.u.dir.dir_head; while (children != NULL) { - kprintf(" %p, id %Ld\n", children, children->id); + kprintf(" %p, id %" B_PRIdINO "\n", children, children->id); children = children->dir_next; } } else if (S_ISLNK(vnode->stream.type)) { @@ -827,11 +827,11 @@ dump_node(int argc, char** argv) partition_info& info = vnode->stream.u.dev.partition->info; kprintf(" raw device node: %p\n", vnode->stream.u.dev.partition->raw_device); - kprintf(" offset: %Ld\n", info.offset); - kprintf(" size: %Ld\n", info.size); - kprintf(" block size: %ld\n", info.logical_block_size); - kprintf(" session: %ld\n", info.session); - kprintf(" partition: %ld\n", info.partition); + kprintf(" offset: %" B_PRIdOFF "\n", info.offset); + kprintf(" size: %" B_PRIdOFF "\n", info.size); + kprintf(" block size: %" B_PRId32 "\n", info.logical_block_size); + kprintf(" session: %" B_PRId32 "\n", info.session); + kprintf(" partition: %" B_PRId32 "\n", info.partition); kprintf(" device: %s\n", info.device); set_debug_variable("_raw", (addr_t)vnode->stream.u.dev.partition->raw_device); diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp index 93f811505c..ec71aa1294 100644 --- a/src/system/kernel/device_manager/device_manager.cpp +++ b/src/system/kernel/device_manager/device_manager.cpp @@ -263,19 +263,23 @@ dump_attribute(device_attr* attr, int32 level) break; case B_INT8_TYPE: case B_UINT8_TYPE: - kprintf("uint8 : %u (%#x)", attr->value.ui8, attr->value.ui8); + kprintf("uint8 : %" B_PRIu8 " (%#" B_PRIx8 ")", attr->value.ui8, + attr->value.ui8); break; case B_INT16_TYPE: case B_UINT16_TYPE: - kprintf("uint16 : %u (%#x)", attr->value.ui16, attr->value.ui16); + kprintf("uint16 : %" B_PRIu16 " (%#" B_PRIx16 ")", attr->value.ui16, + attr->value.ui16); break; case B_INT32_TYPE: case B_UINT32_TYPE: - kprintf("uint32 : %lu (%#lx)", attr->value.ui32, attr->value.ui32); + kprintf("uint32 : %" B_PRIu32 " (%#" B_PRIx32 ")", attr->value.ui32, + attr->value.ui32); break; case B_INT64_TYPE: case B_UINT64_TYPE: - kprintf("uint64 : %Lu (%#Lx)", attr->value.ui64, attr->value.ui64); + kprintf("uint64 : %" B_PRIu64 " (%#" B_PRIx64 ")", attr->value.ui64, + attr->value.ui64); break; default: kprintf("raw data"); @@ -1509,7 +1513,7 @@ device_node::_AddPath(Stack& stack, const char* basePath, if (status == B_OK) status = stack.Push(path); - TRACE((" add path: \"%s\", %ld\n", path->Path(), status)); + TRACE((" add path: \"%s\", %" B_PRId32 "\n", path->Path(), status)); if (status != B_OK) delete path; @@ -2167,9 +2171,9 @@ void device_node::Dump(int32 level) { put_level(level); - kprintf("(%ld) @%p \"%s\" (ref %ld, init %ld, module %p, data %p)\n", level, - this, ModuleName(), fRefCount, fInitialized, DriverModule(), - DriverData()); + kprintf("(%" B_PRId32 ") @%p \"%s\" (ref %" B_PRId32 ", init %" B_PRId32 + ", module %p, data %p)\n", level, this, ModuleName(), fRefCount, + fInitialized, DriverModule(), DriverData()); AttributeList::Iterator attribute = Attributes().GetIterator(); while (attribute.HasNext()) { diff --git a/src/system/kernel/device_manager/dma_resources.cpp b/src/system/kernel/device_manager/dma_resources.cpp index 5c4b3de920..7e334f4e21 100644 --- a/src/system/kernel/device_manager/dma_resources.cpp +++ b/src/system/kernel/device_manager/dma_resources.cpp @@ -79,7 +79,7 @@ DMABuffer::Dump() const kprintf(" bounce buffer: %p (physical %#" B_PRIxPHYSADDR ")\n", fBounceBuffer->address, fBounceBuffer->physical_address); kprintf(" bounce buffer size: %" B_PRIxPHYSADDR "\n", fBounceBuffer->size); - kprintf(" vecs: %lu\n", fVecCount); + kprintf(" vecs: %" B_PRIu32 "\n", fVecCount); for (uint32 i = 0; i < fVecCount; i++) { kprintf(" [%" B_PRIu32 "] %#" B_PRIxGENADDR ", %" B_PRIuGENADDR "\n", diff --git a/src/system/kernel/device_manager/id_generator.cpp b/src/system/kernel/device_manager/id_generator.cpp index 9fadf6e709..29904a7fb7 100644 --- a/src/system/kernel/device_manager/id_generator.cpp +++ b/src/system/kernel/device_manager/id_generator.cpp @@ -225,7 +225,7 @@ dm_free_id(const char* name, uint32 id) // make sure it's really allocated // (very important to keep in sync if ((generator->alloc_map[id / 8] & (1 << (id & 7))) == 0) { - dprintf("id %ld of generator %s wasn't allocated\n", id, + dprintf("id %" B_PRIu32 " of generator %s wasn't allocated\n", id, generator->name); release_generator(generator); diff --git a/src/system/kernel/device_manager/legacy_drivers.cpp b/src/system/kernel/device_manager/legacy_drivers.cpp index 3c8e0cc66a..da7a6a4aa3 100644 --- a/src/system/kernel/device_manager/legacy_drivers.cpp +++ b/src/system/kernel/device_manager/legacy_drivers.cpp @@ -370,8 +370,8 @@ load_driver(legacy_driver *driver) #error Add checks here for new vs old api version! #endif if (*apiVersion > B_CUR_DRIVER_API_VERSION) { - dprintf("devfs: \"%s\" api_version %ld not handled\n", driver->name, - *apiVersion); + dprintf("devfs: \"%s\" api_version %" B_PRId32 " not handled\n", + driver->name, *apiVersion); status = B_BAD_VALUE; goto error1; } @@ -664,8 +664,8 @@ load_driver_symbols(const char *driverName) static status_t reload_driver(legacy_driver *driver) { - dprintf("devfs: reload driver \"%s\" (%ld, %lld)\n", driver->name, - driver->device, driver->node); + dprintf("devfs: reload driver \"%s\" (%" B_PRIdDEV ", %" B_PRIdINO ")\n", + driver->name, driver->device, driver->node); unload_driver(driver); @@ -825,16 +825,16 @@ dump_driver(legacy_driver* driver) kprintf("DEVFS DRIVER: %p\n", driver); kprintf(" name: %s\n", driver->name); kprintf(" path: %s\n", driver->path); - kprintf(" image: %ld\n", driver->image); - kprintf(" device: %ld\n", driver->device); - kprintf(" node: %Ld\n", driver->node); - kprintf(" last modified: %ld.%lu\n", driver->last_modified.tv_sec, + kprintf(" image: %" B_PRId32 "\n", driver->image); + kprintf(" device: %" B_PRIdDEV "\n", driver->device); + kprintf(" node: %" B_PRIdINO "\n", driver->node); + kprintf(" last modified: %" B_PRIdTIME ".%ld\n", driver->last_modified.tv_sec, driver->last_modified.tv_nsec); - kprintf(" devs used: %ld\n", driver->devices_used); - kprintf(" devs published: %ld\n", driver->devices.Count()); + kprintf(" devs used: %" B_PRIu32 "\n", driver->devices_used); + kprintf(" devs published: %" B_PRId32 "\n", driver->devices.Count()); kprintf(" binary updated: %d\n", driver->binary_updated); - kprintf(" priority: %ld\n", driver->priority); - kprintf(" api version: %ld\n", driver->api_version); + kprintf(" priority: %" B_PRId32 "\n", driver->priority); + kprintf(" api version: %" B_PRId32 "\n", driver->api_version); kprintf(" hooks: find_device %p, publish_devices %p\n" " uninit_driver %p, uninit_hardware %p\n", driver->find_device, driver->publish_devices, driver->uninit_driver, @@ -883,7 +883,8 @@ dump_driver(int argc, char** argv) if (driver == NULL) break; - kprintf("%p %5ld %3ld %5ld %c %3ld %s\n", driver, + kprintf("%p %5" B_PRId32 " %3" B_PRIu32 " %5" B_PRId32 " %c " + "%3" B_PRId32 " %s\n", driver, driver->image < 0 ? -1 : driver->image, driver->devices_used, driver->devices.Count(), driver->binary_updated ? 'U' : ' ', driver->priority, @@ -1417,7 +1418,7 @@ legacy_driver_add_preloaded(kernel_args* args) status = add_driver(imagePath.Path(), image->id); if (status != B_OK) { dprintf("legacy_driver_add_preloaded: Failed to add \"%s\": %s\n", - image->name, strerror(status)); + (char *)image->name, strerror(status)); unload_kernel_add_on(image->id); } } diff --git a/src/system/kernel/disk_device_manager/KDiskDevice.cpp b/src/system/kernel/disk_device_manager/KDiskDevice.cpp index b074b4d1c0..1d74c6d005 100644 --- a/src/system/kernel/disk_device_manager/KDiskDevice.cpp +++ b/src/system/kernel/disk_device_manager/KDiskDevice.cpp @@ -346,9 +346,9 @@ KDiskDevice::WriteUserData(UserDataWriter& writer) void KDiskDevice::Dump(bool deep, int32 level) { - OUT("device %ld: %s\n", ID(), Path()); + OUT("device %" B_PRId32 ": %s\n", ID(), Path()); OUT(" media status: %s\n", strerror(fMediaStatus)); - OUT(" device flags: %lx\n", DeviceFlags()); + OUT(" device flags: %" B_PRIx32 "\n", DeviceFlags()); if (fMediaStatus == B_OK) KPartition::Dump(deep, 0); } diff --git a/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp b/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp index 3916f1ae24..076a24bda4 100644 --- a/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp +++ b/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp @@ -261,7 +261,7 @@ KDiskDeviceManager::KDiskDeviceManager() if (fMediaChecker >= 0) resume_thread(fMediaChecker); - DBG(OUT("number of disk systems: %ld\n", CountDiskSystems())); + DBG(OUT("number of disk systems: %" B_PRId32 "\n", CountDiskSystems())); // TODO: Watch the disk systems and the relevant directories. } @@ -285,26 +285,26 @@ KDiskDeviceManager::~KDiskDeviceManager() // some sanity checks if (fPartitions->Count() > 0) { - DBG(OUT("WARNING: There are still %ld unremoved partitions!\n", + DBG(OUT("WARNING: There are still %" B_PRId32 " unremoved partitions!\n", fPartitions->Count())); for (PartitionMap::Iterator it = fPartitions->Begin(); it != fPartitions->End(); ++it) { - DBG(OUT(" partition: %ld\n", it->Value()->ID())); + DBG(OUT(" partition: %" B_PRId32 "\n", it->Value()->ID())); } } if (fObsoletePartitions->Count() > 0) { - DBG(OUT("WARNING: There are still %ld obsolete partitions!\n", + DBG(OUT("WARNING: There are still %" B_PRId32 " obsolete partitions!\n", fObsoletePartitions->Count())); for (PartitionSet::Iterator it = fObsoletePartitions->Begin(); it != fObsoletePartitions->End(); ++it) { - DBG(OUT(" partition: %ld\n", (*it)->ID())); + DBG(OUT(" partition: %" B_PRId32 "\n", (*it)->ID())); } } // remove all disk systems for (int32 cookie = 0; KDiskSystem* diskSystem = NextDiskSystem(&cookie);) { fDiskSystems->Remove(diskSystem->ID()); if (diskSystem->IsLoaded()) { - DBG(OUT("WARNING: Disk system `%s' (%ld) is still loaded!\n", + DBG(OUT("WARNING: Disk system `%s' (%" B_PRId32 ") is still loaded!\n", diskSystem->Name(), diskSystem->ID())); } else delete diskSystem; diff --git a/src/system/kernel/disk_device_manager/KFileDiskDevice.cpp b/src/system/kernel/disk_device_manager/KFileDiskDevice.cpp index bbf93e7d42..11248ac282 100644 --- a/src/system/kernel/disk_device_manager/KFileDiskDevice.cpp +++ b/src/system/kernel/disk_device_manager/KFileDiskDevice.cpp @@ -212,7 +212,7 @@ KFileDiskDevice::_GetDirectoryPath(partition_id id, KPath* path) status_t error = path->SetPath(kFileDevicesDir); if (error == B_OK) { char idBuffer[12]; - snprintf(idBuffer, sizeof(idBuffer), "%ld", id); + snprintf(idBuffer, sizeof(idBuffer), "%" B_PRId32, id); error = path->Append(idBuffer); } return error; diff --git a/src/system/kernel/disk_device_manager/KPartition.cpp b/src/system/kernel/disk_device_manager/KPartition.cpp index aa60d9556e..878ab99a79 100644 --- a/src/system/kernel/disk_device_manager/KPartition.cpp +++ b/src/system/kernel/disk_device_manager/KPartition.cpp @@ -216,7 +216,7 @@ KPartition::PublishDevice() error = devfs_publish_partition(buffer, &info); if (error != B_OK) { dprintf("KPartition::PublishDevice(): Failed to publish partition " - "%ld: %s\n", ID(), strerror(error)); + "%" B_PRId32 ": %s\n", ID(), strerror(error)); free(fPublishedName); fPublishedName = NULL; return error; @@ -237,14 +237,14 @@ KPartition::UnpublishDevice() status_t error = GetPath(&path); if (error != B_OK) { dprintf("KPartition::UnpublishDevice(): Failed to get path for " - "partition %ld: %s\n", ID(), strerror(error)); + "partition %" B_PRId32 ": %s\n", ID(), strerror(error)); return error; } error = devfs_unpublish_partition(path.Path()); if (error != B_OK) { dprintf("KPartition::UnpublishDevice(): Failed to unpublish partition " - "%ld: %s\n", ID(), strerror(error)); + "%" B_PRId32 ": %s\n", ID(), strerror(error)); } free(fPublishedName); @@ -285,7 +285,7 @@ KPartition::RepublishDevice() free(newName); UnpublishDevice(); dprintf("KPartition::RepublishDevice(): Failed to republish partition " - "%ld: %s\n", ID(), strerror(error)); + "%" B_PRId32 ": %s\n", ID(), strerror(error)); return error; } @@ -657,7 +657,7 @@ KPartition::GetFileName(char* buffer, size_t size) const { // If the parent is the device, the name is the index of the partition. if (Parent() == NULL || Parent()->IsDevice()) { - if (snprintf(buffer, size, "%ld", Index()) >= (int)size) + if (snprintf(buffer, size, "%" B_PRId32, Index()) >= (int)size) return B_NAME_TOO_LONG; return B_OK; } @@ -669,7 +669,7 @@ KPartition::GetFileName(char* buffer, size_t size) const return error; size_t len = strlen(buffer); - if (snprintf(buffer + len, size - len, "_%ld", Index()) >= int(size - len)) + if (snprintf(buffer + len, size - len, "_%" B_PRId32, Index()) >= int(size - len)) return B_NAME_TOO_LONG; return B_OK; } @@ -1172,7 +1172,7 @@ KPartition::UninitializeContents(bool logChanges) B_FORCE_UNMOUNT | B_UNMOUNT_BUSY_PARTITION); if (error != B_OK) { dprintf("KPartition::UninitializeContents(): Failed to unmount " - "device %ld: %s\n", VolumeID(), strerror(error)); + "device %" B_PRIdDEV ": %s\n", VolumeID(), strerror(error)); } SetVolumeID(-1); @@ -1302,17 +1302,17 @@ KPartition::Dump(bool deep, int32 level) KPath path; GetPath(&path); if (level > 0) - OUT("%spartition %ld: %s\n", prefix, ID(), path.Path()); - OUT("%s offset: %lld\n", prefix, Offset()); - OUT("%s size: %lld (%.2f MB)\n", prefix, Size(), + OUT("%spartition %" B_PRId32 ": %s\n", prefix, ID(), path.Path()); + OUT("%s offset: %" B_PRIdOFF "\n", prefix, Offset()); + OUT("%s size: %" B_PRIdOFF " (%.2f MB)\n", prefix, Size(), Size() / (1024.0*1024)); - OUT("%s content size: %lld\n", prefix, ContentSize()); - OUT("%s block size: %lu\n", prefix, BlockSize()); - OUT("%s child count: %ld\n", prefix, CountChildren()); - OUT("%s index: %ld\n", prefix, Index()); - OUT("%s status: %lu\n", prefix, Status()); - OUT("%s flags: %lx\n", prefix, Flags()); - OUT("%s volume: %ld\n", prefix, VolumeID()); + OUT("%s content size: %" B_PRIdOFF "\n", prefix, ContentSize()); + OUT("%s block size: %" B_PRIu32 "\n", prefix, BlockSize()); + OUT("%s child count: %" B_PRId32 "\n", prefix, CountChildren()); + OUT("%s index: %" B_PRId32 "\n", prefix, Index()); + OUT("%s status: %" B_PRIu32 "\n", prefix, Status()); + OUT("%s flags: %" B_PRIx32 "\n", prefix, Flags()); + OUT("%s volume: %" B_PRIdDEV "\n", prefix, VolumeID()); OUT("%s disk system: %s\n", prefix, (DiskSystem() ? DiskSystem()->Name() : NULL)); OUT("%s name: %s\n", prefix, Name()); diff --git a/src/system/kernel/disk_device_manager/disk_device_manager.cpp b/src/system/kernel/disk_device_manager/disk_device_manager.cpp index 8d54fa7b49..421dc78f37 100644 --- a/src/system/kernel/disk_device_manager/disk_device_manager.cpp +++ b/src/system/kernel/disk_device_manager/disk_device_manager.cpp @@ -174,11 +174,11 @@ create_child_partition(partition_id partitionID, int32 index, off_t offset, == B_OK) { return child->PartitionData(); } else { - DBG(OUT(" creating child (%ld, %ld) failed\n", partitionID, - index)); + DBG(OUT(" creating child (%" B_PRId32 ", %" B_PRId32 ") failed\n", + partitionID, index)); } } else - DBG(OUT(" partition %ld not found\n", partitionID)); + DBG(OUT(" partition %" B_PRId32 " not found\n", partitionID)); return NULL; } @@ -244,8 +244,8 @@ get_default_partition_content_name(partition_id partitionID, // do one digit precision. uint64 result = uint64(size * 10 + 0.5); - snprintf(buffer, bufferSize, "%s Volume (%ld.%ld %sB)", fileSystemName, - int32(result / 10), int32(result % 10), suffixes[index]); + snprintf(buffer, bufferSize, "%s Volume (%" B_PRId32 ".%" B_PRId32 " %sB)", + fileSystemName, int32(result / 10), int32(result % 10), suffixes[index]); return B_OK; } diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index ad3c291ce2..19d5e55646 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -9,6 +9,7 @@ /*! Contains the ELF loader */ + #include #include @@ -65,8 +66,8 @@ static mutex sImageLoadMutex = MUTEX_INITIALIZER("kimages_load_lock"); static bool sInitialized = false; -static struct Elf32_Sym *elf_find_symbol(struct elf_image_info *image, - const char *name, const elf_version_info *version, bool lookupDefault); +static elf_sym *elf_find_symbol(struct elf_image_info *image, const char *name, + const elf_version_info *version, bool lookupDefault); /*! Calculates hash for an image using its ID */ @@ -74,7 +75,7 @@ static uint32 image_hash(void *_image, const void *_key, uint32 range) { struct elf_image_info *image = (struct elf_image_info *)_image; - image_id id = (image_id)_key; + image_id id = (image_id)(addr_t)_key; if (image != NULL) return image->id % range; @@ -88,7 +89,7 @@ static int image_compare(void *_image, const void *_key) { struct elf_image_info *image = (struct elf_image_info *)_image; - image_id id = (image_id)_key; + image_id id = (image_id)(addr_t)_key; return id - image->id; } @@ -122,11 +123,11 @@ register_elf_image(struct elf_image_info *image) // Haiku API version imageInfo.api_version = 0; - struct Elf32_Sym* symbol = elf_find_symbol(image, + elf_sym* symbol = elf_find_symbol(image, B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME, NULL, true); if (symbol != NULL && symbol->st_shndx != SHN_UNDEF && symbol->st_value > 0 - && ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT + && symbol->Type() == STT_OBJECT && symbol->st_size >= sizeof(uint32)) { addr_t symbolAddress = symbol->st_value + image->text_region.delta; if (symbolAddress >= image->text_region.start @@ -142,7 +143,7 @@ register_elf_image(struct elf_image_info *image) B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME, NULL, true); if (symbol != NULL && symbol->st_shndx != SHN_UNDEF && symbol->st_value > 0 - && ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT + && symbol->Type() == STT_OBJECT && symbol->st_size >= sizeof(uint32)) { addr_t symbolAddress = symbol->st_value + image->text_region.delta; if (symbolAddress >= image->text_region.start @@ -232,7 +233,7 @@ dump_address_info(int argc, char **argv) static struct elf_image_info * find_image(image_id id) { - return (elf_image_info *)hash_lookup(sImagesHash, (void *)id); + return (elf_image_info *)hash_lookup(sImagesHash, (void *)(addr_t)id); } @@ -314,9 +315,9 @@ elf_hash(const char *name) static const char * -get_symbol_type_string(struct Elf32_Sym *symbol) +get_symbol_type_string(elf_sym *symbol) { - switch (ELF32_ST_TYPE(symbol->st_info)) { + switch (symbol->Type()) { case STT_FUNC: return "func"; case STT_OBJECT: @@ -330,9 +331,9 @@ get_symbol_type_string(struct Elf32_Sym *symbol) static const char * -get_symbol_bind_string(struct Elf32_Sym *symbol) +get_symbol_bind_string(elf_sym *symbol) { - switch (ELF32_ST_BIND(symbol->st_info)) { + switch (symbol->Bind()) { case STB_LOCAL: return "loc "; case STB_GLOBAL: @@ -366,7 +367,7 @@ dump_symbol(int argc, char **argv) if (image->num_debug_symbols > 0) { // search extended debug symbol table (contains static symbols) for (uint32 i = 0; i < image->num_debug_symbols; i++) { - struct Elf32_Sym *symbol = &image->debug_symbols[i]; + elf_sym *symbol = &image->debug_symbols[i]; const char *name = image->debug_string_table + symbol->st_name; if (symbol->st_value > 0 && strstr(name, pattern) != 0) { @@ -381,7 +382,7 @@ dump_symbol(int argc, char **argv) for (uint32 i = 0; i < HASHTABSIZE(image); i++) { for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) { - struct Elf32_Sym *symbol = &image->syms[j]; + elf_sym *symbol = &image->syms[j]; const char *name = SYMNAME(image, symbol); if (symbol->st_value > 0 && strstr(name, pattern) != 0) { @@ -413,7 +414,7 @@ dump_symbols(int argc, char **argv) // if the argument looks like a hex number, treat it as such if (argc > 1) { if (isdigit(argv[1][0])) { - uint32 num = strtoul(argv[1], NULL, 0); + addr_t num = strtoul(argv[1], NULL, 0); if (IS_KERNEL_ADDRESS(num)) { // find image at address @@ -428,12 +429,16 @@ dump_symbols(int argc, char **argv) } hash_close(sImagesHash, &iterator, false); - if (image == NULL) - kprintf("No image covers 0x%lx in the kernel!\n", num); + if (image == NULL) { + kprintf("No image covers %#" B_PRIxADDR " in the kernel!\n", + num); + } } else { image = (elf_image_info *)hash_lookup(sImagesHash, (void *)num); - if (image == NULL) - kprintf("image 0x%lx doesn't exist in the kernel!\n", num); + if (image == NULL) { + kprintf("image %#" B_PRIxADDR " doesn't exist in the " + "kernel!\n", num); + } } } else { // look for image by name @@ -458,19 +463,19 @@ dump_symbols(int argc, char **argv) // dump symbols - kprintf("Symbols of image %ld \"%s\":\nAddress Type Size Name\n", - image->id, image->name); + kprintf("Symbols of image %" B_PRId32 " \"%s\":\n", image->id, image->name); + kprintf("%-*s Type Size Name\n", B_PRINTF_POINTER_WIDTH, "Address"); if (image->num_debug_symbols > 0) { // search extended debug symbol table (contains static symbols) for (i = 0; i < image->num_debug_symbols; i++) { - struct Elf32_Sym *symbol = &image->debug_symbols[i]; + elf_sym *symbol = &image->debug_symbols[i]; if (symbol->st_value == 0 || symbol->st_size >= image->text_region.size + image->data_region.size) continue; - kprintf("%08lx %s/%s %5ld %s\n", + kprintf("%0*lx %s/%s %5ld %s\n", B_PRINTF_POINTER_WIDTH, symbol->st_value + image->text_region.delta, get_symbol_type_string(symbol), get_symbol_bind_string(symbol), symbol->st_size, image->debug_string_table + symbol->st_name); @@ -482,7 +487,7 @@ dump_symbols(int argc, char **argv) for (i = 0; i < HASHTABSIZE(image); i++) { for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) { - struct Elf32_Sym *symbol = &image->syms[j]; + elf_sym *symbol = &image->syms[j]; if (symbol->st_value == 0 || symbol->st_size >= image->text_region.size + image->data_region.size) @@ -504,9 +509,9 @@ dump_symbols(int argc, char **argv) static void dump_elf_region(struct elf_region *region, const char *name) { - kprintf(" %s.id %ld\n", name, region->id); - kprintf(" %s.start 0x%lx\n", name, region->start); - kprintf(" %s.size 0x%lx\n", name, region->size); + kprintf(" %s.id %" B_PRId32 "\n", name, region->id); + kprintf(" %s.start %#" B_PRIxADDR "\n", name, region->start); + kprintf(" %s.size %#" B_PRIxSIZE "\n", name, region->size); kprintf(" %s.delta %ld\n", name, region->delta); } @@ -516,22 +521,22 @@ dump_image_info(struct elf_image_info *image) { kprintf("elf_image_info at %p:\n", image); kprintf(" next %p\n", image->next); - kprintf(" id %ld\n", image->id); + kprintf(" id %" B_PRId32 "\n", image->id); dump_elf_region(&image->text_region, "text"); dump_elf_region(&image->data_region, "data"); - kprintf(" dynamic_section 0x%lx\n", image->dynamic_section); + kprintf(" dynamic_section %#" B_PRIxADDR "\n", image->dynamic_section); kprintf(" needed %p\n", image->needed); kprintf(" symhash %p\n", image->symhash); kprintf(" syms %p\n", image->syms); kprintf(" strtab %p\n", image->strtab); kprintf(" rel %p\n", image->rel); - kprintf(" rel_len 0x%x\n", image->rel_len); + kprintf(" rel_len %#x\n", image->rel_len); kprintf(" rela %p\n", image->rela); - kprintf(" rela_len 0x%x\n", image->rela_len); + kprintf(" rela_len %#x\n", image->rela_len); kprintf(" pltrel %p\n", image->pltrel); - kprintf(" pltrel_len 0x%x\n", image->pltrel_len); + kprintf(" pltrel_len %#x\n", image->pltrel_len); - kprintf(" debug_symbols %p (%ld)\n", + kprintf(" debug_symbols %p (%" B_PRIu32 ")\n", image->debug_symbols, image->num_debug_symbols); } @@ -544,16 +549,17 @@ dump_image(int argc, char **argv) // if the argument looks like a hex number, treat it as such if (argc > 1) { - uint32 num = strtoul(argv[1], NULL, 0); + addr_t num = strtoul(argv[1], NULL, 0); if (IS_KERNEL_ADDRESS(num)) { // semi-hack dump_image_info((struct elf_image_info *)num); } else { image = (elf_image_info *)hash_lookup(sImagesHash, (void *)num); - if (image == NULL) - kprintf("image 0x%lx doesn't exist in the kernel!\n", num); - else + if (image == NULL) { + kprintf("image %#" B_PRIxADDR " doesn't exist in the kernel!\n", + num); + } else dump_image_info(image); } return 0; @@ -565,7 +571,7 @@ dump_image(int argc, char **argv) while ((image = (elf_image_info *)hash_next(sImagesHash, &iterator)) != NULL) { - kprintf("%p (%ld) %s\n", image, image->id, image->name); + kprintf("%p (%" B_PRId32 ") %s\n", image, image->id, image->name); } hash_close(sImagesHash, &iterator, false); @@ -576,7 +582,7 @@ dump_image(int argc, char **argv) // Currently unused #if 0 static -void dump_symbol(struct elf_image_info *image, struct Elf32_Sym *sym) +void dump_symbol(struct elf_image_info *image, elf_sym *sym) { kprintf("symbol at %p, in image %p\n", sym, image); @@ -591,25 +597,24 @@ void dump_symbol(struct elf_image_info *image, struct Elf32_Sym *sym) #endif -static struct Elf32_Sym * +static elf_sym * elf_find_symbol(struct elf_image_info *image, const char *name, const elf_version_info *lookupVersion, bool lookupDefault) { if (image->dynamic_section == 0 || HASHTABSIZE(image) == 0) return NULL; - Elf32_Sym* versionedSymbol = NULL; + elf_sym* versionedSymbol = NULL; uint32 versionedSymbolCount = 0; uint32 hash = elf_hash(name) % HASHTABSIZE(image); for (uint32 i = HASHBUCKETS(image)[hash]; i != STN_UNDEF; i = HASHCHAINS(image)[i]) { - Elf32_Sym* symbol = &image->syms[i]; + elf_sym* symbol = &image->syms[i]; // consider only symbols with the right name and binding if (symbol->st_shndx == SHN_UNDEF - || ((ELF32_ST_BIND(symbol->st_info) != STB_GLOBAL) - && (ELF32_ST_BIND(symbol->st_info) != STB_WEAK)) + || ((symbol->Bind() != STB_GLOBAL) && (symbol->Bind() != STB_WEAK)) || strcmp(SYMNAME(image, symbol), name) != 0) { continue; } @@ -703,8 +708,8 @@ elf_find_symbol(struct elf_image_info *image, const char *name, static status_t elf_parse_dynamic_section(struct elf_image_info *image) { - struct Elf32_Dyn *d; - int32 neededOffset = -1; + elf_dyn *d; + ssize_t neededOffset = -1; TRACE(("top of elf_parse_dynamic_section\n")); @@ -712,7 +717,7 @@ elf_parse_dynamic_section(struct elf_image_info *image) image->syms = 0; image->strtab = 0; - d = (struct Elf32_Dyn *)image->dynamic_section; + d = (elf_dyn *)image->dynamic_section; if (!d) return B_ERROR; @@ -730,25 +735,25 @@ elf_parse_dynamic_section(struct elf_image_info *image) + image->text_region.delta); break; case DT_SYMTAB: - image->syms = (struct Elf32_Sym *)(d[i].d_un.d_ptr + image->syms = (elf_sym *)(d[i].d_un.d_ptr + image->text_region.delta); break; case DT_REL: - image->rel = (struct Elf32_Rel *)(d[i].d_un.d_ptr + image->rel = (elf_rel *)(d[i].d_un.d_ptr + image->text_region.delta); break; case DT_RELSZ: image->rel_len = d[i].d_un.d_val; break; case DT_RELA: - image->rela = (struct Elf32_Rela *)(d[i].d_un.d_ptr + image->rela = (elf_rela *)(d[i].d_un.d_ptr + image->text_region.delta); break; case DT_RELASZ: image->rela_len = d[i].d_un.d_val; break; case DT_JMPREL: - image->pltrel = (struct Elf32_Rel *)(d[i].d_un.d_ptr + image->pltrel = (elf_rel *)(d[i].d_un.d_ptr + image->text_region.delta); break; case DT_PLTRELSZ: @@ -758,18 +763,18 @@ elf_parse_dynamic_section(struct elf_image_info *image) image->pltrel_type = d[i].d_un.d_val; break; case DT_VERSYM: - image->symbol_versions = (Elf32_Versym*) + image->symbol_versions = (elf_versym*) (d[i].d_un.d_ptr + image->text_region.delta); break; case DT_VERDEF: - image->version_definitions = (Elf32_Verdef*) + image->version_definitions = (elf_verdef*) (d[i].d_un.d_ptr + image->text_region.delta); break; case DT_VERDEFNUM: image->num_version_definitions = d[i].d_un.d_val; break; case DT_VERNEED: - image->needed_versions = (Elf32_Verneed*) + image->needed_versions = (elf_verneed*) (d[i].d_un.d_ptr + image->text_region.delta); break; case DT_VERNEEDNUM: @@ -818,7 +823,7 @@ assert_defined_image_version(elf_image_info* dependentImage, } // iterate through the defined versions to find the given one - Elf32_Verdef* definition = image->version_definitions; + elf_verdef* definition = image->version_definitions; for (uint32 i = 0; i < image->num_version_definitions; i++) { uint32 versionIndex = VER_NDX(definition->vd_ndx); elf_version_info& info = image->versions[versionIndex]; @@ -828,7 +833,7 @@ assert_defined_image_version(elf_image_info* dependentImage, return B_OK; } - definition = (Elf32_Verdef*) + definition = (elf_verdef*) ((uint8*)definition + definition->vd_next); } @@ -852,7 +857,7 @@ init_image_version_infos(elf_image_info* image) uint32 maxIndex = 0; if (image->version_definitions != NULL) { - Elf32_Verdef* definition = image->version_definitions; + elf_verdef* definition = image->version_definitions; for (uint32 i = 0; i < image->num_version_definitions; i++) { if (definition->vd_version != 1) { dprintf("Unsupported version definition revision: %u\n", @@ -864,13 +869,13 @@ init_image_version_infos(elf_image_info* image) if (versionIndex > maxIndex) maxIndex = versionIndex; - definition = (Elf32_Verdef*) + definition = (elf_verdef*) ((uint8*)definition + definition->vd_next); } } if (image->needed_versions != NULL) { - Elf32_Verneed* needed = image->needed_versions; + elf_verneed* needed = image->needed_versions; for (uint32 i = 0; i < image->num_needed_versions; i++) { if (needed->vn_version != 1) { dprintf("Unsupported version needed revision: %u\n", @@ -878,17 +883,17 @@ init_image_version_infos(elf_image_info* image) return B_BAD_VALUE; } - Elf32_Vernaux* vernaux - = (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux); + elf_vernaux* vernaux + = (elf_vernaux*)((uint8*)needed + needed->vn_aux); for (uint32 k = 0; k < needed->vn_cnt; k++) { uint32 versionIndex = VER_NDX(vernaux->vna_other); if (versionIndex > maxIndex) maxIndex = versionIndex; - vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next); + vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next); } - needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next); + needed = (elf_verneed*)((uint8*)needed + needed->vn_next); } } @@ -908,12 +913,12 @@ init_image_version_infos(elf_image_info* image) // version definitions if (image->version_definitions != NULL) { - Elf32_Verdef* definition = image->version_definitions; + elf_verdef* definition = image->version_definitions; for (uint32 i = 0; i < image->num_version_definitions; i++) { if (definition->vd_cnt > 0 && (definition->vd_flags & VER_FLG_BASE) == 0) { - Elf32_Verdaux* verdaux - = (Elf32_Verdaux*)((uint8*)definition + definition->vd_aux); + elf_verdaux* verdaux + = (elf_verdaux*)((uint8*)definition + definition->vd_aux); uint32 versionIndex = VER_NDX(definition->vd_ndx); elf_version_info& info = image->versions[versionIndex]; @@ -922,19 +927,19 @@ init_image_version_infos(elf_image_info* image) info.file_name = NULL; } - definition = (Elf32_Verdef*) + definition = (elf_verdef*) ((uint8*)definition + definition->vd_next); } } // needed versions if (image->needed_versions != NULL) { - Elf32_Verneed* needed = image->needed_versions; + elf_verneed* needed = image->needed_versions; for (uint32 i = 0; i < image->num_needed_versions; i++) { const char* fileName = STRING(image, needed->vn_file); - Elf32_Vernaux* vernaux - = (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux); + elf_vernaux* vernaux + = (elf_vernaux*)((uint8*)needed + needed->vn_aux); for (uint32 k = 0; k < needed->vn_cnt; k++) { uint32 versionIndex = VER_NDX(vernaux->vna_other); elf_version_info& info = image->versions[versionIndex]; @@ -942,10 +947,10 @@ init_image_version_infos(elf_image_info* image) info.name = STRING(image, vernaux->vna_name); info.file_name = fileName; - vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next); + vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next); } - needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next); + needed = (elf_verneed*)((uint8*)needed + needed->vn_next); } } @@ -959,12 +964,12 @@ check_needed_image_versions(elf_image_info* image) if (image->needed_versions == NULL) return B_OK; - Elf32_Verneed* needed = image->needed_versions; + elf_verneed* needed = image->needed_versions; for (uint32 i = 0; i < image->num_needed_versions; i++) { elf_image_info* dependency = sKernelImage; - Elf32_Vernaux* vernaux - = (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux); + elf_vernaux* vernaux + = (elf_vernaux*)((uint8*)needed + needed->vn_aux); for (uint32 k = 0; k < needed->vn_cnt; k++) { uint32 versionIndex = VER_NDX(vernaux->vna_other); elf_version_info& info = image->versions[versionIndex]; @@ -974,10 +979,10 @@ check_needed_image_versions(elf_image_info* image) if (error != B_OK) return error; - vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next); + vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next); } - needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next); + needed = (elf_verneed*)((uint8*)needed + needed->vn_next); } return B_OK; @@ -988,11 +993,11 @@ check_needed_image_versions(elf_image_info* image) Returns the resolved symbol's address in \a _symbolAddress. */ status_t -elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol, +elf_resolve_symbol(struct elf_image_info *image, elf_sym *symbol, struct elf_image_info *sharedImage, addr_t *_symbolAddress) { // Local symbols references are always resolved to the given symbol. - if (ELF32_ST_BIND(symbol->st_info) == STB_LOCAL) { + if (symbol->Bind() == STB_LOCAL) { *_symbolAddress = symbol->st_value + image->text_region.delta; return B_OK; } @@ -1017,19 +1022,19 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol, // find the symbol elf_image_info* foundImage = firstImage; - struct Elf32_Sym* foundSymbol = elf_find_symbol(firstImage, symbolName, - versionInfo, false); + elf_sym* foundSymbol = elf_find_symbol(firstImage, symbolName, versionInfo, + false); if (foundSymbol == NULL - || ELF32_ST_BIND(foundSymbol->st_info) == STB_WEAK) { + || foundSymbol->Bind() == STB_WEAK) { // Not found or found a weak definition -- try to resolve in the other // image. - Elf32_Sym* secondSymbol = elf_find_symbol(secondImage, symbolName, + elf_sym* secondSymbol = elf_find_symbol(secondImage, symbolName, versionInfo, false); // If we found a symbol -- take it in case we didn't have a symbol // before or the new symbol is not weak. if (secondSymbol != NULL && (foundSymbol == NULL - || ELF32_ST_BIND(secondSymbol->st_info) != STB_WEAK)) { + || secondSymbol->Bind() != STB_WEAK)) { foundImage = secondImage; foundSymbol = secondSymbol; } @@ -1037,7 +1042,7 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol, if (foundSymbol == NULL) { // Weak undefined symbols get a value of 0, if unresolved. - if (ELF32_ST_BIND(symbol->st_info) == STB_WEAK) { + if (symbol->Bind() == STB_WEAK) { *_symbolAddress = 0; return B_OK; } @@ -1048,12 +1053,11 @@ elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *symbol, } // make sure they're the same type - if (ELF32_ST_TYPE(symbol->st_info) != ELF32_ST_TYPE(foundSymbol->st_info)) { + if (symbol->Type() != foundSymbol->Type()) { dprintf("elf_resolve_symbol: found symbol '%s' in image '%s' " "(requested by image '%s') but wrong type (%d vs. %d)\n", symbolName, foundImage->name, image->name, - ELF32_ST_TYPE(foundSymbol->st_info), - ELF32_ST_TYPE(symbol->st_info)); + foundSymbol->Type(), symbol->Type()); return B_MISSING_SYMBOL; } @@ -1072,8 +1076,7 @@ elf_relocate(struct elf_image_info *image) // deal with the rels first if (image->rel) { - TRACE(("total %i relocs\n", - image->rel_len / (int)sizeof(struct Elf32_Rel))); + TRACE(("total %i rel relocs\n", image->rel_len / (int)sizeof(elf_rel))); status = arch_elf_relocate_rel(image, sKernelImage, image->rel, image->rel_len); @@ -1082,21 +1085,25 @@ elf_relocate(struct elf_image_info *image) } if (image->pltrel) { - TRACE(("total %i plt-relocs\n", - image->pltrel_len / (int)sizeof(struct Elf32_Rel))); - if (image->pltrel_type == DT_REL) { + TRACE(("total %i plt-relocs\n", + image->pltrel_len / (int)sizeof(elf_rel))); status = arch_elf_relocate_rel(image, sKernelImage, image->pltrel, image->pltrel_len); } else { + TRACE(("total %i plt-relocs\n", + image->pltrel_len / (int)sizeof(elf_rela))); status = arch_elf_relocate_rela(image, sKernelImage, - (struct Elf32_Rela *)image->pltrel, image->pltrel_len); + (elf_rela *)image->pltrel, image->pltrel_len); } if (status < B_OK) return status; } if (image->rela) { + TRACE(("total %i rel relocs\n", + image->rela_len / (int)sizeof(elf_rela))); + status = arch_elf_relocate_rela(image, sKernelImage, image->rela, image->rela_len); if (status < B_OK) @@ -1108,18 +1115,18 @@ elf_relocate(struct elf_image_info *image) static int -verify_eheader(struct Elf32_Ehdr *elfHeader) +verify_eheader(elf_ehdr *elfHeader) { if (memcmp(elfHeader->e_ident, ELF_MAGIC, 4) != 0) return B_NOT_AN_EXECUTABLE; - if (elfHeader->e_ident[4] != ELFCLASS32) + if (elfHeader->e_ident[4] != ELF_CLASS) return B_NOT_AN_EXECUTABLE; if (elfHeader->e_phoff == 0) return B_NOT_AN_EXECUTABLE; - if (elfHeader->e_phentsize < sizeof(struct Elf32_Phdr)) + if (elfHeader->e_phentsize < sizeof(elf_phdr)) return B_NOT_AN_EXECUTABLE; return 0; @@ -1132,7 +1139,7 @@ unload_elf_image(struct elf_image_info *image) if (atomic_add(&image->ref_count, -1) > 1) return; - TRACE(("unload image %ld, %s\n", image->id, image->name)); + TRACE(("unload image %" B_PRId32 ", %s\n", image->id, image->name)); unregister_elf_image(image); delete_elf_image(image); @@ -1142,9 +1149,9 @@ unload_elf_image(struct elf_image_info *image) static status_t load_elf_symbol_table(int fd, struct elf_image_info *image) { - struct Elf32_Ehdr *elfHeader = image->elf_header; - struct Elf32_Sym *symbolTable = NULL; - struct Elf32_Shdr *stringHeader = NULL; + elf_ehdr *elfHeader = image->elf_header; + elf_sym *symbolTable = NULL; + elf_shdr *stringHeader = NULL; uint32 numSymbols = 0; char *stringTable; status_t status; @@ -1154,7 +1161,7 @@ load_elf_symbol_table(int fd, struct elf_image_info *image) // get section headers ssize_t size = elfHeader->e_shnum * elfHeader->e_shentsize; - struct Elf32_Shdr *sectionHeaders = (struct Elf32_Shdr *)malloc(size); + elf_shdr *sectionHeaders = (elf_shdr *)malloc(size); if (sectionHeaders == NULL) { dprintf("error allocating space for section headers\n"); return B_NO_MEMORY; @@ -1180,8 +1187,8 @@ load_elf_symbol_table(int fd, struct elf_image_info *image) } // read in symbol table - symbolTable - = (struct Elf32_Sym *)malloc(size = sectionHeaders[i].sh_size); + size = sectionHeaders[i].sh_size; + symbolTable = (elf_sym *)malloc(size); if (symbolTable == NULL) { status = B_NO_MEMORY; goto error1; @@ -1195,7 +1202,7 @@ load_elf_symbol_table(int fd, struct elf_image_info *image) goto error2; } - numSymbols = size / sizeof(struct Elf32_Sym); + numSymbols = size / sizeof(elf_sym); break; } } @@ -1221,7 +1228,7 @@ load_elf_symbol_table(int fd, struct elf_image_info *image) goto error3; } - TRACE(("loaded debug %ld symbols\n", numSymbols)); + TRACE(("loaded %" B_PRId32 " debug symbols\n", numSymbols)); // insert tables into image image->debug_symbols = symbolTable; @@ -1243,7 +1250,7 @@ error1: static status_t -insert_preloaded_image(struct preloaded_image *preloadedImage, bool kernel) +insert_preloaded_image(preloaded_elf_image *preloadedImage, bool kernel) { status_t status; @@ -1258,8 +1265,14 @@ insert_preloaded_image(struct preloaded_image *preloadedImage, bool kernel) image->name = strdup(preloadedImage->name); image->dynamic_section = preloadedImage->dynamic_section.start; - image->text_region = preloadedImage->text_region; - image->data_region = preloadedImage->data_region; + image->text_region.id = preloadedImage->text_region.id; + image->text_region.start = preloadedImage->text_region.start; + image->text_region.size = preloadedImage->text_region.size; + image->text_region.delta = preloadedImage->text_region.delta; + image->data_region.id = preloadedImage->data_region.id; + image->data_region.start = preloadedImage->data_region.start; + image->data_region.size = preloadedImage->data_region.size; + image->data_region.delta = preloadedImage->data_region.delta; status = elf_parse_dynamic_section(image); if (status != B_OK) @@ -1282,9 +1295,9 @@ insert_preloaded_image(struct preloaded_image *preloadedImage, bool kernel) // copy debug symbols to the kernel heap if (preloadedImage->debug_symbols != NULL) { - int32 debugSymbolsSize = sizeof(Elf32_Sym) + int32 debugSymbolsSize = sizeof(elf_sym) * preloadedImage->num_debug_symbols; - image->debug_symbols = (Elf32_Sym*)malloc(debugSymbolsSize); + image->debug_symbols = (elf_sym*)malloc(debugSymbolsSize); if (image->debug_symbols != NULL) { memcpy(image->debug_symbols, preloadedImage->debug_symbols, debugSymbolsSize); @@ -1385,7 +1398,7 @@ public: const elf_region_t& textRegion = image.regions[0]; // search the image for the symbol - Elf32_Sym symbolFound; + elf_sym symbolFound; addr_t deltaFound = INT_MAX; bool exactMatch = false; @@ -1401,7 +1414,7 @@ public: for (uint32 j = bucket; j != STN_UNDEF; _Read(&hashChains[j], j) ? 0 : j = STN_UNDEF) { - Elf32_Sym symbol; + elf_sym symbol; if (!_Read(image.syms + j, symbol)) continue; @@ -1412,8 +1425,7 @@ public: // function and data symbols that have an st_value != 0 (0 // seems to be an indication for a symbol defined elsewhere // -- couldn't verify that in the specs though). - if ((ELF32_ST_TYPE(symbol.st_info) != STT_FUNC - && ELF32_ST_TYPE(symbol.st_info) != STT_OBJECT) + if ((symbol.Type() != STT_FUNC && symbol.Type() != STT_OBJECT) || symbol.st_value == 0 || symbol.st_value + symbol.st_size + textRegion.delta > textRegion.vmstart + textRegion.size) { @@ -1542,7 +1554,7 @@ get_image_symbol(image_id id, const char *name, int32 symbolClass, void **_symbol) { struct elf_image_info *image; - struct Elf32_Sym *symbol; + elf_sym *symbol; status_t status = B_OK; TRACE(("get_image_symbol(%s)\n", name)); @@ -1587,7 +1599,7 @@ elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress, const char **_symbolName, const char **_imageName, bool *_exactMatch) { struct elf_image_info *image; - struct Elf32_Sym *symbolFound = NULL; + elf_sym *symbolFound = NULL; const char *symbolName = NULL; addr_t deltaFound = INT_MAX; bool exactMatch = false; @@ -1617,7 +1629,7 @@ elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress, TRACE((" searching debug symbols...\n")); for (i = 0; i < image->num_debug_symbols; i++) { - struct Elf32_Sym *symbol = &image->debug_symbols[i]; + elf_sym *symbol = &image->debug_symbols[i]; if (symbol->st_value == 0 || symbol->st_size >= image->text_region.size + image->data_region.size) @@ -1645,7 +1657,7 @@ elf_debug_lookup_symbol_address(addr_t address, addr_t *_baseAddress, for (i = 0; i < HASHTABSIZE(image); i++) { for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) { - struct Elf32_Sym *symbol = &image->syms[j]; + elf_sym *symbol = &image->syms[j]; if (symbol->st_value == 0 || symbol->st_size >= image->text_region.size @@ -1746,7 +1758,7 @@ elf_debug_lookup_symbol(const char* searchName) if (image->num_debug_symbols > 0) { // search extended debug symbol table (contains static symbols) for (uint32 i = 0; i < image->num_debug_symbols; i++) { - struct Elf32_Sym *symbol = &image->debug_symbols[i]; + elf_sym *symbol = &image->debug_symbols[i]; const char *name = image->debug_string_table + symbol->st_name; if (symbol->st_value > 0 && !strcmp(name, searchName)) @@ -1757,7 +1769,7 @@ elf_debug_lookup_symbol(const char* searchName) for (uint32 i = 0; i < HASHTABSIZE(image); i++) { for (uint32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) { - struct Elf32_Sym *symbol = &image->syms[j]; + elf_sym *symbol = &image->syms[j]; const char *name = SYMNAME(image, symbol); if (symbol->st_value > 0 && !strcmp(name, searchName)) @@ -1776,7 +1788,7 @@ status_t elf_lookup_kernel_symbol(const char* name, elf_symbol_info* info) { // find the symbol - Elf32_Sym* foundSymbol = elf_find_symbol(sKernelImage, name, NULL, false); + elf_sym* foundSymbol = elf_find_symbol(sKernelImage, name, NULL, false); if (foundSymbol == NULL) return B_MISSING_SYMBOL; @@ -1789,8 +1801,8 @@ elf_lookup_kernel_symbol(const char* name, elf_symbol_info* info) status_t elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) { - struct Elf32_Ehdr elfHeader; - struct Elf32_Phdr *programHeaders = NULL; + elf_ehdr elfHeader; + elf_phdr *programHeaders = NULL; char baseName[B_OS_NAME_LENGTH]; status_t status; ssize_t length; @@ -1827,7 +1839,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) // read program header - programHeaders = (struct Elf32_Phdr *)malloc( + programHeaders = (elf_phdr *)malloc( elfHeader.e_phnum * elfHeader.e_phentsize); if (programHeaders == NULL) { dprintf("error allocating space for program headers\n"); @@ -1884,9 +1896,9 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) B_PAGE_SIZE); if (programHeaders[i].p_flags & PF_WRITE) { // rw/data segment - uint32 memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) + size_t memUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) + programHeaders[i].p_memsz; - uint32 fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) + size_t fileUpperBound = (programHeaders[i].p_vaddr % B_PAGE_SIZE) + programHeaders[i].p_filesz; memUpperBound = ROUNDUP(memUpperBound, B_PAGE_SIZE); @@ -1909,10 +1921,10 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry) // clean garbage brought by mmap (the region behind the file, // at least parts of it are the bss and have to be zeroed) - uint32 start = (uint32)regionAddress + addr_t start = (addr_t)regionAddress + (programHeaders[i].p_vaddr % B_PAGE_SIZE) + programHeaders[i].p_filesz; - uint32 amount = fileUpperBound + size_t amount = fileUpperBound - (programHeaders[i].p_vaddr % B_PAGE_SIZE) - (programHeaders[i].p_filesz); memset((void *)start, 0, amount); @@ -1994,8 +2006,8 @@ error: image_id load_kernel_add_on(const char *path) { - struct Elf32_Phdr *programHeaders; - struct Elf32_Ehdr *elfHeader; + elf_phdr *programHeaders; + elf_ehdr *elfHeader; struct elf_image_info *image; const char *fileName; void *reservedAddress; @@ -2033,7 +2045,7 @@ load_kernel_add_on(const char *path) goto done; } - elfHeader = (struct Elf32_Ehdr *)malloc(sizeof(*elfHeader)); + elfHeader = (elf_ehdr *)malloc(sizeof(*elfHeader)); if (!elfHeader) { status = B_NO_MEMORY; goto error; @@ -2063,7 +2075,7 @@ load_kernel_add_on(const char *path) image->name = strdup(path); vnode = NULL; - programHeaders = (struct Elf32_Phdr *)malloc(elfHeader->e_phnum + programHeaders = (elf_phdr *)malloc(elfHeader->e_phnum * elfHeader->e_phentsize); if (programHeaders == NULL) { dprintf("%s: error allocating space for program headers\n", fileName); @@ -2131,7 +2143,7 @@ load_kernel_add_on(const char *path) char regionName[B_OS_NAME_LENGTH]; elf_region *region; - TRACE(("looking at program header %ld\n", i)); + TRACE(("looking at program header %" B_PRId32 "\n", i)); switch (programHeaders[i].p_type) { case PT_LOAD: @@ -2140,7 +2152,7 @@ load_kernel_add_on(const char *path) image->dynamic_section = programHeaders[i].p_vaddr; continue; default: - dprintf("%s: unhandled pheader type 0x%lx\n", fileName, + dprintf("%s: unhandled pheader type %#" B_PRIx32 "\n", fileName, programHeaders[i].p_type); continue; } @@ -2177,7 +2189,7 @@ load_kernel_add_on(const char *path) textSectionWritable = programHeaders[i].IsReadWrite(); snprintf(regionName, B_OS_NAME_LENGTH, "%s_text", fileName); } else { - dprintf("%s: weird program header flags 0x%lx\n", fileName, + dprintf("%s: weird program header flags %#" B_PRIx32 "\n", fileName, programHeaders[i].p_flags); continue; } @@ -2205,7 +2217,8 @@ load_kernel_add_on(const char *path) programHeaders[i].p_filesz); if (length < B_OK) { status = length; - dprintf("%s: error reading in segment %ld\n", fileName, i); + dprintf("%s: error reading in segment %" B_PRId32 "\n", fileName, + i); goto error5; } } @@ -2347,7 +2360,7 @@ elf_create_memory_image(const char* imageName, addr_t text, size_t textSize, // allocate symbol and string tables -- we allocate an empty symbol table, // so that elf_debug_lookup_symbol_address() won't try the dynamic symbol // table, which we don't have. - Elf32_Sym* symbolTable = (Elf32_Sym*)malloc(0); + elf_sym* symbolTable = (elf_sym*)malloc(0); char* stringTable = (char*)malloc(1); MemoryDeleter symbolTableDeleter(symbolTable); MemoryDeleter stringTableDeleter(stringTable); @@ -2432,19 +2445,19 @@ elf_add_memory_image_symbol(image_id id, const char* name, addr_t address, // resize the symbol table int32 symbolCount = image->num_debug_symbols + 1; - Elf32_Sym* symbolTable = (Elf32_Sym*)realloc( - (Elf32_Sym*)image->debug_symbols, sizeof(Elf32_Sym) * symbolCount); + elf_sym* symbolTable = (elf_sym*)realloc( + (elf_sym*)image->debug_symbols, sizeof(elf_sym) * symbolCount); if (symbolTable == NULL) return B_NO_MEMORY; image->debug_symbols = symbolTable; // enter the symbol - Elf32_Sym& symbol = symbolTable[symbolCount - 1]; - uint32 symbolType = type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC; + elf_sym& symbol = symbolTable[symbolCount - 1]; + symbol.SetInfo(STB_GLOBAL, + type == B_SYMBOL_TYPE_DATA ? STT_OBJECT : STT_FUNC); symbol.st_name = stringIndex; symbol.st_value = address; symbol.st_size = size; - symbol.st_info = ELF32_ST_INFO(STB_GLOBAL, symbolType); symbol.st_other = 0; symbol.st_shndx = 0; image->num_debug_symbols++; @@ -2466,12 +2479,15 @@ elf_init(kernel_args *args) // Build a image structure for the kernel, which has already been loaded. // The preloaded_images were already prepared by the VM. - if (insert_preloaded_image(&args->kernel_image, true) < B_OK) + image = args->kernel_image; + if (insert_preloaded_image(static_cast(image), + true) < B_OK) panic("could not create kernel image.\n"); // Build image structures for all preloaded images. for (image = args->preloaded_images; image != NULL; image = image->next) - insert_preloaded_image(image, false); + insert_preloaded_image(static_cast(image), + false); add_debugger_command("ls", &dump_address_info, "lookup symbol for a particular address"); @@ -2501,7 +2517,7 @@ elf_init(kernel_args *args) values in the table to get the actual symbol addresses. */ status_t -_user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable, +_user_read_kernel_image_symbols(image_id id, elf_sym* symbolTable, int32* _symbolCount, char* stringTable, size_t* _stringTableSize, addr_t* _imageDelta) { @@ -2533,7 +2549,7 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable, // get the tables and infos addr_t imageDelta = image->text_region.delta; - const Elf32_Sym* symbols; + const elf_sym* symbols; int32 symbolCount; const char* strings; @@ -2561,7 +2577,7 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable, // copy symbol table int32 symbolsToCopy = min_c(symbolCount, maxSymbolCount); if (symbolTable != NULL && symbolsToCopy > 0) { - if (user_memcpy(symbolTable, symbols, sizeof(Elf32_Sym) * symbolsToCopy) + if (user_memcpy(symbolTable, symbols, sizeof(elf_sym) * symbolsToCopy) != B_OK) { return B_BAD_ADDRESS; } diff --git a/src/system/kernel/fs/socket.cpp b/src/system/kernel/fs/socket.cpp index 4a3e416c4c..2aca98763b 100644 --- a/src/system/kernel/fs/socket.cpp +++ b/src/system/kernel/fs/socket.cpp @@ -243,7 +243,7 @@ socket_write(struct file_descriptor *descriptor, off_t pos, const void *buffer, static status_t -socket_ioctl(struct file_descriptor *descriptor, uint32 op, void *buffer, +socket_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer, size_t length) { return sStackInterface->ioctl(descriptor->u.socket, op, buffer, length); diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 6737a3046c..ace23089f2 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -320,7 +320,7 @@ static status_t query_rewind(struct file_descriptor* descriptor); static void query_free_fd(struct file_descriptor* descriptor); static status_t query_close(struct file_descriptor* descriptor); -static status_t common_ioctl(struct file_descriptor* descriptor, uint32 op, +static status_t common_ioctl(struct file_descriptor* descriptor, ulong op, void* buffer, size_t length); static status_t common_read_stat(struct file_descriptor* descriptor, struct stat* statData); @@ -1135,8 +1135,8 @@ restart: rw_lock_read_unlock(&sVnodeLock); if (!canWait || --tries < 0) { // vnode doesn't seem to become unbusy - dprintf("vnode %ld:%Ld is not becoming unbusy!\n", mountID, - vnodeID); + dprintf("vnode %" B_PRIdDEV ":%" B_PRIdINO " is not becoming unbusy!\n", + mountID, vnodeID); return B_BUSY; } snooze(5000); // 5 ms @@ -1930,8 +1930,8 @@ get_root_vnode(bool kernel) return root; // That should never happen. - dprintf("get_root_vnode(): IO context for team %ld doesn't have a " - "root\n", team_get_current_team_id()); + dprintf("get_root_vnode(): IO context for team %" B_PRId32 " doesn't " + "have a root\n", team_get_current_team_id()); } inc_vnode_ref_count(sRoot); @@ -2088,8 +2088,8 @@ lookup_dir_entry(struct vnode* dir, const char* name, struct vnode** _vnode) rw_lock_read_unlock(&sVnodeLock); if (*_vnode == NULL) { - panic("lookup_dir_entry(): could not lookup vnode (mountid 0x%lx vnid " - "0x%Lx)\n", dir->device, id); + panic("lookup_dir_entry(): could not lookup vnode (mountid 0x%" B_PRIx32 + " vnid 0x%" B_PRIx64 ")\n", dir->device, id); return B_ENTRY_NOT_FOUND; } @@ -2952,17 +2952,17 @@ _dump_advisory_locking(advisory_locking* locking) if (locking == NULL) return; - kprintf(" lock: %ld", locking->lock); - kprintf(" wait_sem: %ld", locking->wait_sem); + kprintf(" lock: %" B_PRId32, locking->lock); + kprintf(" wait_sem: %" B_PRId32, locking->wait_sem); int32 index = 0; LockList::Iterator iterator = locking->locks.GetIterator(); while (iterator.HasNext()) { struct advisory_lock* lock = iterator.Next(); - kprintf(" [%2ld] team: %ld\n", index++, lock->team); - kprintf(" start: %Ld\n", lock->start); - kprintf(" end: %Ld\n", lock->end); + kprintf(" [%2" B_PRId32 "] team: %" B_PRId32 "\n", index++, lock->team); + kprintf(" start: %" B_PRIdOFF "\n", lock->start); + kprintf(" end: %" B_PRIdOFF "\n", lock->end); kprintf(" shared? %s\n", lock->shared ? "yes" : "no"); } } @@ -2972,7 +2972,7 @@ static void _dump_mount(struct fs_mount* mount) { kprintf("MOUNT: %p\n", mount); - kprintf(" id: %ld\n", mount->id); + kprintf(" id: %" B_PRIdDEV "\n", mount->id); kprintf(" device_name: %s\n", mount->device_name); kprintf(" root_vnode: %p\n", mount->root_vnode); kprintf(" covers: %p\n", mount->root_vnode->covers); @@ -2984,7 +2984,7 @@ _dump_mount(struct fs_mount* mount) fs_volume* volume = mount->volume; while (volume != NULL) { kprintf(" volume %p:\n", volume); - kprintf(" layer: %ld\n", volume->layer); + kprintf(" layer: %" B_PRId32 "\n", volume->layer); kprintf(" private_volume: %p\n", volume->private_volume); kprintf(" ops: %p\n", volume->ops); kprintf(" file_system: %p\n", volume->file_system); @@ -3098,9 +3098,9 @@ static void _dump_vnode(struct vnode* vnode, bool printPath) { kprintf("VNODE: %p\n", vnode); - kprintf(" device: %ld\n", vnode->device); - kprintf(" id: %Ld\n", vnode->id); - kprintf(" ref_count: %ld\n", vnode->ref_count); + kprintf(" device: %" B_PRIdDEV "\n", vnode->device); + kprintf(" id: %" B_PRIdINO "\n", vnode->id); + kprintf(" ref_count: %" B_PRId32 "\n", vnode->ref_count); kprintf(" private_node: %p\n", vnode->private_node); kprintf(" mount: %p\n", vnode->mount); kprintf(" covered_by: %p\n", vnode->covered_by); @@ -3149,16 +3149,16 @@ dump_mount(int argc, char** argv) return 0; } - uint32 id = parse_expression(argv[1]); - struct fs_mount* mount = NULL; + ulong val = parse_expression(argv[1]); + uint32 id = val; - mount = (fs_mount*)hash_lookup(sMountsTable, (void*)&id); + struct fs_mount* mount = (fs_mount*)hash_lookup(sMountsTable, (void*)&id); if (mount == NULL) { if (IS_USER_ADDRESS(id)) { kprintf("fs_mount not found\n"); return 0; } - mount = (fs_mount*)id; + mount = (fs_mount*)val; } _dump_mount(mount); @@ -3174,7 +3174,9 @@ dump_mounts(int argc, char** argv) return 0; } - kprintf("address id root covers cookie fs_name\n"); + kprintf("%-*s id %-*s %-*s %-*s fs_name\n", + B_PRINTF_POINTER_WIDTH, "address", B_PRINTF_POINTER_WIDTH, "root", + B_PRINTF_POINTER_WIDTH, "covers", B_PRINTF_POINTER_WIDTH, "cookie"); struct hash_iterator iterator; struct fs_mount* mount; @@ -3182,7 +3184,7 @@ dump_mounts(int argc, char** argv) hash_open(sMountsTable, &iterator); while ((mount = (struct fs_mount*)hash_next(sMountsTable, &iterator)) != NULL) { - kprintf("%p%4ld %p %p %p %s\n", mount, mount->id, mount->root_vnode, + kprintf("%p%4" B_PRIdDEV " %p %p %p %s\n", mount, mount->id, mount->root_vnode, mount->root_vnode->covers, mount->volume->private_volume, mount->volume->file_system_name); @@ -3257,18 +3259,20 @@ dump_vnodes(int argc, char** argv) struct hash_iterator iterator; struct vnode* vnode; - kprintf("address dev inode ref cache fs-node locking " - "flags\n"); + kprintf("%-*s dev inode ref %-*s %-*s %-*s flags\n", + B_PRINTF_POINTER_WIDTH, "address", B_PRINTF_POINTER_WIDTH, "cache", + B_PRINTF_POINTER_WIDTH, "fs-node", B_PRINTF_POINTER_WIDTH, "locking"); hash_open(sVnodeTable, &iterator); while ((vnode = (struct vnode*)hash_next(sVnodeTable, &iterator)) != NULL) { if (vnode->device != device) continue; - kprintf("%p%4ld%10Ld%5ld %p %p %p %s%s%s\n", vnode, vnode->device, - vnode->id, vnode->ref_count, vnode->cache, vnode->private_node, - vnode->advisory_locking, vnode->IsRemoved() ? "r" : "-", - vnode->IsBusy() ? "b" : "-", vnode->IsUnpublished() ? "u" : "-"); + kprintf("%p%4" B_PRIdDEV "%10" B_PRIdINO "%5" B_PRId32 " %p %p %p %s%s%s\n", + vnode, vnode->device, vnode->id, vnode->ref_count, vnode->cache, + vnode->private_node, vnode->advisory_locking, + vnode->IsRemoved() ? "r" : "-", vnode->IsBusy() ? "b" : "-", + vnode->IsUnpublished() ? "u" : "-"); } hash_close(sVnodeTable, &iterator, false); @@ -3292,7 +3296,8 @@ dump_vnode_caches(int argc, char** argv) if (argc > 1) device = parse_expression(argv[1]); - kprintf("address dev inode cache size pages\n"); + kprintf("%-*s dev inode %-*s size pages\n", + B_PRINTF_POINTER_WIDTH, "address", B_PRINTF_POINTER_WIDTH, "cache"); hash_open(sVnodeTable, &iterator); while ((vnode = (struct vnode*)hash_next(sVnodeTable, &iterator)) != NULL) { @@ -3301,9 +3306,10 @@ dump_vnode_caches(int argc, char** argv) if (device != -1 && vnode->device != device) continue; - kprintf("%p%4ld%10Ld %p %8Ld%8ld\n", vnode, vnode->device, vnode->id, - vnode->cache, (vnode->cache->virtual_end + B_PAGE_SIZE - 1) - / B_PAGE_SIZE, vnode->cache->page_count); + kprintf("%p%4" B_PRIdDEV "%10" B_PRIdINO " %p %8" B_PRIdOFF "%8" B_PRId32 "\n", + vnode, vnode->device, vnode->id, vnode->cache, + (vnode->cache->virtual_end + B_PAGE_SIZE - 1) / B_PAGE_SIZE, + vnode->cache->page_count); } hash_close(sVnodeTable, &iterator, false); @@ -3322,13 +3328,13 @@ dump_io_context(int argc, char** argv) struct io_context* context = NULL; if (argc > 1) { - uint32 num = parse_expression(argv[1]); + ulong num = parse_expression(argv[1]); if (IS_KERNEL_ADDRESS(num)) context = (struct io_context*)num; else { Team* team = team_get_team_struct_locked(num); if (team == NULL) { - kprintf("could not find team with ID %ld\n", num); + kprintf("could not find team with ID %lu\n", num); return 0; } context = (struct io_context*)team->io_context; @@ -3339,12 +3345,13 @@ dump_io_context(int argc, char** argv) kprintf("I/O CONTEXT: %p\n", context); kprintf(" root vnode:\t%p\n", context->root); kprintf(" cwd vnode:\t%p\n", context->cwd); - kprintf(" used fds:\t%lu\n", context->num_used_fds); - kprintf(" max fds:\t%lu\n", context->table_size); + kprintf(" used fds:\t%" B_PRIu32 "\n", context->num_used_fds); + kprintf(" max fds:\t%" B_PRIu32 "\n", context->table_size); - if (context->num_used_fds) - kprintf(" no. type ops ref open mode pos" - " cookie\n"); + if (context->num_used_fds) { + kprintf(" no. type %*s ref open mode pos %*s\n", + B_PRINTF_POINTER_WIDTH, "ops", B_PRINTF_POINTER_WIDTH, "cookie"); + } for (uint32 i = 0; i < context->table_size; i++) { struct file_descriptor* fd = context->fds[i]; @@ -3360,8 +3367,8 @@ dump_io_context(int argc, char** argv) fd->u.vnode); } - kprintf(" used monitors:\t%lu\n", context->num_monitors); - kprintf(" max monitors:\t%lu\n", context->max_monitors); + kprintf(" used monitors:\t%" B_PRIu32 "\n", context->num_monitors); + kprintf(" max monitors:\t%" B_PRIu32 "\n", context->max_monitors); set_debug_variable("_cwd", (addr_t)context->cwd); @@ -3377,8 +3384,8 @@ dump_vnode_usage(int argc, char** argv) return 0; } - kprintf("Unused vnodes: %ld (max unused %ld)\n", sUnusedVnodes, - kMaxUnusedVnodes); + kprintf("Unused vnodes: %" B_PRIu32 " (max unused %" B_PRIu32 ")\n", + sUnusedVnodes, kMaxUnusedVnodes); struct hash_iterator iterator; hash_open(sVnodeTable, &iterator); @@ -3391,7 +3398,8 @@ dump_vnode_usage(int argc, char** argv) hash_close(sVnodeTable, &iterator, false); - kprintf("%lu vnodes total (%ld in use).\n", count, count - sUnusedVnodes); + kprintf("%" B_PRIu32 " vnodes total (%" B_PRIu32 " in use).\n", count, + count - sUnusedVnodes); return 0; } @@ -3449,7 +3457,7 @@ common_file_io_vec_pages(struct vnode* vnode, void* cookie, // now directly read the data from the device // the first file_io_vec can be read directly - if (fileVecs[0].length < numBytes) + if (fileVecs[0].length < (off_t)numBytes) size = fileVecs[0].length; else size = numBytes; @@ -3469,20 +3477,20 @@ common_file_io_vec_pages(struct vnode* vnode, void* cookie, // a) also use this direct I/O for writes (otherwise, it would // overwrite precious data) // b) panic if the term below is true (at least for writes) - if (size > fileVecs[0].length) { + if ((off_t)size > fileVecs[0].length) { //dprintf("warning: device driver %p doesn't respect total length " // "in read_pages() call!\n", ref->device); size = fileVecs[0].length; } - ASSERT(size <= fileVecs[0].length); + ASSERT((off_t)size <= fileVecs[0].length); // If the file portion was contiguous, we're already done now if (size == numBytes) return B_OK; // if we reached the end of the file, we can return as well - if (size != fileVecs[0].length) { + if ((off_t)size != fileVecs[0].length) { *_numBytes = size; return B_OK; } @@ -3525,7 +3533,7 @@ common_file_io_vec_pages(struct vnode* vnode, void* cookie, size = 0; // assign what is left of the current fileVec to the tempVecs - for (size = 0; size < fileLeft && vecIndex < vecCount + for (size = 0; (off_t)size < fileLeft && vecIndex < vecCount && tempCount < MAX_TEMP_IO_VECS;) { // try to satisfy one iovec per iteration (or as much as // possible) @@ -3622,8 +3630,9 @@ new_vnode(fs_volume* volume, ino_t vnodeID, void* privateNode, // file system integrity check: // test if the vnode already exists and bail out if this is the case! if (!nodeCreated) { - panic("vnode %ld:%Ld already exists (node = %p, vnode->node = %p)!", - volume->id, vnodeID, privateNode, vnode->private_node); + panic("vnode %" B_PRIdDEV ":%" B_PRIdINO " already exists (node = %p, " + "vnode->node = %p)!", volume->id, vnodeID, privateNode, + vnode->private_node); return B_ERROR; } @@ -5275,7 +5284,7 @@ create_vnode(struct vnode* directory, const char* name, int openMode, if (vnode == NULL) { panic("vfs: fs_create() returned success but there is no vnode, " - "mount ID %ld!\n", directory->device); + "mount ID %" B_PRIdDEV "!\n", directory->device); return B_BAD_VALUE; } @@ -5895,7 +5904,7 @@ dir_remove(int fd, char* path, bool kernel) static status_t -common_ioctl(struct file_descriptor* descriptor, uint32 op, void* buffer, +common_ioctl(struct file_descriptor* descriptor, ulong op, void* buffer, size_t length) { struct vnode* vnode = descriptor->u.vnode; @@ -5908,7 +5917,7 @@ common_ioctl(struct file_descriptor* descriptor, uint32 op, void* buffer, static status_t -common_fcntl(int fd, int op, uint32 argument, bool kernel) +common_fcntl(int fd, int op, size_t argument, bool kernel) { struct flock flock; @@ -7924,7 +7933,7 @@ _kern_sync(void) while ((device = next_dev(&cookie)) >= 0) { status_t status = fs_sync(device); if (status != B_OK && status != B_BAD_VALUE) { - dprintf("sync: device %ld couldn't sync: %s\n", device, + dprintf("sync: device %" B_PRIdDEV " couldn't sync: %s\n", device, strerror(status)); } } @@ -8076,7 +8085,7 @@ _kern_open_dir(int fd, const char* path) status_t -_kern_fcntl(int fd, int op, uint32 argument) +_kern_fcntl(int fd, int op, size_t argument) { return common_fcntl(fd, op, argument, true); } @@ -8890,7 +8899,7 @@ _user_open_parent_dir(int fd, char* userName, size_t nameLength) status_t -_user_fcntl(int fd, int op, uint32 argument) +_user_fcntl(int fd, int op, size_t argument) { status_t status = common_fcntl(fd, op, argument, false); if (op == F_SETLKW) @@ -9216,8 +9225,8 @@ _user_create_pipe(int* userFDs) status = get_vnode(sRoot->mount->id, nodeID, &vnode, true, false); if (status != B_OK) { // that should not happen - dprintf("_user_create_pipe(): Failed to lookup vnode (%ld, %lld)\n", - sRoot->mount->id, sRoot->id); + dprintf("_user_create_pipe(): Failed to lookup vnode (%" B_PRIdDEV ", " + "%" B_PRIdINO ")\n", sRoot->mount->id, sRoot->id); return status; } diff --git a/src/system/kernel/fs/vfs_boot.cpp b/src/system/kernel/fs/vfs_boot.cpp index 7d4feecc76..3361217a76 100644 --- a/src/system/kernel/fs/vfs_boot.cpp +++ b/src/system/kernel/fs/vfs_boot.cpp @@ -194,8 +194,8 @@ DiskBootMethod::IsBootDevice(KDiskDevice* device, bool strict) return false; } - TRACE(("boot device: bus %ld, device %ld\n", disk->bus_type, - disk->device_type)); + TRACE(("boot device: bus %" B_PRId32 ", device %" B_PRId32 "\n", + disk->bus_type, disk->device_type)); // Assume that CD boots only happen off removable media. if (fMethod == BOOT_METHOD_CD && !device->IsRemovable()) @@ -320,16 +320,15 @@ DiskBootMethod::SortPartitions(KPartition** partitions, int32 count) The boot code should then just try them one by one. */ static status_t -get_boot_partitions(kernel_args* args, PartitionStack& partitions) +get_boot_partitions(KMessage& bootVolume, PartitionStack& partitions) { - const KMessage& bootVolume = args->boot_volume; - dprintf("get_boot_partitions(): boot volume message:\n"); bootVolume.Dump(&dprintf); // create boot method int32 bootMethodType = bootVolume.GetInt32(BOOT_METHOD, BOOT_METHOD_DEFAULT); - dprintf("get_boot_partitions(): boot method type: %ld\n", bootMethodType); + dprintf("get_boot_partitions(): boot method type: %" B_PRId32 "\n", + bootMethodType); BootMethod* bootMethod = NULL; switch (bootMethodType) { @@ -414,7 +413,7 @@ get_boot_partitions(kernel_args* args, PartitionStack& partitions) // sort partition list (e.g.. when booting from CD, CDs should come first in // the list) - if (!args->boot_volume.GetBool(BOOT_VOLUME_USER_SELECTED, false)) + if (!bootVolume.GetBool(BOOT_VOLUME_USER_SELECTED, false)) bootMethod->SortPartitions(partitions.Array(), partitions.CountItems()); return B_OK; @@ -460,8 +459,11 @@ vfs_bootstrap_file_systems(void) void vfs_mount_boot_file_system(kernel_args* args) { + KMessage bootVolume; + bootVolume.SetTo(args->boot_volume, args->boot_volume_size); + PartitionStack partitions; - status_t status = get_boot_partitions(args, partitions); + status_t status = get_boot_partitions(bootVolume, partitions); if (status < B_OK) { panic("get_boot_partitions failed!"); } @@ -512,8 +514,7 @@ vfs_mount_boot_file_system(kernel_args* args) // whether the module images the boot loader has pre-loaded are the same as // on the boot volume. That is the case when booting from hard disk or CD, // but not via network. - int32 bootMethodType = args->boot_volume.GetInt32(BOOT_METHOD, - BOOT_METHOD_DEFAULT); + int32 bootMethodType = bootVolume.GetInt32(BOOT_METHOD, BOOT_METHOD_DEFAULT); bool bootingFromBootLoaderVolume = bootMethodType == BOOT_METHOD_HARD_DISK || bootMethodType == BOOT_METHOD_CD; module_init_post_boot_device(bootingFromBootLoaderVolume); diff --git a/src/system/kernel/fs/vfs_request_io.cpp b/src/system/kernel/fs/vfs_request_io.cpp index 677c554ac0..afa5b0659b 100644 --- a/src/system/kernel/fs/vfs_request_io.cpp +++ b/src/system/kernel/fs/vfs_request_io.cpp @@ -140,7 +140,7 @@ do_iterative_fd_io_iterate(void* _cookie, io_request* request, TRACE_RIO("[%ld] do_iterative_fd_io_iterate(request: %p)\n", find_thread(NULL), request); - static const int32 kMaxSubRequests = 8; + static const size_t kMaxSubRequests = 8; iterative_io_cookie* cookie = (iterative_io_cookie*)_cookie; @@ -152,7 +152,7 @@ do_iterative_fd_io_iterate(void* _cookie, io_request* request, // get the next file vecs file_io_vec vecs[kMaxSubRequests]; - uint32 vecCount = kMaxSubRequests; + size_t vecCount = kMaxSubRequests; status_t error = cookie->get_vecs(cookie->cookie, request, requestOffset, requestLength, vecs, &vecCount); if (error != B_OK && error != B_BUFFER_OVERFLOW) @@ -161,11 +161,11 @@ do_iterative_fd_io_iterate(void* _cookie, io_request* request, *_partialTransfer = true; return B_OK; } - TRACE_RIO("[%ld] got %lu file vecs\n", find_thread(NULL), vecCount); + TRACE_RIO("[%ld] got %zu file vecs\n", find_thread(NULL), vecCount); // create subrequests for the file vecs we've got - int32 subRequestCount = 0; - for (uint32 i = 0; i < vecCount && subRequestCount < kMaxSubRequests; i++) { + size_t subRequestCount = 0; + for (size_t i = 0; i < vecCount && subRequestCount < kMaxSubRequests; i++) { off_t vecOffset = vecs[i].offset; off_t vecLength = min_c(vecs[i].length, requestLength); TRACE_RIO("[%ld] vec %lu offset: %lld, length: %lld\n", @@ -270,13 +270,13 @@ do_synchronous_iterative_vnode_io(struct vnode* vnode, void* openCookie, while (error == B_OK && vecLength > 0) { file_io_vec fileVecs[8]; - uint32 fileVecCount = 8; + size_t fileVecCount = 8; error = getVecs(cookie, request, offset, vecLength, fileVecs, &fileVecCount); if (error != B_OK || fileVecCount == 0) break; - for (uint32 i = 0; i < fileVecCount; i++) { + for (size_t i = 0; i < fileVecCount; i++) { const file_io_vec& fileVec = fileVecs[i]; size_t toTransfer = min_c(fileVec.length, (off_t)length); size_t transferred = toTransfer; diff --git a/src/system/kernel/heap.cpp b/src/system/kernel/heap.cpp index 38c4dea880..a2815bff6a 100644 --- a/src/system/kernel/heap.cpp +++ b/src/system/kernel/heap.cpp @@ -313,8 +313,9 @@ dump_page(heap_page *page) count++; kprintf("\t\tpage %p: bin_index: %u; free_count: %u; empty_index: %u; " - "free_list %p (%lu entr%s)\n", page, page->bin_index, page->free_count, - page->empty_index, page->free_list, count, count == 1 ? "y" : "ies"); + "free_list %p (%" B_PRIu32 " entr%s)\n", page, page->bin_index, + page->free_count, page->empty_index, page->free_list, count, + count == 1 ? "y" : "ies"); } @@ -325,8 +326,9 @@ dump_bin(heap_bin *bin) for (heap_page *page = bin->page_list; page != NULL; page = page->next) count++; - kprintf("\telement_size: %lu; max_free_count: %u; page_list %p (%lu pages" - ");\n", bin->element_size, bin->max_free_count, bin->page_list, count); + kprintf("\telement_size: %" B_PRIu32 "; max_free_count: %u; page_list %p " + "(%" B_PRIu32 " pages);\n", bin->element_size, bin->max_free_count, + bin->page_list, count); for (heap_page *page = bin->page_list; page != NULL; page = page->next) dump_page(page); @@ -347,10 +349,11 @@ dump_allocator_areas(heap_allocator *heap) { heap_area *area = heap->all_areas; while (area) { - kprintf("\tarea %p: area: %ld; base: 0x%08lx; size: %lu; page_count: " - "%lu; free_pages: %p (%lu entr%s)\n", area, area->area, area->base, - area->size, area->page_count, area->free_pages, - area->free_page_count, area->free_page_count == 1 ? "y" : "ies"); + kprintf("\tarea %p: area: %" B_PRId32 "; base: %p; size: %zu; page_count: " + "%" B_PRIu32 "; free_pages: %p (%" B_PRIu32 " entr%s)\n", area, + area->area, (void *)area->base, area->size, area->page_count, + area->free_pages, area->free_page_count, + area->free_page_count == 1 ? "y" : "ies"); area = area->all_next; } @@ -361,10 +364,11 @@ dump_allocator_areas(heap_allocator *heap) static void dump_allocator(heap_allocator *heap, bool areas, bool bins) { - kprintf("allocator %p: name: %s; page_size: %lu; bin_count: %lu; pages: " - "%lu; free_pages: %lu; empty_areas: %lu\n", heap, heap->name, - heap->page_size, heap->bin_count, heap->total_pages, - heap->total_free_pages, heap->empty_areas); + kprintf("allocator %p: name: %s; page_size: %" B_PRIu32 "; bin_count: " + "%" B_PRIu32 "; pages: %" B_PRIu32 "; free_pages: %" B_PRIu32 "; " + "empty_areas: %" B_PRIu32 "\n", heap, heap->name, heap->page_size, + heap->bin_count, heap->total_pages, heap->total_free_pages, + heap->empty_areas); if (areas) dump_allocator_areas(heap); @@ -481,8 +485,8 @@ dump_allocations(int argc, char **argv) continue; if (!statsOnly) { - kprintf("address: 0x%08lx; size: %lu bytes\n", - base, elementSize); + kprintf("address: 0x%p; size: %lu bytes\n", + (void *)base, elementSize); } totalSize += elementSize; @@ -502,7 +506,7 @@ dump_allocations(int argc, char **argv) size_t size = pageCount * heap->page_size; if (!statsOnly) { - kprintf("address: 0x%08lx; size: %lu bytes\n", base, + kprintf("address: %p; size: %lu bytes\n", (void *)base, size); } @@ -521,7 +525,7 @@ dump_allocations(int argc, char **argv) break; } - kprintf("total allocations: %lu; total bytes: %lu\n", totalCount, totalSize); + kprintf("total allocations: %" B_PRIu32 "; total bytes: %zu\n", totalCount, totalSize); return 0; } @@ -1096,9 +1100,9 @@ heap_add_area(heap_allocator *heap, area_id areaID, addr_t base, size_t size) pageLocker.Unlock(); areaWriteLocker.Unlock(); - dprintf("heap_add_area: area %ld added to %s heap %p - usable range 0x%08lx " - "- 0x%08lx\n", area->area, heap->name, heap, area->base, - area->base + area->size); + dprintf("heap_add_area: area %" B_PRId32 " added to %s heap %p - usable " + "range %p - %p\n", area->area, heap->name, heap, (void *)area->base, + (void *)(area->base + area->size)); } @@ -1142,9 +1146,9 @@ heap_remove_area(heap_allocator *heap, heap_area *area) heap->total_pages -= area->page_count; heap->total_free_pages -= area->free_page_count; - dprintf("heap_remove_area: area %ld with range 0x%08lx - 0x%08lx removed " - "from %s heap %p\n", area->area, area->base, area->base + area->size, - heap->name, heap); + dprintf("heap_remove_area: area %" B_PRId32 " with range %p - %p removed " + "from %s heap %p\n", area->area, (void *)area->base, + (void *)(area->base + area->size), heap->name, heap); return B_OK; } @@ -1659,7 +1663,7 @@ heap_free(heap_allocator *heap, void *address) if (((addr_t)address - area->base - page->index * heap->page_size) % bin->element_size != 0) { panic("free(): passed invalid pointer %p supposed to be in bin for " - "element size %ld\n", address, bin->element_size); + "element size %" B_PRIu32 "\n", address, bin->element_size); return B_ERROR; } diff --git a/src/system/kernel/image.cpp b/src/system/kernel/image.cpp index 05bd513f06..1de30f7c0a 100644 --- a/src/system/kernel/image.cpp +++ b/src/system/kernel/image.cpp @@ -254,21 +254,23 @@ dump_images_list(int argc, char **argv) team_id id = strtol(argv[1], NULL, 0); team = team_get_team_struct_locked(id); if (team == NULL) { - kprintf("No team with ID %ld found\n", id); + kprintf("No team with ID %" B_PRId32 " found\n", id); return 1; } } else team = thread_get_current_thread()->team; - kprintf("Registered images of team %ld\n", team->id); - kprintf(" ID text size data size name\n"); + kprintf("Registered images of team %" B_PRId32 "\n", team->id); + kprintf(" ID %-*s size %-*s size name\n", + B_PRINTF_POINTER_WIDTH, "text", B_PRINTF_POINTER_WIDTH, "data"); while ((image = (struct image*)list_get_next_item(&team->image_list, image)) != NULL) { image_info *info = &image->info; - kprintf("%6ld %p %-7ld %p %-7ld %s\n", info->id, info->text, info->text_size, - info->data, info->data_size, info->name); + kprintf("%6" B_PRId32 " %p %-7" B_PRId32 " %p %-7" B_PRId32 " %s\n", + info->id, info->text, info->text_size, info->data, info->data_size, + info->name); } return 0; @@ -417,8 +419,8 @@ _user_image_relocated(image_id id) // get an image info error = _get_image_info(id, &info, sizeof(image_info)); if (error != B_OK) { - dprintf("_user_image_relocated(%ld): Failed to get image info: %lx\n", - id, error); + dprintf("_user_image_relocated(%" B_PRId32 "): Failed to get image " + "info: %" B_PRIx32 "\n", id, error); return; } diff --git a/src/system/kernel/int.cpp b/src/system/kernel/int.cpp index d30b320cf2..9916e4b718 100644 --- a/src/system/kernel/int.cpp +++ b/src/system/kernel/int.cpp @@ -80,9 +80,9 @@ dump_int_statistics(int argc, char **argv) && sVectors[i].handler_list == NULL) continue; - kprintf("int %3d, enabled %ld, handled %8lld, unhandled %8lld%s%s\n", - i, sVectors[i].enable_count, sVectors[i].handled_count, - sVectors[i].unhandled_count, + kprintf("int %3d, enabled %" B_PRId32 ", handled %8" B_PRId64 ", " + "unhandled %8" B_PRId64 "%s%s\n", i, sVectors[i].enable_count, + sVectors[i].handled_count,sVectors[i].unhandled_count, B_SPINLOCK_IS_LOCKED(&sVectors[i].vector_lock) ? ", ACTIVE" : "", sVectors[i].handler_list == NULL ? ", no handler" : ""); @@ -106,7 +106,7 @@ dump_int_statistics(int argc, char **argv) if (io->no_handled_info) kprintf("\n"); else - kprintf("%8lld\n", io->handled_count); + kprintf("%8" B_PRId64 "\n", io->handled_count); } kprintf("\n"); diff --git a/src/system/kernel/lib/arch/x86_64/Jamfile b/src/system/kernel/lib/arch/x86_64/Jamfile new file mode 100644 index 0000000000..66f5fb864f --- /dev/null +++ b/src/system/kernel/lib/arch/x86_64/Jamfile @@ -0,0 +1,39 @@ +SubDir HAIKU_TOP src system kernel lib arch x86_64 ; + +# find the generated asm_offsets.h +SubDirHdrs [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR) system kernel arch + $(TARGET_KERNEL_ARCH) ] ; + +SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; + +local librootSources = [ FDirName $(HAIKU_TOP) src system libroot ] ; +local posixSources = [ FDirName $(librootSources) posix ] ; + +SEARCH_SOURCE += [ FDirName $(librootSources) os arch $(TARGET_ARCH) ] ; + +KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o : + atomic.S + byteorder.S + system_time_asm.S + system_time.c + + : $(TARGET_KERNEL_PIC_CCFLAGS) +; + +SEARCH_SOURCE += [ FDirName $(posixSources) arch $(TARGET_ARCH) ] ; + +KernelMergeObject kernel_lib_posix_arch_$(TARGET_ARCH).o : + siglongjmp.S + sigsetjmp.S + kernel_longjmp_return.c + kernel_setjmp_save_sigs.c + + arch_string.S + + : $(TARGET_KERNEL_PIC_CCFLAGS) +; + +# Explicitly tell the build system that arch_string.S includes the generated +# asm_offsets.h. +Includes [ FGristFiles arch_string.S ] + : asm_offsets.h ; diff --git a/src/system/kernel/lib/arch/x86_64/arch_string.S b/src/system/kernel/lib/arch/x86_64/arch_string.S new file mode 100644 index 0000000000..a24bbc8ff6 --- /dev/null +++ b/src/system/kernel/lib/arch/x86_64/arch_string.S @@ -0,0 +1,96 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include "asm_offsets.h" + + +.align 8 +FUNCTION(memcpy_generic): + push %rbp + movq %rsp, %rbp + + // Preserve original destination address for return value. + movq %rdi, %rax + + // size -> %rcx + movq %rdx, %rcx + + // For small copies, always do it bytewise, the additional overhead is + // not worth it. + cmp $24, %rcx + jl .Lmemcpy_generic_byte_copy + + // Do both source and dest have the same alignment? + movq %rsi, %r8 + xorq %rdi, %r8 + test $7, %r8 + jnz .Lmemcpy_generic_byte_copy + + // Align up to an 8-byte boundary. + movq %rdi, %r8 + andq $7, %r8 + jz .Lmemcpy_generic_qword_copy + movq $8, %rcx + subq %r8, %rcx + subq %rcx, %rdx // Subtract from the overall count. + rep + movsb + + // Get back the original count value. + movq %rdx, %rcx +.Lmemcpy_generic_qword_copy: + // Move by quadwords. + shrq $3, %rcx + rep + movsq + + // Get the remaining count. + movq %rdx, %rcx + andq $7, %rcx +.Lmemcpy_generic_byte_copy: + // Move any remaining data by bytes. + rep + movsb + + pop %rbp + ret +FUNCTION_END(memcpy_generic) +SYMBOL(memcpy_generic_end): + + +.align 8 +FUNCTION(memset_generic): + push %rbp + movq %rsp, %rbp + + // Preserve original destination address for return value. + movq %rdi, %r8 + + // size -> %rcx, value -> %al + movq %rdx, %rcx + movl %esi, %eax + + // Move by bytes. + rep + stosb + + movq %r8, %rax + pop %rbp + ret +FUNCTION_END(memset_generic) +SYMBOL(memset_generic_end): + + +FUNCTION(memcpy): + jmp *(gOptimizedFunctions + X86_OPTIMIZED_FUNCTIONS_memcpy) +FUNCTION_END(memcpy) + +FUNCTION(memset): + jmp *(gOptimizedFunctions + X86_OPTIMIZED_FUNCTIONS_memset) +FUNCTION_END(memset) + diff --git a/src/system/kernel/lib/kernel_vsprintf.cpp b/src/system/kernel/lib/kernel_vsprintf.cpp index 84c14109bb..25c275c54f 100644 --- a/src/system/kernel/lib/kernel_vsprintf.cpp +++ b/src/system/kernel/lib/kernel_vsprintf.cpp @@ -407,7 +407,7 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args) } outBuffer.PutString("0x", 2); - number(outBuffer, (uint32)va_arg(args, void *), 16, fieldWidth, + number(outBuffer, (addr_t)va_arg(args, void *), 16, fieldWidth, precision, flags); continue; @@ -450,11 +450,11 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args) } if (qualifier == 'L') - num = va_arg(args, uint64); + num = va_arg(args, unsigned long long); else if (qualifier == 'l') { - num = va_arg(args, uint32); + num = va_arg(args, unsigned long); if ((flags & SIGN) != 0) - num = (ssize_t)num; + num = (long)num; } else if (qualifier == 'z') { num = va_arg(args, size_t); if ((flags & SIGN) != 0) diff --git a/src/system/kernel/locks/lock.cpp b/src/system/kernel/locks/lock.cpp index 1cc5c358cf..fda4d321b6 100644 --- a/src/system/kernel/locks/lock.cpp +++ b/src/system/kernel/locks/lock.cpp @@ -535,17 +535,17 @@ dump_rw_lock_info(int argc, char** argv) kprintf("rw lock %p:\n", lock); kprintf(" name: %s\n", lock->name); - kprintf(" holder: %ld\n", lock->holder); - kprintf(" count: %#lx\n", lock->count); + kprintf(" holder: %" B_PRId32 "\n", lock->holder); + kprintf(" count: %#" B_PRIx32 "\n", lock->count); kprintf(" active readers %d\n", lock->active_readers); kprintf(" pending readers %d\n", lock->pending_readers); - kprintf(" owner count: %#lx\n", lock->owner_count); - kprintf(" flags: %#lx\n", lock->flags); + kprintf(" owner count: %#" B_PRIx32 "\n", lock->owner_count); + kprintf(" flags: %#" B_PRIx32 "\n", lock->flags); kprintf(" waiting threads:"); rw_lock_waiter* waiter = lock->waiters; while (waiter != NULL) { - kprintf(" %ld/%c", waiter->thread->id, waiter->writer ? 'w' : 'r'); + kprintf(" %" B_PRId32 "/%c", waiter->thread->id, waiter->writer ? 'w' : 'r'); waiter = waiter->next; } kputs("\n"); @@ -679,7 +679,7 @@ _mutex_lock(mutex* lock, bool schedulerLocked) lock->holder = thread_get_current_thread_id(); return B_OK; } else if (lock->holder == thread_get_current_thread_id()) { - panic("_mutex_lock(): double lock of %p by thread %ld", lock, + panic("_mutex_lock(): double lock of %p by thread %" B_PRId32, lock, lock->holder); } else if (lock->holder == 0) panic("_mutex_lock(): using unitialized lock %p", lock); @@ -723,9 +723,9 @@ _mutex_unlock(mutex* lock, bool schedulerLocked) #if KDEBUG if (thread_get_current_thread_id() != lock->holder) { - panic("_mutex_unlock() failure: thread %ld is trying to release " - "mutex %p (current holder %ld)\n", thread_get_current_thread_id(), - lock, lock->holder); + panic("_mutex_unlock() failure: thread %" B_PRId32 " is trying to " + "release mutex %p (current holder %" B_PRId32 ")\n", + thread_get_current_thread_id(), lock, lock->holder); return; } #else @@ -798,7 +798,7 @@ _mutex_lock_with_timeout(mutex* lock, uint32 timeoutFlags, bigtime_t timeout) lock->holder = thread_get_current_thread_id(); return B_OK; } else if (lock->holder == thread_get_current_thread_id()) { - panic("_mutex_lock(): double lock of %p by thread %ld", lock, + panic("_mutex_lock(): double lock of %p by thread %" B_PRId32, lock, lock->holder); } else if (lock->holder == 0) panic("_mutex_lock(): using unitialized lock %p", lock); @@ -889,7 +889,7 @@ dump_mutex_info(int argc, char** argv) kprintf(" name: %s\n", lock->name); kprintf(" flags: 0x%x\n", lock->flags); #if KDEBUG - kprintf(" holder: %ld\n", lock->holder); + kprintf(" holder: %" B_PRId32 "\n", lock->holder); #else kprintf(" count: %ld\n", lock->count); #endif @@ -897,7 +897,7 @@ dump_mutex_info(int argc, char** argv) kprintf(" waiting threads:"); mutex_waiter* waiter = lock->waiters; while (waiter != NULL) { - kprintf(" %ld", waiter->thread->id); + kprintf(" %" B_PRId32, waiter->thread->id); waiter = waiter->next; } kputs("\n"); diff --git a/src/system/kernel/low_resource_manager.cpp b/src/system/kernel/low_resource_manager.cpp index d64b675d71..55962db93d 100644 --- a/src/system/kernel/low_resource_manager.cpp +++ b/src/system/kernel/low_resource_manager.cpp @@ -59,9 +59,9 @@ static off_t sWarnMemoryLimit; static off_t sCriticalMemoryLimit; // address space limits -static const off_t kMinNoteSpaceLimit = 128 * 1024 * 1024; -static const off_t kMinWarnSpaceLimit = 64 * 1024 * 1024; -static const off_t kMinCriticalSpaceLimit = 32 * 1024 * 1024; +static const size_t kMinNoteSpaceLimit = 128 * 1024 * 1024; +static const size_t kMinWarnSpaceLimit = 64 * 1024 * 1024; +static const size_t kMinCriticalSpaceLimit = 32 * 1024 * 1024; static int32 sLowPagesState = B_NO_LOW_RESOURCE; @@ -310,8 +310,8 @@ dump_handlers(int argc, char** argv) handler->resources & B_KERNEL_RESOURCE_SEMAPHORES ? 's' : ' ', handler->resources & B_KERNEL_RESOURCE_ADDRESS_SPACE ? 'a' : ' '); - kprintf("%p %p %s %4ld %s\n", handler->function, handler->data, - resources, handler->priority, symbol); + kprintf("%p %p %s %4" B_PRId32 " %s\n", handler->function, + handler->data, resources, handler->priority, symbol); } return 0; diff --git a/src/system/kernel/main.cpp b/src/system/kernel/main.cpp index a5797d8940..6ce9648e39 100644 --- a/src/system/kernel/main.cpp +++ b/src/system/kernel/main.cpp @@ -361,7 +361,7 @@ main2(void *unused) resume_thread(thread); TRACE("Bootscript started\n"); } else - dprintf("error starting \"%s\" error = %ld \n", args[0], thread); + dprintf("error starting \"%s\" error = %" B_PRId32 " \n", args[0], thread); } return 0; diff --git a/src/system/kernel/module.cpp b/src/system/kernel/module.cpp index 0c0be15553..81039b84e3 100644 --- a/src/system/kernel/module.cpp +++ b/src/system/kernel/module.cpp @@ -457,7 +457,7 @@ unload_module_image(module_image* moduleImage, bool remove) ASSERT_LOCKED_RECURSIVE(&sModulesLock); if (moduleImage->ref_count != 0) { - FATAL(("Can't unload %s due to ref_cnt = %ld\n", moduleImage->path, + FATAL(("Can't unload %s due to ref_cnt = %" B_PRId32 "\n", moduleImage->path, moduleImage->ref_count)); return B_ERROR; } @@ -1100,7 +1100,7 @@ register_preloaded_module_image(struct preloaded_image* image) int32 index = 0; TRACE(("register_preloaded_module_image(image = %p, name = \"%s\")\n", - image, image->name)); + image, image->name.Pointer())); image->is_module = false; @@ -1172,8 +1172,8 @@ dump_modules(int argc, char** argv) while ((module = (struct module*)hash_next(sModulesHash, &iterator)) != NULL) { - kprintf("%p: \"%s\", \"%s\" (%ld), refcount = %ld, state = %d, " - "mimage = %p\n", module, module->name, + kprintf("%p: \"%s\", \"%s\" (%" B_PRId32 "), refcount = %" B_PRId32 ", " + "state = %d, mimage = %p\n", module, module->name, module->module_image ? module->module_image->path : "", module->offset, module->ref_count, module->state, module->module_image); @@ -1184,8 +1184,9 @@ dump_modules(int argc, char** argv) while ((image = (struct module_image*)hash_next(sModuleImagesHash, &iterator)) != NULL) { - kprintf("%p: \"%s\" (image_id = %ld), info = %p, refcount = %ld\n", - image, image->path, image->image, image->info, image->ref_count); + kprintf("%p: \"%s\" (image_id = %" B_PRId32 "), info = %p, refcount = " + "%" B_PRId32 "\n", image, image->path, image->image, image->info, + image->ref_count); } return 0; } @@ -1804,7 +1805,7 @@ module_init(kernel_args* args) for (image = args->preloaded_images; image != NULL; image = image->next) { status_t status = register_preloaded_module_image(image); if (status != B_OK && image->is_module) { - dprintf("Could not register image \"%s\": %s\n", image->name, + dprintf("Could not register image \"%s\": %s\n", (char *)image->name, strerror(status)); } } diff --git a/src/system/kernel/port.cpp b/src/system/kernel/port.cpp index fd66ec22af..26fb39d1e3 100644 --- a/src/system/kernel/port.cpp +++ b/src/system/kernel/port.cpp @@ -403,8 +403,9 @@ dump_port_list(int argc, char** argv) || (name != NULL && strstr(port->lock.name, name) == NULL)) continue; - kprintf("%p %8ld %4ld %9ld %9ld %8ld %6ld %s\n", port, - port->id, port->capacity, port->read_count, port->write_count, + kprintf("%p %8" B_PRId32 " %4" B_PRId32 " %9" B_PRIu32 " %9" B_PRId32 + " %8" B_PRId32 " %6" B_PRId32 " %s\n", port, port->id, + port->capacity, port->read_count, port->write_count, port->total_count, port->owner, port->lock.name); } @@ -416,20 +417,20 @@ static void _dump_port_info(Port* port) { kprintf("PORT: %p\n", port); - kprintf(" id: %ld\n", port->id); + kprintf(" id: %" B_PRId32 "\n", port->id); kprintf(" name: \"%s\"\n", port->lock.name); - kprintf(" owner: %ld\n", port->owner); - kprintf(" capacity: %ld\n", port->capacity); - kprintf(" read_count: %ld\n", port->read_count); - kprintf(" write_count: %ld\n", port->write_count); - kprintf(" total count: %ld\n", port->total_count); + kprintf(" owner: %" B_PRId32 "\n", port->owner); + kprintf(" capacity: %" B_PRId32 "\n", port->capacity); + kprintf(" read_count: %" B_PRIu32 "\n", port->read_count); + kprintf(" write_count: %" B_PRId32 "\n", port->write_count); + kprintf(" total count: %" B_PRId32 "\n", port->total_count); if (!port->messages.IsEmpty()) { kprintf("messages:\n"); MessageList::Iterator iterator = port->messages.GetIterator(); while (port_message* message = iterator.Next()) { - kprintf(" %p %08lx %ld\n", message, message->code, message->size); + kprintf(" %p %08" B_PRIx32 " %ld\n", message, message->code, message->size); } } @@ -463,7 +464,8 @@ dump_port_info(int argc, char** argv) int32 num = parse_expression(argv[1]); Port* port = sPorts.Lookup(num); if (port == NULL) { - kprintf("port %ld (%#lx) doesn't exist!\n", num, num); + kprintf("port %" B_PRId32 " (%#" B_PRIx32 ") doesn't exist!\n", + num, num); return 0; } _dump_port_info(port); @@ -1180,7 +1182,7 @@ _get_port_message_info_etc(port_id id, port_message_info* info, // determine tail & get the length of the message port_message* message = port->messages.Head(); if (message == NULL) { - panic("port %ld: no messages found\n", port->id); + panic("port %" B_PRId32 ": no messages found\n", port->id); return B_ERROR; } @@ -1289,7 +1291,7 @@ read_port_etc(port_id id, int32* _code, void* buffer, size_t bufferSize, // determine tail & get the length of the message port_message* message = port->messages.Head(); if (message == NULL) { - panic("port %ld: no messages found\n", port->id); + panic("port %" B_PRId32 ": no messages found\n", port->id); return B_ERROR; } diff --git a/src/system/kernel/posix/xsi_message_queue.cpp b/src/system/kernel/posix/xsi_message_queue.cpp index 67386657fb..278c241f67 100644 --- a/src/system/kernel/posix/xsi_message_queue.cpp +++ b/src/system/kernel/posix/xsi_message_queue.cpp @@ -775,8 +775,9 @@ _user_xsi_msgrcv(int messageQueueID, void *messagePointer, messageQueue = sMessageQueueHashTable.Lookup(messageQueueID); if (result == EIDRM || messageQueue == NULL || (messageQueue != NULL && sequenceNumber != messageQueue->SequenceNumber())) { - TRACE_ERROR(("xsi_msgrcv: message queue id %d (sequence = %ld) " - "got destroyed\n", messageQueueID, sequenceNumber)); + TRACE_ERROR(("xsi_msgrcv: message queue id %d (sequence = " + "%" B_PRIu32 ") got destroyed\n", messageQueueID, + sequenceNumber)); return EIDRM; } else if (result == B_INTERRUPTED) { TRACE_ERROR(("xsi_msgrcv: thread %d got interrupted while " @@ -881,8 +882,9 @@ _user_xsi_msgsnd(int messageQueueID, const void *messagePointer, messageQueue = sMessageQueueHashTable.Lookup(messageQueueID); if (result == EIDRM || messageQueue == NULL || (messageQueue != NULL && sequenceNumber != messageQueue->SequenceNumber())) { - TRACE_ERROR(("xsi_msgsnd: message queue id %d (sequence = %ld) " - "got destroyed\n", messageQueueID, sequenceNumber)); + TRACE_ERROR(("xsi_msgsnd: message queue id %d (sequence = " + "%" B_PRIu32 ") got destroyed\n", messageQueueID, + sequenceNumber)); delete message; notSent = false; result = EIDRM; diff --git a/src/system/kernel/posix/xsi_semaphore.cpp b/src/system/kernel/posix/xsi_semaphore.cpp index 161479c85a..212ee1b592 100644 --- a/src/system/kernel/posix/xsi_semaphore.cpp +++ b/src/system/kernel/posix/xsi_semaphore.cpp @@ -1117,7 +1117,8 @@ _user_xsi_semop(int semaphoreID, struct sembuf *ops, size_t numOps) for (; i < numOps; i++) { short semaphoreNumber = operations[i].sem_num; if (semaphoreNumber >= numberOfSemaphores) { - TRACE_ERROR(("xsi_semop: %ld invalid semaphore number\n", i)); + TRACE_ERROR(("xsi_semop: %" B_PRIu32 " invalid semaphore number" + "\n", i)); result = EINVAL; break; } @@ -1188,8 +1189,9 @@ _user_xsi_semop(int semaphoreID, struct sembuf *ops, size_t numOps) semaphoreSet = sSemaphoreHashTable.Lookup(semaphoreID); if (result == EIDRM || semaphoreSet == NULL || (semaphoreSet != NULL && sequenceNumber != semaphoreSet->SequenceNumber())) { - TRACE_ERROR(("xsi_semop: semaphore set id %d (sequence = %ld) " - "got destroyed\n", semaphoreID, sequenceNumber)); + TRACE_ERROR(("xsi_semop: semaphore set id %d (sequence = " + "%" B_PRIu32 ") got destroyed\n", semaphoreID, + sequenceNumber)); notDone = false; result = EIDRM; } else if (result == B_INTERRUPTED) { diff --git a/src/system/kernel/real_time_clock.cpp b/src/system/kernel/real_time_clock.cpp index 6f99492af8..11f5f43a96 100644 --- a/src/system/kernel/real_time_clock.cpp +++ b/src/system/kernel/real_time_clock.cpp @@ -84,9 +84,9 @@ rtc_debug(int argc, char **argv) = arch_rtc_get_system_time_offset(sRealTimeData); currentTime = (systemTimeOffset + system_time()) / 1000000; - dprintf("system_time: %Ld\n", system_time()); - dprintf("system_time_offset: %Ld\n", systemTimeOffset); - dprintf("current_time: %lu\n", currentTime); + dprintf("system_time: %" B_PRId64 "\n", system_time()); + dprintf("system_time_offset: %" B_PRId64 "\n", systemTimeOffset); + dprintf("current_time: %" B_PRIu32 "\n", currentTime); } else { // If there was an argument, reset the system and hw time. set_real_time_clock(strtoul(argv[1], NULL, 10)); diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 0d571d67dd..e4848d1d48 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -64,7 +64,7 @@ void scheduler_init(void) { int32 cpuCount = smp_get_num_cpus(); - dprintf("scheduler_init: found %ld logical cpu%s\n", cpuCount, + dprintf("scheduler_init: found %" B_PRId32 " logical cpu%s\n", cpuCount, cpuCount != 1 ? "s" : ""); if (cpuCount > 1) { diff --git a/src/system/kernel/scheduler/scheduler_affine.cpp b/src/system/kernel/scheduler/scheduler_affine.cpp index 6045e15f7a..10fa82ce5a 100644 --- a/src/system/kernel/scheduler/scheduler_affine.cpp +++ b/src/system/kernel/scheduler/scheduler_affine.cpp @@ -109,13 +109,13 @@ dump_run_queue(int argc, char **argv) for (int32 i = 0; i < smp_get_num_cpus(); i++) { thread = sRunQueue[i]; - kprintf("Run queue for cpu %ld (%ld threads)\n", i, + kprintf("Run queue for cpu %" B_PRId32 " (%" B_PRId32 " threads)\n", i, sRunQueueSize[i]); if (sRunQueueSize[i] > 0) { kprintf("thread id priority avg. quantum name\n"); while (thread) { - kprintf("%p %-7ld %-8ld %-12ld %s\n", thread, thread->id, - thread->priority, + kprintf("%p %-7" B_PRId32 " %-8" B_PRId32 " %-12" B_PRId32 + " %s\n", thread, thread->id, thread->priority, thread->scheduler_data->GetAverageQuantumUsage(), thread->name); thread = thread->queue_next; diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp b/src/system/kernel/scheduler/scheduler_simple.cpp index 4898781cdf..a68a1c3a47 100644 --- a/src/system/kernel/scheduler/scheduler_simple.cpp +++ b/src/system/kernel/scheduler/scheduler_simple.cpp @@ -67,8 +67,8 @@ dump_run_queue(int argc, char **argv) else { kprintf("thread id priority name\n"); while (thread) { - kprintf("%p %-7ld %-8ld %s\n", thread, thread->id, - thread->priority, thread->name); + kprintf("%p %-7" B_PRId32 " %-8" B_PRId32 " %s\n", thread, + thread->id, thread->priority, thread->name); thread = thread->queue_next; } } diff --git a/src/system/kernel/scheduler/scheduler_simple_smp.cpp b/src/system/kernel/scheduler/scheduler_simple_smp.cpp index 32dd4e2d59..7ca4d7f598 100644 --- a/src/system/kernel/scheduler/scheduler_simple_smp.cpp +++ b/src/system/kernel/scheduler/scheduler_simple_smp.cpp @@ -70,8 +70,8 @@ dump_run_queue(int argc, char **argv) else { kprintf("thread id priority name\n"); while (thread) { - kprintf("%p %-7ld %-8ld %s\n", thread, thread->id, - thread->priority, thread->name); + kprintf("%p %-7" B_PRId32 " %-8" B_PRId32 " %s\n", thread, + thread->id, thread->priority, thread->name); thread = thread->queue_next; } } diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp index ad32ddd349..747428e4c9 100644 --- a/src/system/kernel/sem.cpp +++ b/src/system/kernel/sem.cpp @@ -153,7 +153,8 @@ dump_sem_list(int argc, char** argv) } else if (argc > 1) owner = strtoul(argv[1], NULL, 0); - kprintf("sem id count team last name\n"); + kprintf("%-*s id count team last name\n", B_PRINTF_POINTER_WIDTH, + "sem"); for (i = 0; i < sMaxSems; i++) { struct sem_entry* sem = &sSems[i]; @@ -163,8 +164,8 @@ dump_sem_list(int argc, char** argv) || (owner != -1 && sem->u.used.owner != owner)) continue; - kprintf("%p %6ld %5ld %6ld " - "%6ld " + kprintf("%p %6" B_PRId32 " %5" B_PRId32 " %6" B_PRId32 " " + "%6" B_PRId32 " " " %s\n", sem, sem->id, sem->u.used.count, sem->u.used.owner, sem->u.used.last_acquirer > 0 ? sem->u.used.last_acquirer : 0, @@ -179,16 +180,16 @@ static void dump_sem(struct sem_entry* sem) { kprintf("SEM: %p\n", sem); - kprintf("id: %ld (%#lx)\n", sem->id, sem->id); + kprintf("id: %" B_PRId32 " (%#" B_PRIx32 ")\n", sem->id, sem->id); if (sem->id >= 0) { kprintf("name: '%s'\n", sem->u.used.name); - kprintf("owner: %ld\n", sem->u.used.owner); - kprintf("count: %ld\n", sem->u.used.count); + kprintf("owner: %" B_PRId32 "\n", sem->u.used.owner); + kprintf("count: %" B_PRId32 "\n", sem->u.used.count); kprintf("queue: "); if (!sem->queue.IsEmpty()) { ThreadQueue::Iterator it = sem->queue.GetIterator(); while (queued_thread* entry = it.Next()) - kprintf(" %ld", entry->thread->id); + kprintf(" %" B_PRId32, entry->thread->id); kprintf("\n"); } else kprintf(" -\n"); @@ -198,9 +199,9 @@ dump_sem(struct sem_entry* sem) set_debug_variable("_owner", sem->u.used.owner); #if DEBUG_SEM_LAST_ACQUIRER - kprintf("last acquired by: %ld, count: %ld\n", + kprintf("last acquired by: %" B_PRId32 ", count: %" B_PRId32 "\n", sem->u.used.last_acquirer, sem->u.used.last_acquire_count); - kprintf("last released by: %ld, count: %ld\n", + kprintf("last released by: %" B_PRId32 ", count: %" B_PRId32 "\n", sem->u.used.last_releaser, sem->u.used.last_release_count); if (sem->u.used.last_releaser != 0) @@ -217,7 +218,7 @@ dump_sem(struct sem_entry* sem) unset_debug_variable("_acquirer"); } else { kprintf("next: %p\n", sem->u.unused.next); - kprintf("next_id: %ld\n", sem->u.unused.next_id); + kprintf("next_id: %" B_PRId32 "\n", sem->u.unused.next_id); } } @@ -378,8 +379,8 @@ delete_sem_internal(sem_id id, bool checkPermission) RELEASE_SEM_LOCK(sSems[slot]); RELEASE_SEM_LIST_LOCK(); restore_interrupts(state); - dprintf("thread %ld tried to delete kernel semaphore %ld.\n", - thread_get_current_thread_id(), id); + dprintf("thread %" B_PRId32 " tried to delete kernel semaphore " + "%" B_PRId32 ".\n", thread_get_current_thread_id(), id); return B_NOT_ALLOWED; } @@ -387,7 +388,7 @@ delete_sem_internal(sem_id id, bool checkPermission) list_remove_link(&sSems[slot].u.used.team_link); sSems[slot].u.used.owner = -1; } else - panic("sem %ld has no owner", id); + panic("sem %" B_PRId32 " has no owner", id); RELEASE_SEM_LIST_LOCK(); @@ -769,8 +770,8 @@ switch_sem_etc(sem_id semToBeReleased, sem_id id, int32 count, return B_NO_MORE_SEMS; if (!are_interrupts_enabled()) { - panic("switch_sem_etc: called with interrupts disabled for sem %ld\n", - id); + panic("switch_sem_etc: called with interrupts disabled for sem " + "%" B_PRId32 "\n", id); } if (id < 0) @@ -793,8 +794,8 @@ switch_sem_etc(sem_id semToBeReleased, sem_id id, int32 count, // doesn't have any use outside the kernel if ((flags & B_CHECK_PERMISSION) != 0 && sSems[slot].u.used.owner == team_get_kernel_team_id()) { - dprintf("thread %ld tried to acquire kernel semaphore %ld.\n", - thread_get_current_thread_id(), id); + dprintf("thread %" B_PRId32 " tried to acquire kernel semaphore " + "%" B_PRId32 ".\n", thread_get_current_thread_id(), id); status = B_NOT_ALLOWED; goto err; } @@ -945,7 +946,7 @@ release_sem_etc(sem_id id, int32 count, uint32 flags) // doesn't have any use outside the kernel if ((flags & B_CHECK_PERMISSION) != 0 && sSems[slot].u.used.owner == team_get_kernel_team_id()) { - dprintf("thread %ld tried to release kernel semaphore.\n", + dprintf("thread %" B_PRId32 " tried to release kernel semaphore.\n", thread_get_current_thread_id()); return B_NOT_ALLOWED; } diff --git a/src/system/kernel/slab/MemoryManager.cpp b/src/system/kernel/slab/MemoryManager.cpp index 1f1fa8e0ee..39d6d579be 100644 --- a/src/system/kernel/slab/MemoryManager.cpp +++ b/src/system/kernel/slab/MemoryManager.cpp @@ -1760,7 +1760,8 @@ MemoryManager::_CheckMetaChunk(MetaChunk* metaChunk) /*static*/ int MemoryManager::_DumpRawAllocations(int argc, char** argv) { - kprintf("area meta chunk chunk base size (KB)\n"); + kprintf("%-*s meta chunk chunk %-*s size (KB)\n", + B_PRINTF_POINTER_WIDTH, "area", B_PRINTF_POINTER_WIDTH, "base"); size_t totalSize = 0; @@ -1792,8 +1793,8 @@ MemoryManager::_DumpRawAllocations(int argc, char** argv) } } - kprintf("total: %9" B_PRIuSIZE "\n", - totalSize / 1024); + kprintf("total:%*s%9" B_PRIuSIZE "\n", (2 * B_PRINTF_POINTER_WIDTH) + 21, + "", totalSize / 1024); return 0; } @@ -1970,7 +1971,8 @@ MemoryManager::_DumpArea(int argc, char** argv) /*static*/ int MemoryManager::_DumpAreas(int argc, char** argv) { - kprintf(" base area meta small medium large\n"); + kprintf(" %*s %*s meta small medium large\n", + B_PRINTF_POINTER_WIDTH, "base", B_PRINTF_POINTER_WIDTH, "area"); size_t totalTotalSmall = 0; size_t totalUsedSmall = 0; @@ -2035,7 +2037,7 @@ MemoryManager::_DumpAreas(int argc, char** argv) kprintf(" medium: %" B_PRIuSIZE "/%" B_PRIuSIZE "\n", totalUsedMedium, totalTotalMedium); kprintf(" large: %" B_PRIuSIZE "\n", totalUsedLarge); - kprintf(" memory: %" B_PRIuSIZE "/%" B_PRIuSIZE " KB\n", + kprintf(" memory: %" B_PRIuSIZE "/%" B_PRIu32 " KB\n", (totalUsedSmall * SLAB_CHUNK_SIZE_SMALL + totalUsedMedium * SLAB_CHUNK_SIZE_MEDIUM + totalUsedLarge * SLAB_CHUNK_SIZE_LARGE) / 1024, diff --git a/src/system/kernel/slab/Slab.cpp b/src/system/kernel/slab/Slab.cpp index 8f9bdbe0be..81a8cdd0ad 100644 --- a/src/system/kernel/slab/Slab.cpp +++ b/src/system/kernel/slab/Slab.cpp @@ -258,16 +258,17 @@ dump_slab(::slab* slab) static int dump_slabs(int argc, char* argv[]) { - kprintf("%10s %22s %8s %8s %8s %6s %8s %8s %8s\n", "address", "name", - "objsize", "align", "usage", "empty", "usedobj", "total", "flags"); + kprintf("%*s %22s %8s %8s %8s %6s %8s %8s %8s\n", + B_PRINTF_POINTER_WIDTH + 2, "address", "name", "objsize", "align", + "usage", "empty", "usedobj", "total", "flags"); ObjectCacheList::Iterator it = sObjectCaches.GetIterator(); while (it.HasNext()) { ObjectCache* cache = it.Next(); - kprintf("%p %22s %8lu %8" B_PRIuSIZE " %8lu %6lu %8lu %8lu %8lx\n", - cache, cache->name, cache->object_size, cache->alignment, + kprintf("%p %22s %8lu %8" B_PRIuSIZE " %8lu %6lu %8lu %8lu %8" B_PRIx32 + "\n", cache, cache->name, cache->object_size, cache->alignment, cache->usage, cache->empty_count, cache->used_count, cache->total_objects, cache->flags); } @@ -298,12 +299,13 @@ dump_cache_info(int argc, char* argv[]) kprintf("slab_size: %lu\n", cache->slab_size); kprintf("usage: %lu\n", cache->usage); kprintf("maximum: %lu\n", cache->maximum); - kprintf("flags: 0x%lx\n", cache->flags); + kprintf("flags: 0x%" B_PRIx32 "\n", cache->flags); kprintf("cookie: %p\n", cache->cookie); kprintf("resize entry don't wait: %p\n", cache->resize_entry_dont_wait); kprintf("resize entry can wait: %p\n", cache->resize_entry_can_wait); - kprintf(" slab chunk size used offset free\n"); + kprintf(" %-*s %-*s size used offset free\n", + B_PRINTF_POINTER_WIDTH, "slab", B_PRINTF_POINTER_WIDTH, "chunk"); SlabList::Iterator iterator = cache->empty.GetIterator(); if (iterator.HasNext()) diff --git a/src/system/kernel/smp.cpp b/src/system/kernel/smp.cpp index 899d81c259..bf5f7c7603 100644 --- a/src/system/kernel/smp.cpp +++ b/src/system/kernel/smp.cpp @@ -58,9 +58,9 @@ struct smp_msg { struct smp_msg *next; int32 message; - uint32 data; - uint32 data2; - uint32 data3; + addr_t data; + addr_t data2; + addr_t data3; void *data_ptr; uint32 flags; int32 ref_count; @@ -234,10 +234,10 @@ dump_ici_messages(int argc, char** argv) message = message->next; } - kprintf("ICI broadcast messages: %ld, first: %p\n", count, + kprintf("ICI broadcast messages: %" B_PRId32 ", first: %p\n", count, sBroadcastMessages); - kprintf(" done: %ld\n", doneCount); - kprintf(" unreferenced: %ld\n", unreferencedCount); + kprintf(" done: %" B_PRId32 "\n", doneCount); + kprintf(" unreferenced: %" B_PRId32 "\n", unreferencedCount); // count per-CPU messages for (int32 i = 0; i < sNumCPUs; i++) { @@ -248,8 +248,8 @@ dump_ici_messages(int argc, char** argv) message = message->next; } - kprintf("CPU %ld messages: %ld, first: %p\n", i, count, - sCPUMessages[i]); + kprintf("CPU %" B_PRId32 " messages: %" B_PRId32 ", first: %p\n", i, + count, sCPUMessages[i]); } return 0; @@ -271,15 +271,15 @@ dump_ici_message(int argc, char** argv) smp_msg* message = (smp_msg*)(addr_t)address; kprintf("ICI message %p:\n", message); kprintf(" next: %p\n", message->next); - kprintf(" message: %ld\n", message->message); - kprintf(" data: %ld\n", message->data); - kprintf(" data2: %ld\n", message->data2); - kprintf(" data3: %ld\n", message->data3); + kprintf(" message: %" B_PRId32 "\n", message->message); + kprintf(" data: 0x%lx\n", message->data); + kprintf(" data2: 0x%lx\n", message->data2); + kprintf(" data3: 0x%lx\n", message->data3); kprintf(" data_ptr: %p\n", message->data_ptr); - kprintf(" flags: %lx\n", message->flags); - kprintf(" ref_count: %lx\n", message->ref_count); + kprintf(" flags: %" B_PRIx32 "\n", message->flags); + kprintf(" ref_count: %" B_PRIx32 "\n", message->ref_count); kprintf(" done: %s\n", message->done ? "true" : "false"); - kprintf(" proc_bitmap: %lx\n", message->proc_bitmap); + kprintf(" proc_bitmap: %" B_PRIx32 "\n", message->proc_bitmap); return 0; } @@ -361,7 +361,7 @@ acquire_spinlock(spinlock* lock) oldValue = atomic_or((int32*)lock, 1); if (oldValue != 0) { panic("acquire_spinlock: attempt to acquire lock %p twice on " - "non-SMP system (last caller: %p, value %ld)", lock, + "non-SMP system (last caller: %p, value %" B_PRId32 ")", lock, find_lock_caller(lock), oldValue); } @@ -458,7 +458,7 @@ acquire_spinlock_cpu(int32 currentCPU, spinlock *lock) oldValue = atomic_or((int32*)lock, 1); if (oldValue != 0) { panic("acquire_spinlock_cpu(): attempt to acquire lock %p twice on " - "non-SMP system (last caller: %p, value %ld)", lock, + "non-SMP system (last caller: %p, value %" B_PRId32 ")", lock, find_lock_caller(lock), oldValue); } @@ -716,8 +716,7 @@ process_pending_ici(int32 currentCPU) switch (msg->message) { case SMP_MSG_INVALIDATE_PAGE_RANGE: - arch_cpu_invalidate_TLB_range((addr_t)msg->data, - (addr_t)msg->data2); + arch_cpu_invalidate_TLB_range(msg->data, msg->data2); break; case SMP_MSG_INVALIDATE_PAGE_LIST: arch_cpu_invalidate_TLB_list((addr_t*)msg->data, (int)msg->data2); @@ -755,7 +754,7 @@ process_pending_ici(int32 currentCPU) } default: - dprintf("smp_intercpu_int_handler: got unknown message %ld\n", + dprintf("smp_intercpu_int_handler: got unknown message %" B_PRId32 "\n", msg->message); break; } @@ -861,8 +860,8 @@ smp_intercpu_int_handler(int32 cpu) void -smp_send_ici(int32 targetCPU, int32 message, uint32 data, uint32 data2, - uint32 data3, void* dataPointer, uint32 flags) +smp_send_ici(int32 targetCPU, int32 message, addr_t data, addr_t data2, + addr_t data3, void* dataPointer, uint32 flags) { struct smp_msg *msg; @@ -921,8 +920,8 @@ smp_send_ici(int32 targetCPU, int32 message, uint32 data, uint32 data2, void -smp_send_multicast_ici(cpu_mask_t cpuMask, int32 message, uint32 data, - uint32 data2, uint32 data3, void *dataPointer, uint32 flags) +smp_send_multicast_ici(cpu_mask_t cpuMask, int32 message, addr_t data, + addr_t data2, addr_t data3, void *dataPointer, uint32 flags) { if (!sICIEnabled) return; @@ -984,7 +983,7 @@ smp_send_multicast_ici(cpu_mask_t cpuMask, int32 message, uint32 data, void -smp_send_broadcast_ici(int32 message, uint32 data, uint32 data2, uint32 data3, +smp_send_broadcast_ici(int32 message, addr_t data, addr_t data2, addr_t data3, void *dataPointer, uint32 flags) { struct smp_msg *msg; @@ -1052,7 +1051,7 @@ smp_send_broadcast_ici(int32 message, uint32 data, uint32 data2, uint32 data3, void smp_send_broadcast_ici_interrupts_disabled(int32 currentCPU, int32 message, - uint32 data, uint32 data2, uint32 data3, void *dataPointer, uint32 flags) + addr_t data, addr_t data2, addr_t data3, void *dataPointer, uint32 flags) { if (!sICIEnabled) return; @@ -1276,7 +1275,7 @@ call_all_cpus(void (*func)(void*, int), void* cookie) } if (smp_get_num_cpus() > 1) { - smp_send_broadcast_ici(SMP_MSG_CALL_FUNCTION, (uint32)cookie, + smp_send_broadcast_ici(SMP_MSG_CALL_FUNCTION, (addr_t)cookie, 0, 0, (void*)func, SMP_MSG_FLAG_ASYNC); } @@ -1300,7 +1299,7 @@ call_all_cpus_sync(void (*func)(void*, int), void* cookie) } if (smp_get_num_cpus() > 1) { - smp_send_broadcast_ici(SMP_MSG_CALL_FUNCTION, (uint32)cookie, + smp_send_broadcast_ici(SMP_MSG_CALL_FUNCTION, (addr_t)cookie, 0, 0, (void*)func, SMP_MSG_FLAG_SYNC); } diff --git a/src/system/kernel/system_info.cpp b/src/system/kernel/system_info.cpp index 0315c0d7ea..a97cdcad10 100644 --- a/src/system/kernel/system_info.cpp +++ b/src/system/kernel/system_info.cpp @@ -50,20 +50,23 @@ dump_info(int argc, char **argv) __VERSION__); kprintf("revision: %s\n\n", get_haiku_revision()); - kprintf("cpu count: %ld, active times:\n", smp_get_num_cpus()); + kprintf("cpu count: %" B_PRId32 ", active times:\n", smp_get_num_cpus()); for (int32 i = 0; i < smp_get_num_cpus(); i++) - kprintf(" [%ld] %Ld\n", i + 1, gCPU[i].active_time); + kprintf(" [%" B_PRId32 "] %" B_PRId64 "\n", i + 1, gCPU[i].active_time); // ToDo: Add page_faults kprintf("pages:\t\t%" B_PRIuPHYSADDR " (%" B_PRIuPHYSADDR " max)\n", vm_page_num_pages() - vm_page_num_free_pages(), vm_page_num_pages()); - kprintf("sems:\t\t%ld (%ld max)\n", sem_used_sems(), sem_max_sems()); - kprintf("ports:\t\t%ld (%ld max)\n", port_used_ports(), port_max_ports()); - kprintf("threads:\t%ld (%ld max)\n", thread_used_threads(), - thread_max_threads()); - kprintf("teams:\t\t%ld (%ld max)\n", team_used_teams(), team_max_teams()); + kprintf("sems:\t\t%" B_PRId32 " (%" B_PRId32 " max)\n", sem_used_sems(), + sem_max_sems()); + kprintf("ports:\t\t%" B_PRId32 " (%" B_PRId32 " max)\n", port_used_ports(), + port_max_ports()); + kprintf("threads:\t%" B_PRId32 " (%" B_PRId32 " max)\n", + thread_used_threads(), thread_max_threads()); + kprintf("teams:\t\t%" B_PRId32 " (%" B_PRId32 " max)\n", team_used_teams(), + team_max_teams()); return 0; } diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 62a3677369..e492bcdb1f 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -976,7 +976,7 @@ ProcessGroup::ProcessGroup(pid_t id) ProcessGroup::~ProcessGroup() { - TRACE(("ProcessGroup::~ProcessGroup(): id = %ld\n", group->id)); + TRACE(("ProcessGroup::~ProcessGroup(): id = %" B_PRId32 "\n", id)); // If the group is in the orphaned check list, remove it. MutexLocker orphanedCheckLocker(sOrphanedCheckLock); @@ -1114,38 +1114,39 @@ static void _dump_team_info(Team* team) { kprintf("TEAM: %p\n", team); - kprintf("id: %ld (%#lx)\n", team->id, team->id); + kprintf("id: %" B_PRId32 " (%#" B_PRIx32 ")\n", team->id, + team->id); kprintf("serial_number: %" B_PRId64 "\n", team->serial_number); kprintf("name: '%s'\n", team->Name()); kprintf("args: '%s'\n", team->Args()); kprintf("hash_next: %p\n", team->hash_next); kprintf("parent: %p", team->parent); if (team->parent != NULL) { - kprintf(" (id = %ld)\n", team->parent->id); + kprintf(" (id = %" B_PRId32 ")\n", team->parent->id); } else kprintf("\n"); kprintf("children: %p\n", team->children); kprintf("num_threads: %d\n", team->num_threads); kprintf("state: %d\n", team->state); - kprintf("flags: 0x%lx\n", team->flags); + kprintf("flags: 0x%" B_PRIx32 "\n", team->flags); kprintf("io_context: %p\n", team->io_context); if (team->address_space) kprintf("address_space: %p\n", team->address_space); - kprintf("user data: %p (area %ld)\n", (void*)team->user_data, - team->user_data_area); + kprintf("user data: %p (area %" B_PRId32 ")\n", + (void*)team->user_data, team->user_data_area); kprintf("free user thread: %p\n", team->free_user_threads); kprintf("main_thread: %p\n", team->main_thread); kprintf("thread_list: %p\n", team->thread_list); - kprintf("group_id: %ld\n", team->group_id); - kprintf("session_id: %ld\n", team->session_id); + kprintf("group_id: %" B_PRId32 "\n", team->group_id); + kprintf("session_id: %" B_PRId32 "\n", team->session_id); } static int dump_team_info(int argc, char** argv) { - team_id id = -1; + ulong arg; bool found = false; if (argc < 2) { @@ -1157,10 +1158,10 @@ dump_team_info(int argc, char** argv) return 0; } - id = strtoul(argv[1], NULL, 0); - if (IS_KERNEL_ADDRESS(id)) { + arg = strtoul(argv[1], NULL, 0); + if (IS_KERNEL_ADDRESS(arg)) { // semi-hack - _dump_team_info((Team*)id); + _dump_team_info((Team*)arg); return 0; } @@ -1168,7 +1169,7 @@ dump_team_info(int argc, char** argv) for (TeamTable::Iterator it = sTeamHash.GetIterator(); Team* team = it.Next();) { if ((team->Name() && strcmp(argv[1], team->Name()) == 0) - || team->id == id) { + || team->id == (team_id)arg) { _dump_team_info(team); found = true; break; @@ -1176,7 +1177,7 @@ dump_team_info(int argc, char** argv) } if (!found) - kprintf("team \"%s\" (%ld) doesn't exist!\n", argv[1], id); + kprintf("team \"%s\" (%" B_PRId32 ") doesn't exist!\n", argv[1], (team_id)arg); return 0; } @@ -1184,11 +1185,12 @@ dump_team_info(int argc, char** argv) static int dump_teams(int argc, char** argv) { - kprintf("team id parent name\n"); + kprintf("%-*s id %-*s name\n", B_PRINTF_POINTER_WIDTH, "team", + B_PRINTF_POINTER_WIDTH, "parent"); for (TeamTable::Iterator it = sTeamHash.GetIterator(); Team* team = it.Next();) { - kprintf("%p%7ld %p %s\n", team, team->id, team->parent, team->Name()); + kprintf("%p%7" B_PRId32 " %p %s\n", team, team->id, team->parent, team->Name()); } return 0; @@ -1480,7 +1482,8 @@ team_create_thread_start_internal(void* args) team = thread->team; cache_node_launched(teamArgs->arg_count, teamArgs->flat_args); - TRACE(("team_create_thread_start: entry thread %ld\n", thread->id)); + TRACE(("team_create_thread_start: entry thread %" B_PRId32 "\n", + thread->id)); // Main stack area layout is currently as follows (starting from 0): // @@ -1602,8 +1605,8 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount, const char* path = flatArgs[0]; - TRACE(("load_image_internal: name '%s', args = %p, argCount = %ld\n", - path, flatArgs, argCount)); + TRACE(("load_image_internal: name '%s', args = %p, argCount = %" B_PRId32 + "\n", path, flatArgs, argCount)); // cut the path from the main thread name const char* threadName = strrchr(path, '/'); @@ -1802,8 +1805,9 @@ exec_team(const char* path, char**& _flatArgs, size_t flatArgsSize, const char* threadName; thread_id nubThreadID = -1; - TRACE(("exec_team(path = \"%s\", argc = %ld, envCount = %ld): team %ld\n", - path, argCount, envCount, team->id)); + TRACE(("exec_team(path = \"%s\", argc = %" B_PRId32 ", envCount = %" + B_PRId32 "): team %" B_PRId32 "\n", path, argCount, envCount, + team->id)); T(ExecTeam(path, argCount, flatArgs, envCount, flatArgs + argCount + 1)); @@ -1938,9 +1942,10 @@ fork_team(void) struct area_info info; thread_id threadID; status_t status; - int32 cookie; + ssize_t areaCookie; + int32 imageCookie; - TRACE(("fork_team(): team %ld\n", parentTeam->id)); + TRACE(("fork_team(): team %" B_PRId32 "\n", parentTeam->id)); if (parentTeam == team_get_kernel_team()) return B_NOT_ALLOWED; @@ -2026,8 +2031,8 @@ fork_team(void) // TODO: should be able to handle stack areas differently (ie. don't have // them copy-on-write) - cookie = 0; - while (get_next_area_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { + areaCookie = 0; + while (get_next_area_info(B_CURRENT_TEAM, &areaCookie, &info) == B_OK) { if (info.area == parentTeam->user_data_area) { // don't clone the user area; just create a new one status = create_team_user_data(team); @@ -2054,7 +2059,7 @@ fork_team(void) if (thread->user_thread == NULL) { #if KDEBUG - panic("user data area not found, parent area is %ld", + panic("user data area not found, parent area is %" B_PRId32, parentTeam->user_data_area); #endif status = B_ERROR; @@ -2073,8 +2078,9 @@ fork_team(void) // copy image list image_info imageInfo; - cookie = 0; - while (get_next_image_info(parentTeam->id, &cookie, &imageInfo) == B_OK) { + imageCookie = 0; + while (get_next_image_info(parentTeam->id, &imageCookie, &imageInfo) + == B_OK) { image_id image = register_image(team, &imageInfo, sizeof(imageInfo)); if (image < 0) goto err5; @@ -2237,7 +2243,7 @@ job_control_entry::~job_control_entry() ProcessGroup* group = sGroupHash.Lookup(group_id); if (group == NULL) { panic("job_control_entry::~job_control_entry(): unknown group " - "ID: %ld", group_id); + "ID: %" B_PRId32, group_id); return; } @@ -2302,7 +2308,8 @@ wait_for_child(pid_t child, uint32 flags, siginfo_t& _info) struct job_control_entry* freeDeathEntry = NULL; status_t status = B_OK; - TRACE(("wait_for_child(child = %ld, flags = %ld)\n", child, flags)); + TRACE(("wait_for_child(child = %" B_PRId32 ", flags = %" B_PRId32 ")\n", + child, flags)); T(WaitForChild(child, flags)); @@ -4076,7 +4083,7 @@ _user_load_image(const char* const* userFlatArgs, size_t flatArgsSize, int32 argCount, int32 envCount, int32 priority, uint32 flags, port_id errorPort, uint32 errorToken) { - TRACE(("_user_load_image: argc = %ld\n", argCount)); + TRACE(("_user_load_image: argc = %" B_PRId32 "\n", argCount)); if (argCount < 1) return B_BAD_VALUE; diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 6227dd25e0..e0eae26d2f 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -365,7 +365,7 @@ Thread::Init(bool idleThread) return error; char temp[64]; - snprintf(temp, sizeof(temp), "thread_%ld_retcode_sem", id); + snprintf(temp, sizeof(temp), "thread_%" B_PRId32 "_retcode_sem", id); exit.sem = create_sem(0, temp); if (exit.sem < 0) return exit.sem; @@ -814,8 +814,8 @@ create_thread_user_stack(Team* team, Thread* thread, void* _stackBase, size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + additionalSize); - snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%ld_stack", thread->name, - thread->id); + snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_stack", + thread->name, thread->id); virtual_address_restrictions virtualRestrictions = {}; if (thread->id == team->id) { @@ -913,8 +913,8 @@ thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel) // create the kernel stack char stackName[B_OS_NAME_LENGTH]; - snprintf(stackName, B_OS_NAME_LENGTH, "%s_%ld_kstack", thread->name, - thread->id); + snprintf(stackName, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_kstack", + thread->name, thread->id); thread->kernel_stack_area = create_area(stackName, (void **)&thread->kernel_stack_base, B_ANY_KERNEL_ADDRESS, KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, @@ -1404,7 +1404,7 @@ make_thread_unreal(int argc, char **argv) if (thread->priority > B_DISPLAY_PRIORITY) { thread->priority = thread->next_priority = B_NORMAL_PRIORITY; - kprintf("thread %ld made unreal\n", thread->id); + kprintf("thread %" B_PRId32 " made unreal\n", thread->id); } } @@ -1440,12 +1440,12 @@ set_thread_prio(int argc, char **argv) if (thread->id != id) continue; thread->priority = thread->next_priority = prio; - kprintf("thread %ld set to priority %ld\n", id, prio); + kprintf("thread %" B_PRId32 " set to priority %" B_PRId32 "\n", id, prio); found = true; break; } if (!found) - kprintf("thread %ld (%#lx) not found\n", id, id); + kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id); return 0; } @@ -1473,12 +1473,12 @@ make_thread_suspended(int argc, char **argv) continue; thread->next_state = B_THREAD_SUSPENDED; - kprintf("thread %ld suspended\n", id); + kprintf("thread %" B_PRId32 " suspended\n", id); found = true; break; } if (!found) - kprintf("thread %ld (%#lx) not found\n", id, id); + kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id); return 0; } @@ -1506,13 +1506,13 @@ make_thread_resumed(int argc, char **argv) if (thread->state == B_THREAD_SUSPENDED) { scheduler_enqueue_in_run_queue(thread); - kprintf("thread %ld resumed\n", thread->id); + kprintf("thread %" B_PRId32 " resumed\n", thread->id); } found = true; break; } if (!found) - kprintf("thread %ld (%#lx) not found\n", id, id); + kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id); return 0; } @@ -1540,7 +1540,7 @@ drop_into_debugger(int argc, char **argv) if (err) kprintf("drop failed\n"); else - kprintf("thread %ld dropped into user debugger\n", id); + kprintf("thread %" B_PRId32 " dropped into user debugger\n", id); return 0; } @@ -1594,8 +1594,10 @@ state_to_text(Thread *thread, int32 state) static void print_thread_list_table_head() { - kprintf("thread id state wait for object cpu pri stack " - " team name\n"); + kprintf("%-*s id state wait for %-*s cpu pri %-*s team " + "name\n", + B_PRINTF_POINTER_WIDTH, "thread", B_PRINTF_POINTER_WIDTH, "object", + B_PRINTF_POINTER_WIDTH, "stack"); } @@ -1603,8 +1605,8 @@ static void _dump_thread_info(Thread *thread, bool shortInfo) { if (shortInfo) { - kprintf("%p %6ld %-10s", thread, thread->id, state_to_text(thread, - thread->state)); + kprintf("%p %6" B_PRId32 " %-10s", thread, thread->id, + state_to_text(thread, thread->state)); // does it block on a semaphore or a condition variable? if (thread->state == B_THREAD_WAITING) { @@ -1613,42 +1615,44 @@ _dump_thread_info(Thread *thread, bool shortInfo) { sem_id sem = (sem_id)(addr_t)thread->wait.object; if (sem == thread->msg.read_sem) - kprintf(" "); - else - kprintf("sem %12ld ", sem); + kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, ""); + else { + kprintf("sem %-*" B_PRId32, + B_PRINTF_POINTER_WIDTH + 5, sem); + } break; } case THREAD_BLOCK_TYPE_CONDITION_VARIABLE: - kprintf("cvar %p ", thread->wait.object); + kprintf("cvar %p ", thread->wait.object); break; case THREAD_BLOCK_TYPE_SNOOZE: - kprintf(" "); + kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, ""); break; case THREAD_BLOCK_TYPE_SIGNAL: - kprintf("signal "); + kprintf("signal%*s", B_PRINTF_POINTER_WIDTH + 9, ""); break; case THREAD_BLOCK_TYPE_MUTEX: - kprintf("mutex %p ", thread->wait.object); + kprintf("mutex %p ", thread->wait.object); break; case THREAD_BLOCK_TYPE_RW_LOCK: - kprintf("rwlock %p ", thread->wait.object); + kprintf("rwlock %p ", thread->wait.object); break; case THREAD_BLOCK_TYPE_OTHER: - kprintf("other "); + kprintf("other%*s", B_PRINTF_POINTER_WIDTH + 10, ""); break; default: - kprintf("??? %p ", thread->wait.object); + kprintf("??? %p ", thread->wait.object); break; } } else - kprintf(" - "); + kprintf("-%*s", B_PRINTF_POINTER_WIDTH + 14, ""); // on which CPU does it run? if (thread->cpu) @@ -1656,7 +1660,7 @@ _dump_thread_info(Thread *thread, bool shortInfo) else kprintf(" -"); - kprintf("%4ld %p%5ld %s\n", thread->priority, + kprintf("%4" B_PRId32 " %p%5" B_PRId32 " %s\n", thread->priority, (void *)thread->kernel_stack_base, thread->team->id, thread->name != NULL ? thread->name : ""); @@ -1668,13 +1672,15 @@ _dump_thread_info(Thread *thread, bool shortInfo) struct thread_death_entry *death = NULL; kprintf("THREAD: %p\n", thread); - kprintf("id: %ld (%#lx)\n", thread->id, thread->id); + kprintf("id: %" B_PRId32 " (%#" B_PRIx32 ")\n", thread->id, + thread->id); kprintf("serial_number: %" B_PRId64 "\n", thread->serial_number); kprintf("name: \"%s\"\n", thread->name); kprintf("hash_next: %p\nteam_next: %p\nq_next: %p\n", thread->hash_next, thread->team_next, thread->queue_next); - kprintf("priority: %ld (next %ld, I/O: %ld)\n", thread->priority, - thread->next_priority, thread->io_priority); + kprintf("priority: %" B_PRId32 " (next %" B_PRId32 ", " + "I/O: %" B_PRId32 ")\n", thread->priority, thread->next_priority, + thread->io_priority); kprintf("state: %s\n", state_to_text(thread, thread->state)); kprintf("next_state: %s\n", state_to_text(thread, thread->next_state)); kprintf("cpu: %p ", thread->cpu); @@ -1682,11 +1688,11 @@ _dump_thread_info(Thread *thread, bool shortInfo) kprintf("(%d)\n", thread->cpu->cpu_num); else kprintf("\n"); - kprintf("sig_pending: %#llx (blocked: %#llx" - ", before sigsuspend(): %#llx)\n", - (long long)thread->ThreadPendingSignals(), - (long long)thread->sig_block_mask, - (long long)thread->sigsuspend_original_unblocked_mask); + kprintf("sig_pending: %#" B_PRIx64 " (blocked: %#" B_PRIx64 + ", before sigsuspend(): %#" B_PRIx64 ")\n", + (int64)thread->ThreadPendingSignals(), + (int64)thread->sig_block_mask, + (int64)thread->sigsuspend_original_unblocked_mask); kprintf("in_kernel: %d\n", thread->in_kernel); if (thread->state == B_THREAD_WAITING) { @@ -1699,7 +1705,7 @@ _dump_thread_info(Thread *thread, bool shortInfo) if (sem == thread->msg.read_sem) kprintf("data\n"); else - kprintf("semaphore %ld\n", sem); + kprintf("semaphore %" B_PRId32 "\n", sem); break; } @@ -1736,25 +1742,26 @@ _dump_thread_info(Thread *thread, bool shortInfo) kprintf("fault_handler: %p\n", (void *)thread->fault_handler); kprintf("team: %p, \"%s\"\n", thread->team, thread->team->Name()); - kprintf(" exit.sem: %ld\n", thread->exit.sem); - kprintf(" exit.status: %#lx (%s)\n", thread->exit.status, strerror(thread->exit.status)); + kprintf(" exit.sem: %" B_PRId32 "\n", thread->exit.sem); + kprintf(" exit.status: %#" B_PRIx32 " (%s)\n", thread->exit.status, + strerror(thread->exit.status)); kprintf(" exit.waiters:\n"); while ((death = (struct thread_death_entry*)list_get_next_item( &thread->exit.waiters, death)) != NULL) { - kprintf("\t%p (thread %ld)\n", death, death->thread); + kprintf("\t%p (thread %" B_PRId32 ")\n", death, death->thread); } - kprintf("kernel_stack_area: %ld\n", thread->kernel_stack_area); + kprintf("kernel_stack_area: %" B_PRId32 "\n", thread->kernel_stack_area); kprintf("kernel_stack_base: %p\n", (void *)thread->kernel_stack_base); - kprintf("user_stack_area: %ld\n", thread->user_stack_area); + kprintf("user_stack_area: %" B_PRId32 "\n", thread->user_stack_area); kprintf("user_stack_base: %p\n", (void *)thread->user_stack_base); kprintf("user_local_storage: %p\n", (void *)thread->user_local_storage); kprintf("user_thread: %p\n", (void *)thread->user_thread); kprintf("kernel_errno: %#x (%s)\n", thread->kernel_errno, strerror(thread->kernel_errno)); - kprintf("kernel_time: %Ld\n", thread->kernel_time); - kprintf("user_time: %Ld\n", thread->user_time); - kprintf("flags: 0x%lx\n", thread->flags); + kprintf("kernel_time: %" B_PRId64 "\n", thread->kernel_time); + kprintf("user_time: %" B_PRId64 "\n", thread->user_time); + kprintf("flags: 0x%" B_PRIx32 "\n", thread->flags); kprintf("architecture dependant section:\n"); arch_thread_dump_info(&thread->arch_info); } @@ -1778,11 +1785,11 @@ dump_thread_info(int argc, char **argv) for (; argi < argc; argi++) { const char *name = argv[argi]; - int32 id = strtoul(name, NULL, 0); + ulong arg = strtoul(name, NULL, 0); - if (IS_KERNEL_ADDRESS(id)) { + if (IS_KERNEL_ADDRESS(arg)) { // semi-hack - _dump_thread_info((Thread *)id, shortInfo); + _dump_thread_info((Thread *)arg, shortInfo); continue; } @@ -1790,7 +1797,7 @@ dump_thread_info(int argc, char **argv) bool found = false; for (ThreadHashTable::Iterator it = sThreadHash.GetIterator(); Thread* thread = it.Next();) { - if (!strcmp(name, thread->name) || thread->id == id) { + if (!strcmp(name, thread->name) || thread->id == (thread_id)arg) { _dump_thread_info(thread, shortInfo); found = true; break; @@ -1798,7 +1805,7 @@ dump_thread_info(int argc, char **argv) } if (!found) - kprintf("thread \"%s\" (%ld) doesn't exist!\n", name, id); + kprintf("thread \"%s\" (%" B_PRId32 ") doesn't exist!\n", name, (thread_id)arg); } return 0; @@ -1881,8 +1888,8 @@ thread_exit(void) struct thread_debug_info debugInfo; team_id teamID = team->id; - TRACE(("thread %ld exiting w/return code %#lx\n", thread->id, - thread->exit.status)); + TRACE(("thread %" B_PRId32 " exiting w/return code %#" B_PRIx32 "\n", + thread->id, thread->exit.status)); if (!are_interrupts_enabled()) panic("thread_exit() called with interrupts disabled!\n"); @@ -2087,7 +2094,8 @@ thread_exit(void) kernelTeam->Unlock(); } - TRACE(("thread_exit: thread %ld now a kernel thread!\n", thread->id)); + TRACE(("thread_exit: thread %" B_PRId32 " now a kernel thread!\n", + thread->id)); } free(threadDeathEntry); @@ -2224,7 +2232,7 @@ thread_at_kernel_entry(bigtime_t now) { Thread *thread = thread_get_current_thread(); - TRACE(("thread_at_kernel_entry: entry thread %ld\n", thread->id)); + TRACE(("thread_at_kernel_entry: entry thread %" B_PRId32 "\n", thread->id)); // track user time SpinLocker threadTimeLocker(thread->time_lock); @@ -2247,7 +2255,7 @@ thread_at_kernel_exit(void) { Thread *thread = thread_get_current_thread(); - TRACE(("thread_at_kernel_exit: exit thread %ld\n", thread->id)); + TRACE(("thread_at_kernel_exit: exit thread %" B_PRId32 "\n", thread->id)); handle_signals(thread); @@ -2271,7 +2279,8 @@ thread_at_kernel_exit_no_signals(void) { Thread *thread = thread_get_current_thread(); - TRACE(("thread_at_kernel_exit_no_signals: exit thread %ld\n", thread->id)); + TRACE(("thread_at_kernel_exit_no_signals: exit thread %" B_PRId32 "\n", + thread->id)); // track kernel time bigtime_t now = system_time(); @@ -2526,7 +2535,7 @@ wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, if (status == B_OK) { // this should never happen as the thread deletes the semaphore on exit - panic("could acquire exit_sem for thread %ld\n", id); + panic("could acquire exit_sem for thread %" B_PRId32 "\n", id); } else if (status == B_BAD_SEM_ID) { // this is the way the thread normally exits status = B_OK; @@ -2693,7 +2702,7 @@ thread_init(kernel_args *args) area_info info; char name[64]; - sprintf(name, "idle thread %lu", i + 1); + sprintf(name, "idle thread %" B_PRIu32, i + 1); thread = new(&sIdleThreads[i]) Thread(name, i == 0 ? team_get_kernel_team_id() : -1, &gCPU[i]); if (thread == NULL || thread->Init(true) != B_OK) { @@ -2707,7 +2716,7 @@ thread_init(kernel_args *args) thread->priority = thread->next_priority = B_IDLE_PRIORITY; thread->state = B_THREAD_RUNNING; thread->next_state = B_THREAD_READY; - sprintf(name, "idle thread %lu kstack", i + 1); + sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1); thread->kernel_stack_area = find_area(name); if (get_area_info(thread->kernel_stack_area, &info) != B_OK) diff --git a/src/system/kernel/util/khash.cpp b/src/system/kernel/util/khash.cpp index f21835411a..b3bdd53a9f 100644 --- a/src/system/kernel/util/khash.cpp +++ b/src/system/kernel/util/khash.cpp @@ -424,13 +424,13 @@ hash_dump_table(struct hash_table* table) { uint32 i; - dprintf("hash table %p, table size: %lu, elements: %u\n", table, + dprintf("hash table %p, table size: %" B_PRIu32 ", elements: %u\n", table, table->table_size, table->num_elements); for (i = 0; i < table->table_size; i++) { struct hash_element* element = table->table[i]; if (element != NULL) { - dprintf("%6lu:", i); + dprintf("%6" B_PRIu32 ":", i); while (element != NULL) { dprintf(" %p", element); element = (hash_element*)NEXT(table, element); diff --git a/src/system/kernel/vm/VMAddressSpace.cpp b/src/system/kernel/vm/VMAddressSpace.cpp index 7763149ecd..46f3e12e1a 100644 --- a/src/system/kernel/vm/VMAddressSpace.cpp +++ b/src/system/kernel/vm/VMAddressSpace.cpp @@ -195,8 +195,9 @@ VMAddressSpace::Create(team_id teamID, addr_t base, size_t size, bool kernel, return status; } - TRACE(("VMAddressSpace::Create(): team %ld (%skernel): %#lx bytes starting at " - "%#lx => %p\n", teamID, kernel ? "" : "!", size, base, addressSpace)); + TRACE(("VMAddressSpace::Create(): team %" B_PRId32 " (%skernel): %#lx " + "bytes starting at %#lx => %p\n", teamID, kernel ? "" : "!", size, + base, addressSpace)); // create the corresponding translation map status = arch_vm_translation_map_create_map(kernel, @@ -343,8 +344,9 @@ VMAddressSpace::_DumpCommand(int argc, char** argv) /*static*/ int VMAddressSpace::_DumpListCommand(int argc, char** argv) { - kprintf(" address id base end area count " - " area size\n"); + kprintf(" %*s id %*s %*s area count area size\n", + B_PRINTF_POINTER_WIDTH, "address", B_PRINTF_POINTER_WIDTH, "base", + B_PRINTF_POINTER_WIDTH, "end"); AddressSpaceTable::Iterator it = sAddressSpaceTable.GetIterator(); while (VMAddressSpace* space = it.Next()) { diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp index 8bdfed4256..78925e9500 100644 --- a/src/system/kernel/vm/VMAnonymousCache.cpp +++ b/src/system/kernel/vm/VMAnonymousCache.cpp @@ -238,8 +238,8 @@ dump_swap_info(int argc, char** argv) for (SwapFileList::Iterator it = sSwapFileList.GetIterator(); swap_file* file = it.Next();) { swap_addr_t total = file->last_slot - file->first_slot; - kprintf(" vnode: %p, pages: total: %lu, free: %lu\n", - file->vnode, total, file->bmp->free_slots); + kprintf(" vnode: %p, pages: total: %" B_PRIu32 ", free: %" B_PRIu32 + "\n", file->vnode, total, file->bmp->free_slots); totalSwapPages += total; freeSwapPages += file->bmp->free_slots; @@ -247,12 +247,12 @@ dump_swap_info(int argc, char** argv) kprintf("\n"); kprintf("swap space in pages:\n"); - kprintf("total: %9lu\n", totalSwapPages); - kprintf("available: %9llu\n", sAvailSwapSpace / B_PAGE_SIZE); - kprintf("reserved: %9llu\n", + kprintf("total: %9" B_PRIu32 "\n", totalSwapPages); + kprintf("available: %9" B_PRIdOFF "\n", sAvailSwapSpace / B_PAGE_SIZE); + kprintf("reserved: %9" B_PRIdOFF "\n", totalSwapPages - sAvailSwapSpace / B_PAGE_SIZE); - kprintf("used: %9lu\n", totalSwapPages - freeSwapPages); - kprintf("free: %9lu\n", freeSwapPages); + kprintf("used: %9" B_PRIu32 "\n", totalSwapPages - freeSwapPages); + kprintf("free: %9" B_PRIu32 "\n", freeSwapPages); return 0; } @@ -321,7 +321,8 @@ find_swap_file(swap_addr_t slotIndex) } } - panic("find_swap_file(): can't find swap file for slot %ld\n", slotIndex); + panic("find_swap_file(): can't find swap file for slot %" B_PRIu32 "\n", + slotIndex); return NULL; } @@ -465,8 +466,9 @@ VMAnonymousCache::Init(bool canOvercommit, int32 numPrecommittedPages, int32 numGuardPages, uint32 allocationFlags) { TRACE("%p->VMAnonymousCache::Init(canOvercommit = %s, " - "numPrecommittedPages = %ld, numGuardPages = %ld)\n", this, - canOvercommit ? "yes" : "no", numPrecommittedPages, numGuardPages); + "numPrecommittedPages = %" B_PRId32 ", numGuardPages = %" B_PRId32 + ")\n", this, canOvercommit ? "yes" : "no", numPrecommittedPages, + numGuardPages); status_t error = VMCache::Init(CACHE_TYPE_RAM, allocationFlags); if (error != B_OK) @@ -545,7 +547,7 @@ VMAnonymousCache::Resize(off_t newSize, int priority) status_t VMAnonymousCache::Commit(off_t size, int priority) { - TRACE("%p->VMAnonymousCache::Commit(%lld)\n", this, size); + TRACE("%p->VMAnonymousCache::Commit(%" B_PRIdOFF ")\n", this, size); // If we can overcommit, we don't commit here, but in Fault(). We always // unreserve memory, if we're asked to shrink our commitment, though. @@ -967,8 +969,9 @@ VMAnonymousCache::_SwapBlockGetAddress(off_t pageIndex) status_t VMAnonymousCache::_Commit(off_t size, int priority) { - TRACE("%p->VMAnonymousCache::_Commit(%lld), already committed: %lld " - "(%lld swap)\n", this, size, committed_size, fCommittedSwapSize); + TRACE("%p->VMAnonymousCache::_Commit(%" B_PRIdOFF "), already committed: " + "%" B_PRIdOFF " (%" B_PRIdOFF " swap)\n", this, size, committed_size, + fCommittedSwapSize); // Basic strategy: reserve swap space first, only when running out of swap // space, reserve real memory. @@ -982,8 +985,8 @@ VMAnonymousCache::_Commit(off_t size, int priority) fCommittedSwapSize += swap_space_reserve(size - fCommittedSwapSize); committed_size = fCommittedSwapSize + committedMemory; if (size > fCommittedSwapSize) { - TRACE("%p->VMAnonymousCache::_Commit(%lld), reserved only %lld " - "swap\n", this, size, fCommittedSwapSize); + TRACE("%p->VMAnonymousCache::_Commit(%" B_PRIdOFF "), reserved " + "only %" B_PRIdOFF " swap\n", this, size, fCommittedSwapSize); } } @@ -1016,8 +1019,8 @@ VMAnonymousCache::_Commit(off_t size, int priority) off_t toReserve = size - committed_size; if (vm_try_reserve_memory(toReserve, priority, 1000000) != B_OK) { - dprintf("%p->VMAnonymousCache::_Commit(%lld): Failed to reserve %lld " - "bytes of RAM\n", this, size, toReserve); + dprintf("%p->VMAnonymousCache::_Commit(%" B_PRIdOFF "): Failed to " + "reserve %" B_PRIdOFF " bytes of RAM\n", this, size, toReserve); return B_NO_MEMORY; } @@ -1599,8 +1602,8 @@ swap_init_post_modules() status_t error = _kern_write_stat(fd, NULL, false, &stat, sizeof(struct stat), B_STAT_SIZE | B_STAT_SIZE_INSECURE); if (error != B_OK) { - dprintf("%s: Failed to resize %s to %lld bytes: %s\n", __func__, - swapPath, swapSize, strerror(error)); + dprintf("%s: Failed to resize %s to %" B_PRIdOFF " bytes: %s\n", + __func__, swapPath, swapSize, strerror(error)); } close(fd); diff --git a/src/system/kernel/vm/VMCache.cpp b/src/system/kernel/vm/VMCache.cpp index 2e845de85b..a174f1d99f 100644 --- a/src/system/kernel/vm/VMCache.cpp +++ b/src/system/kernel/vm/VMCache.cpp @@ -769,7 +769,7 @@ VMCache::LookupPage(off_t offset) void VMCache::InsertPage(vm_page* page, off_t offset) { - TRACE(("VMCache::InsertPage(): cache %p, page %p, offset %Ld\n", + TRACE(("VMCache::InsertPage(): cache %p, page %p, offset %" B_PRIdOFF "\n", this, page, offset)); AssertLocked(); @@ -1054,8 +1054,8 @@ VMCache::WriteModified() status_t VMCache::SetMinimalCommitment(off_t commitment, int priority) { - TRACE(("VMCache::SetMinimalCommitment(cache %p, commitment %Ld)\n", - this, commitment)); + TRACE(("VMCache::SetMinimalCommitment(cache %p, commitment %" B_PRIdOFF + ")\n", this, commitment)); AssertLocked(); T(SetMinimalCommitment(this, commitment)); @@ -1088,8 +1088,8 @@ VMCache::SetMinimalCommitment(off_t commitment, int priority) status_t VMCache::Resize(off_t newSize, int priority) { - TRACE(("VMCache::Resize(cache %p, newSize %Ld) old size %Ld\n", - this, newSize, this->virtual_end)); + TRACE(("VMCache::Resize(cache %p, newSize %" B_PRIdOFF ") old size %" + B_PRIdOFF "\n", this, newSize, this->virtual_end)); this->AssertLocked(); T(Resize(this, newSize)); @@ -1325,24 +1325,24 @@ void VMCache::Dump(bool showPages) const { kprintf("CACHE %p:\n", this); - kprintf(" ref_count: %ld\n", RefCount()); + kprintf(" ref_count: %" B_PRId32 "\n", RefCount()); kprintf(" source: %p\n", source); kprintf(" type: %s\n", vm_cache_type_to_string(type)); - kprintf(" virtual_base: 0x%Lx\n", virtual_base); - kprintf(" virtual_end: 0x%Lx\n", virtual_end); - kprintf(" temporary: %ld\n", temporary); + kprintf(" virtual_base: 0x%" B_PRIx64 "\n", virtual_base); + kprintf(" virtual_end: 0x%" B_PRIx64 "\n", virtual_end); + kprintf(" temporary: %" B_PRIu32 "\n", temporary); kprintf(" lock: %p\n", &fLock); #if KDEBUG - kprintf(" lock.holder: %ld\n", fLock.holder); + kprintf(" lock.holder: %" B_PRId32 "\n", fLock.holder); #endif kprintf(" areas:\n"); for (VMArea* area = areas; area != NULL; area = area->cache_next) { - kprintf(" area 0x%lx, %s\n", area->id, area->name); + kprintf(" area 0x%" B_PRIx32 ", %s\n", area->id, area->name); kprintf("\tbase_addr: 0x%lx, size: 0x%lx\n", area->Base(), area->Size()); - kprintf("\tprotection: 0x%lx\n", area->protection); - kprintf("\towner: 0x%lx\n", area->address_space->ID()); + kprintf("\tprotection: 0x%" B_PRIx32 "\n", area->protection); + kprintf("\towner: 0x%" B_PRIx32 "\n", area->address_space->ID()); } kprintf(" consumers:\n"); @@ -1367,7 +1367,7 @@ VMCache::Dump(bool showPages) const } } } else - kprintf("\t%ld in cache\n", page_count); + kprintf("\t%" B_PRIu32 " in cache\n", page_count); } @@ -1400,7 +1400,7 @@ VMCache::_MergeWithOnlyConsumer() { VMCache* consumer = consumers.RemoveHead(); - TRACE(("merge vm cache %p (ref == %ld) with vm cache %p\n", + TRACE(("merge vm cache %p (ref == %" B_PRId32 ") with vm cache %p\n", this, this->fRefCount, consumer)); T(Merge(this, consumer)); diff --git a/src/system/kernel/vm/VMUserAddressSpace.cpp b/src/system/kernel/vm/VMUserAddressSpace.cpp index 11782af2cb..32730a41cb 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.cpp +++ b/src/system/kernel/vm/VMUserAddressSpace.cpp @@ -203,7 +203,8 @@ VMUserAddressSpace::CanResizeArea(VMArea* area, size_t newSize) // also be resized in that area // TODO: if there is free space after the reserved area, it could // be used as well... - return next->id == RESERVED_AREA_ID && next->cache_offset <= area->Base() + return next->id == RESERVED_AREA_ID + && (uint64)next->cache_offset <= (uint64)area->Base() && next->Base() + (next->Size() - 1) >= newEnd; } @@ -218,7 +219,7 @@ VMUserAddressSpace::ResizeArea(VMArea* _area, size_t newSize, VMUserArea* next = fAreas.GetNext(area); if (next != NULL && next->Base() <= newEnd) { if (next->id != RESERVED_AREA_ID - || next->cache_offset > area->Base() + || (uint64)next->cache_offset > (uint64)area->Base() || next->Base() + (next->Size() - 1) < newEnd) { panic("resize situation for area %p has changed although we " "should have the address space lock", area); @@ -361,11 +362,11 @@ VMUserAddressSpace::Dump() const for (VMUserAreaList::ConstIterator it = fAreas.GetIterator(); VMUserArea* area = it.Next();) { - kprintf(" area 0x%lx: ", area->id); + kprintf(" area 0x%" B_PRIx32 ": ", area->id); kprintf("base_addr = 0x%lx ", area->Base()); kprintf("size = 0x%lx ", area->Size()); kprintf("name = '%s' ", area->name); - kprintf("protection = 0x%lx\n", area->protection); + kprintf("protection = 0x%" B_PRIx32 "\n", area->protection); } } @@ -460,8 +461,8 @@ VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end, bool foundSpot = false; TRACE(("VMUserAddressSpace::_InsertAreaSlot: address space %p, start " - "0x%lx, size %ld, end 0x%lx, addressSpec %ld, area %p\n", this, start, - size, end, addressSpec, area)); + "0x%lx, size %ld, end 0x%lx, addressSpec %" B_PRIu32 ", area %p\n", + this, start, size, end, addressSpec, area)); // do some sanity checking if (start < fBase || size == 0 || end > fEndAddress @@ -513,8 +514,8 @@ second_chance: // find a hole big enough for a new area if (last == NULL) { // see if we can build it at the beginning of the virtual map - addr_t alignedBase = ROUNDUP(fBase, alignment); - if (is_valid_spot(fBase, alignedBase, size, + addr_t alignedBase = ROUNDUP(start, alignment); + if (is_valid_spot(start, alignedBase, size, next == NULL ? end : next->Base())) { foundSpot = true; area->SetBase(alignedBase); diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index e289def87f..1559491fe5 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -784,10 +784,11 @@ map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset, uint32 flags, const virtual_address_restrictions* addressRestrictions, bool kernel, VMArea** _area, void** _virtualAddress) { - TRACE(("map_backing_store: aspace %p, cache %p, virtual %p, offset 0x%Lx, " - "size %lu, addressSpec %ld, wiring %d, protection %d, area %p, areaName " - "'%s'\n", addressSpace, cache, addressRestrictions->address, offset, - size, addressRestrictions->address_specification, wiring, protection, + TRACE(("map_backing_store: aspace %p, cache %p, virtual %p, offset 0x%" + B_PRIx64 ", size %" B_PRIuADDR ", addressSpec %" B_PRIu32 ", wiring %d" + ", protection %d, area %p, areaName '%s'\n", addressSpace, cache, + addressRestrictions->address, offset, size, + addressRestrictions->address_specification, wiring, protection, _area, areaName)); cache->AssertLocked(); @@ -1191,7 +1192,8 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size, uint32 pageAllocFlags = (flags & CREATE_AREA_DONT_CLEAR) == 0 ? VM_PAGE_ALLOC_CLEAR : 0; - TRACE(("create_anonymous_area [%ld] %s: size 0x%lx\n", team, name, size)); + TRACE(("create_anonymous_area [%" B_PRId32 "] %s: size 0x%" B_PRIxADDR "\n", + team, name, size)); size = PAGE_ALIGN(size); @@ -1557,10 +1559,10 @@ vm_map_physical_memory(team_id team, const char* name, void** _address, VMCache* cache; addr_t mapOffset; - TRACE(("vm_map_physical_memory(aspace = %ld, \"%s\", virtual = %p, " - "spec = %ld, size = %lu, protection = %ld, phys = %#" B_PRIxPHYSADDR - ")\n", team, name, *_address, addressSpec, size, protection, - physicalAddress)); + TRACE(("vm_map_physical_memory(aspace = %" B_PRId32 ", \"%s\", virtual = %p" + ", spec = %" B_PRIu32 ", size = %" B_PRIxADDR ", protection = %" + B_PRIu32 ", phys = %#" B_PRIxPHYSADDR ")\n", team, name, *_address, + addressSpec, size, protection, physicalAddress)); if (!arch_vm_supports_protection(protection)) return B_NOT_SUPPORTED; @@ -1664,10 +1666,10 @@ vm_map_physical_memory_vecs(team_id team, const char* name, void** _address, uint32 addressSpec, addr_t* _size, uint32 protection, struct generic_io_vec* vecs, uint32 vecCount) { - TRACE(("vm_map_physical_memory_vecs(team = %ld, \"%s\", virtual = %p, " - "spec = %ld, _size = %p, protection = %ld, vecs = %p, " - "vecCount = %ld)\n", team, name, *_address, addressSpec, _size, - protection, vecs, vecCount)); + TRACE(("vm_map_physical_memory_vecs(team = %" B_PRId32 ", \"%s\", virtual " + "= %p, spec = %" B_PRIu32 ", _size = %p, protection = %" B_PRIu32 ", " + "vecs = %p, vecCount = %" B_PRIu32 ")\n", team, name, *_address, + addressSpec, _size, protection, vecs, vecCount)); if (!arch_vm_supports_protection(protection) || (addressSpec & B_MTR_MASK) != 0) { @@ -1859,8 +1861,8 @@ _vm_map_file(team_id team, const char* name, void** _address, // copy of a file at a given time, ie. later changes should not // make it into the mapped copy -- this will need quite some changes // to be done in a nice way - TRACE(("_vm_map_file(fd = %d, offset = %Ld, size = %lu, mapping %ld)\n", - fd, offset, size, mapping)); + TRACE(("_vm_map_file(fd = %d, offset = %" B_PRIdOFF ", size = %lu, mapping " + "%" B_PRIu32 ")\n", fd, offset, size, mapping)); offset = ROUNDDOWN(offset, B_PAGE_SIZE); size = PAGE_ALIGN(size); @@ -2249,7 +2251,8 @@ delete_area(VMAddressSpace* addressSpace, VMArea* area, status_t vm_delete_area(team_id team, area_id id, bool kernel) { - TRACE(("vm_delete_area(team = 0x%lx, area = 0x%lx)\n", team, id)); + TRACE(("vm_delete_area(team = 0x%" B_PRIx32 ", area = 0x%" B_PRIx32 ")\n", + team, id)); // lock the address space and make sure the area isn't wired AddressSpaceWriteLocker locker; @@ -2520,8 +2523,8 @@ static status_t vm_set_area_protection(team_id team, area_id areaID, uint32 newProtection, bool kernel) { - TRACE(("vm_set_area_protection(team = %#lx, area = %#lx, protection = " - "%#lx)\n", team, areaID, newProtection)); + TRACE(("vm_set_area_protection(team = %#" B_PRIx32 ", area = %#" B_PRIx32 + ", protection = %#" B_PRIx32 ")\n", team, areaID, newProtection)); if (!arch_vm_supports_protection(newProtection)) return B_NOT_SUPPORTED; @@ -2972,16 +2975,16 @@ display_mem(int argc, char** argv) switch (itemSize) { case 1: - kprintf(" %02x", *(uint8*)&value); + kprintf(" %02" B_PRIx8, *(uint8*)&value); break; case 2: - kprintf(" %04x", *(uint16*)&value); + kprintf(" %04" B_PRIx16, *(uint16*)&value); break; case 4: - kprintf(" %08lx", *(uint32*)&value); + kprintf(" %08" B_PRIx32, *(uint32*)&value); break; case 8: - kprintf(" %016Lx", *(uint64*)&value); + kprintf(" %016" B_PRIx64, *(uint64*)&value); break; } } @@ -3106,15 +3109,15 @@ dump_caches_recursively(VMCache* cache, cache_info& info, int level) for (int i = 0; i < level; i++) kprintf(" "); - kprintf("%p: type: %s, base: %lld, size: %lld, pages: %lu", cache, - vm_cache_type_to_string(cache->type), cache->virtual_base, - cache->virtual_end, cache->page_count); + kprintf("%p: type: %s, base: %" B_PRIdOFF ", size: %" B_PRIdOFF ", " + "pages: %" B_PRIu32, cache, vm_cache_type_to_string(cache->type), + cache->virtual_base, cache->virtual_end, cache->page_count); if (level == 0) kprintf("/%lu", info.page_count); if (cache->type == CACHE_TYPE_RAM || (level == 0 && info.committed > 0)) { - kprintf(", committed: %lld", cache->committed_size); + kprintf(", committed: %" B_PRIdOFF, cache->committed_size); if (level == 0) kprintf("/%lu", info.committed); @@ -3123,12 +3126,12 @@ dump_caches_recursively(VMCache* cache, cache_info& info, int level) // areas if (cache->areas != NULL) { VMArea* area = cache->areas; - kprintf(", areas: %ld (%s, team: %ld)", area->id, area->name, - area->address_space->ID()); + kprintf(", areas: %" B_PRId32 " (%s, team: %" B_PRId32 ")", area->id, + area->name, area->address_space->ID()); while (area->cache_next != NULL) { area = area->cache_next; - kprintf(", %ld", area->id); + kprintf(", %" B_PRId32, area->id); } } @@ -3194,9 +3197,9 @@ dump_caches(int argc, char** argv) kprintf("total committed memory: %" B_PRIdOFF ", total used pages: %" B_PRIuPHYSADDR "\n", totalCommitted, totalPages); - kprintf("%lu caches (%lu root caches), sorted by %s per cache " - "tree...\n\n", totalCount, rootCount, - sortByPageCount ? "page count" : "committed size"); + kprintf("%" B_PRIu32 " caches (%" B_PRIu32 " root caches), sorted by %s " + "per cache tree...\n\n", totalCount, rootCount, sortByPageCount ? + "page count" : "committed size"); if (rootCount <= (uint32)kCacheInfoTableCount) { for (uint32 i = 0; i < rootCount; i++) { @@ -3258,16 +3261,16 @@ dump_area_struct(VMArea* area, bool mappings) { kprintf("AREA: %p\n", area); kprintf("name:\t\t'%s'\n", area->name); - kprintf("owner:\t\t0x%lx\n", area->address_space->ID()); - kprintf("id:\t\t0x%lx\n", area->id); + kprintf("owner:\t\t0x%" B_PRIx32 "\n", area->address_space->ID()); + kprintf("id:\t\t0x%" B_PRIx32 "\n", area->id); kprintf("base:\t\t0x%lx\n", area->Base()); kprintf("size:\t\t0x%lx\n", area->Size()); - kprintf("protection:\t0x%lx\n", area->protection); + kprintf("protection:\t0x%" B_PRIx32 "\n", area->protection); kprintf("wiring:\t\t0x%x\n", area->wiring); kprintf("memory_type:\t%#" B_PRIx32 "\n", area->MemoryType()); kprintf("cache:\t\t%p\n", area->cache); kprintf("cache_type:\t%s\n", vm_cache_type_to_string(area->cache_type)); - kprintf("cache_offset:\t0x%Lx\n", area->cache_offset); + kprintf("cache_offset:\t0x%" B_PRIx64 "\n", area->cache_offset); kprintf("cache_next:\t%p\n", area->cache_next); kprintf("cache_prev:\t%p\n", area->cache_prev); @@ -3284,7 +3287,7 @@ dump_area_struct(VMArea* area, bool mappings) while (iterator.Next() != NULL) { count++; } - kprintf("page mappings:\t%lu\n", count); + kprintf("page mappings:\t%" B_PRIu32 "\n", count); } } @@ -3369,7 +3372,9 @@ dump_area_list(int argc, char** argv) name = argv[1]; } - kprintf("addr id base\t\tsize protect lock name\n"); + kprintf("%-*s id %-*s %-*sprotect lock name\n", + B_PRINTF_POINTER_WIDTH, "addr", B_PRINTF_POINTER_WIDTH, "base", + B_PRINTF_POINTER_WIDTH, "size"); VMAreaHashTable::Iterator it = VMAreaHash::GetIterator(); while ((area = it.Next()) != NULL) { @@ -3377,9 +3382,9 @@ dump_area_list(int argc, char** argv) || (name != NULL && strstr(area->name, name) == NULL)) continue; - kprintf("%p %5lx %p\t%p %4lx\t%4d %s\n", area, area->id, - (void*)area->Base(), (void*)area->Size(), area->protection, - area->wiring, area->name); + kprintf("%p %5" B_PRIx32 " %p %p %4" B_PRIx32 " %4d %s\n", area, + area->id, (void*)area->Base(), (void*)area->Size(), + area->protection, area->wiring, area->name); } return 0; } @@ -3405,7 +3410,7 @@ dump_available_memory(int argc, char** argv) void vm_delete_areas(struct VMAddressSpace* addressSpace, bool deletingAddressSpace) { - TRACE(("vm_delete_areas: called on address space 0x%lx\n", + TRACE(("vm_delete_areas: called on address space 0x%" B_PRIx32 "\n", addressSpace->ID())); addressSpace->WriteLock(); @@ -3538,8 +3543,9 @@ vm_free_unused_boot_loader_range(addr_t start, addr_t size) static void -create_preloaded_image_areas(struct preloaded_image* image) +create_preloaded_image_areas(struct preloaded_image* _image) { + preloaded_elf_image* image = static_cast(_image); char name[B_OS_NAME_LENGTH]; void* address; int32 length; @@ -3585,7 +3591,7 @@ vm_free_kernel_args(kernel_args* args) TRACE(("vm_free_kernel_args()\n")); for (i = 0; i < args->num_kernel_args_ranges; i++) { - area_id area = area_for((void*)args->kernel_args_range[i].start); + area_id area = area_for((void*)(addr_t)args->kernel_args_range[i].start); if (area >= B_OK) delete_area(area); } @@ -3598,7 +3604,7 @@ allocate_kernel_args(kernel_args* args) TRACE(("allocate_kernel_args()\n")); for (uint32 i = 0; i < args->num_kernel_args_ranges; i++) { - void* address = (void*)args->kernel_args_range[i].start; + void* address = (void*)(addr_t)args->kernel_args_range[i].start; create_area("_kernel args_", &address, B_EXACT_ADDRESS, args->kernel_args_range[i].size, B_ALREADY_WIRED, @@ -3614,7 +3620,7 @@ unreserve_boot_loader_ranges(kernel_args* args) for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) { vm_unreserve_address_range(VMAddressSpace::KernelID(), - (void*)args->virtual_allocated_range[i].start, + (void*)(addr_t)args->virtual_allocated_range[i].start, args->virtual_allocated_range[i].size); } } @@ -3626,13 +3632,13 @@ reserve_boot_loader_ranges(kernel_args* args) TRACE(("reserve_boot_loader_ranges()\n")); for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) { - void* address = (void*)args->virtual_allocated_range[i].start; + void* address = (void*)(addr_t)args->virtual_allocated_range[i].start; // If the address is no kernel address, we just skip it. The // architecture specific code has to deal with it. if (!IS_KERNEL_ADDRESS(address)) { - dprintf("reserve_boot_loader_ranges(): Skipping range: %p, %lu\n", - address, args->virtual_allocated_range[i].size); + dprintf("reserve_boot_loader_ranges(): Skipping range: %p, %" + B_PRIu64 "\n", address, args->virtual_allocated_range[i].size); continue; } @@ -3842,7 +3848,7 @@ vm_init(kernel_args* args) allocate_kernel_args(args); - create_preloaded_image_areas(&args->kernel_image); + create_preloaded_image_areas(args->kernel_image); // allocate areas for preloaded images for (image = args->preloaded_images; image != NULL; image = image->next) @@ -3852,7 +3858,7 @@ vm_init(kernel_args* args) for (i = 0; i < args->num_cpus; i++) { char name[64]; - sprintf(name, "idle thread %lu kstack", i + 1); + sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1); address = (void*)args->cpu_kstack[i].start; create_area(name, &address, B_EXACT_ADDRESS, args->cpu_kstack[i].size, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); @@ -4035,7 +4041,7 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser, if (status < B_OK) { dprintf("vm_page_fault: vm_soft_fault returned error '%s' on fault at " - "0x%lx, ip 0x%lx, write %d, user %d, thread 0x%lx\n", + "0x%lx, ip 0x%lx, write %d, user %d, thread 0x%" B_PRIx32 "\n", strerror(status), address, faultAddress, isWrite, isUser, thread_get_current_thread_id()); if (!isUser) { @@ -4052,19 +4058,22 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser, } } else { #if 1 - addressSpace->ReadLock(); - // TODO: remove me once we have proper userland debugging support // (and tools) - VMArea* area = addressSpace->LookupArea(faultAddress); + VMArea* area = NULL; + if (addressSpace != NULL) { + addressSpace->ReadLock(); + area = addressSpace->LookupArea(faultAddress); + } Thread* thread = thread_get_current_thread(); - dprintf("vm_page_fault: thread \"%s\" (%ld) in team \"%s\" (%ld) " - "tried to %s address %#lx, ip %#lx (\"%s\" +%#lx)\n", - thread->name, thread->id, thread->team->Name(), - thread->team->id, isWrite ? "write" : "read", address, - faultAddress, area ? area->name : "???", - faultAddress - (area ? area->Base() : 0x0)); + dprintf("vm_page_fault: thread \"%s\" (%" B_PRId32 ") in team " + "\"%s\" (%" B_PRId32 ") tried to %s address %#lx, ip %#lx " + "(\"%s\" +%#lx)\n", thread->name, thread->id, + thread->team->Name(), thread->team->id, + isWrite ? "write" : "read", address, faultAddress, + area ? area->name : "???", faultAddress - (area ? + area->Base() : 0x0)); // We can print a stack trace of the userland thread here. // TODO: The user_memcpy() below can cause a deadlock, if it causes a page @@ -4083,7 +4092,7 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser, #endif } frame; # ifdef __INTEL__ - struct iframe* iframe = i386_get_user_iframe(); + struct iframe* iframe = x86_get_user_iframe(); if (iframe == NULL) panic("iframe is NULL!"); @@ -4120,28 +4129,25 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser, } # endif // 0 (stack trace) - addressSpace->ReadUnlock(); + if (addressSpace != NULL) + addressSpace->ReadUnlock(); #endif - // TODO: the fault_callback is a temporary solution for vm86 - if (thread->fault_callback == NULL - || thread->fault_callback(address, faultAddress, isWrite)) { - // If the thread has a signal handler for SIGSEGV, we simply - // send it the signal. Otherwise we notify the user debugger - // first. - struct sigaction action; - if ((sigaction(SIGSEGV, NULL, &action) == 0 - && action.sa_handler != SIG_DFL - && action.sa_handler != SIG_IGN) - || user_debug_exception_occurred(B_SEGMENT_VIOLATION, - SIGSEGV)) { - Signal signal(SIGSEGV, - status == B_PERMISSION_DENIED - ? SEGV_ACCERR : SEGV_MAPERR, - EFAULT, thread->team->id); - signal.SetAddress((void*)address); - send_signal_to_thread(thread, signal, 0); - } + // If the thread has a signal handler for SIGSEGV, we simply + // send it the signal. Otherwise we notify the user debugger + // first. + struct sigaction action; + if ((sigaction(SIGSEGV, NULL, &action) == 0 + && action.sa_handler != SIG_DFL + && action.sa_handler != SIG_IGN) + || user_debug_exception_occurred(B_SEGMENT_VIOLATION, + SIGSEGV)) { + Signal signal(SIGSEGV, + status == B_PERMISSION_DENIED + ? SEGV_ACCERR : SEGV_MAPERR, + EFAULT, thread->team->id); + signal.SetAddress((void*)address); + send_signal_to_thread(thread, signal, 0); } } } @@ -4357,8 +4363,9 @@ static status_t vm_soft_fault(VMAddressSpace* addressSpace, addr_t originalAddress, bool isWrite, bool isUser, vm_page** wirePage, VMAreaWiredRange* wiredRange) { - FTRACE(("vm_soft_fault: thid 0x%lx address 0x%lx, isWrite %d, isUser %d\n", - thread_get_current_thread_id(), originalAddress, isWrite, isUser)); + FTRACE(("vm_soft_fault: thid 0x%" B_PRIx32 " address 0x%" B_PRIxADDR ", " + "isWrite %d, isUser %d\n", thread_get_current_thread_id(), + originalAddress, isWrite, isUser)); PageFaultContext context(addressSpace, isWrite); @@ -4394,8 +4401,8 @@ vm_soft_fault(VMAddressSpace* addressSpace, addr_t originalAddress, // check permissions uint32 protection = get_area_page_protection(area, address); if (isUser && (protection & B_USER_PROTECTION) == 0) { - dprintf("user access on kernel area 0x%lx at %p\n", area->id, - (void*)originalAddress); + dprintf("user access on kernel area 0x%" B_PRIx32 " at %p\n", + area->id, (void*)originalAddress); TPF(PageFaultError(area->id, VMPageFaultTracing::PAGE_FAULT_ERROR_KERNEL_ONLY)); status = B_PERMISSION_DENIED; @@ -4403,16 +4410,16 @@ vm_soft_fault(VMAddressSpace* addressSpace, addr_t originalAddress, } if (isWrite && (protection & (B_WRITE_AREA | (isUser ? 0 : B_KERNEL_WRITE_AREA))) == 0) { - dprintf("write access attempted on write-protected area 0x%lx at" - " %p\n", area->id, (void*)originalAddress); + dprintf("write access attempted on write-protected area 0x%" + B_PRIx32 " at %p\n", area->id, (void*)originalAddress); TPF(PageFaultError(area->id, VMPageFaultTracing::PAGE_FAULT_ERROR_WRITE_PROTECTED)); status = B_PERMISSION_DENIED; break; } else if (!isWrite && (protection & (B_READ_AREA | (isUser ? 0 : B_KERNEL_READ_AREA))) == 0) { - dprintf("read access attempted on read-protected area 0x%lx at" - " %p\n", area->id, (void*)originalAddress); + dprintf("read access attempted on read-protected area 0x%" B_PRIx32 + " at %p\n", area->id, (void*)originalAddress); TPF(PageFaultError(area->id, VMPageFaultTracing::PAGE_FAULT_ERROR_READ_PROTECTED)); status = B_PERMISSION_DENIED; @@ -4673,7 +4680,7 @@ vm_try_reserve_memory(size_t amount, int priority, bigtime_t timeout) //dprintf("try to reserve %lu bytes, %Lu left\n", amount, sAvailableMemory); - if (sAvailableMemory >= amount + reserve) { + if (sAvailableMemory >= (off_t)(amount + reserve)) { sAvailableMemory -= amount; return B_OK; } @@ -4696,7 +4703,7 @@ vm_try_reserve_memory(size_t amount, int priority, bigtime_t timeout) sNeededMemory -= amount; - if (sAvailableMemory >= amount + reserve) { + if (sAvailableMemory >= (off_t)(amount + reserve)) { sAvailableMemory -= amount; return B_OK; } @@ -5601,8 +5608,8 @@ get_memory_map_etc(team_id team, const void* address, size_t numBytes, addr_t offset = 0; bool interrupts = are_interrupts_enabled(); - TRACE(("get_memory_map_etc(%ld, %p, %lu bytes, %ld entries)\n", team, - address, numBytes, numEntries)); + TRACE(("get_memory_map_etc(%" B_PRId32 ", %p, %lu bytes, %" B_PRIu32 " " + "entries)\n", team, address, numBytes, numEntries)); if (numEntries == 0 || numBytes == 0) return B_BAD_VALUE; @@ -5742,7 +5749,7 @@ _get_area_info(area_id id, area_info* info, size_t size) status_t -_get_next_area_info(team_id team, int32* cookie, area_info* info, size_t size) +_get_next_area_info(team_id team, ssize_t* cookie, area_info* info, size_t size) { addr_t nextBase = *(addr_t*)cookie; @@ -5771,8 +5778,7 @@ _get_next_area_info(team_id team, int32* cookie, area_info* info, size_t size) } fill_area_info(area, info, size); - *cookie = (int32)(area->Base()); - // TODO: Not 64 bit safe! + *cookie = (ssize_t)(area->Base()); return B_OK; } @@ -5979,13 +5985,13 @@ _user_get_area_info(area_id area, area_info* userInfo) status_t -_user_get_next_area_info(team_id team, int32* userCookie, area_info* userInfo) +_user_get_next_area_info(team_id team, ssize_t* userCookie, area_info* userInfo) { - int32 cookie; + ssize_t cookie; if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo) - || user_memcpy(&cookie, userCookie, sizeof(int32)) < B_OK) + || user_memcpy(&cookie, userCookie, sizeof(ssize_t)) < B_OK) return B_BAD_ADDRESS; area_info info; @@ -5996,7 +6002,7 @@ _user_get_next_area_info(team_id team, int32* userCookie, area_info* userInfo) //info.protection &= B_USER_PROTECTION; - if (user_memcpy(userCookie, &cookie, sizeof(int32)) < B_OK + if (user_memcpy(userCookie, &cookie, sizeof(ssize_t)) < B_OK || user_memcpy(userInfo, &info, sizeof(area_info)) < B_OK) return B_BAD_ADDRESS; diff --git a/src/system/kernel/vm/vm_page.cpp b/src/system/kernel/vm/vm_page.cpp index d2add5a297..47011a2ee1 100644 --- a/src/system/kernel/vm/vm_page.cpp +++ b/src/system/kernel/vm/vm_page.cpp @@ -943,8 +943,8 @@ dump_page(int argc, char **argv) && physicalAddress / B_PAGE_SIZE == page->physical_page_number) { VMArea* area = addressSpace->LookupArea(address); - kprintf(" aspace %ld, area %ld: %#" B_PRIxADDR - " (%c%c%s%s)\n", addressSpace->ID(), + kprintf(" aspace %" B_PRId32 ", area %" B_PRId32 ": %#" + B_PRIxADDR " (%c%c%s%s)\n", addressSpace->ID(), area != NULL ? area->id : -1, address, (flags & B_KERNEL_READ_AREA) != 0 ? 'r' : '-', (flags & B_KERNEL_WRITE_AREA) != 0 ? 'w' : '-', @@ -1117,7 +1117,7 @@ dump_page_stats(int argc, char **argv) kprintf("unreserved free pages: %" B_PRId32 "\n", sUnreservedFreePages); kprintf("unsatisfied page reservations: %" B_PRId32 "\n", sUnsatisfiedPageReservations); - kprintf("mapped pages: %lu\n", gMappedPagesCount); + kprintf("mapped pages: %" B_PRId32 "\n", gMappedPagesCount); kprintf("longest free pages run: %" B_PRIuPHYSADDR " pages (at %" B_PRIuPHYSADDR ")\n", longestFreeRun.Length(), sPages[longestFreeRun.start].physical_page_number); @@ -2449,8 +2449,8 @@ page_writer(void* /*unused*/) writtenPages += numPages; if (writtenPages >= 1024) { bigtime_t now = system_time(); - TRACE(("page writer: wrote 1024 pages (total: %llu ms, " - "collect: %llu ms, write: %llu ms)\n", + TRACE(("page writer: wrote 1024 pages (total: %" B_PRIu64 " ms, " + "collect: %" B_PRIu64 " ms, write: %" B_PRIu64 " ms)\n", (now - lastWrittenTime) / 1000, pageCollectionTime / 1000, pageWritingTime / 1000)); lastWrittenTime = now; @@ -2808,9 +2808,10 @@ full_scan_inactive_pages(page_stats& pageStats, int32 despairLevel) queueLocker.Unlock(); time = system_time() - time; - TRACE_DAEMON(" -> inactive scan (%7lld us): scanned: %7lu, " - "moved: %lu -> cached, %lu -> modified, %lu -> active\n", time, - pagesScanned, pagesToCached, pagesToModified, pagesToActive); + TRACE_DAEMON(" -> inactive scan (%7" B_PRId64 " us): scanned: %7" B_PRIu32 + ", moved: %" B_PRIu32 " -> cached, %" B_PRIu32 " -> modified, %" + B_PRIu32 " -> active\n", time, pagesScanned, pagesToCached, + pagesToModified, pagesToActive); // wake up the page writer, if we tossed it some pages if (pagesToModified > 0) @@ -2904,9 +2905,9 @@ full_scan_active_pages(page_stats& pageStats, int32 despairLevel) } time = system_time() - time; - TRACE_DAEMON(" -> active scan (%7lld us): scanned: %7lu, " - "moved: %lu -> inactive, encountered %lu accessed ones\n", time, - pagesScanned, pagesToInactive, pagesAccessed); + TRACE_DAEMON(" -> active scan (%7" B_PRId64 " us): scanned: %7" B_PRIu32 + ", moved: %" B_PRIu32 " -> inactive, encountered %" B_PRIu32 " accessed" + " ones\n", time, pagesScanned, pagesToInactive, pagesAccessed); } @@ -2934,9 +2935,10 @@ page_daemon_idle_scan(page_stats& pageStats) static void page_daemon_full_scan(page_stats& pageStats, int32 despairLevel) { - TRACE_DAEMON("page daemon: full run: free: %lu, cached: %lu, " - "to free: %lu\n", pageStats.totalFreePages, pageStats.cachedPages, - pageStats.unsatisfiedReservations + sFreeOrCachedPagesTarget + TRACE_DAEMON("page daemon: full run: free: %" B_PRIu32 ", cached: %" + B_PRIu32 ", to free: %" B_PRIu32 "\n", pageStats.totalFreePages, + pageStats.cachedPages, pageStats.unsatisfiedReservations + + sFreeOrCachedPagesTarget - (pageStats.totalFreePages + pageStats.cachedPages)); // Walk the inactive list and transfer pages to the cached and modified diff --git a/src/system/ldscripts/x86_64/boot_loader_bios_ia32.ld b/src/system/ldscripts/x86_64/boot_loader_bios_ia32.ld new file mode 100644 index 0000000000..6cc9efd4a6 --- /dev/null +++ b/src/system/ldscripts/x86_64/boot_loader_bios_ia32.ld @@ -0,0 +1,33 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) + +ENTRY(_start) +SECTIONS +{ + . = 0x10000; + + /* text/read-only data */ + .text : { *(.text .gnu.linkonce.t.*) } + + . = ALIGN(0x4); + __ctor_list = .; + .ctors : { *(.ctors) } + __ctor_end = .; + + .rodata : { *(.rodata .rodata.*) } + + /* writable data */ + . = ALIGN(0x1000); + __data_start = .; + .data : { *(.data .gnu.linkonce.d.*) } + + /* uninitialized data (in same segment as writable data) */ + __bss_start = .; + .bss : { *(.bss) } + + . = ALIGN(0x1000); + _end = . ; + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame .dtors .stab .stabstr .debug*) } +} diff --git a/src/system/ldscripts/x86_64/boot_loader_pxe_ia32.ld b/src/system/ldscripts/x86_64/boot_loader_pxe_ia32.ld new file mode 100644 index 0000000000..6cc9efd4a6 --- /dev/null +++ b/src/system/ldscripts/x86_64/boot_loader_pxe_ia32.ld @@ -0,0 +1,33 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) + +ENTRY(_start) +SECTIONS +{ + . = 0x10000; + + /* text/read-only data */ + .text : { *(.text .gnu.linkonce.t.*) } + + . = ALIGN(0x4); + __ctor_list = .; + .ctors : { *(.ctors) } + __ctor_end = .; + + .rodata : { *(.rodata .rodata.*) } + + /* writable data */ + . = ALIGN(0x1000); + __data_start = .; + .data : { *(.data .gnu.linkonce.d.*) } + + /* uninitialized data (in same segment as writable data) */ + __bss_start = .; + .bss : { *(.bss) } + + . = ALIGN(0x1000); + _end = . ; + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame .dtors .stab .stabstr .debug*) } +} diff --git a/src/system/ldscripts/x86_64/kernel.ld b/src/system/ldscripts/x86_64/kernel.ld new file mode 100644 index 0000000000..5b454248db --- /dev/null +++ b/src/system/ldscripts/x86_64/kernel.ld @@ -0,0 +1,55 @@ +OUTPUT_FORMAT("elf64-x86-64") +OUTPUT_ARCH("i386:x86-64") + +ENTRY(_start) +SECTIONS +{ + . = 0xFFFFFFFF80000000 + SIZEOF_HEADERS; + + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rela.got : { *(.rela.got) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.init : { *(.rela.init) } + .rela.fini : { *(.rela.fini) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x90909090 + .plt : { *(.plt) } + + /* text/read-only data */ + .text : { *(.text .text.* .gnu.linkonce.t.*) } =0x90909090 + + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + + /* writable data */ + . = ALIGN (0x1000); + __data_start = .; + .data : { *(.data .data.* .gnu.linkonce.d.*) } + + . = ALIGN(0x4); + __ctor_list = .; + .ctors : { *(.ctors) } + __ctor_end = .; + __dtor_list = .; + .dtors : { *(.dtors) } + __dtor_end = .; + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + + /* uninitialized data (in same segment as writable data) */ + __bss_start = .; + .bss : { *(.bss .bss.* .gnu.linkonce.b.*) } + + . = ALIGN(0x1000); + _end = . ; + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame) } +} diff --git a/src/system/ldscripts/x86_64/runtime_loader.ld b/src/system/ldscripts/x86_64/runtime_loader.ld new file mode 100644 index 0000000000..a83a6de457 --- /dev/null +++ b/src/system/ldscripts/x86_64/runtime_loader.ld @@ -0,0 +1,53 @@ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) + +ENTRY(runtime_loader) +SEARCH_DIR("libgcc"); +SECTIONS +{ + . = 0x00200000 + SIZEOF_HEADERS; + + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rela.got : { *(.rela.got) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.init : { *(.rela.init) } + .rela.fini : { *(.rela.fini) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x90909090 + .plt : { *(.plt) } + + /* text/read-only data */ + .text : { *(.text .text.* .gnu.linkonce.t.*) } =0x90909090 + + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + + /* writable data */ + . = ALIGN (CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); + __data_start = .; + PROVIDE(_data_start = .); + .data : { *(.data .gnu.linkonce.d.*) } + + __ctor_list = .; + PROVIDE (_ctor_list = .); + .ctors : { *(.ctors) } + PROVIDE (__ctor_end = .); + + + /* uninitialized data (in same segment as writable data) */ + PROVIDE (__bss_start = .); + .bss : { *(.bss) } + + . = ALIGN(0x1000); + PROVIDE (_end = .); + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame .dtors) } +} diff --git a/src/system/libroot/os/arch/arm/Jamfile b/src/system/libroot/os/arch/arm/Jamfile index 52b5f241fb..2ebb171b6d 100644 --- a/src/system/libroot/os/arch/arm/Jamfile +++ b/src/system/libroot/os/arch/arm/Jamfile @@ -9,6 +9,7 @@ MergeObject os_arch_$(TARGET_ARCH).o : atomic.S byteorder.S system_time.c + stack_frame.c thread.c time.c tls.c diff --git a/src/system/libroot/os/arch/arm/stack_frame.c b/src/system/libroot/os/arch/arm/stack_frame.c new file mode 100644 index 0000000000..30223cbcea --- /dev/null +++ b/src/system/libroot/os/arch/arm/stack_frame.c @@ -0,0 +1,27 @@ +/* + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol + */ + +#include + +#include + + +void* +get_stack_frame(void) +{ + // TODO: Implement! + return NULL; +} + + +void* +__arch_get_caller(void) +{ + // TODO: Implement! + return NULL; +} diff --git a/src/system/libroot/os/arch/arm/system_time.c b/src/system/libroot/os/arch/arm/system_time.c index 7fd1fd4dd1..6514ae92e4 100644 --- a/src/system/libroot/os/arch/arm/system_time.c +++ b/src/system/libroot/os/arch/arm/system_time.c @@ -1,6 +1,9 @@ /* - * Copyright 2006, Ingo Weinhold . - * All rights reserved. Distributed under the terms of the MIT License. + * Copyright 2012, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol */ #include @@ -9,10 +12,29 @@ #include #include +static vint32 *sConversionFactor; + +void +__arm_setup_system_time(vint32 *cvFactor) +{ + sConversionFactor = cvFactor; +} + + +//XXX: this is a hack +// remove me when platform code works +static int64 +__arm_get_time_base(void) +{ + static uint64 time_dilation_field = 0; + return time_dilation_field++; +} bigtime_t system_time(void) { -#warning ARM:WRITEME - return 0; + uint64 timeBase = __arm_get_time_base(); + + uint32 cv = *sConversionFactor; + return (timeBase >> 32) * cv + (((timeBase & 0xffffffff) * cv) >> 32); } diff --git a/src/system/libroot/os/arch/x86/Jamfile b/src/system/libroot/os/arch/x86/Jamfile index 7806e44481..786a76eeda 100644 --- a/src/system/libroot/os/arch/x86/Jamfile +++ b/src/system/libroot/os/arch/x86/Jamfile @@ -19,7 +19,7 @@ MergeObject os_arch_$(TARGET_ARCH).o : system_info.c system_time_asm.S thread.c - time.c + time.cpp tls.c $(compatibilitySources) diff --git a/src/system/libroot/os/arch/x86/time.c b/src/system/libroot/os/arch/x86/time.cpp similarity index 100% rename from src/system/libroot/os/arch/x86/time.c rename to src/system/libroot/os/arch/x86/time.cpp diff --git a/src/system/libroot/os/arch/x86_64/Jamfile b/src/system/libroot/os/arch/x86_64/Jamfile new file mode 100644 index 0000000000..72a195ed84 --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/Jamfile @@ -0,0 +1,17 @@ +SubDir HAIKU_TOP src system libroot os arch x86_64 ; + +UsePrivateKernelHeaders ; + # TODO: Replace by "UsePrivateHeaders libroot" after resolving the TODO in + # time.c! +UsePrivateSystemHeaders ; + +MergeObject os_arch_$(TARGET_ARCH).o : + atomic.S + byteorder.S + get_stack_frame.S + system_info.cpp + system_time_asm.S + thread.cpp + time.cpp + tls.cpp +; diff --git a/src/system/libroot/os/arch/x86_64/atomic.S b/src/system/libroot/os/arch/x86_64/atomic.S new file mode 100644 index 0000000000..7abf2d2743 --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/atomic.S @@ -0,0 +1,128 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + + +.text + +/* int32 atomic_set(vint32 *value, int32 newValue) */ +FUNCTION(atomic_set): + movl %esi, %eax + lock + xchgl %eax, (%rdi) + ret +FUNCTION_END(atomic_set) + +/* int32 atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst) */ +FUNCTION(atomic_test_and_set): + movl %edx, %eax + lock + cmpxchgl %esi, (%rdi) + ret +FUNCTION_END(atomic_test_and_set) + +/* int32 atomic_add(vint32 *value, int32 addValue) */ +FUNCTION(atomic_add): + movl %esi, %eax + lock + xaddl %eax, (%rdi) + ret +FUNCTION_END(atomic_add) + +/* int32 atomic_and(vint32 *value, int32 andValue) */ +FUNCTION(atomic_and): + movl (%rdi), %eax +1: movl %eax, %edx + movl %eax, %ecx + andl %esi, %edx + lock + cmpxchgl %edx, (%rdi) + jnz 1b + movl %ecx, %eax + ret +FUNCTION_END(atomic_and) + +/* int32 atomic_or(vint32 *value, int32 orValue) */ +FUNCTION(atomic_or): + movl (%rdi), %eax +1: movl %eax, %edx + movl %eax, %ecx + orl %esi, %edx + lock + cmpxchgl %edx, (%rdi) + jnz 1b + movl %ecx, %eax + ret +FUNCTION_END(atomic_or) + +/* int32 atomic_get(vint32 *value) */ +FUNCTION(atomic_get): + movl (%rdi), %eax +1: lock + cmpxchgl %eax, (%rdi) + jnz 1b + ret +FUNCTION_END(atomic_get) + +/* int64 atomic_set64(vint64 *value, int64 newValue) */ +FUNCTION(atomic_set64): + movq %rsi, %rax + lock + xchgq %rax, (%rdi) + ret +FUNCTION_END(atomic_set64) + +/* int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) */ +FUNCTION(atomic_test_and_set64): + movq %rdx, %rax + lock + cmpxchgq %rsi, (%rdi) + ret +FUNCTION_END(atomic_test_and_set64) + +/* int64 atomic_add64(vint64 *value, int64 addValue) */ +FUNCTION(atomic_add64): + movq %rsi, %rax + lock + xaddq %rax, (%rdi) + ret +FUNCTION_END(atomic_add64) + +/* int64 atomic_and64(vint64 *value, int64 andValue) */ +FUNCTION(atomic_and64): + movq (%rdi), %rax +1: movq %rax, %rdx + movq %rax, %rcx + andq %rsi, %rdx + lock + cmpxchgq %rdx, (%rdi) + jnz 1b + movq %rcx, %rax + ret +FUNCTION_END(atomic_and64) + +/* int64 atomic_or64(vint64 *value, int64 orValue) */ +FUNCTION(atomic_or64): + movq (%rdi), %rax +1: movq %rax, %rdx + movq %rax, %rcx + orq %rsi, %rdx + lock + cmpxchgq %rdx, (%rdi) + jnz 1b + movq %rcx, %rax + ret +FUNCTION_END(atomic_or64) + +/* int64 atomic_get64(vint64 *value) */ +FUNCTION(atomic_get64): + movq (%rdi), %rax +1: lock + cmpxchgq %rax, (%rdi) + jnz 1b + ret +FUNCTION_END(atomic_get64) diff --git a/src/system/libroot/os/arch/x86_64/byteorder.S b/src/system/libroot/os/arch/x86_64/byteorder.S new file mode 100644 index 0000000000..9b346809fa --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/byteorder.S @@ -0,0 +1,54 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + + +/* uint16 __swap_int16(uint16 value) */ +FUNCTION(__swap_int16): + movl %edi, %eax + bswap %eax + shr $16, %eax + ret +FUNCTION_END(__swap_int16) + +/* uint32 __swap_int32(uint32 value) */ +FUNCTION(__swap_int32): + movl %edi, %eax + bswap %eax + ret +FUNCTION_END(__swap_int32) + +/* uint64 __swap_int64(uint64 value) */ +FUNCTION(__swap_int64): + movq %rdi, %rax + bswap %rax + ret +FUNCTION_END(__swap_int64) + +/* float __swap_float(float value) */ +FUNCTION(__swap_float): + sub $8, %rsp + movss %xmm0, (%rsp) + movl (%rsp), %eax + bswap %eax + movl %eax, (%rsp) + movss (%rsp), %xmm0 + add $8, %rsp + ret +FUNCTION_END(__swap_float) + +/* double __swap_double(double value) */ +FUNCTION(__swap_double): + sub $8, %rsp + movsd %xmm0, (%rsp) + movq (%rsp), %rax + bswap %rax + movq %rax, (%rsp) + movsd (%rsp), %xmm0 + add $8, %rsp + ret +FUNCTION_END(__swap_double) diff --git a/src/system/libroot/os/arch/x86_64/get_stack_frame.S b/src/system/libroot/os/arch/x86_64/get_stack_frame.S new file mode 100644 index 0000000000..0eaee36523 --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/get_stack_frame.S @@ -0,0 +1,22 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. +*/ + + +#include + + +/* void* get_stack_frame(void) */ +FUNCTION(get_stack_frame): + movq %rbp, %rax + ret +FUNCTION_END(get_stack_frame) + + +/* void* __arch_get_caller(void); */ +FUNCTION(__arch_get_caller): + movq 8(%rbp), %rax + ret +FUNCTION_END(__arch_get_caller) + diff --git a/src/system/libroot/os/arch/x86_64/syscalls.inc b/src/system/libroot/os/arch/x86_64/syscalls.inc new file mode 100644 index 0000000000..9a4881cddc --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/syscalls.inc @@ -0,0 +1,55 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include + + +// The kernel follows the AMD64 ABI for parameter passing (first 6 arguments in +// registers and the remaining ones in on the stack), except that RCX (argument +// 4) is overwritten by the SYSCALL instruction, so it is moved to R10. Syscall +// number goes in RAX. + + +#define _SYSCALL_NO_RCX(name, n) \ + .align 8; \ + FUNCTION(name): \ + movq $n, %rax; \ + syscall; \ + ret; \ + FUNCTION_END(name) + +#define _SYSCALL_RCX(name, n) \ + .align 8; \ + FUNCTION(name): \ + movq %rcx, %r10; \ + movq $n, %rax; \ + syscall; \ + ret; \ + FUNCTION_END(name) + + +#define SYSCALL0(name, n) _SYSCALL_NO_RCX(name, n) +#define SYSCALL1(name, n) _SYSCALL_NO_RCX(name, n) +#define SYSCALL2(name, n) _SYSCALL_NO_RCX(name, n) +#define SYSCALL3(name, n) _SYSCALL_NO_RCX(name, n) +#define SYSCALL4(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL5(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL6(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL7(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL8(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL9(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL10(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL11(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL12(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL13(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL14(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL15(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL16(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL17(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL18(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL19(name, n) _SYSCALL_RCX(name, n) +#define SYSCALL20(name, n) _SYSCALL_RCX(name, n) + diff --git a/src/system/libroot/os/arch/x86_64/system_info.cpp b/src/system/libroot/os/arch/x86_64/system_info.cpp new file mode 100644 index 0000000000..03a3e4c440 --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/system_info.cpp @@ -0,0 +1,16 @@ +/* + * Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include +#include + + +status_t +get_cpuid(cpuid_info* info, uint32 eaxRegister, uint32 cpuNum) +{ + return _kern_get_cpuid(info, eaxRegister, cpuNum); +} + diff --git a/src/system/libroot/os/arch/x86_64/system_time.c b/src/system/libroot/os/arch/x86_64/system_time.c new file mode 100644 index 0000000000..6b4e3d7df9 --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/system_time.c @@ -0,0 +1,4 @@ +/* + Just a dummy to avoid a special case in the build system. system_time() + is implemented in system_time_asm.S. +*/ diff --git a/src/system/libroot/os/arch/x86_64/system_time_asm.S b/src/system/libroot/os/arch/x86_64/system_time_asm.S new file mode 100644 index 0000000000..6af491a36d --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/system_time_asm.S @@ -0,0 +1,76 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + + +#include + + +/* saves the conversion factor needed for system_time */ +.lcomm cv_factor 8 +.lcomm cv_factor_nsecs 8 + + +.text + + +FUNCTION(__x86_setup_system_time): + movq %rdi, cv_factor(%rip) + movq %rsi, cv_factor_nsecs(%rip) + ret +FUNCTION_END(__x86_setup_system_time) + + +/* int64 system_time(); */ +FUNCTION(system_time): + // (rdtsc * cv_factor) >> 32. + // Factor is pre-shifted left by 32 bits. + + movq cv_factor(%rip), %rcx + + // Load 64-bit TSC into %eax (low), %edx (high). + rdtsc + + // Convert into a single 64-bit value. + shl $32, %rdx + orq %rdx, %rax + + // Multiply by conversion factor, result in %rax (low), %rdx (high). + mulq %rcx + + // Due to pre-shifting of the factor the whole result in high. + movq %rdx, %rax + ret +FUNCTION_END(system_time) + + +/* int64 system_time_nsecs(); */ +FUNCTION(system_time_nsecs): + // Same algorithm as system_time(), but with a different factor. + // (rdtsc * cv_factor_nsecs) >> 32. + // Factor has not been pre-shifted here, otherwise we may lose the upper + // 32 bits. + + movq cv_factor_nsecs(%rip), %rcx + + // Load 64-bit TSC into %eax (low), %edx (high). + rdtsc + + // Convert into a single 64-bit value. + shl $32, %rdx + orq %rdx, %rax + + // Multiply by conversion factor, result in %rax (low), %rdx (high). + mulq %rcx + + // Shift the result right by 32 bits. + shr $32, %rax + shl $32, %rdx + orq %rdx, %rax + ret +FUNCTION_END(system_time_nsecs) diff --git a/src/system/libroot/os/arch/x86_64/thread.cpp b/src/system/libroot/os/arch/x86_64/thread.cpp new file mode 100644 index 0000000000..10614ba6c6 --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/thread.cpp @@ -0,0 +1,22 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include +#include "syscalls.h" + + +thread_id +find_thread(const char* name) +{ + if (!name) { + thread_id thread; + __asm__ __volatile__ ("movq %%fs:8, %%rax" : "=a" (thread)); + return thread; + } + + return _kern_find_thread(name); +} + diff --git a/src/system/libroot/os/arch/x86_64/time.cpp b/src/system/libroot/os/arch/x86_64/time.cpp new file mode 100644 index 0000000000..8b95ed1c62 --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/time.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include + + +void +__arch_init_time(real_time_data* data, bool setDefaults) +{ + uint32 conversionFactor; + uint64 conversionFactorNsecs; + + if (setDefaults) { + data->arch_data.system_time_offset = 0; + data->arch_data.system_time_conversion_factor = 100000; + } + + // TODO: this should only store a pointer to that value + // When resolving this TODO, also resolve the one in the Jamfile. + + conversionFactor = data->arch_data.system_time_conversion_factor; + conversionFactorNsecs = (uint64)conversionFactor * 1000; + + // The x86_64 system_time() implementation uses 64-bit multiplication and + // therefore shifting is not necessary for low frequencies (it's also not + // too likely that there'll be any x86_64 CPUs clocked under 1GHz). + __x86_setup_system_time((uint64)conversionFactor << 32, + conversionFactorNsecs); +} + + +bigtime_t +__arch_get_system_time_offset(struct real_time_data *data) +{ + //we don't use atomic_get64 because memory is read-only, maybe find another way to lock + return data->arch_data.system_time_offset; +} + diff --git a/src/system/libroot/os/arch/x86_64/tls.cpp b/src/system/libroot/os/arch/x86_64/tls.cpp new file mode 100644 index 0000000000..733dc7b2e3 --- /dev/null +++ b/src/system/libroot/os/arch/x86_64/tls.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#ifndef _NO_INLINE_ASM +# define _NO_INLINE_ASM 1 +#endif + +#include +#include + +#include + + +static int32 gNextSlot = TLS_FIRST_FREE_SLOT; + + +int32 +tls_allocate(void) +{ + int32 next = atomic_add(&gNextSlot, 1); + if (next >= TLS_MAX_KEYS) + return B_NO_MEMORY; + + return next; +} + + +void* +tls_get(int32 _index) +{ + int64 index = _index; + void* ret; + + __asm__ __volatile__ ( + "movq %%fs:(, %%rdi, 8), %%rax" + : "=a" (ret) : "D" (index)); + return ret; +} + + +void** +tls_address(int32 _index) +{ + int64 index = _index; + void** ret; + + __asm__ __volatile__ ( + "movq %%fs:0, %%rax\n\t" + "leaq (%%rax, %%rdi, 8), %%rax\n\t" + : "=a" (ret) : "D" (index)); + return ret; +} + + +void +tls_set(int32 _index, void* value) +{ + int64 index = _index; + __asm__ __volatile__ ( + "movq %%rsi, %%fs:(, %%rdi, 8)" + : : "D" (index), "S" (value)); +} diff --git a/src/system/libroot/os/area.c b/src/system/libroot/os/area.c index bb28838a91..0fedf2fc48 100644 --- a/src/system/libroot/os/area.c +++ b/src/system/libroot/os/area.c @@ -70,7 +70,7 @@ _get_area_info(area_id id, area_info *areaInfo, size_t size) status_t -_get_next_area_info(team_id team, int32 *cookie, area_info *areaInfo, size_t size) +_get_next_area_info(team_id team, ssize_t *cookie, area_info *areaInfo, size_t size) { // size is not yet used, but may, if area_info changes (void)size; diff --git a/src/system/libroot/os/debug.c b/src/system/libroot/os/debug.c index 7ef95aa28a..a952edc96a 100644 --- a/src/system/libroot/os/debug.c +++ b/src/system/libroot/os/debug.c @@ -60,7 +60,7 @@ bool _rtDebugFlag = true; void debugger(const char *message) { - debug_printf("%ld: DEBUGGER: %s\n", find_thread(NULL), message); + debug_printf("%" B_PRId32 ": DEBUGGER: %s\n", find_thread(NULL), message); _kern_debugger(message); } @@ -261,8 +261,8 @@ _debuggerAssert(const char *file, int line, const char *message) "Assert failed: File: %s, Line: %d, %s", file, line, message); - debug_printf("%ld: ASSERT: %s:%d %s\n", find_thread(NULL), file, line, - buffer); + debug_printf("%" B_PRId32 ": ASSERT: %s:%d %s\n", find_thread(NULL), file, + line, buffer); _kern_debugger(buffer); return 0; diff --git a/src/system/libroot/os/syscalls.S b/src/system/libroot/os/syscalls.S index 770da146bc..b7b3e87b02 100644 --- a/src/system/libroot/os/syscalls.S +++ b/src/system/libroot/os/syscalls.S @@ -1,6 +1,9 @@ #ifdef ARCH_x86 # include "arch/x86/syscalls.inc" #endif +#ifdef ARCH_x86_64 +# include "arch/x86_64/syscalls.inc" +#endif #ifdef ARCH_alpha # include "arch/alpha/syscalls.inc" #endif diff --git a/src/system/libroot/posix/arch/arm/Jamfile b/src/system/libroot/posix/arch/arm/Jamfile index 1526728d45..8eb8fd60b2 100644 --- a/src/system/libroot/posix/arch/arm/Jamfile +++ b/src/system/libroot/posix/arch/arm/Jamfile @@ -1,10 +1,16 @@ SubDir HAIKU_TOP src system libroot posix arch arm ; + +UsePrivateHeaders [ FDirName system arch $(TARGET_ARCH) ] ; + local genericSources = + setjmp_save_sigs.c ; MergeObject posix_arch_$(TARGET_ARCH).o : fenv.c + sigsetjmp.S + siglongjmp.S $(genericSources) ; diff --git a/src/system/libroot/posix/arch/x86_64/Jamfile b/src/system/libroot/posix/arch/x86_64/Jamfile new file mode 100644 index 0000000000..5891f1b3e5 --- /dev/null +++ b/src/system/libroot/posix/arch/x86_64/Jamfile @@ -0,0 +1,19 @@ +SubDir HAIKU_TOP src system libroot posix arch x86_64 ; + +UsePrivateSystemHeaders ; + +local genericSources = + setjmp_save_sigs.c + longjmp_return.c +; + +MergeObject posix_arch_$(TARGET_ARCH).o : + fenv.c + sigsetjmp.S + siglongjmp.S + + $(genericSources) +; + +SEARCH on [ FGristFiles $(genericSources) ] + = [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; diff --git a/src/system/libroot/posix/arch/x86_64/fenv.c b/src/system/libroot/posix/arch/x86_64/fenv.c new file mode 100644 index 0000000000..d342453cee --- /dev/null +++ b/src/system/libroot/posix/arch/x86_64/fenv.c @@ -0,0 +1,149 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +const fenv_t __fe_dfl_env = { + { 0xffff0000 | __INITIAL_FPUCW__, + 0xffff0000, + 0xffffffff, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff } + }, + __INITIAL_MXCSR__ +}; + +int +fesetexceptflag(const fexcept_t *flagp, int excepts) +{ + fenv_t env; + + __fnstenv(&env.__x87); + env.__x87.__status &= ~excepts; + env.__x87.__status |= *flagp & excepts; + __fldenv(env.__x87); + + __stmxcsr(&env.__mxcsr); + env.__mxcsr &= ~excepts; + env.__mxcsr |= *flagp & excepts; + __ldmxcsr(env.__mxcsr); + + return (0); +} + +int +feraiseexcept(int excepts) +{ + fexcept_t ex = excepts; + + fesetexceptflag(&ex, excepts); + __fwait(); + return (0); +} + +int +fegetenv(fenv_t *envp) +{ + + __fnstenv(&envp->__x87); + __stmxcsr(&envp->__mxcsr); + /* + * fnstenv masks all exceptions, so we need to restore the + * control word to avoid this side effect. + */ + __fldcw(envp->__x87.__control); + return (0); +} + +int +feholdexcept(fenv_t *envp) +{ + uint32_t mxcsr; + + __stmxcsr(&mxcsr); + __fnstenv(&envp->__x87); + __fnclex(); + envp->__mxcsr = mxcsr; + mxcsr &= ~FE_ALL_EXCEPT; + mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT; + __ldmxcsr(mxcsr); + return (0); +} + +int +feupdateenv(const fenv_t *envp) +{ + uint32_t mxcsr; + uint16_t status; + + __fnstsw(&status); + __stmxcsr(&mxcsr); + fesetenv(envp); + feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT); + return (0); +} + +int +__feenableexcept(int mask) +{ + uint32_t mxcsr, omask; + uint16_t control; + + mask &= FE_ALL_EXCEPT; + __fnstcw(&control); + __stmxcsr(&mxcsr); + omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; + control &= ~mask; + __fldcw(control); + mxcsr &= ~(mask << _SSE_EMASK_SHIFT); + __ldmxcsr(mxcsr); + return (omask); +} + +int +__fedisableexcept(int mask) +{ + uint32_t mxcsr, omask; + uint16_t control; + + mask &= FE_ALL_EXCEPT; + __fnstcw(&control); + __stmxcsr(&mxcsr); + omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; + control |= mask; + __fldcw(control); + mxcsr |= mask << _SSE_EMASK_SHIFT; + __ldmxcsr(mxcsr); + return (omask); +} + +__weak_reference(__feenableexcept, feenableexcept); +__weak_reference(__fedisableexcept, fedisableexcept); diff --git a/src/system/libroot/posix/arch/x86_64/setjmp_internal.h b/src/system/libroot/posix/arch/x86_64/setjmp_internal.h new file mode 100644 index 0000000000..6d7ed7c56f --- /dev/null +++ b/src/system/libroot/posix/arch/x86_64/setjmp_internal.h @@ -0,0 +1,20 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ +#ifndef SETJMP_INTERNAL_H +#define SETJMP_INTERNAL_H + + +#define JMP_REGS_IP 0 +#define JMP_REGS_SP 8 +#define JMP_REGS_BP 16 +#define JMP_REGS_BX 24 +#define JMP_REGS_R12 32 +#define JMP_REGS_R13 40 +#define JMP_REGS_R14 48 +#define JMP_REGS_R15 56 + +#include + +#endif /* SETJMP_INTERNAL_H */ diff --git a/src/system/libroot/posix/arch/x86_64/siglongjmp.S b/src/system/libroot/posix/arch/x86_64/siglongjmp.S new file mode 100644 index 0000000000..c42f7adb11 --- /dev/null +++ b/src/system/libroot/posix/arch/x86_64/siglongjmp.S @@ -0,0 +1,32 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + +#include "setjmp_internal.h" + + +/* int __siglongjmp(jmp_buf buffer, int value) */ +FUNCTION(siglongjmp): +FUNCTION(longjmp): +FUNCTION(_longjmp): + // Restore new callee-save registers. + movq JMP_REGS_R15(%rdi), %r15 + movq JMP_REGS_R14(%rdi), %r14 + movq JMP_REGS_R13(%rdi), %r13 + movq JMP_REGS_R12(%rdi), %r12 + movq JMP_REGS_BX(%rdi), %rbx + movq JMP_REGS_BP(%rdi), %rbp + + // Restore new stack pointer and push return address. + movq JMP_REGS_SP(%rdi), %rsp + movq JMP_REGS_IP(%rdi), %rax + push %rax + + // __longjmp_return restores the signal mask and sets the return value. + call __longjmp_return@PLT + ret +FUNCTION_END(siglongjmp) + + +#pragma weak longjmp=siglongjmp diff --git a/src/system/libroot/posix/arch/x86_64/sigsetjmp.S b/src/system/libroot/posix/arch/x86_64/sigsetjmp.S new file mode 100644 index 0000000000..70866974dc --- /dev/null +++ b/src/system/libroot/posix/arch/x86_64/sigsetjmp.S @@ -0,0 +1,39 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + +#include "setjmp_internal.h" + + +/* int sigsetjmp(jmp_buf buffer, int saveMask) */ +FUNCTION(__sigsetjmp): +FUNCTION(sigsetjmp): + // Save instruction/stack pointers. + movq (%rsp), %rax + movq %rax, JMP_REGS_IP(%rdi) + leaq 8(%rsp), %rax + movq %rax, JMP_REGS_SP(%rdi) + + // Save callee-save registers. + movq %rbp, JMP_REGS_BP(%rdi) + movq %rbx, JMP_REGS_BX(%rdi) + movq %r12, JMP_REGS_R12(%rdi) + movq %r13, JMP_REGS_R13(%rdi) + movq %r14, JMP_REGS_R14(%rdi) + movq %r15, JMP_REGS_R15(%rdi) + + // __setjmp_save_sigs handles signal mask and return value. + jmp __setjmp_save_sigs@PLT +FUNCTION_END(setjmp) + + +/* int setjmp(jmp_buf buffer) */ +FUNCTION(setjmp): + // Jump to sigsetjmp with a zero saveMask. + xorl %esi, %esi + jmp sigsetjmp@PLT +FUNCTION_END(setjmp) + + +#pragma weak _setjmp=setjmp diff --git a/src/system/libroot/posix/crypt/crypt_util.c b/src/system/libroot/posix/crypt/crypt_util.c index 0dedf5427f..c72a55fcc2 100644 --- a/src/system/libroot/posix/crypt/crypt_util.c +++ b/src/system/libroot/posix/crypt/crypt_util.c @@ -23,6 +23,8 @@ * */ +#include + #ifdef DEBUG #include #endif diff --git a/src/system/libroot/posix/crypt/ufc-crypt.h b/src/system/libroot/posix/crypt/ufc-crypt.h index 13da8b4737..aa77ae7d65 100644 --- a/src/system/libroot/posix/crypt/ufc-crypt.h +++ b/src/system/libroot/posix/crypt/ufc-crypt.h @@ -23,6 +23,8 @@ * */ +#include + /* * Requirements for datatypes: * @@ -99,10 +101,15 @@ typedef long long long64; #ifndef _UFC_64_ #ifndef _UFC_32_ +#if B_HAIKU_64_BIT +#define _UFC_64_ +typedef unsigned long long64; +#else #define _UFC_32_ -typedef unsigned long ufc_long; typedef unsigned long long32; #endif +typedef unsigned long ufc_long; +#endif #endif diff --git a/src/system/libroot/posix/fcntl.cpp b/src/system/libroot/posix/fcntl.cpp index 2f99596145..1a82dec027 100644 --- a/src/system/libroot/posix/fcntl.cpp +++ b/src/system/libroot/posix/fcntl.cpp @@ -65,7 +65,7 @@ fcntl(int fd, int op, ...) { va_list args; va_start(args, op); - uint32 argument = va_arg(args, uint32); + size_t argument = va_arg(args, size_t); va_end(args); status_t error = _kern_fcntl(fd, op, argument); diff --git a/src/system/libroot/posix/glibc/arch/arm/Jamfile b/src/system/libroot/posix/glibc/arch/arm/Jamfile index b4c2f6dad5..5299ee5cd3 100644 --- a/src/system/libroot/posix/glibc/arch/arm/Jamfile +++ b/src/system/libroot/posix/glibc/arch/arm/Jamfile @@ -33,14 +33,49 @@ local genericSources = s_isinf.c s_isinff.c s_isnan.c s_isnanf.c s_signbit.c s_signbitf.c s_signbitl.c + + s_floor.c s_floorf.c + s_ceil.c s_ceilf.c + s_modf.c + w_pow.c e_pow.c slowpow.c + w_exp.c e_exp.c slowexp.c + s_frexp.c s_expm1.c + dosincos.c + doasin.c + sincos32.c + branred.c + halfulp.c + mpa.c mplog.c mpexp.c + s_sin.c + s_atan.c + s_tan.c + e_asin.c w_asin.c + e_log10.c w_log10.c + e_acos.c w_acos.c + e_atan2.c w_atan2.c mpatan2.c mpatan.c mptan.c mpsqrt.c w_sqrt.c w_sqrtf.c + e_fmod.c w_fmod.c + e_log.c w_log.c + e_cosh.c w_cosh.c + e_sinh.c w_sinh.c + s_ldexp.c s_ldexpf.c + s_scalbnf.c s_scalbn.c + s_copysign.c + s_tanh.c + s_lround.c s_lroundf.c s_round.c s_roundf.c ; MergeObject posix_gnu_arch_$(TARGET_ARCH)_generic.o : $(genericSources) ; +MergeObject posix_gnu_arch_$(TARGET_ARCH)_others.o : + e_sqrt.c + e_sqrtf.c +; + MergeObjectFromObjects posix_gnu_arch_$(TARGET_ARCH).o : : posix_gnu_arch_$(TARGET_ARCH)_generic.o + posix_gnu_arch_$(TARGET_ARCH)_others.o ; SEARCH on [ FGristFiles $(genericSources) ] diff --git a/src/system/libroot/posix/glibc/arch/arm/e_log.c b/src/system/libroot/posix/glibc/arch/arm/e_log.c new file mode 100644 index 0000000000..1a9967b546 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/arm/e_log.c @@ -0,0 +1,203 @@ +/* + * IBM Accurate Mathematical Library + * written by International Business Machines Corp. + * Copyright (C) 2001 Free Software Foundation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +/*********************************************************************/ +/* */ +/* MODULE_NAME:ulog.c */ +/* */ +/* FUNCTION:ulog */ +/* */ +/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h ulog.h */ +/* mpexp.c mplog.c mpa.c */ +/* ulog.tbl */ +/* */ +/* An ultimate log routine. Given an IEEE double machine number x */ +/* it computes the correctly rounded (to nearest) value of log(x). */ +/* Assumption: Machine arithmetic operations are performed in */ +/* round to nearest mode of IEEE 754 standard. */ +/* */ +/*********************************************************************/ + + +#include "endian.h" +#include "dla.h" +#include "mpa.h" +#include "MathLib.h" +#include "math_private.h" + +void __mplog(mp_no *, mp_no *, int); + +/*********************************************************************/ +/* An ultimate log routine. Given an IEEE double machine number x */ +/* it computes the correctly rounded (to nearest) value of log(x). */ +/*********************************************************************/ +double __ieee754_log(double x) { +#define M 4 + static const int pr[M]={8,10,18,32}; + int i,j,n,ux,dx,p; +#if 0 + int k; +#endif + double dbl_n,u,p0,q,r0,w,nln2a,luai,lubi,lvaj,lvbj, + sij,ssij,ttij,A,B,B0,y,y1,y2,polI,polII,sa,sb, + t1,t2,t3,t4,t5,t6,t7,t8,t,ra,rb,ww, + a0,aa0,s1,s2,ss2,s3,ss3,a1,aa1,a,aa,b,bb,c; + number num; + mp_no mpx,mpy,mpy1,mpy2,mperr; + +#include "ulog.tbl" +#include "ulog.h" + + /* Treating special values of x ( x<=0, x=INF, x=NaN etc.). */ + + num.d = x; ux = num.i[HIGH_HALF]; dx = num.i[LOW_HALF]; + n=0; + if (ux < 0x00100000) { + if (((ux & 0x7fffffff) | dx) == 0) return MHALF/ZERO; /* return -INF */ + if (ux < 0) return (x-x)/ZERO; /* return NaN */ + n -= 54; x *= two54.d; /* scale x */ + num.d = x; + } + if (ux >= 0x7ff00000) return x+x; /* INF or NaN */ + + /* Regular values of x */ + + w = x-ONE; + if (ABS(w) > U03) { goto case_03; } + + + /*--- Stage I, the case abs(x-1) < 0.03 */ + + t8 = MHALF*w; + EMULV(t8,w,a,aa,t1,t2,t3,t4,t5) + EADD(w,a,b,bb) + + /* Evaluate polynomial II */ + polII = (b0.d+w*(b1.d+w*(b2.d+w*(b3.d+w*(b4.d+ + w*(b5.d+w*(b6.d+w*(b7.d+w*b8.d))))))))*w*w*w; + c = (aa+bb)+polII; + + /* End stage I, case abs(x-1) < 0.03 */ + if ((y=b+(c+b*E2)) == b+(c-b*E2)) return y; + + /*--- Stage II, the case abs(x-1) < 0.03 */ + + a = d11.d+w*(d12.d+w*(d13.d+w*(d14.d+w*(d15.d+w*(d16.d+ + w*(d17.d+w*(d18.d+w*(d19.d+w*d20.d)))))))); + EMULV(w,a,s2,ss2,t1,t2,t3,t4,t5) + ADD2(d10.d,dd10.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d9.d,dd9.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d8.d,dd8.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d7.d,dd7.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d6.d,dd6.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d5.d,dd5.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d4.d,dd4.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d3.d,dd3.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d2.d,dd2.d,s2,ss2,s3,ss3,t1,t2) + MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + MUL2(w,ZERO,s2,ss2,s3,ss3,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(w,ZERO, s3,ss3, b, bb,t1,t2) + + /* End stage II, case abs(x-1) < 0.03 */ + if ((y=b+(bb+b*E4)) == b+(bb-b*E4)) return y; + goto stage_n; + + /*--- Stage I, the case abs(x-1) > 0.03 */ + case_03: + + /* Find n,u such that x = u*2**n, 1/sqrt(2) < u < sqrt(2) */ + n += (num.i[HIGH_HALF] >> 20) - 1023; + num.i[HIGH_HALF] = (num.i[HIGH_HALF] & 0x000fffff) | 0x3ff00000; + if (num.d > SQRT_2) { num.d *= HALF; n++; } + u = num.d; dbl_n = (double) n; + + /* Find i such that ui=1+(i-75)/2**8 is closest to u (i= 0,1,2,...,181) */ + num.d += h1.d; + i = (num.i[HIGH_HALF] & 0x000fffff) >> 12; + + /* Find j such that vj=1+(j-180)/2**16 is closest to v=u/ui (j= 0,...,361) */ + num.d = u*Iu[i].d + h2.d; + j = (num.i[HIGH_HALF] & 0x000fffff) >> 4; + + /* Compute w=(u-ui*vj)/(ui*vj) */ + p0=(ONE+(i-75)*DEL_U)*(ONE+(j-180)*DEL_V); + q=u-p0; r0=Iu[i].d*Iv[j].d; w=q*r0; + + /* Evaluate polynomial I */ + polI = w+(a2.d+a3.d*w)*w*w; + + /* Add up everything */ + nln2a = dbl_n*LN2A; + luai = Lu[i][0].d; lubi = Lu[i][1].d; + lvaj = Lv[j][0].d; lvbj = Lv[j][1].d; + EADD(luai,lvaj,sij,ssij) + EADD(nln2a,sij,A ,ttij) + B0 = (((lubi+lvbj)+ssij)+ttij)+dbl_n*LN2B; + B = polI+B0; + + /* End stage I, case abs(x-1) >= 0.03 */ + if ((y=A+(B+E1)) == A+(B-E1)) return y; + + + /*--- Stage II, the case abs(x-1) > 0.03 */ + + /* Improve the accuracy of r0 */ + EMULV(p0,r0,sa,sb,t1,t2,t3,t4,t5) + t=r0*((ONE-sa)-sb); + EADD(r0,t,ra,rb) + + /* Compute w */ + MUL2(q,ZERO,ra,rb,w,ww,t1,t2,t3,t4,t5,t6,t7,t8) + + EADD(A,B0,a0,aa0) + + /* Evaluate polynomial III */ + s1 = (c3.d+(c4.d+c5.d*w)*w)*w; + EADD(c2.d,s1,s2,ss2) + MUL2(s2,ss2,w,ww,s3,ss3,t1,t2,t3,t4,t5,t6,t7,t8) + MUL2(s3,ss3,w,ww,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(s2,ss2,w,ww,s3,ss3,t1,t2) + ADD2(s3,ss3,a0,aa0,a1,aa1,t1,t2) + + /* End stage II, case abs(x-1) >= 0.03 */ + if ((y=a1+(aa1+E3)) == a1+(aa1-E3)) return y; + + + /* Final stages. Use multi-precision arithmetic. */ + stage_n: + + for (i=0; i>14]; + s=a.x; + /*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/ + if (k>0x000fffff && k<0x7ff00000) { + y=1.0-t*(t*s); + t=t*(rt0+y*(rt1+y*(rt2+y*rt3))); + c.i[HIGH_HALF]=0x20000000+((k&0x7fe00000)>>1); + y=t*s; + hy=(y+big)-big; + del=0.5*t*((s-hy*hy)-(y-hy)*(y+hy)); + res=y+del; + if (res == (res+1.002*((y-res)+del))) return res*c.x; + else { + res1=res+1.5*((y-res)+del); + EMULV(res,res1,z,zz,p,hx,tx,hy,ty); /* (z+zz)=res*res1 */ + return ((((z-s)+zz)<0)?max(res,res1):min(res,res1))*c.x; + } + } + else { + if ((k & 0x7ff00000) == 0x7ff00000) + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */ + if (x==0) return x; /* sqrt(+0)=+0, sqrt(-0)=-0 */ + if (k<0) return (x-x)/(x-x); /* sqrt(-ve)=sNaN */ + return tm256.x*__ieee754_sqrt(x*t512.x); + } +} diff --git a/src/system/libroot/posix/glibc/arch/arm/e_sqrtf.c b/src/system/libroot/posix/glibc/arch/arm/e_sqrtf.c new file mode 100644 index 0000000000..7648ef4bca --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/arm/e_sqrtf.c @@ -0,0 +1,97 @@ +/* e_sqrtf.c -- float version of e_sqrt.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_sqrtf.c,v 1.4 1995/05/10 20:46:19 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const float one = 1.0, tiny=1.0e-30; +#else +static float one = 1.0, tiny=1.0e-30; +#endif + +#ifdef __STDC__ + float __ieee754_sqrtf(float x) +#else + float __ieee754_sqrtf(x) + float x; +#endif +{ + float z; + int32_t sign = (int)0x80000000; + int32_t ix,s,q,m,t,i; + u_int32_t r; + + GET_FLOAT_WORD(ix,x); + + /* take care of Inf and NaN */ + if((ix&0x7f800000)==0x7f800000) { + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if(ix<=0) { + if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ + else if(ix<0) + return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix>>23); + if(m==0) { /* subnormal x */ + for(i=0;(ix&0x00800000)==0;i++) ix<<=1; + m -= i-1; + } + m -= 127; /* unbias exponent */ + ix = (ix&0x007fffff)|0x00800000; + if(m&1) /* odd m, double x to make it even */ + ix += ix; + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix += ix; + q = s = 0; /* q = sqrt(x) */ + r = 0x01000000; /* r = moving bit from right to left */ + + while(r!=0) { + t = s+r; + if(t<=ix) { + s = t+r; + ix -= t; + q += r; + } + ix += ix; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if(ix!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (z>one) + q += 2; + else + q += (q&1); + } + } + ix = (q>>1)+0x3f000000; + ix += (m <<23); + SET_FLOAT_WORD(z,ix); + return z; +} diff --git a/src/system/libroot/posix/glibc/arch/arm/uroot.h b/src/system/libroot/posix/glibc/arch/arm/uroot.h new file mode 100644 index 0000000000..02b74cb262 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/arm/uroot.h @@ -0,0 +1,44 @@ +/* + * IBM Accurate Mathematical Library + * Written by International Business Machines Corp. + * Copyright (C) 2001 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/******************************************************************/ +/* */ +/* MODULE_NAME:uroot.h */ +/* */ +/* common data and variables prototype and definition */ +/******************************************************************/ + +#ifndef UROOT_H +#define UROOT_H + +#ifdef BIG_ENDI + static const mynumber +/**/ t512 = {{0x5ff00000, 0x00000000 }}, /* 2^512 */ +/**/ tm256 = {{0x2ff00000, 0x00000000 }}; /* 2^-256 */ + +#else +#ifdef LITTLE_ENDI + static const mynumber +/**/ t512 = {{0x00000000, 0x5ff00000 }}, /* 2^512 */ +/**/ tm256 = {{0x00000000, 0x2ff00000 }}; /* 2^-256 */ +#endif +#endif + +#endif diff --git a/src/system/libroot/posix/glibc/arch/generic/e_atanhl.c b/src/system/libroot/posix/glibc/arch/generic/e_atanhl.c new file mode 100644 index 0000000000..fdcd1e9fe8 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/e_atanhl.c @@ -0,0 +1,79 @@ +/* s_atanhl.c -- long double version of s_atan.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* __ieee754_atanhl(x) + * Method : + * 1.Reduced x to positive by atanh(-x) = -atanh(x) + * 2.For x>=0.5 + * 1 2x x + * atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x)) + * + * Special cases: + * atanhl(x) is NaN if |x| > 1 with signal; + * atanhl(NaN) is that NaN with no signal; + * atanhl(+-1) is +-INF with signal. + * + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const long double one = 1.0, huge = 1e4900L; +#else +static long double one = 1.0, huge = 1e4900L; +#endif + +#ifdef __STDC__ +static const long double zero = 0.0; +#else +static double long zero = 0.0; +#endif + +#ifdef __STDC__ + long double __ieee754_atanhl(long double x) +#else + long double __ieee754_atanhl(x) + long double x; +#endif +{ + long double t; + int32_t ix; + u_int32_t se,i0,i1; + GET_LDOUBLE_WORDS(se,i0,i1,x); + ix = se&0x7fff; + if ((ix+((((i0&0x7fffffff)|i1)|(-((i0&0x7fffffff)|i1)))>>31))>0x3fff) + /* |x|>1 */ + return (x-x)/(x-x); + if(ix==0x3fff) + return x/zero; + if(ix<0x3fe3&&(huge+x)>zero) return x; /* x<2**-28 */ + SET_LDOUBLE_EXP(x,ix); + if(ix<0x3ffe) { /* x < 0.5 */ + t = x+x; + t = 0.5*__log1pl(t+t*x/(one-x)); + } else + t = 0.5*__log1pl((x+x)/(one-x)); + if(se<=0x7fff) return t; else return -t; +} diff --git a/src/system/libroot/posix/glibc/arch/generic/e_j0l.c b/src/system/libroot/posix/glibc/arch/generic/e_j0l.c new file mode 100644 index 0000000000..12c906bcbc --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/e_j0l.c @@ -0,0 +1,644 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* Long double expansions are + Copyright (C) 2001 Stephen L. Moshier + and are incorporated herein by permission of the author. The author + reserves the right to distribute this material elsewhere under different + copying permissions. These modifications are distributed here under + the following terms: + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* __ieee754_j0(x), __ieee754_y0(x) + * Bessel function of the first and second kinds of order zero. + * Method -- j0(x): + * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... + * 2. Reduce x to |x| since j0(x)=j0(-x), and + * for x in (0,2) + * j0(x) = 1 - z/4 + z^2*R0/S0, where z = x*x; + * for x in (2,inf) + * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) + * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + * as follow: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (cos(x) + sin(x)) + * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * (To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one.) + * + * 3 Special cases + * j0(nan)= nan + * j0(0) = 1 + * j0(inf) = 0 + * + * Method -- y0(x): + * 1. For x<2. + * Since + * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...) + * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. + * We use the following function to approximate y0, + * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2 + * + * Note: For tiny x, U/V = u0 and j0(x)~1, hence + * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) + * 2. For x>=2. + * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) + * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + * by the method mentioned above. + * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static long double pzero (long double), qzero (long double); +#else +static long double pzero (), qzero (); +#endif + +#ifdef __STDC__ +static const long double +#else +static long double +#endif + huge = 1e4930L, + one = 1.0L, + invsqrtpi = 5.6418958354775628694807945156077258584405e-1L, + tpi = 6.3661977236758134307553505349005744813784e-1L, + + /* J0(x) = 1 - x^2 / 4 + x^4 R0(x^2) / S0(x^2) + 0 <= x <= 2 + peak relative error 1.41e-22 */ + R[5] = { + 4.287176872744686992880841716723478740566E7L, + -6.652058897474241627570911531740907185772E5L, + 7.011848381719789863458364584613651091175E3L, + -3.168040850193372408702135490809516253693E1L, + 6.030778552661102450545394348845599300939E-2L, +}, + + S[4] = { + 2.743793198556599677955266341699130654342E9L, + 3.364330079384816249840086842058954076201E7L, + 1.924119649412510777584684927494642526573E5L, + 6.239282256012734914211715620088714856494E2L, + /* 1.000000000000000000000000000000000000000E0L,*/ +}; + +#ifdef __STDC__ +static const long double zero = 0.0; +#else +static long double zero = 0.0; +#endif + +#ifdef __STDC__ +long double +__ieee754_j0l (long double x) +#else +long double +__ieee754_j0l (x) + long double x; +#endif +{ + long double z, s, c, ss, cc, r, u, v; + int32_t ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + if (ix >= 0x7fff) + return one / (x * x); + x = fabsl (x); + if (ix >= 0x4000) /* |x| >= 2.0 */ + { + __sincosl (x, &s, &c); + ss = s - c; + cc = s + c; + if (ix < 0x7ffe) + { /* make sure x+x not overflow */ + z = -__cosl (x + x); + if ((s * c) < zero) + cc = z / ss; + else + ss = z / cc; + } + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if (ix > 0x4080) /* 2^129 */ + z = (invsqrtpi * cc) / __ieee754_sqrtl (x); + else + { + u = pzero (x); + v = qzero (x); + z = invsqrtpi * (u * cc - v * ss) / __ieee754_sqrtl (x); + } + return z; + } + if (ix < 0x3fef) /* |x| < 2**-16 */ + { + if (huge + x > one) + { /* raise inexact if x != 0 */ + if (ix < 0x3fde) /* |x| < 2^-33 */ + return one; + else + return one - 0.25 * x * x; + } + } + z = x * x; + r = z * (R[0] + z * (R[1] + z * (R[2] + z * (R[3] + z * R[4])))); + s = S[0] + z * (S[1] + z * (S[2] + z * (S[3] + z))); + if (ix < 0x3fff) + { /* |x| < 1.00 */ + return (one - 0.25 * z + z * (r / s)); + } + else + { + u = 0.5 * x; + return ((one + u) * (one - u) + z * (r / s)); + } +} + + +/* y0(x) = 2/pi ln(x) J0(x) + U(x^2)/V(x^2) + 0 < x <= 2 + peak relative error 1.7e-21 */ +#ifdef __STDC__ +static const long double +#else +static long double +#endif +U[6] = { + -1.054912306975785573710813351985351350861E10L, + 2.520192609749295139432773849576523636127E10L, + -1.856426071075602001239955451329519093395E9L, + 4.079209129698891442683267466276785956784E7L, + -3.440684087134286610316661166492641011539E5L, + 1.005524356159130626192144663414848383774E3L, +}; +#ifdef __STDC__ +static const long double +#else +static long double +#endif +V[5] = { + 1.429337283720789610137291929228082613676E11L, + 2.492593075325119157558811370165695013002E9L, + 2.186077620785925464237324417623665138376E7L, + 1.238407896366385175196515057064384929222E5L, + 4.693924035211032457494368947123233101664E2L, + /* 1.000000000000000000000000000000000000000E0L */ +}; + +#ifdef __STDC__ +long double +__ieee754_y0l (long double x) +#else +long double +__ieee754_y0l (x) + long double x; +#endif +{ + long double z, s, c, ss, cc, u, v; + int32_t ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ + if (se & 0x8000) + return zero / (zero * x); + if (ix >= 0x7fff) + return one / (x + x * x); + if ((i0 | i1) == 0) + return -HUGE_VALL + x; /* -inf and overflow exception. */ + if (ix >= 0x4000) + { /* |x| >= 2.0 */ + + /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + * where x0 = x-pi/4 + * Better formula: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) + cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + __sincosl (x, &s, &c); + ss = s - c; + cc = s + c; + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if (ix < 0x7ffe) + { /* make sure x+x not overflow */ + z = -__cosl (x + x); + if ((s * c) < zero) + cc = z / ss; + else + ss = z / cc; + } + if (ix > 0x4080) /* 1e39 */ + z = (invsqrtpi * ss) / __ieee754_sqrtl (x); + else + { + u = pzero (x); + v = qzero (x); + z = invsqrtpi * (u * ss + v * cc) / __ieee754_sqrtl (x); + } + return z; + } + if (ix <= 0x3fde) /* x < 2^-33 */ + { + z = -7.380429510868722527629822444004602747322E-2L + + tpi * __ieee754_logl (x); + return z; + } + z = x * x; + u = U[0] + z * (U[1] + z * (U[2] + z * (U[3] + z * (U[4] + z * U[5])))); + v = V[0] + z * (V[1] + z * (V[2] + z * (V[3] + z * (V[4] + z)))); + return (u / v + tpi * (__ieee754_j0l (x) * __ieee754_logl (x))); +} + +/* The asymptotic expansions of pzero is + * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. + * For x >= 2, We approximate pzero by + * pzero(x) = 1 + s^2 R(s^2) / S(s^2) + */ +#ifdef __STDC__ +static const long double pR8[7] = { +#else +static long double pR8[7] = { +#endif + /* 8 <= x <= inf + Peak relative error 4.62 */ + -4.094398895124198016684337960227780260127E-9L, + -8.929643669432412640061946338524096893089E-7L, + -6.281267456906136703868258380673108109256E-5L, + -1.736902783620362966354814353559382399665E-3L, + -1.831506216290984960532230842266070146847E-2L, + -5.827178869301452892963280214772398135283E-2L, + -2.087563267939546435460286895807046616992E-2L, +}; +#ifdef __STDC__ +static const long double pS8[6] = { +#else +static long double pS8[6] = { +#endif + 5.823145095287749230197031108839653988393E-8L, + 1.279281986035060320477759999428992730280E-5L, + 9.132668954726626677174825517150228961304E-4L, + 2.606019379433060585351880541545146252534E-2L, + 2.956262215119520464228467583516287175244E-1L, + 1.149498145388256448535563278632697465675E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +#ifdef __STDC__ +static const long double pR5[7] = { +#else +static long double pR5[7] = { +#endif + /* 4.54541015625 <= x <= 8 + Peak relative error 6.51E-22 */ + -2.041226787870240954326915847282179737987E-7L, + -2.255373879859413325570636768224534428156E-5L, + -7.957485746440825353553537274569102059990E-4L, + -1.093205102486816696940149222095559439425E-2L, + -5.657957849316537477657603125260701114646E-2L, + -8.641175552716402616180994954177818461588E-2L, + -1.354654710097134007437166939230619726157E-2L, +}; +#ifdef __STDC__ +static const long double pS5[6] = { +#else +static long double pS5[6] = { +#endif + 2.903078099681108697057258628212823545290E-6L, + 3.253948449946735405975737677123673867321E-4L, + 1.181269751723085006534147920481582279979E-2L, + 1.719212057790143888884745200257619469363E-1L, + 1.006306498779212467670654535430694221924E0L, + 2.069568808688074324555596301126375951502E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +#ifdef __STDC__ +static const long double pR3[7] = { +#else +static long double pR3[7] = { +#endif + /* 2.85711669921875 <= x <= 4.54541015625 + peak relative error 5.25e-21 */ + -5.755732156848468345557663552240816066802E-6L, + -3.703675625855715998827966962258113034767E-4L, + -7.390893350679637611641350096842846433236E-3L, + -5.571922144490038765024591058478043873253E-2L, + -1.531290690378157869291151002472627396088E-1L, + -1.193350853469302941921647487062620011042E-1L, + -8.567802507331578894302991505331963782905E-3L, +}; +#ifdef __STDC__ +static const long double pS3[6] = { +#else +static long double pS3[6] = { +#endif + 8.185931139070086158103309281525036712419E-5L, + 5.398016943778891093520574483111255476787E-3L, + 1.130589193590489566669164765853409621081E-1L, + 9.358652328786413274673192987670237145071E-1L, + 3.091711512598349056276917907005098085273E0L, + 3.594602474737921977972586821673124231111E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +#ifdef __STDC__ +static const long double pR2[7] = { +#else +static long double pR2[7] = { +#endif + /* 2 <= x <= 2.85711669921875 + peak relative error 2.64e-21 */ + -1.219525235804532014243621104365384992623E-4L, + -4.838597135805578919601088680065298763049E-3L, + -5.732223181683569266223306197751407418301E-2L, + -2.472947430526425064982909699406646503758E-1L, + -3.753373645974077960207588073975976327695E-1L, + -1.556241316844728872406672349347137975495E-1L, + -5.355423239526452209595316733635519506958E-3L, +}; +#ifdef __STDC__ +static const long double pS2[6] = { +#else +static long double pS2[6] = { +#endif + 1.734442793664291412489066256138894953823E-3L, + 7.158111826468626405416300895617986926008E-2L, + 9.153839713992138340197264669867993552641E-1L, + 4.539209519433011393525841956702487797582E0L, + 8.868932430625331650266067101752626253644E0L, + 6.067161890196324146320763844772857713502E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +#ifdef __STDC__ +static long double +pzero (long double x) +#else +static long double +pzero (x) + long double x; +#endif +{ +#ifdef __STDC__ + const long double *p, *q; +#else + long double *p, *q; +#endif + long double z, r, s; + int32_t ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + if (ix >= 0x4002) + { + p = pR8; + q = pS8; + } /* x >= 8 */ + else + { + i1 = (ix << 16) | (i0 >> 16); + if (i1 >= 0x40019174) /* x >= 4.54541015625 */ + { + p = pR5; + q = pS5; + } + else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */ + { + p = pR3; + q = pS3; + } + else if (ix >= 0x4000) /* x better be >= 2 */ + { + p = pR2; + q = pS2; + } + } + z = one / (x * x); + r = + p[0] + z * (p[1] + + z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6]))))); + s = + q[0] + z * (q[1] + z * (q[2] + z * (q[3] + z * (q[4] + z * (q[5] + z))))); + return (one + z * r / s); +} + + +/* For x >= 8, the asymptotic expansions of qzero is + * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. + * We approximate qzero by + * qzero(x) = s*(-.125 + R(s^2) / S(s^2)) + */ +#ifdef __STDC__ +static const long double qR8[7] = { +#else +static long double qR8[7] = { +#endif + /* 8 <= x <= inf + peak relative error 2.23e-21 */ + 3.001267180483191397885272640777189348008E-10L, + 8.693186311430836495238494289942413810121E-8L, + 8.496875536711266039522937037850596580686E-6L, + 3.482702869915288984296602449543513958409E-4L, + 6.036378380706107692863811938221290851352E-3L, + 3.881970028476167836382607922840452192636E-2L, + 6.132191514516237371140841765561219149638E-2L, +}; +#ifdef __STDC__ +static const long double qS8[7] = { +#else +static long double qS8[7] = { +#endif + 4.097730123753051126914971174076227600212E-9L, + 1.199615869122646109596153392152131139306E-6L, + 1.196337580514532207793107149088168946451E-4L, + 5.099074440112045094341500497767181211104E-3L, + 9.577420799632372483249761659674764460583E-2L, + 7.385243015344292267061953461563695918646E-1L, + 1.917266424391428937962682301561699055943E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +#ifdef __STDC__ +static const long double qR5[7] = { +#else +static long double qR5[7] = { +#endif + /* 4.54541015625 <= x <= 8 + peak relative error 1.03e-21 */ + 3.406256556438974327309660241748106352137E-8L, + 4.855492710552705436943630087976121021980E-6L, + 2.301011739663737780613356017352912281980E-4L, + 4.500470249273129953870234803596619899226E-3L, + 3.651376459725695502726921248173637054828E-2L, + 1.071578819056574524416060138514508609805E-1L, + 7.458950172851611673015774675225656063757E-2L, +}; +#ifdef __STDC__ +static const long double qS5[7] = { +#else +static long double qS5[7] = { +#endif + 4.650675622764245276538207123618745150785E-7L, + 6.773573292521412265840260065635377164455E-5L, + 3.340711249876192721980146877577806687714E-3L, + 7.036218046856839214741678375536970613501E-2L, + 6.569599559163872573895171876511377891143E-1L, + 2.557525022583599204591036677199171155186E0L, + 3.457237396120935674982927714210361269133E0L, + /* 1.000000000000000000000000000000000000000E0L,*/ +}; + +#ifdef __STDC__ +static const long double qR3[7] = { +#else +static long double qR3[7] = { +#endif + /* 2.85711669921875 <= x <= 4.54541015625 + peak relative error 5.24e-21 */ + 1.749459596550816915639829017724249805242E-6L, + 1.446252487543383683621692672078376929437E-4L, + 3.842084087362410664036704812125005761859E-3L, + 4.066369994699462547896426554180954233581E-2L, + 1.721093619117980251295234795188992722447E-1L, + 2.538595333972857367655146949093055405072E-1L, + 8.560591367256769038905328596020118877936E-2L, +}; +#ifdef __STDC__ +static const long double qS3[7] = { +#else +static long double qS3[7] = { +#endif + 2.388596091707517488372313710647510488042E-5L, + 2.048679968058758616370095132104333998147E-3L, + 5.824663198201417760864458765259945181513E-2L, + 6.953906394693328750931617748038994763958E-1L, + 3.638186936390881159685868764832961092476E0L, + 7.900169524705757837298990558459547842607E0L, + 5.992718532451026507552820701127504582907E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +#ifdef __STDC__ +static const long double qR2[7] = { +#else +static long double qR2[7] = { +#endif + /* 2 <= x <= 2.85711669921875 + peak relative error 1.58e-21 */ + 6.306524405520048545426928892276696949540E-5L, + 3.209606155709930950935893996591576624054E-3L, + 5.027828775702022732912321378866797059604E-2L, + 3.012705561838718956481911477587757845163E-1L, + 6.960544893905752937420734884995688523815E-1L, + 5.431871999743531634887107835372232030655E-1L, + 9.447736151202905471899259026430157211949E-2L, +}; +#ifdef __STDC__ +static const long double qS2[7] = { +#else +static long double qS2[7] = { +#endif + 8.610579901936193494609755345106129102676E-4L, + 4.649054352710496997203474853066665869047E-2L, + 8.104282924459837407218042945106320388339E-1L, + 5.807730930825886427048038146088828206852E0L, + 1.795310145936848873627710102199881642939E1L, + 2.281313316875375733663657188888110605044E1L, + 1.011242067883822301487154844458322200143E1L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +#ifdef __STDC__ +static long double +qzero (long double x) +#else +static long double +qzero (x) + long double x; +#endif +{ +#ifdef __STDC__ + const long double *p, *q; +#else + long double *p, *q; +#endif + long double s, r, z; + int32_t ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + if (ix >= 0x4002) /* x >= 8 */ + { + p = qR8; + q = qS8; + } + else + { + i1 = (ix << 16) | (i0 >> 16); + if (i1 >= 0x40019174) /* x >= 4.54541015625 */ + { + p = qR5; + q = qS5; + } + else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */ + { + p = qR3; + q = qS3; + } + else if (ix >= 0x4000) /* x better be >= 2 */ + { + p = qR2; + q = qS2; + } + } + z = one / (x * x); + r = + p[0] + z * (p[1] + + z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6]))))); + s = + q[0] + z * (q[1] + + z * (q[2] + + z * (q[3] + z * (q[4] + z * (q[5] + z * (q[6] + z)))))); + return (-.125 + z * r / s) / x; +} diff --git a/src/system/libroot/posix/glibc/arch/generic/e_j1l.c b/src/system/libroot/posix/glibc/arch/generic/e_j1l.c new file mode 100644 index 0000000000..62a8ce0cb7 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/e_j1l.c @@ -0,0 +1,651 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* Long double expansions are + Copyright (C) 2001 Stephen L. Moshier + and are incorporated herein by permission of the author. The author + reserves the right to distribute this material elsewhere under different + copying permissions. These modifications are distributed here under + the following terms: + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* __ieee754_j1(x), __ieee754_y1(x) + * Bessel function of the first and second kinds of order zero. + * Method -- j1(x): + * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ... + * 2. Reduce x to |x| since j1(x)=-j1(-x), and + * for x in (0,2) + * j1(x) = x/2 + x*z*R0/S0, where z = x*x; + * for x in (2,inf) + * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) + * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + * as follow: + * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (sin(x) + cos(x)) + * (To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one.) + * + * 3 Special cases + * j1(nan)= nan + * j1(0) = 0 + * j1(inf) = 0 + * + * Method -- y1(x): + * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN + * 2. For x<2. + * Since + * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...) + * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function. + * We use the following function to approximate y1, + * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2 + * Note: For tiny x, 1/x dominate y1 and hence + * y1(tiny) = -2/pi/tiny + * 3. For x>=2. + * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + * by method mentioned above. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static long double pone (long double), qone (long double); +#else +static long double pone (), qone (); +#endif + +#ifdef __STDC__ +static const long double +#else +static long double +#endif + huge = 1e4930L, + one = 1.0L, + invsqrtpi = 5.6418958354775628694807945156077258584405e-1L, + tpi = 6.3661977236758134307553505349005744813784e-1L, + + /* J1(x) = .5 x + x x^2 R(x^2) / S(x^2) + 0 <= x <= 2 + Peak relative error 4.5e-21 */ +R[5] = { + -9.647406112428107954753770469290757756814E7L, + 2.686288565865230690166454005558203955564E6L, + -3.689682683905671185891885948692283776081E4L, + 2.195031194229176602851429567792676658146E2L, + -5.124499848728030297902028238597308971319E-1L, +}, + + S[4] = +{ + 1.543584977988497274437410333029029035089E9L, + 2.133542369567701244002565983150952549520E7L, + 1.394077011298227346483732156167414670520E5L, + 5.252401789085732428842871556112108446506E2L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +#ifdef __STDC__ +static const long double zero = 0.0; +#else +static long double zero = 0.0; +#endif + + +#ifdef __STDC__ +long double +__ieee754_j1l (long double x) +#else +long double +__ieee754_j1l (x) + long double x; +#endif +{ + long double z, c, r, s, ss, cc, u, v, y; + int32_t ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + if (ix >= 0x7fff) + return one / x; + y = fabsl (x); + if (ix >= 0x4000) + { /* |x| >= 2.0 */ + __sincosl (y, &s, &c); + ss = -s - c; + cc = s - c; + if (ix < 0x7ffe) + { /* make sure y+y not overflow */ + z = __cosl (y + y); + if ((s * c) > zero) + cc = z / ss; + else + ss = z / cc; + } + /* + * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + */ + if (ix > 0x4080) + z = (invsqrtpi * cc) / __ieee754_sqrtl (y); + else + { + u = pone (y); + v = qone (y); + z = invsqrtpi * (u * cc - v * ss) / __ieee754_sqrtl (y); + } + if (se & 0x8000) + return -z; + else + return z; + } + if (ix < 0x3fde) /* |x| < 2^-33 */ + { + if (huge + x > one) + return 0.5 * x; /* inexact if x!=0 necessary */ + } + z = x * x; + r = z * (R[0] + z * (R[1]+ z * (R[2] + z * (R[3] + z * R[4])))); + s = S[0] + z * (S[1] + z * (S[2] + z * (S[3] + z))); + r *= x; + return (x * 0.5 + r / s); +} + + +/* Y1(x) = 2/pi * (log(x) * j1(x) - 1/x) + x R(x^2) + 0 <= x <= 2 + Peak relative error 2.3e-23 */ +#ifdef __STDC__ +static const long double U0[6] = { +#else +static long double U0[6] = { +#endif + -5.908077186259914699178903164682444848615E10L, + 1.546219327181478013495975514375773435962E10L, + -6.438303331169223128870035584107053228235E8L, + 9.708540045657182600665968063824819371216E6L, + -6.138043997084355564619377183564196265471E4L, + 1.418503228220927321096904291501161800215E2L, +}; +#ifdef __STDC__ +static const long double V0[5] = { +#else +static long double V0[5] = { +#endif + 3.013447341682896694781964795373783679861E11L, + 4.669546565705981649470005402243136124523E9L, + 3.595056091631351184676890179233695857260E7L, + 1.761554028569108722903944659933744317994E5L, + 5.668480419646516568875555062047234534863E2L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + + +#ifdef __STDC__ +long double +__ieee754_y1l (long double x) +#else +long double +__ieee754_y1l (x) + long double x; +#endif +{ + long double z, s, c, ss, cc, u, v; + int32_t ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ + if (se & 0x8000) + return zero / (zero * x); + if (ix >= 0x7fff) + return one / (x + x * x); + if ((i0 | i1) == 0) + return -HUGE_VALL + x; /* -inf and overflow exception. */ + if (ix >= 0x4000) + { /* |x| >= 2.0 */ + __sincosl (x, &s, &c); + ss = -s - c; + cc = s - c; + if (ix < 0x7fe00000) + { /* make sure x+x not overflow */ + z = __cosl (x + x); + if ((s * c) > zero) + cc = z / ss; + else + ss = z / cc; + } + /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + * where x0 = x-3pi/4 + * Better formula: + * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (cos(x) + sin(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + if (ix > 0x4080) + z = (invsqrtpi * ss) / __ieee754_sqrtl (x); + else + { + u = pone (x); + v = qone (x); + z = invsqrtpi * (u * ss + v * cc) / __ieee754_sqrtl (x); + } + return z; + } + if (ix <= 0x3fbe) + { /* x < 2**-65 */ + return (-tpi / x); + } + z = x * x; + u = U0[0] + z * (U0[1] + z * (U0[2] + z * (U0[3] + z * (U0[4] + z * U0[5])))); + v = V0[0] + z * (V0[1] + z * (V0[2] + z * (V0[3] + z * (V0[4] + z)))); + return (x * (u / v) + + tpi * (__ieee754_j1l (x) * __ieee754_logl (x) - one / x)); +} + + +/* For x >= 8, the asymptotic expansions of pone is + * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. + * We approximate pone by + * pone(x) = 1 + (R/S) + */ + +/* J1(x) cosX + Y1(x) sinX = sqrt( 2/(pi x)) P1(x) + P1(x) = 1 + z^2 R(z^2), z=1/x + 8 <= x <= inf (0 <= z <= 0.125) + Peak relative error 5.2e-22 */ + +#ifdef __STDC__ +static const long double pr8[7] = { +#else +static long double pr8[7] = { +#endif + 8.402048819032978959298664869941375143163E-9L, + 1.813743245316438056192649247507255996036E-6L, + 1.260704554112906152344932388588243836276E-4L, + 3.439294839869103014614229832700986965110E-3L, + 3.576910849712074184504430254290179501209E-2L, + 1.131111483254318243139953003461511308672E-1L, + 4.480715825681029711521286449131671880953E-2L, +}; +#ifdef __STDC__ +static const long double ps8[6] = { +#else +static long double ps8[6] = { +#endif + 7.169748325574809484893888315707824924354E-8L, + 1.556549720596672576431813934184403614817E-5L, + 1.094540125521337139209062035774174565882E-3L, + 3.060978962596642798560894375281428805840E-2L, + 3.374146536087205506032643098619414507024E-1L, + 1.253830208588979001991901126393231302559E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +/* J1(x) cosX + Y1(x) sinX = sqrt( 2/(pi x)) P1(x) + P1(x) = 1 + z^2 R(z^2), z=1/x + 4.54541015625 <= x <= 8 + Peak relative error 7.7e-22 */ +#ifdef __STDC__ +static const long double pr5[7] = { +#else +static long double pr5[7] = { +#endif + 4.318486887948814529950980396300969247900E-7L, + 4.715341880798817230333360497524173929315E-5L, + 1.642719430496086618401091544113220340094E-3L, + 2.228688005300803935928733750456396149104E-2L, + 1.142773760804150921573259605730018327162E-1L, + 1.755576530055079253910829652698703791957E-1L, + 3.218803858282095929559165965353784980613E-2L, +}; +#ifdef __STDC__ +static const long double ps5[6] = { +#else +static long double ps5[6] = { +#endif + 3.685108812227721334719884358034713967557E-6L, + 4.069102509511177498808856515005792027639E-4L, + 1.449728676496155025507893322405597039816E-2L, + 2.058869213229520086582695850441194363103E-1L, + 1.164890985918737148968424972072751066553E0L, + 2.274776933457009446573027260373361586841E0L, + /* 1.000000000000000000000000000000000000000E0L,*/ +}; + +/* J1(x) cosX + Y1(x) sinX = sqrt( 2/(pi x)) P1(x) + P1(x) = 1 + z^2 R(z^2), z=1/x + 2.85711669921875 <= x <= 4.54541015625 + Peak relative error 6.5e-21 */ +#ifdef __STDC__ +static const long double pr3[7] = { +#else +static long double pr3[7] = { +#endif + 1.265251153957366716825382654273326407972E-5L, + 8.031057269201324914127680782288352574567E-4L, + 1.581648121115028333661412169396282881035E-2L, + 1.179534658087796321928362981518645033967E-1L, + 3.227936912780465219246440724502790727866E-1L, + 2.559223765418386621748404398017602935764E-1L, + 2.277136933287817911091370397134882441046E-2L, +}; +#ifdef __STDC__ +static const long double ps3[6] = { +#else +static long double ps3[6] = { +#endif + 1.079681071833391818661952793568345057548E-4L, + 6.986017817100477138417481463810841529026E-3L, + 1.429403701146942509913198539100230540503E-1L, + 1.148392024337075609460312658938700765074E0L, + 3.643663015091248720208251490291968840882E0L, + 3.990702269032018282145100741746633960737E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +/* J1(x) cosX + Y1(x) sinX = sqrt( 2/(pi x)) P1(x) + P1(x) = 1 + z^2 R(z^2), z=1/x + 2 <= x <= 2.85711669921875 + Peak relative error 3.5e-21 */ +#ifdef __STDC__ +static const long double pr2[7] = { +#else +static long double pr2[7] = { +#endif + 2.795623248568412225239401141338714516445E-4L, + 1.092578168441856711925254839815430061135E-2L, + 1.278024620468953761154963591853679640560E-1L, + 5.469680473691500673112904286228351988583E-1L, + 8.313769490922351300461498619045639016059E-1L, + 3.544176317308370086415403567097130611468E-1L, + 1.604142674802373041247957048801599740644E-2L, +}; +#ifdef __STDC__ +static const long double ps2[6] = { +#else +static long double ps2[6] = { +#endif + 2.385605161555183386205027000675875235980E-3L, + 9.616778294482695283928617708206967248579E-2L, + 1.195215570959693572089824415393951258510E0L, + 5.718412857897054829999458736064922974662E0L, + 1.065626298505499086386584642761602177568E1L, + 6.809140730053382188468983548092322151791E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + + +#ifdef __STDC__ +static long double +pone (long double x) +#else +static long double +pone (x) + long double x; +#endif +{ +#ifdef __STDC__ + const long double *p, *q; +#else + long double *p, *q; +#endif + long double z, r, s; + int32_t ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + if (ix >= 0x4002) /* x >= 8 */ + { + p = pr8; + q = ps8; + } + else + { + i1 = (ix << 16) | (i0 >> 16); + if (i1 >= 0x40019174) /* x >= 4.54541015625 */ + { + p = pr5; + q = ps5; + } + else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */ + { + p = pr3; + q = ps3; + } + else if (ix >= 0x4000) /* x better be >= 2 */ + { + p = pr2; + q = ps2; + } + } + z = one / (x * x); + r = p[0] + z * (p[1] + + z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6]))))); + s = q[0] + z * (q[1] + z * (q[2] + z * (q[3] + z * (q[4] + z * (q[5] + z))))); + return one + z * r / s; +} + + +/* For x >= 8, the asymptotic expansions of qone is + * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate pone by + * qone(x) = s*(0.375 + (R/S)) + */ + +/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x), + Q1(x) = z(.375 + z^2 R(z^2)), z=1/x + 8 <= x <= inf + Peak relative error 8.3e-22 */ + +#ifdef __STDC__ +static const long double qr8[7] = { +#else +static long double qr8[7] = { +#endif + -5.691925079044209246015366919809404457380E-10L, + -1.632587664706999307871963065396218379137E-7L, + -1.577424682764651970003637263552027114600E-5L, + -6.377627959241053914770158336842725291713E-4L, + -1.087408516779972735197277149494929568768E-2L, + -6.854943629378084419631926076882330494217E-2L, + -1.055448290469180032312893377152490183203E-1L, +}; +#ifdef __STDC__ +static const long double qs8[7] = { +#else +static long double qs8[7] = { +#endif + 5.550982172325019811119223916998393907513E-9L, + 1.607188366646736068460131091130644192244E-6L, + 1.580792530091386496626494138334505893599E-4L, + 6.617859900815747303032860443855006056595E-3L, + 1.212840547336984859952597488863037659161E-1L, + 9.017885953937234900458186716154005541075E-1L, + 2.201114489712243262000939120146436167178E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x), + Q1(x) = z(.375 + z^2 R(z^2)), z=1/x + 4.54541015625 <= x <= 8 + Peak relative error 4.1e-22 */ +#ifdef __STDC__ +static const long double qr5[7] = { +#else +static long double qr5[7] = { +#endif + -6.719134139179190546324213696633564965983E-8L, + -9.467871458774950479909851595678622044140E-6L, + -4.429341875348286176950914275723051452838E-4L, + -8.539898021757342531563866270278505014487E-3L, + -6.818691805848737010422337101409276287170E-2L, + -1.964432669771684034858848142418228214855E-1L, + -1.333896496989238600119596538299938520726E-1L, +}; +#ifdef __STDC__ +static const long double qs5[7] = { +#else +static long double qs5[7] = { +#endif + 6.552755584474634766937589285426911075101E-7L, + 9.410814032118155978663509073200494000589E-5L, + 4.561677087286518359461609153655021253238E-3L, + 9.397742096177905170800336715661091535805E-2L, + 8.518538116671013902180962914473967738771E-1L, + 3.177729183645800174212539541058292579009E0L, + 4.006745668510308096259753538973038902990E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x), + Q1(x) = z(.375 + z^2 R(z^2)), z=1/x + 2.85711669921875 <= x <= 4.54541015625 + Peak relative error 2.2e-21 */ +#ifdef __STDC__ +static const long double qr3[7] = { +#else +static long double qr3[7] = { +#endif + -3.618746299358445926506719188614570588404E-6L, + -2.951146018465419674063882650970344502798E-4L, + -7.728518171262562194043409753656506795258E-3L, + -8.058010968753999435006488158237984014883E-2L, + -3.356232856677966691703904770937143483472E-1L, + -4.858192581793118040782557808823460276452E-1L, + -1.592399251246473643510898335746432479373E-1L, +}; +#ifdef __STDC__ +static const long double qs3[7] = { +#else +static long double qs3[7] = { +#endif + 3.529139957987837084554591421329876744262E-5L, + 2.973602667215766676998703687065066180115E-3L, + 8.273534546240864308494062287908662592100E-2L, + 9.613359842126507198241321110649974032726E-1L, + 4.853923697093974370118387947065402707519E0L, + 1.002671608961669247462020977417828796933E1L, + 7.028927383922483728931327850683151410267E0L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + +/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x), + Q1(x) = z(.375 + z^2 R(z^2)), z=1/x + 2 <= x <= 2.85711669921875 + Peak relative error 6.9e-22 */ +#ifdef __STDC__ +static const long double qr2[7] = { +#else +static long double qr2[7] = { +#endif + -1.372751603025230017220666013816502528318E-4L, + -6.879190253347766576229143006767218972834E-3L, + -1.061253572090925414598304855316280077828E-1L, + -6.262164224345471241219408329354943337214E-1L, + -1.423149636514768476376254324731437473915E0L, + -1.087955310491078933531734062917489870754E0L, + -1.826821119773182847861406108689273719137E-1L, +}; +#ifdef __STDC__ +static const long double qs2[7] = { +#else +static long double qs2[7] = { +#endif + 1.338768933634451601814048220627185324007E-3L, + 7.071099998918497559736318523932241901810E-2L, + 1.200511429784048632105295629933382142221E0L, + 8.327301713640367079030141077172031825276E0L, + 2.468479301872299311658145549931764426840E1L, + 2.961179686096262083509383820557051621644E1L, + 1.201402313144305153005639494661767354977E1L, + /* 1.000000000000000000000000000000000000000E0L, */ +}; + + +#ifdef __STDC__ +static long double +qone (long double x) +#else +static long double +qone (x) + long double x; +#endif +{ +#ifdef __STDC__ + const long double *p, *q; +#else + long double *p, *q; +#endif + static long double s, r, z; + int32_t ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + if (ix >= 0x4002) /* x >= 8 */ + { + p = qr8; + q = qs8; + } + else + { + i1 = (ix << 16) | (i0 >> 16); + if (i1 >= 0x40019174) /* x >= 4.54541015625 */ + { + p = qr5; + q = qs5; + } + else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */ + { + p = qr3; + q = qs3; + } + else if (ix >= 0x4000) /* x better be >= 2 */ + { + p = qr2; + q = qs2; + } + } + z = one / (x * x); + r = + p[0] + z * (p[1] + + z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6]))))); + s = + q[0] + z * (q[1] + + z * (q[2] + + z * (q[3] + z * (q[4] + z * (q[5] + z * (q[6] + z)))))); + return (.375 + z * r / s) / x; +} diff --git a/src/system/libroot/posix/glibc/arch/generic/e_jnl.c b/src/system/libroot/posix/glibc/arch/generic/e_jnl.c new file mode 100644 index 0000000000..3d715d36aa --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/e_jnl.c @@ -0,0 +1,386 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* Modifications for long double are + Copyright (C) 2001 Stephen L. Moshier + and are incorporated herein by permission of the author. The author + reserves the right to distribute this material elsewhere under different + copying permissions. These modifications are distributed here under + the following terms: + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + * __ieee754_jn(n, x), __ieee754_yn(n, x) + * floating point Bessel's function of the 1st and 2nd kind + * of order n + * + * Special cases: + * y0(0)=y1(0)=yn(n,0) = -inf with overflow signal; + * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. + * Note 2. About jn(n,x), yn(n,x) + * For n=0, j0(x) is called, + * for n=1, j1(x) is called, + * for nx, a continued fraction approximation to + * j(n,x)/j(n-1,x) is evaluated and then backward + * recursion is used starting from a supposed value + * for j(n,x). The resulting value of j(0,x) is + * compared with the actual value to correct the + * supposed value of j(n,x). + * + * yn(n,x) is similar in all respects, except + * that forward recursion is used for all + * values of n>1. + * + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const long double +#else +static long double +#endif + invsqrtpi = 5.64189583547756286948079e-1L, two = 2.0e0L, one = 1.0e0L; + +#ifdef __STDC__ +static const long double zero = 0.0L; +#else +static long double zero = 0.0L; +#endif + +#ifdef __STDC__ +long double +__ieee754_jnl (int n, long double x) +#else +long double +__ieee754_jnl (n, x) + int n; + long double x; +#endif +{ + u_int32_t se, i0, i1; + int32_t i, ix, sgn; + long double a, b, temp, di; + long double z, w; + + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) + */ + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + + /* if J(n,NaN) is NaN */ + if ((ix == 0x7fff) && ((i0 & 0x7fffffff) != 0)) + return x + x; + if (n < 0) + { + n = -n; + x = -x; + se ^= 0x8000; + } + if (n == 0) + return (__ieee754_j0l (x)); + if (n == 1) + return (__ieee754_j1l (x)); + sgn = (n & 1) & (se >> 15); /* even n -- 0, odd n -- sign(x) */ + x = fabsl (x); + if ((ix | i0 | i1) == 0 || ix >= 0x7fff) /* if x is 0 or inf */ + b = zero; + else if ((long double) n <= x) + { + /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ + if (ix >= 0x412D) + { /* x > 2**302 */ + + /* ??? This might be a futile gesture. + If x exceeds X_TLOSS anyway, the wrapper function + will set the result to zero. */ + + /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + long double s; + long double c; + __sincosl (x, &s, &c); + switch (n & 3) + { + case 0: + temp = c + s; + break; + case 1: + temp = -c + s; + break; + case 2: + temp = -c - s; + break; + case 3: + temp = c - s; + break; + } + b = invsqrtpi * temp / __ieee754_sqrtl (x); + } + else + { + a = __ieee754_j0l (x); + b = __ieee754_j1l (x); + for (i = 1; i < n; i++) + { + temp = b; + b = b * ((long double) (i + i) / x) - a; /* avoid underflow */ + a = temp; + } + } + } + else + { + if (ix < 0x3fde) + { /* x < 2**-33 */ + /* x is tiny, return the first Taylor expansion of J(n,x) + * J(n,x) = 1/n!*(x/2)^n - ... + */ + if (n >= 400) /* underflow, result < 10^-4952 */ + b = zero; + else + { + temp = x * 0.5; + b = temp; + for (a = one, i = 2; i <= n; i++) + { + a *= (long double) i; /* a = n! */ + b *= temp; /* b = (x/2)^n */ + } + b = b / a; + } + } + else + { + /* use backward recurrence */ + /* x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- ------ ------ ..... + * 2n - 2(n+1) - 2(n+2) + * + * 1 1 1 + * (for large x) = ---- ------ ------ ..... + * 2n 2(n+1) 2(n+2) + * -- - ------ - ------ - + * x x x + * + * Let w = 2n/x and h=2/x, then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms needed, let + * Q(0) = w, Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + * When Q(k) > 1e4 good for single + * When Q(k) > 1e9 good for double + * When Q(k) > 1e17 good for quadruple + */ + /* determine k */ + long double t, v; + long double q0, q1, h, tmp; + int32_t k, m; + w = (n + n) / (long double) x; + h = 2.0L / (long double) x; + q0 = w; + z = w + h; + q1 = w * z - 1.0L; + k = 1; + while (q1 < 1.0e11L) + { + k += 1; + z += h; + tmp = z * q1 - q0; + q0 = q1; + q1 = tmp; + } + m = n + n; + for (t = zero, i = 2 * (n + k); i >= m; i -= 2) + t = one / (i / x - t); + a = t; + b = one; + /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * Hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01 + * double 7.09782712893383973096e+02 + * long double 1.1356523406294143949491931077970765006170e+04 + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + tmp = n; + v = two / x; + tmp = tmp * __ieee754_logl (fabsl (v * tmp)); + + if (tmp < 1.1356523406294143949491931077970765006170e+04L) + { + for (i = n - 1, di = (long double) (i + i); i > 0; i--) + { + temp = b; + b *= di; + b = b / x - a; + a = temp; + di -= two; + } + } + else + { + for (i = n - 1, di = (long double) (i + i); i > 0; i--) + { + temp = b; + b *= di; + b = b / x - a; + a = temp; + di -= two; + /* scale b to avoid spurious overflow */ + if (b > 1e100L) + { + a /= b; + t /= b; + b = one; + } + } + } + b = (t * __ieee754_j0l (x) / b); + } + } + if (sgn == 1) + return -b; + else + return b; +} + +#ifdef __STDC__ +long double +__ieee754_ynl (int n, long double x) +#else +long double +__ieee754_ynl (n, x) + int n; + long double x; +#endif +{ + u_int32_t se, i0, i1; + int32_t i, ix; + int32_t sign; + long double a, b, temp; + + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + /* if Y(n,NaN) is NaN */ + if ((ix == 0x7fff) && ((i0 & 0x7fffffff) != 0)) + return x + x; + if ((ix | i0 | i1) == 0) + return -HUGE_VALL + x; /* -inf and overflow exception. */ + if (se & 0x8000) + return zero / (zero * x); + sign = 1; + if (n < 0) + { + n = -n; + sign = 1 - ((n & 1) << 1); + } + if (n == 0) + return (__ieee754_y0l (x)); + if (n == 1) + return (sign * __ieee754_y1l (x)); + if (ix == 0x7fff) + return zero; + if (ix >= 0x412D) + { /* x > 2**302 */ + + /* ??? See comment above on the possible futility of this. */ + + /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + long double s; + long double c; + __sincosl (x, &s, &c); + switch (n & 3) + { + case 0: + temp = s - c; + break; + case 1: + temp = -s - c; + break; + case 2: + temp = -s + c; + break; + case 3: + temp = s + c; + break; + } + b = invsqrtpi * temp / __ieee754_sqrtl (x); + } + else + { + a = __ieee754_y0l (x); + b = __ieee754_y1l (x); + /* quit if b is -inf */ + GET_LDOUBLE_WORDS (se, i0, i1, b); + for (i = 1; i < n && se != 0xffff; i++) + { + temp = b; + b = ((long double) (i + i) / x) * b - a; + GET_LDOUBLE_WORDS (se, i0, i1, b); + a = temp; + } + } + if (sign > 0) + return b; + else + return -b; +} diff --git a/src/system/libroot/posix/glibc/arch/generic/e_rem_pio2.c b/src/system/libroot/posix/glibc/arch/generic/e_rem_pio2.c new file mode 100644 index 0000000000..a8a8cdb2b2 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/e_rem_pio2.c @@ -0,0 +1,183 @@ +/* @(#)e_rem_pio2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_rem_pio2.c,v 1.8 1995/05/10 20:46:02 jtc Exp $"; +#endif + +/* __ieee754_rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include "math.h" +#include "math_private.h" + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +#ifdef __STDC__ +static const int32_t two_over_pi[] = { +#else +static int32_t two_over_pi[] = { +#endif +0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, +0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, +0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, +0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, +0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, +0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, +0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, +0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, +0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, +0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, +0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, +}; + +#ifdef __STDC__ +static const int32_t npio2_hw[] = { +#else +static int32_t npio2_hw[] = { +#endif +0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C, +0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C, +0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A, +0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C, +0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB, +0x404858EB, 0x404921FB, +}; + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 33 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 33 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const double +#else +static double +#endif +zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ +pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ +pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ +pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ +pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ +pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + +#ifdef __STDC__ + int32_t __ieee754_rem_pio2(double x, double *y) +#else + int32_t __ieee754_rem_pio2(x,y) + double x,y[]; +#endif +{ + double z,w,t,r,fn; + double tx[3]; + int32_t e0,i,j,nx,n,ix,hx; + u_int32_t low; + + GET_HIGH_WORD(hx,x); /* high word of x */ + ix = hx&0x7fffffff; + if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - pio2_1; + if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z - pio2_1t; + y[1] = (z-y[0])-pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z-y[0])-pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z + pio2_1t; + y[1] = (z-y[0])+pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z-y[0])+pio2_2t; + } + return -1; + } + } + if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ + t = fabs(x); + n = (int32_t) (t*invpio2+half); + fn = (double)n; + r = t-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 85 bit */ + if(n<32&&ix!=npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + u_int32_t high; + j = ix>>20; + y[0] = r-w; + GET_HIGH_WORD(high,y[0]); + i = j-((high>>20)&0x7ff); + if(i>16) { /* 2nd iteration needed, good to 118 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + GET_HIGH_WORD(high,y[0]); + i = j-((high>>20)&0x7ff); + if(i>49) { /* 3rd iteration need, 151 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7ff00000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + GET_LOW_WORD(low,x); + SET_LOW_WORD(z,low); + e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */ + SET_HIGH_WORD(z, ix - ((int32_t)(e0<<20))); + for(i=0;i<2;i++) { + tx[i] = (double)((int32_t)(z)); + z = (z-tx[i])*two24; + } + tx[2] = z; + nx = 3; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi); + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + return n; +} diff --git a/src/system/libroot/posix/glibc/arch/generic/s_asinhl.c b/src/system/libroot/posix/glibc/arch/generic/s_asinhl.c new file mode 100644 index 0000000000..6eb434c44b --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_asinhl.c @@ -0,0 +1,70 @@ +/* s_asinhl.c -- long double version of s_asinh.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* asinhl(x) + * Method : + * Based on + * asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ] + * we have + * asinhl(x) := x if 1+x*x=1, + * := signl(x)*(logl(x)+ln2)) for large |x|, else + * := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else + * := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2))) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const long double +#else +static long double +#endif +one = 1.000000000000000000000e+00L, /* 0x3FFF, 0x00000000, 0x00000000 */ +ln2 = 6.931471805599453094287e-01L, /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */ +huge= 1.000000000000000000e+4900L; + +#ifdef __STDC__ + long double __asinhl(long double x) +#else + long double __asinhl(x) + long double x; +#endif +{ + long double t,w; + int32_t hx,ix; + GET_LDOUBLE_EXP(hx,x); + ix = hx&0x7fff; + if(ix==0x7fff) return x+x; /* x is inf or NaN */ + if(ix< 0x3fde) { /* |x|<2**-34 */ + if(huge+x>one) return x; /* return x inexact except 0 */ + } + if(ix>0x4020) { /* |x| > 2**34 */ + w = __ieee754_logl(fabsl(x))+ln2; + } else if (ix>0x4000) { /* 2**34 > |x| > 2.0 */ + t = fabsl(x); + w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t)); + } else { /* 2.0 > |x| > 2**-28 */ + t = x*x; + w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t))); + } + if(hx&0x8000) return -w; else return w; +} +weak_alias (__asinhl, asinhl) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_cbrtl.c b/src/system/libroot/posix/glibc/arch/generic/s_cbrtl.c new file mode 100644 index 0000000000..0f8227a04b --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_cbrtl.c @@ -0,0 +1,71 @@ +/* Compute cubic root of double value. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Dirk Alboth and + Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "math.h" +#include "math_private.h" + + +#define CBRT2 1.2599210498948731648 /* 2^(1/3) */ +#define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */ + +/* We don't use long double values here since U need not be computed + with full precision. */ +static const double factor[5] = +{ + 1.0 / SQR_CBRT2, + 1.0 / CBRT2, + 1.0, + CBRT2, + SQR_CBRT2 +}; + +static const long double third = 0.3333333333333333333333333L; + +long double +__cbrtl (long double x) +{ + long double xm, u; + int xe; + + /* Reduce X. XM now is an range 1.0 to 0.5. */ + xm = __frexpl (fabs (x), &xe); + + /* If X is not finite or is null return it (with raising exceptions + if necessary. + Note: *Our* version of `frexp' sets XE to zero if the argument is + Inf or NaN. This is not portable but faster. */ + if (xe == 0 && fpclassify (x) <= FP_ZERO) + return x + x; + + u = (((-1.34661104733595206551E-1 * xm + + 5.46646013663955245034E-1) * xm + - 9.54382247715094465250E-1) * xm + + 1.13999833547172932737E0) * xm + + 4.02389795645447521269E-1; + + u *= factor[2 + xe % 3]; + u = __ldexpl (x > 0.0 ? u : -u, xe / 3); + + u -= (u - (x / (u * u))) * third; + u -= (u - (x / (u * u))) * third; + return u; +} +weak_alias (__cbrtl, cbrtl) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_fdim.c b/src/system/libroot/posix/glibc/arch/generic/s_fdim.c new file mode 100644 index 0000000000..5804e631c3 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_fdim.c @@ -0,0 +1,40 @@ +/* Return positive difference between arguments. + Copyright (C) 1997, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +double +__fdim (double x, double y) +{ + int clsx = fpclassify (x); + int clsy = fpclassify (y); + + if (clsx == FP_NAN || clsy == FP_NAN + || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE)) + /* Raise invalid flag. */ + return x - y; + + return x <= y ? 0 : x - y; +} +weak_alias (__fdim, fdim) +#ifdef NO_LONG_DOUBLE +strong_alias (__fdim, __fdiml) +weak_alias (__fdim, fdiml) +#endif diff --git a/src/system/libroot/posix/glibc/arch/generic/s_fdimf.c b/src/system/libroot/posix/glibc/arch/generic/s_fdimf.c new file mode 100644 index 0000000000..2f3ce303ae --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_fdimf.c @@ -0,0 +1,36 @@ +/* Return positive difference between arguments. + Copyright (C) 1997, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +float +__fdimf (float x, float y) +{ + int clsx = fpclassify (x); + int clsy = fpclassify (y); + + if (clsx == FP_NAN || clsy == FP_NAN + || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE)) + /* Raise invalid flag. */ + return x - y; + + return x <= y ? 0 : x - y; +} +weak_alias (__fdimf, fdimf) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_frexpl.c b/src/system/libroot/posix/glibc/arch/generic/s_frexpl.c new file mode 100644 index 0000000000..0caa90b035 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_frexpl.c @@ -0,0 +1,70 @@ +/* s_frexpl.c -- long double version of s_frexp.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* + * for non-zero x + * x = frexpl(arg,&exp); + * return a long double fp quantity x such that 0.5 <= |x| <1.0 + * and the corresponding binary exponent "exp". That is + * arg = x*2^exp. + * If arg is inf, 0.0, or NaN, then frexpl(arg,&exp) returns arg + * with *exp=0. + */ + +#include +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const long double +#else +static long double +#endif +#if LDBL_MANT_DIG == 64 +two65 = 3.68934881474191032320e+19L; /* 0x4040, 0x80000000, 0x00000000 */ +#else +# error "Cannot handle this MANT_DIG" +#endif + + +#ifdef __STDC__ + long double __frexpl(long double x, int *eptr) +#else + long double __frexpl(x, eptr) + long double x; int *eptr; +#endif +{ + u_int32_t se, hx, ix, lx; + GET_LDOUBLE_WORDS(se,hx,lx,x); + ix = 0x7fff&se; + *eptr = 0; + if(ix==0x7fff||((ix|hx|lx)==0)) return x; /* 0,inf,nan */ + if (ix==0x0000) { /* subnormal */ + x *= two65; + GET_LDOUBLE_EXP(se,x); + ix = se&0x7fff; + *eptr = -65; + } + *eptr += ix-16382; + se = (se & 0x8000) | 0x3ffe; + SET_LDOUBLE_EXP(x,se); + return x; +} +weak_alias (__frexpl, frexpl) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_ldexpl.c b/src/system/libroot/posix/glibc/arch/generic/s_ldexpl.c new file mode 100644 index 0000000000..df8b29f94d --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_ldexpl.c @@ -0,0 +1,37 @@ +/* s_ldexpl.c -- long double version of s_ldexp.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +#include +#include "math_private.h" +#include + +#ifdef __STDC__ + long double __ldexpl(long double value, int exp) +#else + long double __ldexpl(value, exp) + long double value; int exp; +#endif +{ + if(!__finitel(value)||value==0.0) return value; + value = __scalbnl(value,exp); + if(!__finitel(value)||value==0.0) __set_errno (ERANGE); + return value; +} +weak_alias (__ldexpl, ldexpl) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_nearbyint.c b/src/system/libroot/posix/glibc/arch/generic/s_nearbyint.c new file mode 100644 index 0000000000..71e14cfb6d --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_nearbyint.c @@ -0,0 +1,105 @@ +/* Adapted for use as nearbyint by Ulrich Drepper . */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $"; +#endif + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +#ifdef __STDC__ + double __nearbyint(double x) +#else + double __nearbyint(x) + double x; +#endif +{ + fenv_t env; + int32_t i0,j0,sx; + u_int32_t i,i1; + double w,t; + EXTRACT_WORDS(i0,i1,x); + sx = (i0>>31)&1; + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { + if(((i0&0x7fffffff)|i1)==0) return x; + i1 |= (i0&0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1|-i1)>>12)&0x80000; + SET_HIGH_WORD(x,i0); + feholdexcept (&env); + w = TWO52[sx]+x; + t = w-TWO52[sx]; + fesetenv (&env); + GET_HIGH_WORD(i0,t); + SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + i>>=1; + if(((i0&i)|i1)!=0) { + if (j0==19) + i1 = 0x40000000; + else if (j0<18) + i0 = (i0&(~i))|((0x20000)>>j0); + else + { + i0 &= ~i; + i1 = 0x80000000; + } + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + i>>=1; + if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); + } + INSERT_WORDS(x,i0,i1); + feholdexcept (&env); + w = TWO52[sx]+x; + t = w-TWO52[sx]; + fesetenv (&env); + return t; +} +weak_alias (__nearbyint, nearbyint) +#ifdef NO_LONG_DOUBLE +strong_alias (__nearbyint, __nearbyintl) +weak_alias (__nearbyint, nearbyintl) +#endif diff --git a/src/system/libroot/posix/glibc/arch/generic/s_nearbyintf.c b/src/system/libroot/posix/glibc/arch/generic/s_nearbyintf.c new file mode 100644 index 0000000000..7d6f262f51 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_nearbyintf.c @@ -0,0 +1,77 @@ +/* s_rintf.c -- float version of s_rint.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ +/* Adapted for use as nearbyint by Ulrich Drepper . */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + +#include +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; + +#ifdef __STDC__ + float __nearbyintf(float x) +#else + float __nearbyintf(x) + float x; +#endif +{ + fenv_t env; + int32_t i0,j0,sx; + u_int32_t i,i1; + float w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + if((i0&0x7fffffff)==0) return x; + i1 = (i0&0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1|-i1)>>9)&0x400000; + SET_FLOAT_WORD(x,i0); + feholdexcept (&env); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + fesetenv (&env); + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + feholdexcept (&env); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + fesetenv (&env); + return t; +} +weak_alias (__nearbyintf, nearbyintf) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_rint.c b/src/system/libroot/posix/glibc/arch/generic/s_rint.c new file mode 100644 index 0000000000..4e6381efbe --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_rint.c @@ -0,0 +1,98 @@ +/* @(#)s_rint.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $"; +#endif + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +#ifdef __STDC__ + double __rint(double x) +#else + double __rint(x) + double x; +#endif +{ + int32_t i0,j0,sx; + u_int32_t i,i1; + double w,t; + EXTRACT_WORDS(i0,i1,x); + sx = (i0>>31)&1; + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { + if(((i0&0x7fffffff)|i1)==0) return x; + i1 |= (i0&0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1|-i1)>>12)&0x80000; + SET_HIGH_WORD(x,i0); + w = TWO52[sx]+x; + t = w-TWO52[sx]; + GET_HIGH_WORD(i0,t); + SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + i>>=1; + if(((i0&i)|i1)!=0) { + if (j0==19) + i1 = 0x40000000; + else if (j0<18) + i0 = (i0&(~i))|((0x20000)>>j0); + else + { + i0 &= ~i; + i1 = 0x80000000; + } + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + i>>=1; + if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); + } + INSERT_WORDS(x,i0,i1); + w = TWO52[sx]+x; + return w-TWO52[sx]; +} +weak_alias (__rint, rint) +#ifdef NO_LONG_DOUBLE +strong_alias (__rint, __rintl) +weak_alias (__rint, rintl) +#endif diff --git a/src/system/libroot/posix/glibc/arch/generic/s_rintf.c b/src/system/libroot/posix/glibc/arch/generic/s_rintf.c new file mode 100644 index 0000000000..4e5b409b29 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_rintf.c @@ -0,0 +1,72 @@ +/* s_rintf.c -- float version of s_rint.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_rintf.c,v 1.4 1995/05/10 20:48:06 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; + +#ifdef __STDC__ + float __rintf(float x) +#else + float __rintf(x) + float x; +#endif +{ + int32_t i0,j0,sx; + u_int32_t i,i1; + float w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + if((i0&0x7fffffff)==0) return x; + i1 = (i0&0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1|-i1)>>9)&0x400000; + SET_FLOAT_WORD(x,i0); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + w = TWO23[sx]+x; + return w-TWO23[sx]; +} +weak_alias (__rintf, rintf) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_scalbln.c b/src/system/libroot/posix/glibc/arch/generic/s_scalbln.c new file mode 100644 index 0000000000..aa6134f093 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_scalbln.c @@ -0,0 +1,70 @@ +/* @(#)s_scalbn.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_scalbn.c,v 1.8 1995/05/10 20:48:08 jtc Exp $"; +#endif + +/* + * scalbn (double x, int n) + * scalbn(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ +huge = 1.0e+300, +tiny = 1.0e-300; + +#ifdef __STDC__ + double __scalbln (double x, long int n) +#else + double __scalbln (x,n) + double x; long int n; +#endif +{ + int32_t k,hx,lx; + EXTRACT_WORDS(hx,lx,x); + k = (hx&0x7ff00000)>>20; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ + x *= two54; + GET_HIGH_WORD(hx,x); + k = ((hx&0x7ff00000)>>20) - 54; + } + if (k==0x7ff) return x+x; /* NaN or Inf */ + k = k+n; + if (n> 50000 || k > 0x7fe) + return huge*__copysign(huge,x); /* overflow */ + if (n< -50000) return tiny*__copysign(tiny,x); /*underflow*/ + if (k > 0) /* normal result */ + {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} + if (k <= -54) + return tiny*__copysign(tiny,x); /*underflow*/ + k += 54; /* subnormal result */ + SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); + return x*twom54; +} +weak_alias (__scalbln, scalbln) +#ifdef NO_LONG_DOUBLE +strong_alias (__scalbln, __scalblnl) +weak_alias (__scalbln, scalblnl) +#endif diff --git a/src/system/libroot/posix/glibc/arch/generic/s_scalblnf.c b/src/system/libroot/posix/glibc/arch/generic/s_scalblnf.c new file mode 100644 index 0000000000..4ed48733cf --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_scalblnf.c @@ -0,0 +1,63 @@ +/* s_scalbnf.c -- float version of s_scalbn.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_scalbnf.c,v 1.4 1995/05/10 20:48:10 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +two25 = 3.355443200e+07, /* 0x4c000000 */ +twom25 = 2.9802322388e-08, /* 0x33000000 */ +huge = 1.0e+30, +tiny = 1.0e-30; + +#ifdef __STDC__ + float __scalblnf (float x, long int n) +#else + float __scalblnf (x,n) + float x; long int n; +#endif +{ + int32_t k,ix; + GET_FLOAT_WORD(ix,x); + k = (ix&0x7f800000)>>23; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((ix&0x7fffffff)==0) return x; /* +-0 */ + x *= two25; + GET_FLOAT_WORD(ix,x); + k = ((ix&0x7f800000)>>23) - 25; + } + if (k==0xff) return x+x; /* NaN or Inf */ + k = k+n; + if (n> 50000 || k > 0xfe) + return huge*copysignf(huge,x); /* overflow */ + if (n< -50000) + return tiny*copysignf(tiny,x); /*underflow*/ + if (k > 0) /* normal result */ + {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} + if (k <= -25) + return tiny*copysignf(tiny,x); /*underflow*/ + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); + return x*twom25; +} +weak_alias (__scalblnf, scalblnf) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_scalblnl.c b/src/system/libroot/posix/glibc/arch/generic/s_scalblnl.c new file mode 100644 index 0000000000..8e556fabe1 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_scalblnl.c @@ -0,0 +1,71 @@ +/* s_scalbnl.c -- long double version of s_scalbn.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* + * scalbnl (long double x, int n) + * scalbnl(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const long double +#else +static long double +#endif +two63 = 4.50359962737049600000e+15, +twom63 = 1.08420217248550443400e-19, +huge = 1.0e+4900L, +tiny = 1.0e-4900L; + +#ifdef __STDC__ + long double __scalblnl (long double x, long int n) +#else + long double __scalblnl (x,n) + long double x; long int n; +#endif +{ + int32_t k,es,hx,lx; + GET_LDOUBLE_WORDS(es,hx,lx,x); + k = es&0x7fff; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ + x *= two63; + GET_LDOUBLE_EXP(es,x); + k = (hx&0x7fff) - 63; + } + if (k==0x7fff) return x+x; /* NaN or Inf */ + k = k+n; + if (n> 50000 || k > 0x7ffe) + return huge*__copysignl(huge,x); /* overflow */ + if (n< -50000) + return tiny*__copysignl(tiny,x); + if (k > 0) /* normal result */ + {SET_LDOUBLE_EXP(x,(es&0x8000)|k); return x;} + if (k <= -63) + return tiny*__copysignl(tiny,x); /*underflow*/ + k += 63; /* subnormal result */ + SET_LDOUBLE_EXP(x,(es&0x8000)|k); + return x*twom63; +} +weak_alias (__scalblnl, scalblnl) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_tanhl.c b/src/system/libroot/posix/glibc/arch/generic/s_tanhl.c new file mode 100644 index 0000000000..45cea903e3 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_tanhl.c @@ -0,0 +1,95 @@ +/* s_tanhl.c -- long double version of s_tanh.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* tanhl(x) + * Return the Hyperbolic Tangent of x + * + * Method : + * x -x + * e - e + * 0. tanhl(x) is defined to be ----------- + * x -x + * e + e + * 1. reduce x to non-negative by tanhl(-x) = -tanhl(x). + * 2. 0 <= x <= 2**-55 : tanhl(x) := x*(one+x) + * -t + * 2**-55 < x <= 1 : tanhl(x) := -----; t = expm1l(-2x) + * t + 2 + * 2 + * 1 <= x <= 23.0 : tanhl(x) := 1- ----- ; t=expm1l(2x) + * t + 2 + * 23.0 < x <= INF : tanhl(x) := 1. + * + * Special cases: + * tanhl(NaN) is NaN; + * only tanhl(0)=0 is exact for finite argument. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const long double one=1.0, two=2.0, tiny = 1.0e-4900L; +#else +static long double one=1.0, two=2.0, tiny = 1.0e-4900L; +#endif + +#ifdef __STDC__ + long double __tanhl(long double x) +#else + long double __tanhl(x) + long double x; +#endif +{ + long double t,z; + int32_t se; + u_int32_t j0,j1,ix; + + /* High word of |x|. */ + GET_LDOUBLE_WORDS(se,j0,j1,x); + ix = se&0x7fff; + + /* x is INF or NaN */ + if(ix==0x7fff) { + /* for NaN it's not important which branch: tanhl(NaN) = NaN */ + if (se&0x8000) return one/x-one; /* tanhl(-inf)= -1; */ + else return one/x+one; /* tanhl(+inf)=+1 */ + } + + /* |x| < 23 */ + if (ix < 0x4003 || (ix == 0x4003 && j0 < 0xb8000000u)) {/* |x|<23 */ + if ((ix|j0|j1) == 0) + return x; /* x == +- 0 */ + if (ix<0x3fc8) /* |x|<2**-55 */ + return x*(one+tiny); /* tanh(small) = small */ + if (ix>=0x3fff) { /* |x|>=1 */ + t = __expm1l(two*fabsl(x)); + z = one - two/(t+two); + } else { + t = __expm1l(-two*fabsl(x)); + z= -t/(t+two); + } + /* |x| > 23, return +-1 */ + } else { + z = one - tiny; /* raised inexact flag */ + } + return (se&0x8000)? -z: z; +} +weak_alias (__tanhl, tanhl) diff --git a/src/system/libroot/posix/glibc/arch/generic/t_exp2.h b/src/system/libroot/posix/glibc/arch/generic/t_exp2.h new file mode 100644 index 0000000000..1fd73338cf --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/t_exp2.h @@ -0,0 +1,585 @@ +/* These values are accurate to 52+12 bits when represented as + a double. */ +static const double exp2_accuratetable[512] = { +0.707106781187802013759 /* 0x0.b504f333fb3f80007 */, +0.708064712808760599040 /* 0x0.b543baa0f71b38000 */, +0.709023942160304065938 /* 0x0.b58297d3a8d518002 */, +0.709984470998547667624 /* 0x0.b5c18ad39b4ba0001 */, +0.710946301084324217006 /* 0x0.b60093a85e8d30001 */, +0.711909434180505784637 /* 0x0.b63fb25984e628005 */, +0.712873872052760648733 /* 0x0.b67ee6eea3b5f8003 */, +0.713839616467838999908 /* 0x0.b6be316f518c98001 */, +0.714806669195984345523 /* 0x0.b6fd91e328d148007 */, +0.715775032009894562898 /* 0x0.b73d0851c69e20002 */, +0.716744706683768884058 /* 0x0.b77c94c2c9b3d0003 */, +0.717715694995770148178 /* 0x0.b7bc373dd52eb0003 */, +0.718687998724665488852 /* 0x0.b7fbefca8cd530004 */, +0.719661619652575468291 /* 0x0.b83bbe70981da8001 */, +0.720636559564428180758 /* 0x0.b87ba337a194b0006 */, +0.721612820246623098989 /* 0x0.b8bb9e27556508004 */, +0.722590403488338473025 /* 0x0.b8fbaf4762c798006 */, +0.723569311081411870036 /* 0x0.b93bd69f7be1d0000 */, +0.724549544820974333906 /* 0x0.b97c1437567828007 */, +0.725531106502312561633 /* 0x0.b9bc6816a87ae8002 */, +0.726513997924421062181 /* 0x0.b9fcd2452bee00000 */, +0.727498220889519875430 /* 0x0.ba3d52ca9e6148002 */, +0.728483777200401694265 /* 0x0.ba7de9aebe05c8003 */, +0.729470668664712662563 /* 0x0.babe96f94e62a8002 */, +0.730458897090379144517 /* 0x0.baff5ab2134df0004 */, +0.731448464287988597833 /* 0x0.bb4034e0d38ab0000 */, +0.732439372072965166897 /* 0x0.bb81258d5b2d60001 */, +0.733431622260458326859 /* 0x0.bbc22cbf75fd28001 */, +0.734425216668725511232 /* 0x0.bc034a7ef32c00001 */, +0.735420157118880535324 /* 0x0.bc447ed3a50fe0005 */, +0.736416445434497690674 /* 0x0.bc85c9c560b350001 */, +0.737414083433310718618 /* 0x0.bcc72b5bf4b4e0000 */, +0.738413072966152328496 /* 0x0.bd08a39f5417a8007 */, +0.739413415848264365956 /* 0x0.bd4a32974abcd0002 */, +0.740415113911250699637 /* 0x0.bd8bd84bb68300002 */, +0.741418168994518067562 /* 0x0.bdcd94c47ddd30003 */, +0.742422582936659858376 /* 0x0.be0f6809865968006 */, +0.743428357577745613238 /* 0x0.be515222b72530003 */, +0.744435494762383687126 /* 0x0.be935317fc6ba0002 */, +0.745443996335090397492 /* 0x0.bed56af1423de8001 */, +0.746453864145572798553 /* 0x0.bf1799b67a6248007 */, +0.747465100043933849969 /* 0x0.bf59df6f970e70002 */, +0.748477705883256683178 /* 0x0.bf9c3c248dbee8001 */, +0.749491683518965001732 /* 0x0.bfdeafdd568308000 */, +0.750507034813367890373 /* 0x0.c0213aa1f0fc38004 */, +0.751523761622240105153 /* 0x0.c063dc7a559ca0003 */, +0.752541865811731880422 /* 0x0.c0a6956e883ed8000 */, +0.753561349247157341600 /* 0x0.c0e965868bd220006 */, +0.754582213796583967110 /* 0x0.c12c4cca664cb8002 */, +0.755604461332336940791 /* 0x0.c16f4b42225350006 */, +0.756628093726406381068 /* 0x0.c1b260f5ca2c48002 */, +0.757653112855631305506 /* 0x0.c1f58ded6d72d8001 */, +0.758679520599333412360 /* 0x0.c238d2311e7d08001 */, +0.759707318837184453227 /* 0x0.c27c2dc8f00368005 */, +0.760736509456435783249 /* 0x0.c2bfa0bcfd1400000 */, +0.761767094336480043995 /* 0x0.c3032b155818d0000 */, +0.762799075372231349951 /* 0x0.c346ccda248cc0001 */, +0.763832454453522768941 /* 0x0.c38a8613805488005 */, +0.764867233473625618441 /* 0x0.c3ce56c98d1ca8005 */, +0.765903414329434539816 /* 0x0.c4123f04708d80002 */, +0.766940998920452976510 /* 0x0.c4563ecc532dc0001 */, +0.767979989148100838946 /* 0x0.c49a56295f9f88006 */, +0.769020386915772125040 /* 0x0.c4de8523c2b0a0001 */, +0.770062194131770905170 /* 0x0.c522cbc3ae94e0003 */, +0.771105412703856241146 /* 0x0.c5672a1154e6b8004 */, +0.772150044545352520777 /* 0x0.c5aba014ed5f18003 */, +0.773196091570364285606 /* 0x0.c5f02dd6b09288003 */, +0.774243555696622731700 /* 0x0.c634d35edb1260003 */, +0.775292438842697939641 /* 0x0.c67990b5aa5c18004 */, +0.776342742931542928455 /* 0x0.c6be65e360bed8000 */, +0.777394469888802008854 /* 0x0.c70352f0437f50004 */, +0.778447621641124243320 /* 0x0.c74857e498fd00006 */, +0.779502200118583399303 /* 0x0.c78d74c8ab5b60000 */, +0.780558207255445668515 /* 0x0.c7d2a9a4c959f8000 */, +0.781615644985491186966 /* 0x0.c817f681412f80002 */, +0.782674515247667956808 /* 0x0.c85d5b6666c150006 */, +0.783734819983036512536 /* 0x0.c8a2d85c904760003 */, +0.784796561133562109454 /* 0x0.c8e86d6c14f850002 */, +0.785859740645942328471 /* 0x0.c92e1a9d513ec8002 */, +0.786924360469767103536 /* 0x0.c973dff8a4b390007 */, +0.787990422552312885808 /* 0x0.c9b9bd866c6440007 */, +0.789057928854407064640 /* 0x0.c9ffb34f1444b0001 */, +0.790126881326406182996 /* 0x0.ca45c15afcc570001 */, +0.791197281930050233534 /* 0x0.ca8be7b292db38000 */, +0.792269132620954885659 /* 0x0.cad2265e3cbee8000 */, +0.793342435380726906957 /* 0x0.cb187d667d3d38006 */, +0.794417192158282659010 /* 0x0.cb5eecd3b33158006 */, +0.795493404931386649540 /* 0x0.cba574ae5d2e80001 */, +0.796571075671306805268 /* 0x0.cbec14fef2a348004 */, +0.797650206352955137846 /* 0x0.cc32cdcdef0000000 */, +0.798730798954342069432 /* 0x0.cc799f23d11d18000 */, +0.799812855456121796232 /* 0x0.ccc089091abb28004 */, +0.800896377841454287795 /* 0x0.cd078b86505c18003 */, +0.801981368096190028208 /* 0x0.cd4ea6a3f97720007 */, +0.803067828208752554378 /* 0x0.cd95da6aa057b8007 */, +0.804155760170129796375 /* 0x0.cddd26e2d21b28001 */, +0.805245165974338261710 /* 0x0.ce248c151f3330001 */, +0.806336047619038653883 /* 0x0.ce6c0a0a1c1350001 */, +0.807428407102107836855 /* 0x0.ceb3a0ca5d6be0006 */, +0.808522246427078927792 /* 0x0.cefb505e7e2550007 */, +0.809617567597010201484 /* 0x0.cf4318cf18a268002 */, +0.810714372621179513182 /* 0x0.cf8afa24ce1c98004 */, +0.811812663508675536069 /* 0x0.cfd2f4683f9810005 */, +0.812912442272482604912 /* 0x0.d01b07a2126188003 */, +0.814013710929394895825 /* 0x0.d06333daeff618001 */, +0.815116471495287542325 /* 0x0.d0ab791b80d028006 */, +0.816220725993571205593 /* 0x0.d0f3d76c75b330000 */, +0.817326476447408967199 /* 0x0.d13c4ed67f1cf8000 */, +0.818433724883006474832 /* 0x0.d184df6250e3b0001 */, +0.819542473330909460055 /* 0x0.d1cd8918a3a328004 */, +0.820652723822034690935 /* 0x0.d2164c02305fa0002 */, +0.821764478391968422618 /* 0x0.d25f2827b53fb0005 */, +0.822877739077315761840 /* 0x0.d2a81d91f188b8000 */, +0.823992507918612782109 /* 0x0.d2f12c49a8d290005 */, +0.825108786960634610365 /* 0x0.d33a5457a35e40003 */, +0.826226578247117093869 /* 0x0.d38395c4a84848007 */, +0.827345883828319528258 /* 0x0.d3ccf09985d958004 */, +0.828466705754248966560 /* 0x0.d41664df0a1320005 */, +0.829589046080638992111 /* 0x0.d45ff29e094330000 */, +0.830712906863802391671 /* 0x0.d4a999df585a20005 */, +0.831838290163696481037 /* 0x0.d4f35aabd04a60006 */, +0.832965198041969556729 /* 0x0.d53d350c4be258002 */, +0.834093632565442222342 /* 0x0.d5872909aba050007 */, +0.835223595802037643865 /* 0x0.d5d136acd138e8006 */, +0.836355089820669306292 /* 0x0.d61b5dfe9f7780004 */, +0.837488116698010487424 /* 0x0.d6659f0801afa8005 */, +0.838622678508982644113 /* 0x0.d6aff9d1e147d8004 */, +0.839758777333464490056 /* 0x0.d6fa6e652d19e0000 */, +0.840896415254110962690 /* 0x0.d744fccad70d00003 */, +0.842035594355151628676 /* 0x0.d78fa50bd2c3b0000 */, +0.843176316724478125433 /* 0x0.d7da673117e730007 */, +0.844318584453106590905 /* 0x0.d8254343a19038003 */, +0.845462399634695271912 /* 0x0.d870394c6dbf30003 */, +0.846607764365415071965 /* 0x0.d8bb49547d37c0004 */, +0.847754680744707056494 /* 0x0.d9067364d45608003 */, +0.848903150873708822763 /* 0x0.d951b7867953b0006 */, +0.850053176859071113491 /* 0x0.d99d15c2787a30006 */, +0.851204760807439786431 /* 0x0.d9e88e21de11a0003 */, +0.852357904828824897169 /* 0x0.da3420adba1508003 */, +0.853512611037803181642 /* 0x0.da7fcd6f2184d8005 */, +0.854668881550406100980 /* 0x0.dacb946f2afaf8000 */, +0.855826718478671755185 /* 0x0.db1775b6e8ad48000 */, +0.856986123964844970247 /* 0x0.db63714f8e0818006 */, +0.858147100114499461478 /* 0x0.dbaf87422625b8000 */, +0.859309649060962410524 /* 0x0.dbfbb797daa460002 */, +0.860473772936213743282 /* 0x0.dc480259d3a710001 */, +0.861639473872910177676 /* 0x0.dc9467913a0f48006 */, +0.862806754008130227807 /* 0x0.dce0e7473b9b28003 */, +0.863975615481124226159 /* 0x0.dd2d8185086c20006 */, +0.865146060433749419813 /* 0x0.dd7a3653d38168005 */, +0.866318091005120138881 /* 0x0.ddc705bcccd628000 */, +0.867491709362415264210 /* 0x0.de13efc9434100004 */, +0.868666917636779056818 /* 0x0.de60f4825df9b8005 */, +0.869843717989716047624 /* 0x0.deae13f16599c0003 */, +0.871022112578215268471 /* 0x0.defb4e1f9dc388002 */, +0.872202103559697183859 /* 0x0.df48a3164a92f0001 */, +0.873383693097737778847 /* 0x0.df9612deb6e878007 */, +0.874566883362160263365 /* 0x0.dfe39d82348310001 */, +0.875751676517234511901 /* 0x0.e031430a0f0688000 */, +0.876938074732511840819 /* 0x0.e07f037f97e548001 */, +0.878126080186539592654 /* 0x0.e0ccdeec2a75e0006 */, +0.879315695055312818168 /* 0x0.e11ad5591f4078001 */, +0.880506921518618312932 /* 0x0.e168e6cfd2f880004 */, +0.881699761760385225541 /* 0x0.e1b71359a6df60003 */, +0.882894217964411143207 /* 0x0.e2055afffc1178000 */, +0.884090292325693805080 /* 0x0.e253bdcc3ffbb8001 */, +0.885287987031581180559 /* 0x0.e2a23bc7d7a1d8002 */, +0.886487304278189114386 /* 0x0.e2f0d4fc31ab80004 */, +0.887688246263368285778 /* 0x0.e33f8972bea8a8005 */, +0.888890815189881999840 /* 0x0.e38e5934f49010007 */, +0.890095013257492739835 /* 0x0.e3dd444c460bd0007 */, +0.891300842677948068626 /* 0x0.e42c4ac232f380000 */, +0.892508305659222567226 /* 0x0.e47b6ca036f8b8005 */, +0.893717404414979710310 /* 0x0.e4caa9efd40e58002 */, +0.894928141160697743242 /* 0x0.e51a02ba8e2610007 */, +0.896140518115016826430 /* 0x0.e5697709ecab90000 */, +0.897354537501434679237 /* 0x0.e5b906e77c61d0006 */, +0.898570201543732793877 /* 0x0.e608b25cca5ba8005 */, +0.899787512470129891014 /* 0x0.e6587973688ce8002 */, +0.901006472512270728537 /* 0x0.e6a85c34ecadb8000 */, +0.902227083902570559127 /* 0x0.e6f85aaaed4f20006 */, +0.903449348881299796343 /* 0x0.e74874df09a530003 */, +0.904673269686823378091 /* 0x0.e798aadadecba0007 */, +0.905898848559668845585 /* 0x0.e7e8fca80c3ee0001 */, +0.907126087750156795426 /* 0x0.e8396a503c3fe0005 */, +0.908354989505901100354 /* 0x0.e889f3dd1615b0002 */, +0.909585556079328783087 /* 0x0.e8da9958465228007 */, +0.910817789726044213523 /* 0x0.e92b5acb7d0578001 */, +0.912051692703457872481 /* 0x0.e97c38406c3c30003 */, +0.913287267274154990210 /* 0x0.e9cd31c0cbb370001 */, +0.914524515702244578108 /* 0x0.ea1e475654d540000 */, +0.915763440256158633982 /* 0x0.ea6f790ac5cc78001 */, +0.917004043205012497909 /* 0x0.eac0c6e7dd8448007 */, +0.918246326823137892807 /* 0x0.eb1230f760a428007 */, +0.919490293387826285200 /* 0x0.eb63b7431714a8007 */, +0.920735945178816406225 /* 0x0.ebb559d4cb6f30007 */, +0.921983284479243714322 /* 0x0.ec0718b64c0940002 */, +0.923232313574974705626 /* 0x0.ec58f3f16a3910002 */, +0.924483034755387955725 /* 0x0.ecaaeb8ffb3168005 */, +0.925735450311948926408 /* 0x0.ecfcff9bd67078000 */, +0.926989562542820610982 /* 0x0.ed4f301edad1a0007 */, +0.928245373740515189457 /* 0x0.eda17d22e0f9b0001 */, +0.929502886213858126045 /* 0x0.edf3e6b1d37d40001 */, +0.930762102264245716494 /* 0x0.ee466cd594c5c8005 */, +0.932023024199046146183 /* 0x0.ee990f980dcdb0005 */, +0.933285654329454095216 /* 0x0.eeebcf032bc470007 */, +0.934549994971191289044 /* 0x0.ef3eab20e0d3c0001 */, +0.935816048439005676599 /* 0x0.ef91a3fb1e1340004 */, +0.937083817055075818404 /* 0x0.efe4b99bdcc618006 */, +0.938353303143720007819 /* 0x0.f037ec0d1889b8000 */, +0.939624509028518128972 /* 0x0.f08b3b58cc2bb8006 */, +0.940897437041863904384 /* 0x0.f0dea788fc2a90000 */, +0.942172089516254085427 /* 0x0.f13230a7ad21b8003 */, +0.943448468787511540534 /* 0x0.f185d6bee754e0006 */, +0.944726577195256100890 /* 0x0.f1d999d8b73478005 */, +0.946006417082291717338 /* 0x0.f22d79ff2cb130000 */, +0.947287990793413858827 /* 0x0.f281773c59ec48007 */, +0.948571300678290207925 /* 0x0.f2d5919a566268001 */, +0.949856349088629370320 /* 0x0.f329c9233bceb0001 */, +0.951143138379053731954 /* 0x0.f37e1de1272068002 */, +0.952431670908847949364 /* 0x0.f3d28fde3a6728006 */, +0.953721949039916472305 /* 0x0.f4271f249a93f0001 */, +0.955013975135367898520 /* 0x0.f47bcbbe6deab0001 */, +0.956307751564417496418 /* 0x0.f4d095b5e16638004 */, +0.957603280698967163097 /* 0x0.f5257d1524f590006 */, +0.958900564911197350604 /* 0x0.f57a81e668d628000 */, +0.960199606581278120057 /* 0x0.f5cfa433e60e50007 */, +0.961500408088936442422 /* 0x0.f624e407d527a0007 */, +0.962802971817578789903 /* 0x0.f67a416c72b760006 */, +0.964107300155846558292 /* 0x0.f6cfbc6c011458004 */, +0.965413395493874504368 /* 0x0.f7255510c439a8002 */, +0.966721260225105960572 /* 0x0.f77b0b6503c5b8006 */, +0.968030896745834645873 /* 0x0.f7d0df730a7940005 */, +0.969342307458006424716 /* 0x0.f826d145294be8003 */, +0.970655494764855020231 /* 0x0.f87ce0e5b29fd8000 */, +0.971970461071268720958 /* 0x0.f8d30e5efaa8f0004 */, +0.973287208789983648852 /* 0x0.f92959bb5e3c08001 */, +0.974605740331924708124 /* 0x0.f97fc305383028004 */, +0.975926058115625383329 /* 0x0.f9d64a46ebb9f8004 */, +0.977248164559556209435 /* 0x0.fa2cef8adbfc68004 */, +0.978572062087848637573 /* 0x0.fa83b2db7253d0007 */, +0.979897753126343307191 /* 0x0.fada944319fda0005 */, +0.981225240104636631254 /* 0x0.fb3193cc425870002 */, +0.982554525455618277276 /* 0x0.fb88b1815e61d0003 */, +0.983885611617111077747 /* 0x0.fbdfed6ce683e0007 */, +0.985218501026348891812 /* 0x0.fc3747995282f8006 */, +0.986553196127724962867 /* 0x0.fc8ec0112202a0005 */, +0.987889699367056062238 /* 0x0.fce656ded63710002 */, +0.989228013193998778636 /* 0x0.fd3e0c0cf48d50005 */, +0.990568140061241164686 /* 0x0.fd95dfa605c7b0003 */, +0.991910082424819927754 /* 0x0.fdedd1b4965710004 */, +0.993253842749249660216 /* 0x0.fe45e2433bfea0000 */, +0.994599423484053835071 /* 0x0.fe9e115c7c05f0005 */, +0.995946827107488830167 /* 0x0.fef65f0afb4c28006 */, +0.997296056085008264529 /* 0x0.ff4ecb59509cc8001 */, +0.998647112892057764479 /* 0x0.ffa756521dbfd0007 */, +1.000000000000000000000 /* 0x1.00000000000000000 */, +1.001354719891689004659 /* 0x1.0058c86da14aa0005 */, +1.002711275050312211844 /* 0x1.00b1afa5abead0003 */, +1.004069667960743483835 /* 0x1.010ab5b2cc0660009 */, +1.005429901112333324093 /* 0x1.0163da9fb2af30008 */, +1.006791976999887428009 /* 0x1.01bd1e7716f6a0008 */, +1.008155898118476168101 /* 0x1.02168143b03890006 */, +1.009521666967782227439 /* 0x1.027003103ae320002 */, +1.010889286051850133326 /* 0x1.02c9a3e7783030002 */, +1.012258757875921233497 /* 0x1.032363d42aaa8000e */, +1.013630084952214405194 /* 0x1.037d42e11c88d0000 */, +1.015003269791313389451 /* 0x1.03d741191635a0001 */, +1.016378314911229763267 /* 0x1.04315e86e84630008 */, +1.017755222831652872635 /* 0x1.048b9b35652800002 */, +1.019133996077934645224 /* 0x1.04e5f72f65827000b */, +1.020514637175266248212 /* 0x1.0540727fc1cfa0006 */, +1.021897148653734488385 /* 0x1.059b0d3157ebb0002 */, +1.023281533050062419584 /* 0x1.05f5c74f0cfeb0002 */, +1.024667792897328677539 /* 0x1.0650a0e3c22ee0003 */, +1.026055930738840826806 /* 0x1.06ab99fa63e1b0008 */, +1.027445949118511947550 /* 0x1.0706b29ddf2700009 */, +1.028837850584049418178 /* 0x1.0761ead9253ab0009 */, +1.030231637685799839262 /* 0x1.07bd42b72a3f80008 */, +1.031627312979383592802 /* 0x1.0818ba42e824a000c */, +1.033024879021186448496 /* 0x1.0874518759b0b0008 */, +1.034424338374263729911 /* 0x1.08d0088f80ffa0006 */, +1.035825693601787333992 /* 0x1.092bdf66604e30005 */, +1.037228947273990842283 /* 0x1.0987d617019cd000a */, +1.038634101961269928846 /* 0x1.09e3ecac6f199000f */, +1.040041160239590700707 /* 0x1.0a402331b91270002 */, +1.041450124688240164200 /* 0x1.0a9c79b1f37c3000b */, +1.042860997889083929381 /* 0x1.0af8f038352160000 */, +1.044273782427270314011 /* 0x1.0b5586cf986890006 */, +1.045688480893644856116 /* 0x1.0bb23d833dfbf0006 */, +1.047105095879385272564 /* 0x1.0c0f145e46e330007 */, +1.048523629981608529302 /* 0x1.0c6c0b6bdaadc000f */, +1.049944085800634585634 /* 0x1.0cc922b72470a000f */, +1.051366465939483019223 /* 0x1.0d265a4b5238b0007 */, +1.052790773004648849929 /* 0x1.0d83b23395e510002 */, +1.054217009607077093512 /* 0x1.0de12a7b263970006 */, +1.055645178360430591625 /* 0x1.0e3ec32d3cf680000 */, +1.057075281882416506511 /* 0x1.0e9c7c55184f5000e */, +1.058507322794714378170 /* 0x1.0efa55fdfad51000a */, +1.059941303721639416236 /* 0x1.0f58503329fed0003 */, +1.061377227289284297385 /* 0x1.0fb66affed37f0000 */, +1.062815096132297298980 /* 0x1.1014a66f95540000c */, +1.064254912884593951029 /* 0x1.1073028d725850007 */, +1.065696680185205469411 /* 0x1.10d17f64d9ea2000b */, +1.067140400676658718053 /* 0x1.11301d012586a0007 */, +1.068586077004890055886 /* 0x1.118edb6db26ab0003 */, +1.070033711820396415998 /* 0x1.11edbab5e2d6e000b */, +1.071483307775789262099 /* 0x1.124cbae51b5ef0001 */, +1.072934867526001312439 /* 0x1.12abdc06c3240000c */, +1.074388393734249103080 /* 0x1.130b1e264a62e0005 */, +1.075843889063253344684 /* 0x1.136a814f20ccd0003 */, +1.077301356179926061823 /* 0x1.13ca058cbaaed000b */, +1.078760797756675327056 /* 0x1.1429aaea9260e000e */, +1.080222216468626150775 /* 0x1.148971742537c0009 */, +1.081685614993597610617 /* 0x1.14e95934f37e8000b */, +1.083150996013011013776 /* 0x1.1549623881762000d */, +1.084618362213087383633 /* 0x1.15a98c8a58a6a000b */, +1.086087716284427351384 /* 0x1.1609d8360768c0008 */, +1.087559060917626885283 /* 0x1.166a45471c13f0008 */, +1.089032398810997337465 /* 0x1.16cad3c92d7b50009 */, +1.090507732647478578212 /* 0x1.172b83c7c18b5000f */, +1.091985065182095926460 /* 0x1.178c554ead72a000c */, +1.093464399073070136880 /* 0x1.17ed48695befe000c */, +1.094945737045367906172 /* 0x1.184e5d23812500007 */, +1.096429081816546080591 /* 0x1.18af9388c90e40005 */, +1.097914436104650892651 /* 0x1.1910eba4e031a0001 */, +1.099401802629782043408 /* 0x1.19726583755720003 */, +1.100891184121537858001 /* 0x1.19d4013041b860007 */, +1.102382583308144647940 /* 0x1.1a35beb6fd0cd0007 */, +1.103876002922312915544 /* 0x1.1a979e2363fa10000 */, +1.105371445702084232160 /* 0x1.1af99f8139025000e */, +1.106868914387219016199 /* 0x1.1b5bc2dc408b9000e */, +1.108368411723785085252 /* 0x1.1bbe084045eb30002 */, +1.109869940458469095340 /* 0x1.1c206fb91524c000e */, +1.111373503344554869449 /* 0x1.1c82f952817cc0001 */, +1.112879103137133007859 /* 0x1.1ce5a51860344000f */, +1.114386742595953938610 /* 0x1.1d4873168babf000e */, +1.115896424484008608911 /* 0x1.1dab6358e1d4a000f */, +1.117408151567338414664 /* 0x1.1e0e75eb43f9c000c */, +1.118921926613465345265 /* 0x1.1e71aad995078000f */, +1.120437752409564780022 /* 0x1.1ed5022fcd8600003 */, +1.121955631720569668277 /* 0x1.1f387bf9cd88b0000 */, +1.123475567332998359439 /* 0x1.1f9c18438cdec000a */, +1.124997562033035469759 /* 0x1.1fffd71902f970002 */, +1.126521618608448571713 /* 0x1.2063b88629079000e */, +1.128047739853580200284 /* 0x1.20c7bc96ff72a0002 */, +1.129575928566289189112 /* 0x1.212be3578a81e0006 */, +1.131106187546149888259 /* 0x1.21902cd3d05f70007 */, +1.132638519598779369743 /* 0x1.21f49917ddda5000c */, +1.134172927531616359481 /* 0x1.2259282fc1c24000e */, +1.135709414157753949251 /* 0x1.22bdda27911e90007 */, +1.137247982292643566662 /* 0x1.2322af0b638e60007 */, +1.138788634756517259562 /* 0x1.2387a6e755f270000 */, +1.140331374372893558110 /* 0x1.23ecc1c788c890006 */, +1.141876203969685699176 /* 0x1.2451ffb821639000c */, +1.143423126377846266197 /* 0x1.24b760c5486dc0009 */, +1.144972144431494420774 /* 0x1.251ce4fb2a0cc0005 */, +1.146523260971646252006 /* 0x1.25828c65f9fb8000d */, +1.148076478839068270690 /* 0x1.25e85711ebaeb0000 */, +1.149631800883562204903 /* 0x1.264e450b3c8a30008 */, +1.151189229953253789786 /* 0x1.26b4565e281a20003 */, +1.152748768902654319399 /* 0x1.271a8b16f0f000002 */, +1.154310420590433317050 /* 0x1.2780e341de2fc0001 */, +1.155874187878668246681 /* 0x1.27e75eeb3abc90007 */, +1.157440073633736243899 /* 0x1.284dfe1f5633e000a */, +1.159008080725518974322 /* 0x1.28b4c0ea840d90001 */, +1.160578212048386514965 /* 0x1.291ba75932ae60000 */, +1.162150470417516290340 /* 0x1.2982b177796850008 */, +1.163724858777502646494 /* 0x1.29e9df51fdd900001 */, +1.165301379991388053320 /* 0x1.2a5130f50bf34000e */, +1.166880036952526289469 /* 0x1.2ab8a66d10fdc0008 */, +1.168460832550151540268 /* 0x1.2b203fc675b7a000a */, +1.170043769683112966389 /* 0x1.2b87fd0dad7260008 */, +1.171628851252754177681 /* 0x1.2befde4f2e3da000d */, +1.173216080163546060084 /* 0x1.2c57e397719940002 */, +1.174805459325657830448 /* 0x1.2cc00cf2f7491000c */, +1.176396991650083379037 /* 0x1.2d285a6e3ff90000b */, +1.177990680055698513602 /* 0x1.2d90cc15d4ff90005 */, +1.179586527463262646306 /* 0x1.2df961f641c57000c */, +1.181184536796979545103 /* 0x1.2e621c1c157cd000d */, +1.182784710984701836994 /* 0x1.2ecafa93e35af0004 */, +1.184387052960675701386 /* 0x1.2f33fd6a459cb0000 */, +1.185991565661414393112 /* 0x1.2f9d24abd8fd1000e */, +1.187598252026902612178 /* 0x1.300670653e083000a */, +1.189207115003001469262 /* 0x1.306fe0a31bc040008 */, +1.190818157535919796833 /* 0x1.30d9757219895000e */, +1.192431382587621380206 /* 0x1.31432edef01a1000f */, +1.194046793097208292195 /* 0x1.31ad0cf63f0630008 */, +1.195664392040319823392 /* 0x1.32170fc4ce0db000c */, +1.197284182375793593084 /* 0x1.32813757527750005 */, +1.198906167074650808198 /* 0x1.32eb83ba8eef3000f */, +1.200530349107333139048 /* 0x1.3355f4fb457e5000d */, +1.202156731453099647353 /* 0x1.33c08b2641df9000c */, +1.203785317090505513368 /* 0x1.342b46484f07b0005 */, +1.205416109005122526928 /* 0x1.3496266e3fa270005 */, +1.207049110184904572310 /* 0x1.35012ba4e8fa10000 */, +1.208684323627194912036 /* 0x1.356c55f92aabb0004 */, +1.210321752322854882437 /* 0x1.35d7a577dd33f0004 */, +1.211961399276747286580 /* 0x1.36431a2de8748000d */, +1.213603267492579629347 /* 0x1.36aeb4283309e000c */, +1.215247359985374142610 /* 0x1.371a7373b00160000 */, +1.216893679753690671322 /* 0x1.3786581d404e90000 */, +1.218542229828181611183 /* 0x1.37f26231e82e4000c */, +1.220193013225231215567 /* 0x1.385e91be9c2d20002 */, +1.221846032973555429280 /* 0x1.38cae6d05e66f0000 */, +1.223501292099485437962 /* 0x1.393761742e5830001 */, +1.225158793636904830441 /* 0x1.39a401b713cb3000e */, +1.226818540625497444577 /* 0x1.3a10c7a61ceae0007 */, +1.228480536107136034131 /* 0x1.3a7db34e5a4a50003 */, +1.230144783126481566885 /* 0x1.3aeac4bcdf8d60001 */, +1.231811284734168454619 /* 0x1.3b57fbfec6e950008 */, +1.233480043984379381835 /* 0x1.3bc559212e7a2000f */, +1.235151063936380300149 /* 0x1.3c32dc3139f2a0004 */, +1.236824347652524913647 /* 0x1.3ca0853c106ac000e */, +1.238499898199571624970 /* 0x1.3d0e544eddd240003 */, +1.240177718649636107175 /* 0x1.3d7c4976d3fcd0000 */, +1.241857812073360767273 /* 0x1.3dea64c1231f70004 */, +1.243540181554270152039 /* 0x1.3e58a63b099920005 */, +1.245224830175077013244 /* 0x1.3ec70df1c4e46000e */, +1.246911761022835740725 /* 0x1.3f359bf29741c000e */, +1.248600977188942806639 /* 0x1.3fa4504ac7b800009 */, +1.250292481770148400634 /* 0x1.40132b07a330d000a */, +1.251986277866492969263 /* 0x1.40822c367a340000b */, +1.253682368581898742876 /* 0x1.40f153e4a18e0000d */, +1.255380757024939564249 /* 0x1.4160a21f73289000d */, +1.257081446308726757662 /* 0x1.41d016f44deaa000c */, +1.258784439550028944083 /* 0x1.423fb27094c090008 */, +1.260489739869405489991 /* 0x1.42af74a1aec1c0006 */, +1.262197350394008266193 /* 0x1.431f5d950a453000c */, +1.263907274252603851764 /* 0x1.438f6d58176860004 */, +1.265619514578811388761 /* 0x1.43ffa3f84b9eb000d */, +1.267334074511444086425 /* 0x1.44700183221180008 */, +1.269050957191869555296 /* 0x1.44e0860618b930006 */, +1.270770165768063009230 /* 0x1.4551318eb4d20000e */, +1.272491703389059036805 /* 0x1.45c2042a7cc26000b */, +1.274215573211836316547 /* 0x1.4632fde6ffacd000d */, +1.275941778396075143580 /* 0x1.46a41ed1cfac40001 */, +1.277670322103555911043 /* 0x1.471566f8812ac0000 */, +1.279401207505722393185 /* 0x1.4786d668b33260005 */, +1.281134437771823675369 /* 0x1.47f86d3002637000a */, +1.282870016078732078362 /* 0x1.486a2b5c13c00000e */, +1.284607945607987078432 /* 0x1.48dc10fa916bd0004 */, +1.286348229545787758022 /* 0x1.494e1e192aaa30007 */, +1.288090871080605159846 /* 0x1.49c052c5913df000c */, +1.289835873406902644341 /* 0x1.4a32af0d7d8090002 */, +1.291583239722392528754 /* 0x1.4aa532feab5e10002 */, +1.293332973229098792374 /* 0x1.4b17dea6db8010008 */, +1.295085077135345708087 /* 0x1.4b8ab213d57d9000d */, +1.296839554650994097442 /* 0x1.4bfdad53629e10003 */, +1.298596408992440220988 /* 0x1.4c70d0735358a000d */, +1.300355643380135983739 /* 0x1.4ce41b817c99e0001 */, +1.302117261036232376282 /* 0x1.4d578e8bb52cb0003 */, +1.303881265192249561154 /* 0x1.4dcb299fde2920008 */, +1.305647659079073541490 /* 0x1.4e3eeccbd7f4c0003 */, +1.307416445934474813521 /* 0x1.4eb2d81d8a86f000b */, +1.309187629001237640529 /* 0x1.4f26eba2e35a5000e */, +1.310961211525240921493 /* 0x1.4f9b2769d35090009 */, +1.312737196755087820678 /* 0x1.500f8b804e4a30000 */, +1.314515587949291131086 /* 0x1.508417f4530d00009 */, +1.316296388365203462468 /* 0x1.50f8ccd3df1840003 */, +1.318079601265708777911 /* 0x1.516daa2cf60020002 */, +1.319865229921343141607 /* 0x1.51e2b00da3c2b0007 */, +1.321653277603506371251 /* 0x1.5257de83f5512000d */, +1.323443747588034513690 /* 0x1.52cd359dfc7d5000e */, +1.325236643161341820781 /* 0x1.5342b569d6baa000f */, +1.327031967602244177939 /* 0x1.53b85df59921b0000 */, +1.328829724206201046165 /* 0x1.542e2f4f6b17e0006 */, +1.330629916266568235675 /* 0x1.54a4298571b27000e */, +1.332432547083447937938 /* 0x1.551a4ca5d97190009 */, +1.334237619959296017340 /* 0x1.559098bed16bf0008 */, +1.336045138203900251029 /* 0x1.56070dde90c800000 */, +1.337855105129210686631 /* 0x1.567dac13510cd0009 */, +1.339667524053662184301 /* 0x1.56f4736b52e2c000c */, +1.341482398296830025383 /* 0x1.576b63f4d8333000f */, +1.343299731186792467254 /* 0x1.57e27dbe2c40e0003 */, +1.345119526053918823702 /* 0x1.5859c0d59cd37000f */, +1.346941786233264881662 /* 0x1.58d12d497cd9a0005 */, +1.348766515064854010261 /* 0x1.5948c32824b87000c */, +1.350593715891792223641 /* 0x1.59c0827ff03890007 */, +1.352423392064920459908 /* 0x1.5a386b5f43a3e0006 */, +1.354255546937278120764 /* 0x1.5ab07dd485af1000c */, +1.356090183865519494030 /* 0x1.5b28b9ee21085000f */, +1.357927306213322804534 /* 0x1.5ba11fba8816e000b */, +1.359766917346459269620 /* 0x1.5c19af482f8f2000f */, +1.361609020638567812980 /* 0x1.5c9268a594cc00004 */, +1.363453619463660171403 /* 0x1.5d0b4be135916000c */, +1.365300717204201985683 /* 0x1.5d84590998eeb0005 */, +1.367150317245710233754 /* 0x1.5dfd902d494e40001 */, +1.369002422974674892971 /* 0x1.5e76f15ad22c40008 */, +1.370857037789471544224 /* 0x1.5ef07ca0cc166000b */, +1.372714165088220639199 /* 0x1.5f6a320dcf5280006 */, +1.374573808273481745378 /* 0x1.5fe411b0790800009 */, +1.376435970755022220096 /* 0x1.605e1b976e4b1000e */, +1.378300655944092456600 /* 0x1.60d84fd155d15000e */, +1.380167867259843417228 /* 0x1.6152ae6cdf0030003 */, +1.382037608124419003675 /* 0x1.61cd3778bc879000d */, +1.383909881963391264069 /* 0x1.6247eb03a4dc40009 */, +1.385784692209972801544 /* 0x1.62c2c91c56d9b0002 */, +1.387662042298923203992 /* 0x1.633dd1d1930ec0001 */, +1.389541935670444372533 /* 0x1.63b90532200630004 */, +1.391424375772021271329 /* 0x1.6434634ccc4cc0007 */, +1.393309366052102982208 /* 0x1.64afec30677e90008 */, +1.395196909966106124701 /* 0x1.652b9febc8e0f000d */, +1.397087010973788290271 /* 0x1.65a77e8dcc7f10004 */, +1.398979672539331309267 /* 0x1.66238825534170000 */, +1.400874898129892187656 /* 0x1.669fbcc1415600008 */, +1.402772691220124823310 /* 0x1.671c1c708328e000a */, +1.404673055288671035301 /* 0x1.6798a7420988b000d */, +1.406575993818903302975 /* 0x1.68155d44ca77a000f */, +1.408481510297352468121 /* 0x1.68923e87bf70e000a */, +1.410389608216942924956 /* 0x1.690f4b19e8f74000c */, +1.412300291075172076232 /* 0x1.698c830a4c94c0008 */ +}; +#define S (1.0/4503599627370496.0) /* 2^-52 */ +static const float exp2_deltatable[512] = { + 11527*S, -963*S, 884*S, -781*S, -2363*S, -3441*S, 123*S, 526*S, + -6*S, 1254*S, -1138*S, 1519*S, 1576*S, -65*S, 1040*S, 793*S, + -1662*S, -5063*S, -387*S, 968*S, -941*S, 984*S, -2856*S, -545*S, + 495*S, -5246*S, -2109*S, 1281*S, 2075*S, 909*S, -1642*S,-78233*S, +-31653*S, -265*S, 130*S, 430*S, 2482*S, -742*S, 1616*S, -2213*S, + -519*S, 20*S, -3134*S,-13981*S, 1343*S, -1740*S, 247*S, 1679*S, + -1097*S, 3131*S, 871*S, -1480*S, 1936*S, -1827*S, 17325*S, 528*S, + -322*S, 1404*S, -152*S, -1845*S, -212*S, 2639*S, -476*S, 2960*S, + -962*S, -1012*S, -1231*S, 3030*S, 1659*S, -486*S, 2154*S, 1728*S, + -2793*S, 699*S, -1560*S, -2125*S, 2156*S, 142*S, -1888*S, 4426*S, +-13443*S, 1970*S, -50*S, 1771*S,-43399*S, 4979*S, -2448*S, -370*S, + 1414*S, 1075*S, 232*S, 206*S, 873*S, 2141*S, 2970*S, 1279*S, + -2331*S, 336*S, -2595*S, 753*S, -3384*S, -616*S, 89*S, -818*S, + 5755*S, -241*S, -528*S, -661*S, -3777*S, -354*S, 250*S, 3881*S, + 2632*S, -2131*S, 2565*S, -316*S, 1746*S, -2541*S, -1324*S, -50*S, + 2564*S, -782*S, 1176*S, 6452*S, -1002*S, 1288*S, 336*S, -185*S, + 3063*S, 3784*S, 2169*S, 686*S, 328*S, -400*S, 312*S, -4517*S, + -1457*S, 1046*S, -1530*S, -685*S, 1328*S,-49815*S, -895*S, 1063*S, + -2091*S, -672*S, -1710*S, -665*S, 1545*S, 1819*S,-45265*S, 3548*S, + -554*S, -568*S, 4752*S, -1907*S,-13738*S, 675*S, 9611*S, -1115*S, + -815*S, 408*S, -1281*S, -937*S,-16376*S, -4772*S, -1440*S, 992*S, + 788*S, 10364*S, -1602*S, -661*S, -1783*S, -265*S, -20*S, -3781*S, + -861*S, -345*S, -994*S, 1364*S, -5339*S, 1620*S, 9390*S, -1066*S, + -305*S, -170*S, 175*S, 2461*S, -490*S, -769*S, -1450*S, 3315*S, + 2418*S, -45*S, -852*S, -1295*S, -488*S, -96*S, 1142*S, -2639*S, + 7905*S, -9306*S, -3859*S, 760*S, 1057*S, -1570*S, 3977*S, 209*S, + -514*S, 7151*S, 1646*S, 627*S, 599*S, -774*S, -1468*S, 633*S, + -473*S, 851*S, 2406*S, 143*S, 74*S, 4260*S, 1177*S, -913*S, + 2670*S, -3298*S, -1662*S, -120*S, -3264*S, -2148*S, 410*S, 2078*S, + -2098*S, -926*S, 3580*S, -1289*S, 2450*S, -1158*S, 907*S, -590*S, + 986*S, 1801*S, 1145*S, -1677*S, 3455*S, 956*S, 710*S, 144*S, + 153*S, -255*S, -1898*S, 28102*S, 2748*S, 1194*S, -3009*S, 7076*S, + 0*S, -2720*S, 711*S, 1225*S, -3034*S, -473*S, 378*S, -1046*S, + 962*S, -2006*S, 4647*S, 3206*S, 1769*S, -2665*S, 1254*S, 2025*S, + -2430*S, 6193*S, 1224*S, -856*S, -1592*S, -325*S, -1521*S, 1827*S, + -264*S, 2403*S, -1065*S, 967*S, -681*S, -2106*S, -474*S, 1333*S, + -893*S, 2296*S, 592*S, -1220*S, -326*S, 990*S, 139*S, 206*S, + -779*S, -1683*S, 1238*S, 6098*S, 136*S, 1197*S, 790*S, -107*S, + -1004*S, -2449*S, 939*S, 5568*S, 156*S, 1812*S, 2792*S, -1094*S, + -2677*S, -251*S, 2297*S, 943*S, -1329*S, 2883*S, -853*S, -2626*S, +-105929*S, -6552*S, 1095*S, -1508*S, 1003*S, 5039*S, -2600*S, -749*S, + 1790*S, 890*S, 2016*S, -1073*S, 624*S, -2084*S, -1536*S, -1330*S, + 358*S, 2444*S, -179*S,-25759*S, -243*S, -552*S, -124*S, 3766*S, + 1192*S, -1614*S, 6*S, -1227*S, 345*S, -981*S, -295*S, -1006*S, + -995*S, -1195*S, 706*S, 2512*S, -1758*S, -734*S, -6286*S, -922*S, + 1530*S, 1542*S, 1223*S, 61*S, -83*S, 522*S,116937*S, -914*S, + -418*S, -7339*S, 249*S, -520*S, -762*S, 426*S, -505*S, 2664*S, + -1093*S, -1035*S, 2130*S, 4878*S, 1982*S, 1551*S, 2304*S, 193*S, + 1532*S, -7268*S, 24357*S, 531*S, 2676*S, -1170*S, 1465*S, -1917*S, + 2143*S, 1466*S, -7*S, -7300*S, 3297*S, -1197*S, -289*S, -1548*S, + 26226*S, 4401*S, 4123*S, -1588*S, 4243*S, 4069*S, -1276*S, -2010*S, + 1407*S, 1478*S, 488*S, -2366*S, -2909*S, -2534*S, -1285*S, 7095*S, + -645*S, -2089*S, -944*S, -40*S, -1363*S, -833*S, 917*S, 1609*S, + 1286*S, 1677*S, 1613*S, -2295*S, -1248*S, 40*S, 26*S, 2038*S, + 698*S, 2675*S, -1755*S, -3522*S, -1614*S, -6111*S, 270*S, 1822*S, + -234*S, -2844*S, -1201*S, -830*S, 1193*S, 2354*S, 47*S, 1522*S, + -78*S, -640*S, 2425*S, -1596*S, 1563*S, 1169*S, -1006*S, -83*S, + 2362*S, -3521*S, -314*S, 1814*S, -1751*S, 305*S, 1715*S, -3741*S, + 7847*S, 1291*S, 1206*S, 36*S, 1397*S, -1419*S, -1194*S, -2014*S, + 1742*S, -578*S, -207*S, 875*S, 1539*S, 2826*S, -1165*S, -909*S, + 1849*S, 927*S, 2018*S, -981*S, 1637*S, -463*S, 905*S, 6618*S, + 400*S, 630*S, 2614*S, 900*S, 2323*S, -1094*S, -1858*S, -212*S, + -2069*S, 747*S, 1845*S, -1450*S, 444*S, -213*S, -438*S, 1158*S, + 4738*S, 2497*S, -370*S, -2016*S, -518*S, -1160*S, -1510*S, 123*S +}; +/* Maximum magnitude in above table: 116937 */ +#undef S diff --git a/src/system/libroot/posix/glibc/arch/generic/t_exp2f.h b/src/system/libroot/posix/glibc/arch/generic/t_exp2f.h new file mode 100644 index 0000000000..f4b94b0498 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/t_exp2f.h @@ -0,0 +1,352 @@ +/* Accurate tables for exp2f(). + Copyright (C) 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Geoffrey Keating + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This table has the property that, for all integers -128 <= i <= 127, + exp(i/256.0 + __exp2f_deltatable[i-128]) == __exp2f_atable[i+128] + r + for some -2^-35 < r < 2^-35 (abs(r) < 2^-36 if i <= 0); and that + __exp2f_deltatable[i+128] == t * 2^-30 + for integer t so that abs(t) <= 43447 * 2^0. */ + +#define W30 (9.31322575e-10) +static const float __exp2f_deltatable[256] = { + -810*W30, 283*W30, -1514*W30, 1304*W30, + -1148*W30, -98*W30, -744*W30, -156*W30, + -419*W30, -155*W30, 474*W30, 167*W30, + -1984*W30, -826*W30, 692*W30, 781*W30, + -578*W30, -411*W30, -129*W30, -1500*W30, + 654*W30, -141*W30, -816*W30, -53*W30, + 148*W30, 493*W30, -2214*W30, 760*W30, + 260*W30, 750*W30, -1300*W30, 1424*W30, + -1445*W30, -339*W30, -680*W30, -349*W30, + -922*W30, 531*W30, 193*W30, -2892*W30, + 290*W30, -2145*W30, -276*W30, 485*W30, + -695*W30, 215*W30, -7093*W30, 412*W30, + -4596*W30, 367*W30, 592*W30, -615*W30, + -97*W30, -1066*W30, 972*W30, -226*W30, + -625*W30, -374*W30, -5647*W30, -180*W30, + 20349*W30, -447*W30, 111*W30, -4164*W30, + -87*W30, -21*W30, -251*W30, 66*W30, + -517*W30, 2093*W30, -263*W30, 182*W30, + -601*W30, 475*W30, -483*W30, -1251*W30, + -373*W30, 1471*W30, -92*W30, -215*W30, + -97*W30, -190*W30, 0*W30, -290*W30, + -2647*W30, 1940*W30, -582*W30, 28*W30, + 833*W30, 1493*W30, 34*W30, 321*W30, + 3327*W30, -35*W30, 177*W30, -135*W30, + -796*W30, -428*W30, 129*W30, 9332*W30, + -12*W30, -69*W30, -1743*W30, 6508*W30, + -60*W30, 359*W30, 43447*W30, 15*W30, + -23*W30, -305*W30, -375*W30, -652*W30, + 667*W30, 269*W30, -1575*W30, 185*W30, + -329*W30, 200*W30, 6002*W30, 163*W30, + -647*W30, 19*W30, -603*W30, -755*W30, + 742*W30, -438*W30, 3587*W30, 2560*W30, + 0*W30, -520*W30, -241*W30, -299*W30, + -1270*W30, -991*W30, -1138*W30, 255*W30, + -1192*W30, 1722*W30, 1023*W30, 3700*W30, + -1388*W30, -1551*W30, -2549*W30, 27*W30, + 282*W30, 673*W30, 113*W30, 1561*W30, + 72*W30, 873*W30, 87*W30, -395*W30, + -433*W30, 629*W30, 3440*W30, -284*W30, + -592*W30, -103*W30, -46*W30, -3844*W30, + 1712*W30, 303*W30, 1555*W30, -631*W30, + -1400*W30, -961*W30, -854*W30, -276*W30, + 407*W30, 833*W30, -345*W30, -1501*W30, + 121*W30, -1581*W30, 400*W30, 150*W30, + 1224*W30, -139*W30, -563*W30, 879*W30, + 933*W30, 2939*W30, 788*W30, 211*W30, + 530*W30, -192*W30, 706*W30, -13347*W30, + 1065*W30, 3*W30, 111*W30, -208*W30, + -360*W30, -532*W30, -291*W30, 483*W30, + 987*W30, -33*W30, -1373*W30, -166*W30, + -1174*W30, -3955*W30, 1601*W30, -280*W30, + 1405*W30, 600*W30, -1659*W30, -23*W30, + 390*W30, 449*W30, 570*W30, -13143*W30, + -9*W30, -1646*W30, 1201*W30, 294*W30, + 2181*W30, -1173*W30, 1388*W30, -4504*W30, + 190*W30, -2304*W30, 211*W30, 239*W30, + 48*W30, -817*W30, 1018*W30, 1828*W30, + -663*W30, 1408*W30, 408*W30, -36*W30, + 1295*W30, -230*W30, 1341*W30, 9*W30, + 40*W30, 705*W30, 186*W30, 376*W30, + 557*W30, 5866*W30, 363*W30, -1558*W30, + 718*W30, 669*W30, 1369*W30, -2972*W30, + -468*W30, -121*W30, -219*W30, 667*W30, + 29954*W30, 366*W30, 48*W30, -203*W30 +}; + +static const float __exp2f_atable[256] /* __attribute__((mode(SF))) */ = { + 0.707106411447, /* 0x0.b504ecfff */ + 0.709024071690, /* 0x0.b58299fff */ + 0.710945606239, /* 0x0.b60088000 */ + 0.712874472142, /* 0x0.b67ef1000 */ + 0.714806139464, /* 0x0.b6fd88fff */ + 0.716744661340, /* 0x0.b77c94000 */ + 0.718687653549, /* 0x0.b7fbea000 */ + 0.720636486992, /* 0x0.b87ba1fff */ + 0.722590208040, /* 0x0.b8fbabfff */ + 0.724549472323, /* 0x0.b97c12fff */ + 0.726514220228, /* 0x0.b9fcd5fff */ + 0.728483855735, /* 0x0.ba7deb000 */ + 0.730457961549, /* 0x0.baff4afff */ + 0.732438981522, /* 0x0.bb811efff */ + 0.734425544748, /* 0x0.bc0350000 */ + 0.736416816713, /* 0x0.bc85d0000 */ + 0.738412797450, /* 0x0.bd089efff */ + 0.740414917465, /* 0x0.bd8bd4fff */ + 0.742422521111, /* 0x0.be0f66fff */ + 0.744434773914, /* 0x0.be9346fff */ + 0.746454179287, /* 0x0.bf179f000 */ + 0.748477637755, /* 0x0.bf9c3afff */ + 0.750506639473, /* 0x0.c02133fff */ + 0.752541840064, /* 0x0.c0a694fff */ + 0.754582285889, /* 0x0.c12c4e000 */ + 0.756628334525, /* 0x0.c1b265000 */ + 0.758678436269, /* 0x0.c238bffff */ + 0.760736882681, /* 0x0.c2bfa6fff */ + 0.762799203401, /* 0x0.c346cf000 */ + 0.764867603790, /* 0x0.c3ce5d000 */ + 0.766940355298, /* 0x0.c45633fff */ + 0.769021093841, /* 0x0.c4de90fff */ + 0.771104693409, /* 0x0.c5671dfff */ + 0.773195922364, /* 0x0.c5f02afff */ + 0.775292098512, /* 0x0.c6798afff */ + 0.777394294745, /* 0x0.c70350000 */ + 0.779501736166, /* 0x0.c78d6d000 */ + 0.781615912910, /* 0x0.c817fafff */ + 0.783734917628, /* 0x0.c8a2d9fff */ + 0.785858273516, /* 0x0.c92e02000 */ + 0.787990570071, /* 0x0.c9b9c0000 */ + 0.790125787245, /* 0x0.ca45aefff */ + 0.792268991467, /* 0x0.cad223fff */ + 0.794417440881, /* 0x0.cb5ef0fff */ + 0.796570718287, /* 0x0.cbec0efff */ + 0.798730909811, /* 0x0.cc79a0fff */ + 0.800892710672, /* 0x0.cd074dfff */ + 0.803068041795, /* 0x0.cd95ddfff */ + 0.805242776881, /* 0x0.ce2464000 */ + 0.807428598393, /* 0x0.ceb3a3fff */ + 0.809617877002, /* 0x0.cf431dfff */ + 0.811812341211, /* 0x0.cfd2eefff */ + 0.814013659956, /* 0x0.d06333000 */ + 0.816220164311, /* 0x0.d0f3ce000 */ + 0.818434238424, /* 0x0.d184e7fff */ + 0.820652604094, /* 0x0.d21649fff */ + 0.822877407074, /* 0x0.d2a818000 */ + 0.825108587751, /* 0x0.d33a51000 */ + 0.827342867839, /* 0x0.d3ccbdfff */ + 0.829588949684, /* 0x0.d45ff1000 */ + 0.831849217401, /* 0x0.d4f411fff */ + 0.834093391880, /* 0x0.d58724fff */ + 0.836355149750, /* 0x0.d61b5f000 */ + 0.838620424257, /* 0x0.d6afd3fff */ + 0.840896368027, /* 0x0.d744fc000 */ + 0.843176305293, /* 0x0.d7da66fff */ + 0.845462262643, /* 0x0.d87037000 */ + 0.847754716864, /* 0x0.d90673fff */ + 0.850052893157, /* 0x0.d99d10fff */ + 0.852359056469, /* 0x0.da3433fff */ + 0.854668736446, /* 0x0.dacb91fff */ + 0.856986224651, /* 0x0.db6373000 */ + 0.859309315673, /* 0x0.dbfbb1fff */ + 0.861639738080, /* 0x0.dc946bfff */ + 0.863975346095, /* 0x0.dd2d7d000 */ + 0.866317391394, /* 0x0.ddc6f9fff */ + 0.868666708472, /* 0x0.de60f1000 */ + 0.871022939695, /* 0x0.defb5c000 */ + 0.873383641229, /* 0x0.df9611fff */ + 0.875751554968, /* 0x0.e03141000 */ + 0.878126025200, /* 0x0.e0ccde000 */ + 0.880506813521, /* 0x0.e168e4fff */ + 0.882894217966, /* 0x0.e2055afff */ + 0.885287821299, /* 0x0.e2a239000 */ + 0.887686729423, /* 0x0.e33f6ffff */ + 0.890096127973, /* 0x0.e3dd56fff */ + 0.892507970338, /* 0x0.e47b67000 */ + 0.894928157336, /* 0x0.e51a03000 */ + 0.897355020043, /* 0x0.e5b90efff */ + 0.899788379682, /* 0x0.e65888000 */ + 0.902227103705, /* 0x0.e6f85afff */ + 0.904673457151, /* 0x0.e798ae000 */ + 0.907128036008, /* 0x0.e8398afff */ + 0.909585535528, /* 0x0.e8da99000 */ + 0.912051796915, /* 0x0.e97c3a000 */ + 0.914524436003, /* 0x0.ea1e46000 */ + 0.917003571999, /* 0x0.eac0bf000 */ + 0.919490039339, /* 0x0.eb63b2fff */ + 0.921983361257, /* 0x0.ec071a000 */ + 0.924488604054, /* 0x0.ecab48fff */ + 0.926989555360, /* 0x0.ed4f30000 */ + 0.929502844812, /* 0x0.edf3e6000 */ + 0.932021975503, /* 0x0.ee98fdfff */ + 0.934553921208, /* 0x0.ef3eecfff */ + 0.937083780759, /* 0x0.efe4b8fff */ + 0.939624726786, /* 0x0.f08b3f000 */ + 0.942198514924, /* 0x0.f133ebfff */ + 0.944726586343, /* 0x0.f1d99a000 */ + 0.947287976728, /* 0x0.f28176fff */ + 0.949856162070, /* 0x0.f329c5fff */ + 0.952431440345, /* 0x0.f3d28bfff */ + 0.955013573175, /* 0x0.f47bc5000 */ + 0.957603693021, /* 0x0.f52584000 */ + 0.960199773321, /* 0x0.f5cfa7000 */ + 0.962801992906, /* 0x0.f67a31000 */ + 0.965413510788, /* 0x0.f72556fff */ + 0.968030691152, /* 0x0.f7d0dc000 */ + 0.970655620084, /* 0x0.f87ce2fff */ + 0.973290979849, /* 0x0.f92998fff */ + 0.975926160805, /* 0x0.f9d64bfff */ + 0.978571653370, /* 0x0.fa83ac000 */ + 0.981225252139, /* 0x0.fb3193fff */ + 0.983885228626, /* 0x0.fbdfe6fff */ + 0.986552715296, /* 0x0.fc8eb7fff */ + 0.989228487027, /* 0x0.fd3e14000 */ + 0.991909801964, /* 0x0.fdedcd000 */ + 0.994601726545, /* 0x0.fe9e38000 */ + 0.997297704209, /* 0x0.ff4ee6fff */ + 1.000000000000, /* 0x1.000000000 */ + 1.002710938457, /* 0x1.00b1aa000 */ + 1.005429744692, /* 0x1.0163d7ffe */ + 1.008155703526, /* 0x1.02167dffe */ + 1.010888457284, /* 0x1.02c995fff */ + 1.013629436498, /* 0x1.037d38000 */ + 1.016377568250, /* 0x1.043152000 */ + 1.019134163841, /* 0x1.04e5f9ffe */ + 1.021896362316, /* 0x1.059b00000 */ + 1.024668931945, /* 0x1.0650b3ffe */ + 1.027446627635, /* 0x1.0706be001 */ + 1.030234098408, /* 0x1.07bd6bffe */ + 1.033023953416, /* 0x1.087441ffe */ + 1.035824656494, /* 0x1.092bce000 */ + 1.038632392900, /* 0x1.09e3d0001 */ + 1.041450142840, /* 0x1.0a9c79ffe */ + 1.044273972530, /* 0x1.0b558a001 */ + 1.047105550795, /* 0x1.0c0f1c001 */ + 1.049944162390, /* 0x1.0cc924001 */ + 1.052791833895, /* 0x1.0d83c4001 */ + 1.055645227426, /* 0x1.0e3ec3fff */ + 1.058507919326, /* 0x1.0efa60001 */ + 1.061377286898, /* 0x1.0fb66bfff */ + 1.064254641510, /* 0x1.1072fdffe */ + 1.067140102389, /* 0x1.113018000 */ + 1.070034146304, /* 0x1.11edc1fff */ + 1.072937250162, /* 0x1.12ac04001 */ + 1.075843691823, /* 0x1.136a7dfff */ + 1.078760385496, /* 0x1.1429a3ffe */ + 1.081685543070, /* 0x1.14e958000 */ + 1.084618330005, /* 0x1.15a98c000 */ + 1.087556362176, /* 0x1.166a18001 */ + 1.090508937863, /* 0x1.172b98001 */ + 1.093464612954, /* 0x1.17ed4bfff */ + 1.096430182434, /* 0x1.18afa5ffe */ + 1.099401354802, /* 0x1.19725e000 */ + 1.102381587017, /* 0x1.1a35adfff */ + 1.105370759965, /* 0x1.1af994000 */ + 1.108367800686, /* 0x1.1bbdfdffe */ + 1.111373305331, /* 0x1.1c82f6000 */ + 1.114387035385, /* 0x1.1d4878001 */ + 1.117408752440, /* 0x1.1e0e7ffff */ + 1.120437502874, /* 0x1.1ed4fe000 */ + 1.123474478729, /* 0x1.1f9c06000 */ + 1.126521706601, /* 0x1.2063ba001 */ + 1.129574775716, /* 0x1.212bd0001 */ + 1.132638812065, /* 0x1.21f49e000 */ + 1.135709524130, /* 0x1.22bddbffe */ + 1.138789534565, /* 0x1.2387b5fff */ + 1.141876101508, /* 0x1.2451fe000 */ + 1.144971728301, /* 0x1.251cddffe */ + 1.148077130296, /* 0x1.25e861ffe */ + 1.151189923305, /* 0x1.26b462001 */ + 1.154312610610, /* 0x1.278107ffe */ + 1.157440662410, /* 0x1.284e08001 */ + 1.160578370109, /* 0x1.291baa001 */ + 1.163725256932, /* 0x1.29e9e6000 */ + 1.166879892324, /* 0x1.2ab8a3ffe */ + 1.170044302935, /* 0x1.2b8805fff */ + 1.173205971694, /* 0x1.2c5739ffe */ + 1.176397800428, /* 0x1.2d2867ffe */ + 1.179586529747, /* 0x1.2df962001 */ + 1.182784795737, /* 0x1.2ecafbffe */ + 1.185991406414, /* 0x1.2f9d21ffe */ + 1.189206838636, /* 0x1.306fdc001 */ + 1.192430973067, /* 0x1.314328000 */ + 1.195664167430, /* 0x1.32170c001 */ + 1.198906540890, /* 0x1.32eb8a001 */ + 1.202157497408, /* 0x1.33c098000 */ + 1.205416083326, /* 0x1.349625fff */ + 1.208683252332, /* 0x1.356c43fff */ + 1.211961269402, /* 0x1.364318001 */ + 1.215246438983, /* 0x1.371a64000 */ + 1.218539118740, /* 0x1.37f22dffe */ + 1.221847295770, /* 0x1.38cafc000 */ + 1.225158572187, /* 0x1.39a3fdfff */ + 1.228481650325, /* 0x1.3a7dc5ffe */ + 1.231811761846, /* 0x1.3b5803fff */ + 1.235149741144, /* 0x1.3c32c5ffe */ + 1.238499879811, /* 0x1.3d0e53ffe */ + 1.241858124726, /* 0x1.3dea69fff */ + 1.245225191102, /* 0x1.3ec713fff */ + 1.248601436624, /* 0x1.3fa458000 */ + 1.251975655584, /* 0x1.40817a001 */ + 1.255380749731, /* 0x1.4160a2001 */ + 1.258783102010, /* 0x1.423f9bffe */ + 1.262198328973, /* 0x1.431f6e000 */ + 1.265619754780, /* 0x1.43ffa7fff */ + 1.269052743928, /* 0x1.44e0a4001 */ + 1.272490739830, /* 0x1.45c1f4000 */ + 1.275942921659, /* 0x1.46a432001 */ + 1.279397487615, /* 0x1.478697ffe */ + 1.282870173427, /* 0x1.486a2dffe */ + 1.286346316319, /* 0x1.494dfdffe */ + 1.289836049094, /* 0x1.4a32b2001 */ + 1.293333172770, /* 0x1.4b17e1ffe */ + 1.296839594835, /* 0x1.4bfdadfff */ + 1.300354957560, /* 0x1.4ce40fffe */ + 1.303882122055, /* 0x1.4dcb38001 */ + 1.307417988757, /* 0x1.4eb2f1ffe */ + 1.310960650439, /* 0x1.4f9b1dfff */ + 1.314516782746, /* 0x1.50842bfff */ + 1.318079948424, /* 0x1.516daffff */ + 1.321653246888, /* 0x1.5257de000 */ + 1.325237751030, /* 0x1.5342c8001 */ + 1.328829526907, /* 0x1.542e2c000 */ + 1.332433700535, /* 0x1.551a5fffe */ + 1.336045145966, /* 0x1.56070dffe */ + 1.339667558645, /* 0x1.56f473ffe */ + 1.343300342533, /* 0x1.57e287ffe */ + 1.346941947961, /* 0x1.58d130001 */ + 1.350594043714, /* 0x1.59c087ffe */ + 1.354256033883, /* 0x1.5ab085fff */ + 1.357932448365, /* 0x1.5ba175ffe */ + 1.361609339707, /* 0x1.5c926dfff */ + 1.365299344044, /* 0x1.5d8441ffe */ + 1.369003057507, /* 0x1.5e76fc001 */ + 1.372714757920, /* 0x1.5f6a3c000 */ + 1.376437187179, /* 0x1.605e2fffe */ + 1.380165219333, /* 0x1.615282001 */ + 1.383909463864, /* 0x1.6247e3ffe */ + 1.387661933907, /* 0x1.633dd0000 */ + 1.391424179060, /* 0x1.64345fffe */ + 1.395197510706, /* 0x1.652ba9fff */ + 1.399006724329, /* 0x1.66254dffe */ + 1.402773022651, /* 0x1.671c22000 */ + 1.406576037403, /* 0x1.68155dfff */ + 1.410389423392, /* 0x1.690f48001 */ +}; diff --git a/src/system/libroot/posix/glibc/arch/x86/ldbl2mpn.c b/src/system/libroot/posix/glibc/arch/x86/ldbl2mpn.c index bf4e4ff43f..4194b10068 100644 --- a/src/system/libroot/posix/glibc/arch/x86/ldbl2mpn.c +++ b/src/system/libroot/posix/glibc/arch/x86/ldbl2mpn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 2000, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -46,7 +46,7 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, #elif BITS_PER_MP_LIMB == 64 /* Hopefully the compiler will combine the two bitfield extracts and this composition into just the original quadword extract. */ - res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; + res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; #define N 1 #else #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" @@ -109,6 +109,13 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, } } } + else if (u.ieee.exponent < 0x7fff +#if N == 2 + && res_ptr[0] == 0 +#endif + && res_ptr[N - 1] == 0) + /* Pseudo zero. */ + *expt = 0; return N; } diff --git a/src/system/libroot/posix/glibc/arch/x86_64/Jamfile b/src/system/libroot/posix/glibc/arch/x86_64/Jamfile new file mode 100644 index 0000000000..8be5c91044 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/Jamfile @@ -0,0 +1,136 @@ +SubDir HAIKU_TOP src system libroot posix glibc arch x86_64 ; + +SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc include arch $(TARGET_ARCH) ; +SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc include arch generic ; +SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc include ; +SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc libio ; +SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc stdlib ; +SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc math ; +SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc ; + +SubDirHdrs $(HAIKU_TOP) src system libroot posix glibc arch generic ; + +UsePrivateHeaders libroot ; + +if $(OPTIM) = -O0 { + OPTIM = -O ; +} + +# don't compile with debugging +DEBUG = 0 ; + +SubDirCcFlags -D_GNU_SOURCE -D_IEEE_LIBM -DPIC ; +SubDirAsFlags -DPIC ; + +local genericSources = + cmp.c dbl2mpn.c divrem.c + memrchr.c + mpn2dbl.c mpn2flt.c mpn2ldbl.c + mul.c mul_n.c + + branred.c doasin.c dosincos.c halfulp.c mpa.c mpatan.c mpatan2.c mpexp.c + mplog.c mpsqrt.c mptan.c sincos32.c slowexp.c slowpow.c + + e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_acoshl.c e_asin.c e_asinf.c + e_asinl.c e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_atanhl.c e_cosh.c + e_coshf.c e_coshl.c e_exp.c e_exp10.c e_exp10f.c e_exp10l.c e_exp2.c + e_exp2f.c e_expf.c e_fmod.c e_fmodf.c e_gamma_r.c e_gammaf_r.c e_gammal_r.c + e_hypot.c e_hypotf.c e_hypotl.c e_j0.c e_j0f.c e_j0l.c e_j1.c e_j1f.c + e_j1l.c e_jn.c e_jnf.c e_jnl.c e_lgamma_r.c e_lgammaf_r.c e_lgammal_r.c + e_log.c e_log10.c e_log10f.c e_log2.c e_log2f.c e_logf.c e_pow.c e_powf.c + e_rem_pio2.c e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c + e_scalbf.c e_sinh.c e_sinhf.c e_sinhl.c + + k_cos.c k_cosf.c k_rem_pio2.c k_rem_pio2f.c k_sin.c k_sinf.c k_tan.c + k_tanf.c + + s_asinh.c s_asinhf.c s_asinhl.c s_atan.c s_atanf.c s_cacos.c s_cacosf.c + s_cacosh.c s_cacoshf.c s_cacoshl.c s_cacosl.c s_casin.c s_casinf.c + s_casinh.c s_casinhf.c s_casinhl.c s_casinl.c s_catan.c s_catanf.c + s_catanh.c s_catanhf.c s_catanhl.c s_catanl.c s_cbrt.c s_cbrtf.c + s_cbrtl.c s_ccos.c s_ccosf.c s_ccosh.c s_ccoshf.c s_ccoshl.c s_ccosl.c + s_ceil.c s_ceilf.c s_cexp.c s_cexpf.c s_cexpl.c s_clog.c s_clog10.c + s_clog10f.c s_clog10l.c s_clogf.c s_clogl.c s_cos.c s_cosf.c s_cpow.c + s_cpowf.c s_cpowl.c s_cproj.c s_cprojf.c s_cprojl.c s_csin.c s_csinf.c + s_csinh.c s_csinhf.c s_csinhl.c s_csinl.c s_csqrt.c s_csqrtf.c s_csqrtl.c + s_ctan.c s_ctanf.c s_ctanh.c s_ctanhf.c s_ctanhl.c s_ctanl.c s_erf.c + s_erff.c s_erfl.c s_expm1.c s_expm1f.c s_fdim.c s_fdimf.c s_finite.c + s_finitef.c s_floor.c s_floorf.c s_fma.c s_fmaf.c s_fmal.c s_fpclassify.c + s_fpclassifyf.c s_frexp.c s_frexpf.c s_frexpl.c s_ilogb.c s_ilogbf.c + s_isinf.c s_isinff.c s_isnan.c s_isnanf.c s_ldexp.c s_ldexpf.c s_ldexpl.c + s_llround.c s_llroundf.c s_llroundl.c s_log1p.c s_log1pf.c s_logb.c + s_logbf.c s_lround.c s_lroundf.c s_lroundl.c s_matherr.c s_modf.c s_modff.c + s_modfl.c s_nan.c s_nanf.c s_nanl.c s_nearbyint.c s_nearbyintf.c + s_nextafter.c s_nextafterf.c s_nexttowardl.c s_remquo.c s_remquof.c + s_remquol.c s_rint.c s_rintf.c s_round.c s_roundf.c s_roundl.c s_scalbln.c + s_scalblnf.c s_scalblnl.c s_scalbn.c s_scalbnf.c s_signbit.c s_signbitf.c + s_signbitl.c s_signgam.c s_significand.c s_significandf.c s_sin.c + s_sincosf.c s_sinf.c s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_tanhl.c + s_trunc.c s_truncf.c + + t_exp.c + + w_acos.c w_acosf.c w_acosh.c w_acoshf.c w_acoshl.c w_acosl.c w_asin.c + w_asinf.c w_asinl.c w_atan2.c w_atan2f.c w_atan2l.c w_atanh.c w_atanhf.c + w_atanhl.c w_cosh.c w_coshf.c w_coshl.c w_drem.c w_dremf.c w_dreml.c + w_exp.c w_exp10.c w_exp10f.c w_exp10l.c w_exp2.c w_exp2f.c w_exp2l.c + w_expf.c w_expl.c w_fmod.c w_fmodf.c w_fmodl.c w_hypot.c w_hypotf.c + w_hypotl.c w_j0.c w_j0f.c w_j0l.c w_j1.c w_j1f.c w_j1l.c w_jn.c w_jnf.c + w_jnl.c w_lgamma.c w_lgamma_r.c w_lgammaf.c w_lgammaf_r.c w_lgammal.c + w_lgammal_r.c w_log.c w_log10.c w_log10f.c w_log10l.c w_log2.c w_log2f.c + w_log2l.c w_logf.c w_logl.c w_pow.c w_powf.c w_powl.c w_remainder.c + w_remainderf.c w_remainderl.c w_scalb.c w_scalbf.c w_scalbl.c w_sinh.c + w_sinhf.c w_sinhl.c w_sqrt.c w_sqrtf.c w_sqrtl.c w_tgamma.c w_tgammaf.c + w_tgammal.c +; + + +MergeObject posix_gnu_arch_$(TARGET_ARCH)_e.o : + e_acosl.c e_atan2l.c e_exp2l.S e_expl.c e_fmodl.S e_log10l.S e_log2l.S + e_logl.S e_powl.S e_remainderl.S e_rem_pio2l.c e_scalbl.S e_sqrt.c + e_sqrtf.c e_sqrtl.c +; + + +MergeObject posix_gnu_arch_$(TARGET_ARCH)_k.o : + k_cosl.c k_rem_pio2l.c k_sinl.c k_tanl.c +; + +MergeObject posix_gnu_arch_$(TARGET_ARCH)_s.o : + s_atanl.c s_ceill.S s_copysignf.S s_copysignl.S s_copysign.S s_cosl.S + s_expm1l.S s_fabs.c s_fabsf.c s_fabsl.S s_fdiml.S s_finitel.S s_floorl.S + s_fmaxf.S s_fmaxl.S s_fmax.S s_fminf.S s_fminl.S s_fmin.S s_fpclassifyl.c + s_ilogbl.S s_isinfl.c s_isnanl.c s_llrintf.S s_llrintl.S s_llrint.S + s_log1pl.S s_logbl.c s_lrintf.S s_lrintl.S s_lrint.S s_nearbyintl.S + s_nextafterl.c s_nexttoward.c s_nexttowardf.c s_rintl.c s_scalbnl.S + s_significandl.c s_sincosl.S s_sincos.S s_sinl.S s_tanl.S s_truncl.S +; + +MergeObject posix_gnu_arch_$(TARGET_ARCH)_other.o : + add_n.S + addmul_1.S + fegetround.c + fesetenv.c + fesetround.c + ldbl2mpn.c + + mul_1.S + lshift.S rshift.S + sub_n.S + submul_1.S +; + +MergeObject posix_gnu_arch_$(TARGET_ARCH)_generic.o : + $(genericSources) +; + +MergeObjectFromObjects posix_gnu_arch_$(TARGET_ARCH).o : : + posix_gnu_arch_$(TARGET_ARCH)_e.o + posix_gnu_arch_$(TARGET_ARCH)_k.o + posix_gnu_arch_$(TARGET_ARCH)_s.o + posix_gnu_arch_$(TARGET_ARCH)_other.o + posix_gnu_arch_$(TARGET_ARCH)_generic.o +; + +SEARCH on [ FGristFiles $(genericSources) ] + = [ FDirName $(HAIKU_TOP) src system libroot posix glibc arch generic ] ; diff --git a/src/system/libroot/posix/glibc/arch/x86_64/add_n.S b/src/system/libroot/posix/glibc/arch/x86_64/add_n.S new file mode 100644 index 0000000000..7883f6c840 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/add_n.S @@ -0,0 +1,42 @@ +/* Add two limb vectors of the same length > 0 and store sum in a third + limb vector. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + The GNU MP Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY (__mpn_add_n) + leaq (%rsi,%rcx,8), %rsi + leaq (%rdi,%rcx,8), %rdi + leaq (%rdx,%rcx,8), %rdx + negq %rcx + xorl %eax, %eax # clear cy + .p2align 2 +L(loop): + movq (%rsi,%rcx,8), %rax + movq (%rdx,%rcx,8), %r10 + adcq %r10, %rax + movq %rax, (%rdi,%rcx,8) + incq %rcx + jne L(loop) + movq %rcx, %rax # zero %rax + adcq %rax, %rax + ret +END (__mpn_add_n) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/addmul_1.S b/src/system/libroot/posix/glibc/arch/x86_64/addmul_1.S new file mode 100644 index 0000000000..bdb5226a33 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/addmul_1.S @@ -0,0 +1,46 @@ +/* AMD64 __mpn_addmul_1 -- Multiply a limb vector with a limb and add + the result to a second limb vector. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + The GNU MP Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY (__mpn_addmul_1) + movq %rdx, %r11 + leaq (%rsi,%rdx,8), %rsi + leaq (%rdi,%rdx,8), %rdi + negq %r11 + xorl %r8d, %r8d + xorl %r10d, %r10d + .p2align 2 +L(loop): + movq (%rsi,%r11,8), %rax + mulq %rcx + addq (%rdi,%r11,8), %rax + adcq %r10, %rdx + addq %r8, %rax + movq %r10, %r8 + movq %rax, (%rdi,%r11,8) + adcq %rdx, %r8 + incq %r11 + jne L(loop) + movq %r8, %rax + ret +END (__mpn_addmul_1) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_acosl.c b/src/system/libroot/posix/glibc/arch/x86_64/e_acosl.c new file mode 100644 index 0000000000..61db1481bb --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_acosl.c @@ -0,0 +1,25 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + */ + +#include "math_private.h" + +long double +__ieee754_acosl (long double x) +{ + long double res; + + /* acosl = atanl (sqrtl(1 - x^2) / x) */ + asm ( "fld %%st\n" + "fmul %%st(0)\n" /* x^2 */ + "fld1\n" + "fsubp\n" /* 1 - x^2 */ + "fsqrt\n" /* sqrtl (1 - x^2) */ + "fxch %%st(1)\n" + "fpatan" + : "=t" (res) : "0" (x) : "st(1)"); + return res; +} diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_atan2l.c b/src/system/libroot/posix/glibc/arch/x86_64/e_atan2l.c new file mode 100644 index 0000000000..c3b1795f9a --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_atan2l.c @@ -0,0 +1,18 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + */ + +#include "math_private.h" + +long double +__ieee754_atan2l (long double y, long double x) +{ + long double res; + + asm ("fpatan" : "=t" (res) : "u" (y), "0" (x) : "st(1)"); + + return res; +} diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_exp2l.S b/src/system/libroot/posix/glibc/arch/x86_64/e_exp2l.S new file mode 100644 index 0000000000..336b989098 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_exp2l.S @@ -0,0 +1,38 @@ +/* + * Written by J.T. Conklin . + * Adapted for exp2 by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + * Public domain. + */ + +#include + +ENTRY(__ieee754_exp2l) + fldt 8(%rsp) +/* I added the following ugly construct because exp(+-Inf) resulted + in NaN. The ugliness results from the bright minds at Intel. + For the i686 the code can be written better. + -- drepper@cygnus.com. */ + fxam /* Is NaN or +-Inf? */ + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 1f /* Is +-Inf, jump. */ + fld %st + frndint /* int(x) */ + fsubr %st,%st(1) /* fract(x) */ + fxch + f2xm1 /* 2^(fract(x)) - 1 */ + fld1 + faddp /* 2^(fract(x)) */ + fscale /* e^x */ + fstp %st(1) + ret + +1: testl $0x200, %eax /* Test sign. */ + jz 2f /* If positive, jump. */ + fstp %st + fldz /* Set result to 0. */ +2: ret +END (__ieee754_exp2l) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_expl.c b/src/system/libroot/posix/glibc/arch/x86_64/e_expl.c new file mode 100644 index 0000000000..1b299239e7 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_expl.c @@ -0,0 +1,77 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + */ + +/* + * The 8087 method for the exponential function is to calculate + * exp(x) = 2^(x log2(e)) + * after separating integer and fractional parts + * x log2(e) = i + f, |f| <= .5 + * 2^i is immediate but f needs to be precise for long double accuracy. + * Suppress range reduction error in computing f by the following. + * Separate x into integer and fractional parts + * x = xi + xf, |xf| <= .5 + * Separate log2(e) into the sum of an exact number c0 and small part c1. + * c0 + c1 = log2(e) to extra precision + * Then + * f = (c0 xi - i) + c0 xf + c1 x + * where c0 xi is exact and so also is (c0 xi - i). + * -- moshier@na-net.ornl.gov + */ + +#include "math_private.h" + +static const long double c0 = 1.44268798828125L; +static const long double c1 = 7.05260771340735992468e-6L; + +long double +__ieee754_expl (long double x) +{ + long double res; + +/* I added the following ugly construct because expl(+-Inf) resulted + in NaN. The ugliness results from the bright minds at Intel. + For the i686 the code can be written better. + -- drepper@cygnus.com. */ + asm ("fxam\n\t" /* Is NaN or +-Inf? */ + "fstsw %%ax\n\t" + "movb $0x45, %%dh\n\t" + "andb %%ah, %%dh\n\t" + "cmpb $0x05, %%dh\n\t" + "je 1f\n\t" /* Is +-Inf, jump. */ + "fldl2e\n\t" /* 1 log2(e) */ + "fmul %%st(1),%%st\n\t" /* 1 x log2(e) */ + "frndint\n\t" /* 1 i */ + "fld %%st(1)\n\t" /* 2 x */ + "frndint\n\t" /* 2 xi */ + "fld %%st(1)\n\t" /* 3 i */ + "fldt %2\n\t" /* 4 c0 */ + "fld %%st(2)\n\t" /* 5 xi */ + "fmul %%st(1),%%st\n\t" /* 5 c0 xi */ + "fsubp %%st,%%st(2)\n\t" /* 4 f = c0 xi - i */ + "fld %%st(4)\n\t" /* 5 x */ + "fsub %%st(3),%%st\n\t" /* 5 xf = x - xi */ + "fmulp %%st,%%st(1)\n\t" /* 4 c0 xf */ + "faddp %%st,%%st(1)\n\t" /* 3 f = f + c0 xf */ + "fldt %3\n\t" /* 4 */ + "fmul %%st(4),%%st\n\t" /* 4 c1 * x */ + "faddp %%st,%%st(1)\n\t" /* 3 f = f + c1 * x */ + "f2xm1\n\t" /* 3 2^(fract(x * log2(e))) - 1 */ + "fld1\n\t" /* 4 1.0 */ + "faddp\n\t" /* 3 2^(fract(x * log2(e))) */ + "fstp %%st(1)\n\t" /* 2 */ + "fscale\n\t" /* 2 scale factor is st(1); e^x */ + "fstp %%st(1)\n\t" /* 1 */ + "fstp %%st(1)\n\t" /* 0 */ + "jmp 2f\n\t" + "1:\ttestl $0x200, %%eax\n\t" /* Test sign. */ + "jz 2f\n\t" /* If positive, jump. */ + "fstp %%st\n\t" + "fldz\n\t" /* Set result to 0. */ + "2:\t\n" + : "=t" (res) : "0" (x), "m" (c0), "m" (c1) : "ax", "dx"); + return res; +} diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_fmodl.S b/src/system/libroot/posix/glibc/arch/x86_64/e_fmodl.S new file mode 100644 index 0000000000..2967bf224b --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_fmodl.S @@ -0,0 +1,22 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +RCSID("$NetBSD: $") + +ENTRY(__ieee754_fmodl) + fldt 24(%rsp) + fldt 8(%rsp) +1: fprem + fstsw %ax + and $04,%ah + jnz 1b + fstp %st(1) + ret +END (__ieee754_fmodl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_log10l.S b/src/system/libroot/posix/glibc/arch/x86_64/e_log10l.S new file mode 100644 index 0000000000..633234b744 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_log10l.S @@ -0,0 +1,67 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * + * Changed to use fyl2xp1 for values near 1, . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +RCSID("$NetBSD: $") + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(one,@object) +one: .double 1.0 + ASM_SIZE_DIRECTIVE(one) + /* It is not important that this constant is precise. It is only + a value which is known to be on the safe side for using the + fyl2xp1 instruction. */ + ASM_TYPE_DIRECTIVE(limit,@object) +limit: .double 0.29 + ASM_SIZE_DIRECTIVE(limit) + + +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__ieee754_log10l) + fldlg2 // log10(2) + fldt 8(%rsp) // x : log10(2) + fxam + fnstsw + fld %st // x : x : log10(2) + testb $1, %ah + jnz 3f // in case x is NaN or ±Inf +4: fsubl MO(one) // x-1 : x : log10(2) + fld %st // x-1 : x-1 : x : log10(2) + fabs // |x-1| : x-1 : x : log10(2) + fcompl MO(limit) // x-1 : x : log10(2) + fnstsw // x-1 : x : log10(2) + andb $0x45, %ah + jz 2f + fstp %st(1) // x-1 : log10(2) + fyl2xp1 // log10(x) + ret + +2: fstp %st(0) // x : log10(2) + fyl2x // log10(x) + ret + +3: testb $4, %ah + jnz 4b // in case x is ±Inf + fstp %st(1) + fstp %st(1) + ret +END(__ieee754_log10l) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_log2l.S b/src/system/libroot/posix/glibc/arch/x86_64/e_log2l.S new file mode 100644 index 0000000000..f04d30a05a --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_log2l.S @@ -0,0 +1,64 @@ +/* + * Written by J.T. Conklin . + * Adapted for use as log2 by Ulrich Drepper . + * Public domain. + * + * Changed to use fyl2xp1 for values near 1, . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(one,@object) +one: .double 1.0 + ASM_SIZE_DIRECTIVE(one) + /* It is not important that this constant is precise. It is only + a value which is known to be on the safe side for using the + fyl2xp1 instruction. */ + ASM_TYPE_DIRECTIVE(limit,@object) +limit: .double 0.29 + ASM_SIZE_DIRECTIVE(limit) + + +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__ieee754_log2l) + fldl MO(one) + fldt 8(%rsp) // x : 1 + fxam + fnstsw + fld %st // x : x : 1 + testb $1, %ah + jnz 3f // in case x is NaN or ±Inf +4: fsub %st(2), %st // x-1 : x : 1 + fld %st // x-1 : x-1 : x : 1 + fabs // |x-1| : x-1 : x : 1 + fcompl MO(limit) // x-1 : x : 1 + fnstsw // x-1 : x : 1 + andb $0x45, %ah + jz 2f + fstp %st(1) // x-1 : 1 + fyl2xp1 // log(x) + ret + +2: fstp %st(0) // x : 1 + fyl2x // log(x) + ret + +3: testb $4, %ah + jnz 4b // in case x is ±Inf + fstp %st(1) + fstp %st(1) + ret +END (__ieee754_log2l) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_logl.S b/src/system/libroot/posix/glibc/arch/x86_64/e_logl.S new file mode 100644 index 0000000000..2ba91eedfd --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_logl.S @@ -0,0 +1,66 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +RCSID("$NetBSD: $") + + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(one,@object) +one: .double 1.0 + ASM_SIZE_DIRECTIVE(one) + /* It is not important that this constant is precise. It is only + a value which is known to be on the safe side for using the + fyl2xp1 instruction. */ + ASM_TYPE_DIRECTIVE(limit,@object) +limit: .double 0.29 + ASM_SIZE_DIRECTIVE(limit) + + +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__ieee754_logl) + fldln2 // log(2) + fldt 8(%rsp) // x : log(2) + fxam + fnstsw + fld %st // x : x : log(2) + testb $1, %ah + jnz 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) + fld %st // x-1 : x-1 : x : log(2) + fabs // |x-1| : x-1 : x : log(2) + fcompl MO(limit) // x-1 : x : log(2) + fnstsw // x-1 : x : log(2) + andb $0x45, %ah + jz 2f + fstp %st(1) // x-1 : log(2) + fyl2xp1 // log(x) + ret + +2: fstp %st(0) // x : log(2) + fyl2x // log(x) + ret + +3: testb $4, %ah + jnz 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret +END (__ieee754_logl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_powl.S b/src/system/libroot/posix/glibc/arch/x86_64/e_powl.S new file mode 100644 index 0000000000..4959bea7ac --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_powl.S @@ -0,0 +1,341 @@ +/* ix87 specific implementation of pow function. + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2007 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(infinity,@object) +inf_zero: +infinity: + .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f + ASM_SIZE_DIRECTIVE(infinity) + ASM_TYPE_DIRECTIVE(zero,@object) +zero: .double 0.0 + ASM_SIZE_DIRECTIVE(zero) + ASM_TYPE_DIRECTIVE(minf_mzero,@object) +minf_mzero: +minfinity: + .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff +mzero: + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 + ASM_SIZE_DIRECTIVE(minf_mzero) + ASM_TYPE_DIRECTIVE(one,@object) +one: .double 1.0 + ASM_SIZE_DIRECTIVE(one) + ASM_TYPE_DIRECTIVE(limit,@object) +limit: .double 0.29 + ASM_SIZE_DIRECTIVE(limit) + ASM_TYPE_DIRECTIVE(p63,@object) +p63: + .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43 + ASM_SIZE_DIRECTIVE(p63) + +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__ieee754_powl) + fldt 24(%rsp) // y + fxam + + + fnstsw + movb %ah, %dl + andb $0x45, %ah + cmpb $0x40, %ah // is y == 0 ? + je 11f + + cmpb $0x05, %ah // is y == ±inf ? + je 12f + + cmpb $0x01, %ah // is y == NaN ? + je 30f + + fldt 8(%rsp) // x : y + + fxam + fnstsw + movb %ah, %dh + andb $0x45, %ah + cmpb $0x40, %ah + je 20f // x is ±0 + + cmpb $0x05, %ah + je 15f // x is ±inf + + fxch // y : x + + /* fistpll raises invalid exception for |y| >= 1L<<63. */ + fldl MO(p63) // 1L<<63 : y : x + fld %st(1) // y : 1L<<63 : y : x + fabs // |y| : 1L<<63 : y : x + fcomip %st(1), %st // 1L<<63 : y : x + fstp %st(0) // y : x + jnc 2f + + /* First see whether `y' is a natural number. In this case we + can use a more precise algorithm. */ + fld %st // y : y : x + fistpll -8(%rsp) // y : x + fildll -8(%rsp) // int(y) : y : x + fucomip %st(1),%st // y : x + jne 2f + + /* OK, we have an integer value for y. */ + mov -8(%rsp),%eax + mov -4(%rsp),%edx + orl $0, %edx + fstp %st(0) // x + jns 4f // y >= 0, jump + fdivrl MO(one) // 1/x (now referred to as x) + negl %eax + adcl $0, %edx + negl %edx +4: fldl MO(one) // 1 : x + fxch + +6: shrdl $1, %edx, %eax + jnc 5f + fxch + fmul %st(1) // x : ST*x + fxch +5: fmul %st(0), %st // x*x : ST*x + shrl $1, %edx + movl %eax, %ecx + orl %edx, %ecx + jnz 6b + fstp %st(0) // ST*x + ret + + /* y is ±NAN */ +30: fldt 8(%rsp) // x : y + fldl MO(one) // 1.0 : x : y + fucomip %st(1),%st // x : y + je 31f + fxch // y : x +31: fstp %st(1) + ret + + .align ALIGNARG(4) +2: /* y is a real number. */ + fxch // x : y + fldl MO(one) // 1.0 : x : y + fldl MO(limit) // 0.29 : 1.0 : x : y + fld %st(2) // x : 0.29 : 1.0 : x : y + fsub %st(2) // x-1 : 0.29 : 1.0 : x : y + fabs // |x-1| : 0.29 : 1.0 : x : y + fucompp // 1.0 : x : y + fnstsw + fxch // x : 1.0 : y + test $4500,%eax + jz 7f + fsub %st(1) // x-1 : 1.0 : y + fyl2xp1 // log2(x) : y + jmp 8f + +7: fyl2x // log2(x) : y +8: fmul %st(1) // y*log2(x) : y + fxam + fnstsw + andb $0x45, %ah + cmpb $0x05, %ah // is y*log2(x) == ±inf ? + je 28f + fst %st(1) // y*log2(x) : y*log2(x) + frndint // int(y*log2(x)) : y*log2(x) + fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) + fxch // fract(y*log2(x)) : int(y*log2(x)) + f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) + faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x)) + fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x)) + fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) + ret + +28: fstp %st(1) // y*log2(x) + fldl MO(one) // 1 : y*log2(x) + fscale // 2^(y*log2(x)) : y*log2(x) + fstp %st(1) // 2^(y*log2(x)) + ret + + // pow(x,±0) = 1 + .align ALIGNARG(4) +11: fstp %st(0) // pop y + fldl MO(one) + ret + + // y == ±inf + .align ALIGNARG(4) +12: fstp %st(0) // pop y + fldl MO(one) // 1 + fldt 8(%rsp) // x : 1 + fabs // abs(x) : 1 + fucompp // < 1, == 1, or > 1 + fnstsw + andb $0x45, %ah + cmpb $0x45, %ah + je 13f // jump if x is NaN + + cmpb $0x40, %ah + je 14f // jump if |x| == 1 + + shlb $1, %ah + xorb %ah, %dl + andl $2, %edx +#ifdef PIC + lea inf_zero(%rip),%rcx + fldl (%rcx, %rdx, 4) +#else + fldl inf_zero(,%rdx, 4) +#endif + ret + + .align ALIGNARG(4) +14: fldl MO(one) + ret + + .align ALIGNARG(4) +13: fldt 8(%rsp) // load x == NaN + ret + + .align ALIGNARG(4) + // x is ±inf +15: fstp %st(0) // y + testb $2, %dh + jz 16f // jump if x == +inf + + // We must find out whether y is an odd integer. + fld %st // y : y + fistpll -8(%rsp) // y + fildll -8(%rsp) // int(y) : y + fucomip %st(1),%st + ffreep %st // + jne 17f + + // OK, the value is an integer, but is it odd? + mov -8(%rsp), %eax + mov -4(%rsp), %edx + andb $1, %al + jz 18f // jump if not odd + // It's an odd integer. + shrl $31, %edx +#ifdef PIC + lea minf_mzero(%rip),%rcx + fldl (%rcx, %rdx, 8) +#else + fldl minf_mzero(,%rdx, 8) +#endif + ret + + .align ALIGNARG(4) +16: fcompl MO(zero) + fnstsw + shrl $5, %eax + andl $8, %eax +#ifdef PIC + lea inf_zero(%rip),%rcx + fldl (%rcx, %rax, 1) +#else + fldl inf_zero(,%rax, 1) +#endif + ret + + .align ALIGNARG(4) +17: shll $30, %edx // sign bit for y in right position +18: shrl $31, %edx +#ifdef PIC + lea inf_zero(%rip),%rcx + fldl (%rcx, %rdx, 8) +#else + fldl inf_zero(,%rdx, 8) +#endif + ret + + .align ALIGNARG(4) + // x is ±0 +20: fstp %st(0) // y + testb $2, %dl + jz 21f // y > 0 + + // x is ±0 and y is < 0. We must find out whether y is an odd integer. + testb $2, %dh + jz 25f + + fld %st // y : y + fistpll -8(%rsp) // y + fildll -8(%rsp) // int(y) : y + fucomip %st(1),%st + ffreep %st // + jne 26f + + // OK, the value is an integer, but is it odd? + mov -8(%rsp),%eax + mov -4(%rsp),%edx + andb $1, %al + jz 27f // jump if not odd + // It's an odd integer. + // Raise divide-by-zero exception and get minus infinity value. + fldl MO(one) + fdivl MO(zero) + fchs + ret + +25: fstp %st(0) +26: +27: // Raise divide-by-zero exception and get infinity value. + fldl MO(one) + fdivl MO(zero) + ret + + .align ALIGNARG(4) + // x is ±0 and y is > 0. We must find out whether y is an odd integer. +21: testb $2, %dh + jz 22f + + fld %st // y : y + fistpll -8(%rsp) // y + fildll -8(%rsp) // int(y) : y + fucomip %st(1),%st + ffreep %st // + jne 23f + + // OK, the value is an integer, but is it odd? + mov -8(%rsp),%eax + mov -4(%rsp),%edx + andb $1, %al + jz 24f // jump if not odd + // It's an odd integer. + fldl MO(mzero) + ret + +22: fstp %st(0) +23: +24: fldl MO(zero) + ret + +END(__ieee754_powl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_rem_pio2l.c b/src/system/libroot/posix/glibc/arch/x86_64/e_rem_pio2l.c new file mode 100644 index 0000000000..1347b0468c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_rem_pio2l.c @@ -0,0 +1,3 @@ +/* Empty. This file is only meant to avoid compiling the file with the + same name in the libm-ieee754 directory. The code is not used since + there is an assembler version for all users of this file. */ diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_remainderl.S b/src/system/libroot/posix/glibc/arch/x86_64/e_remainderl.S new file mode 100644 index 0000000000..480b1cad8b --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_remainderl.S @@ -0,0 +1,20 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +ENTRY(__ieee754_remainderl) + fldt 24(%rsp) + fldt 8(%rsp) +1: fprem1 + fstsw %ax + testl $0x400,%eax + jnz 1b + fstp %st(1) + ret +END (__ieee754_remainderl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_scalbl.S b/src/system/libroot/posix/glibc/arch/x86_64/e_scalbl.S new file mode 100644 index 0000000000..6b229705ba --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_scalbl.S @@ -0,0 +1,100 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger + * + * Correct handling of y==-inf + */ + +#include + +RCSID("$NetBSD: $") + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(zero_nan,@object) +zero_nan: + .double 0.0 +nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f +minus_zero: + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 + .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f + ASM_SIZE_DIRECTIVE(zero_nan) + + +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__ieee754_scalbl) + fldt 24(%rsp) + fxam + fnstsw + fldt 8(%rsp) + andl $0x4700, %eax + cmpl $0x0700, %eax + je 1f + andl $0x4500, %eax + cmpl $0x0100, %eax + je 2f + fxam + fnstsw + andl $0x4500, %eax + cmpl $0x0100, %eax + je 3f + fld %st(1) + frndint + fcomip %st(2), %st + jne 4f + fscale + fstp %st(1) + ret + + /* y is -inf */ +1: fxam + fnstsw + movl 16(%rsp), %edx + shrl $5, %eax + fstp %st + fstp %st + andl $0x8000, %edx + andl $8, %eax + jnz 4f + shrl $11, %edx + addl %edx, %eax +#ifdef PIC + lea zero_nan(%rip),%rdx + fldl (%rdx,%rax,1) +#else + fldl zero_nan(%rax, 1) +#endif + ret + + /* The result is NaN, but we must not raise an exception. + So use a variable. */ +2: fstp %st + fstp %st + fldl MO(nan) + ret + + /* The first parameter is a NaN. Return it. */ +3: fstp %st(1) + ret + + /* Return NaN and raise the invalid exception. */ +4: fstp %st + fstp %st + fldz + fdiv %st + ret +END(__ieee754_scalbl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_sqrt.c b/src/system/libroot/posix/glibc/arch/x86_64/e_sqrt.c new file mode 100644 index 0000000000..0791c453a7 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_sqrt.c @@ -0,0 +1,30 @@ +/* Square root of floating point number. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "math_private.h" + +double +__ieee754_sqrt (double x) +{ + double res; + + asm ("sqrtsd %0, %1" : "=x" (res) : "x" (x)); + + return res; +} diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_sqrtf.c b/src/system/libroot/posix/glibc/arch/x86_64/e_sqrtf.c new file mode 100644 index 0000000000..922e03f318 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_sqrtf.c @@ -0,0 +1,30 @@ +/* Square root of floating point number. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "math_private.h" + +float +__ieee754_sqrtf (float x) +{ + float res; + + asm ("sqrtss %0, %1" : "=x" (res) : "x" (x)); + + return res; +} diff --git a/src/system/libroot/posix/glibc/arch/x86_64/e_sqrtl.c b/src/system/libroot/posix/glibc/arch/x86_64/e_sqrtl.c new file mode 100644 index 0000000000..34cc6eafee --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/e_sqrtl.c @@ -0,0 +1,18 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + */ + +#include "math_private.h" + +long double +__ieee754_sqrtl (long double x) +{ + long double res; + + asm ("fsqrt" : "=t" (res) : "0" (x)); + + return res; +} diff --git a/src/system/libroot/posix/glibc/arch/x86_64/fegetround.c b/src/system/libroot/posix/glibc/arch/x86_64/fegetround.c new file mode 100644 index 0000000000..f237b18d1d --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/fegetround.c @@ -0,0 +1,33 @@ +/* Return current rounding direction. + Copyright (C) 1997, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +int +fegetround (void) +{ + int cw; + /* We only check the x87 FPU unit. The SSE unit should be the same + - and if it's not the same there's no way to signal it. */ + + __asm__ ("fnstcw %0" : "=m" (*&cw)); + + return cw & 0xc00; +} diff --git a/src/system/libroot/posix/glibc/arch/x86_64/fesetenv.c b/src/system/libroot/posix/glibc/arch/x86_64/fesetenv.c new file mode 100644 index 0000000000..8a3b7a0744 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/fesetenv.c @@ -0,0 +1,89 @@ +/* Install given floating-point environment. + Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + + +int +fesetenv (const fenv_t *envp) +{ + fenv_t temp; + + /* Install the environment specified by ENVP. But there are a few + values which we do not want to come from the saved environment. + Therefore, we get the current environment and replace the values + we want to use from the environment specified by the parameter. */ + __asm__ ("fnstenv %0\n" + "stmxcsr %1" : "=m" (*&temp), "=m" (*&temp.__mxcsr)); + + if (envp == FE_DFL_ENV) + { + temp.__control_word |= FE_ALL_EXCEPT; + temp.__control_word &= ~FE_TOWARDZERO; + temp.__status_word &= ~FE_ALL_EXCEPT; + temp.__eip = 0; + temp.__cs_selector = 0; + temp.__opcode = 0; + temp.__data_offset = 0; + temp.__data_selector = 0; + /* Set mask for SSE MXCSR. */ + temp.__mxcsr |= (FE_ALL_EXCEPT << 7); + /* Set rounding to FE_TONEAREST. */ + temp.__mxcsr &= ~ 0x6000; + temp.__mxcsr |= (FE_TONEAREST << 3); + } + else if (envp == FE_NOMASK_ENV) + { + temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO); + temp.__status_word &= ~FE_ALL_EXCEPT; + temp.__eip = 0; + temp.__cs_selector = 0; + temp.__opcode = 0; + temp.__data_offset = 0; + temp.__data_selector = 0; + /* Set mask for SSE MXCSR. */ + /* Set rounding to FE_TONEAREST. */ + temp.__mxcsr &= ~ 0x6000; + temp.__mxcsr |= (FE_TONEAREST << 3); + /* Do not mask exceptions. */ + temp.__mxcsr &= ~(FE_ALL_EXCEPT << 7); + } + else + { + temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO); + temp.__control_word |= (envp->__control_word + & (FE_ALL_EXCEPT | FE_TOWARDZERO)); + temp.__status_word &= ~FE_ALL_EXCEPT; + temp.__status_word |= envp->__status_word & FE_ALL_EXCEPT; + temp.__eip = envp->__eip; + temp.__cs_selector = envp->__cs_selector; + temp.__opcode = envp->__opcode; + temp.__data_offset = envp->__data_offset; + temp.__data_selector = envp->__data_selector; + temp.__mxcsr = envp->__mxcsr; + } + + __asm__ ("fldenv %0\n" + "ldmxcsr %1" : : "m" (temp), "m" (temp.__mxcsr)); + + /* Success. */ + return 0; +} +libm_hidden_def (fesetenv) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/fesetround.c b/src/system/libroot/posix/glibc/arch/x86_64/fesetround.c new file mode 100644 index 0000000000..408116eee8 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/fesetround.c @@ -0,0 +1,47 @@ +/* Set current rounding direction. + Copyright (C) 2001, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +int +fesetround (int round) +{ + unsigned short int cw; + int mxcsr; + + if ((round & ~0xc00) != 0) + /* ROUND is no valid rounding mode. */ + return 1; + + /* First set the x87 FPU. */ + asm ("fnstcw %0" : "=m" (*&cw)); + cw &= ~0xc00; + cw |= round; + asm ("fldcw %0" : : "m" (*&cw)); + + /* And now the MSCSR register for SSE, the precision is at different bit + positions in the different units, we need to shift it 3 bits. */ + asm ("stmxcsr %0" : "=m" (*&mxcsr)); + mxcsr &= ~ 0x6000; + mxcsr |= round << 3; + asm ("ldmxcsr %0" : : "m" (*&mxcsr)); + + return 0; +} +libm_hidden_def (fesetround) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/k_cosl.c b/src/system/libroot/posix/glibc/arch/x86_64/k_cosl.c new file mode 100644 index 0000000000..eea55a98d2 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/k_cosl.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/src/system/libroot/posix/glibc/arch/x86_64/k_rem_pio2l.c b/src/system/libroot/posix/glibc/arch/x86_64/k_rem_pio2l.c new file mode 100644 index 0000000000..eea55a98d2 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/k_rem_pio2l.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/src/system/libroot/posix/glibc/arch/x86_64/k_sinl.c b/src/system/libroot/posix/glibc/arch/x86_64/k_sinl.c new file mode 100644 index 0000000000..eea55a98d2 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/k_sinl.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/src/system/libroot/posix/glibc/arch/x86_64/k_tanl.c b/src/system/libroot/posix/glibc/arch/x86_64/k_tanl.c new file mode 100644 index 0000000000..eea55a98d2 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/k_tanl.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/src/system/libroot/posix/glibc/arch/x86_64/ldbl2mpn.c b/src/system/libroot/posix/glibc/arch/x86_64/ldbl2mpn.c new file mode 100644 index 0000000000..66ac0a47a4 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/ldbl2mpn.c @@ -0,0 +1 @@ +#include "../x86/ldbl2mpn.c" diff --git a/src/system/libroot/posix/glibc/arch/x86_64/lshift.S b/src/system/libroot/posix/glibc/arch/x86_64/lshift.S new file mode 100644 index 0000000000..5ac66f0a36 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/lshift.S @@ -0,0 +1,60 @@ +/* AMD64 __mpn_lshift -- + Copyright 2004, 2006 Free Software Foundation, Inc. + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + The GNU MP Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + + .text +ENTRY (__mpn_lshift) + movq -8(%rsi,%rdx,8), %mm7 + movd %ecx, %mm1 + movl $64, %eax + subl %ecx, %eax + movd %eax, %mm0 + movq %mm7, %mm3 + psrlq %mm0, %mm7 + movd %mm7, %rax + subq $2, %rdx + jl L(endo) + .p2align 2 +L(loop): + movq (%rsi,%rdx,8), %mm6 + movq %mm6, %mm2 + psrlq %mm0, %mm6 + psllq %mm1, %mm3 + por %mm6, %mm3 + movq %mm3, 8(%rdi,%rdx,8) + je L(ende) + movq -8(%rsi,%rdx,8), %mm7 + movq %mm7, %mm3 + psrlq %mm0, %mm7 + psllq %mm1, %mm2 + por %mm7, %mm2 + movq %mm2, (%rdi,%rdx,8) + subq $2, %rdx + jge L(loop) +L(endo): + movq %mm3, %mm2 +L(ende): + psllq %mm1, %mm2 + movq %mm2, (%rdi) + emms + ret +END (__mpn_lshift) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/math_private.h b/src/system/libroot/posix/glibc/arch/x86_64/math_private.h new file mode 100644 index 0000000000..4febcbb5ec --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/math_private.h @@ -0,0 +1,21 @@ +#ifndef _MATH_PRIVATE_H + +#define math_opt_barrier(x) \ +({ __typeof(x) __x; \ + if (sizeof (x) <= sizeof (double)) \ + __asm ("" : "=x" (__x) : "0" (x)); \ + else \ + __asm ("" : "=t" (__x) : "0" (x)); \ + __x; }) +#define math_force_eval(x) \ +do \ + { \ + if (sizeof (x) <= sizeof (double)) \ + __asm __volatile ("" : : "x" (x)); \ + else \ + __asm __volatile ("" : : "f" (x)); \ + } \ +while (0) + +#include +#endif diff --git a/src/system/libroot/posix/glibc/arch/x86_64/mul_1.S b/src/system/libroot/posix/glibc/arch/x86_64/mul_1.S new file mode 100644 index 0000000000..978916b72c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/mul_1.S @@ -0,0 +1,42 @@ +/* AMD64 __mpn_mul_1 -- Multiply a limb vector with a limb and store + the result in a second limb vector. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + The GNU MP Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include +#include "asm-syntax.h" + + .text +ENTRY (__mpn_mul_1) + movq %rdx, %r11 + leaq (%rsi,%rdx,8), %rsi + leaq (%rdi,%rdx,8), %rdi + negq %r11 + xorl %r8d, %r8d +L(loop): + movq (%rsi,%r11,8), %rax + mulq %rcx + addq %r8, %rax + movl $0, %r8d + adcq %rdx, %r8 + movq %rax, (%rdi,%r11,8) + incq %r11 + jne L(loop) + movq %r8, %rax + ret +END (__mpn_mul_1) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/rshift.S b/src/system/libroot/posix/glibc/arch/x86_64/rshift.S new file mode 100644 index 0000000000..ee0c8aa15c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/rshift.S @@ -0,0 +1,62 @@ +/* AMD64 __mpn_rshift -- + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + The GNU MP Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY (__mpn_rshift) + movq (%rsi), %mm7 + movd %ecx, %mm1 + movl $64, %eax + subl %ecx, %eax + movd %eax, %mm0 + movq %mm7, %mm3 + psllq %mm0, %mm7 + movd %mm7, %rax + leaq (%rsi,%rdx,8), %rsi + leaq (%rdi,%rdx,8), %rdi + negq %rdx + addq $2, %rdx + jg L(endo) + .p2align 2 +L(loop): + movq -8(%rsi,%rdx,8), %mm6 + movq %mm6, %mm2 + psllq %mm0, %mm6 + psrlq %mm1, %mm3 + por %mm6, %mm3 + movq %mm3, -16(%rdi,%rdx,8) + je L(ende) + movq (%rsi,%rdx,8), %mm7 + movq %mm7, %mm3 + psllq %mm0, %mm7 + psrlq %mm1, %mm2 + por %mm7, %mm2 + movq %mm2, -8(%rdi,%rdx,8) + addq $2, %rdx + jle L(loop) +L(endo): + movq %mm3, %mm2 +L(ende): + psrlq %mm1, %mm2 + movq %mm2, -8(%rdi) + emms + ret +END (__mpn_rshift) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_atanl.c b/src/system/libroot/posix/glibc/arch/x86_64/s_atanl.c new file mode 100644 index 0000000000..fff764817b --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_atanl.c @@ -0,0 +1,22 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + */ + +#include "math_private.h" + +long double +__atanl (long double x) +{ + long double res; + + asm ("fld1\n" + "fpatan" + : "=t" (res) : "0" (x)); + + return res; +} + +weak_alias (__atanl, atanl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_ceill.S b/src/system/libroot/posix/glibc/arch/x86_64/s_ceill.S new file mode 100644 index 0000000000..efc8dd995e --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_ceill.S @@ -0,0 +1,31 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper + * Changes for x86-64 by Andreas Jaeger + * Public domain. + */ + +#include + + +ENTRY(__ceill) + fldt 8(%rsp) + + fstcw -4(%rsp) /* store fpu control word */ + + /* We use here %edx although only the low 1 bits are defined. + But none of the operations should care and they are faster + than the 16 bit operations. */ + movl $0x0800,%edx /* round towards +oo */ + orl -4(%rsp),%edx + andl $0xfbff,%edx + movl %edx,-8(%rsp) + fldcw -8(%rsp) /* load modified control word */ + + frndint /* round */ + + fldcw -4(%rsp) /* restore original control word */ + + ret +END (__ceill) +weak_alias (__ceill, ceill) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_copysign.S b/src/system/libroot/posix/glibc/arch/x86_64/s_copysign.S new file mode 100644 index 0000000000..f3d9b0cbb4 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_copysign.S @@ -0,0 +1,55 @@ +/* copy sign, double version. + Copyright (C) 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(signmask,@object) +signmask: + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 + .byte 0, 0, 0, 0, 0, 0, 0, 0 + ASM_SIZE_DIRECTIVE(signmask) + ASM_TYPE_DIRECTIVE(othermask,@object) +othermask: + .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f + .byte 0, 0, 0, 0, 0, 0, 0, 0 + ASM_SIZE_DIRECTIVE(othermask) + +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__copysign) + andpd MO(othermask),%xmm0 + andpd MO(signmask),%xmm1 + orpd %xmm1,%xmm0 + ret +END (__copysign) + +weak_alias (__copysign, copysign) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_copysignf.S b/src/system/libroot/posix/glibc/arch/x86_64/s_copysignf.S new file mode 100644 index 0000000000..0fbe1d4c96 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_copysignf.S @@ -0,0 +1,50 @@ +/* copy sign, double version. + Copyright (C) 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(mask,@object) +mask: + .byte 0xff, 0xff, 0xff, 0x7f + ASM_SIZE_DIRECTIVE(mask) + +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__copysignf) + movss MO(mask),%xmm3 + andps %xmm3,%xmm0 + andnps %xmm1,%xmm3 + orps %xmm3,%xmm0 + retq +END (__copysignf) + +weak_alias (__copysignf, copysignf) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_copysignl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_copysignl.S new file mode 100644 index 0000000000..2ffd612d65 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_copysignl.S @@ -0,0 +1,22 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper . + * Adopted for x86-64 by Andreas Jaeger . + * Public domain. + */ + +#include + +RCSID("$NetBSD: $") + +ENTRY(__copysignl) + movl 32(%rsp),%edx + movl 16(%rsp),%eax + andl $0x8000,%edx + andl $0x7fff,%eax + orl %edx,%eax + movl %eax,16(%rsp) + fldt 8(%rsp) + ret +END (__copysignl) +weak_alias (__copysignl, copysignl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_cosl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_cosl.S new file mode 100644 index 0000000000..e9f669369c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_cosl.S @@ -0,0 +1,40 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + * Fixed errno handling by Ulrich Drepper . + */ + +#include + +ENTRY(__cosl) + fldt 8(%rsp) + fxam + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 3f +4: fcos + fnstsw %ax + testl $0x400,%eax + jnz 1f + ret + .align ALIGNARG(4) +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fnstsw %ax + testl $0x400,%eax + jnz 2b + fstp %st(1) + fcos + ret +3: //call __errno_location@PLT + //movl $EDOM, (%rax) + jmp 4b +END (__cosl) +weak_alias (__cosl, cosl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_expm1l.S b/src/system/libroot/posix/glibc/arch/x86_64/s_expm1l.S new file mode 100644 index 0000000000..eeffc3ebf5 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_expm1l.S @@ -0,0 +1,89 @@ +/* ix87 specific implementation of exp(x)-1. + Copyright (C) 1996,1997,2001,2002,2008,2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + Based on code by John C. Bowman . + Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */ + +#include + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(minus1,@object) +minus1: .double -1.0 + ASM_SIZE_DIRECTIVE(minus1) + ASM_TYPE_DIRECTIVE(one,@object) +one: .double 1.0 + ASM_SIZE_DIRECTIVE(one) + ASM_TYPE_DIRECTIVE(l2e,@object) +l2e: .tfloat 1.442695040888963407359924681002 + ASM_SIZE_DIRECTIVE(l2e) + +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__expm1l) + movzwl 8+8(%rsp), %eax // load sign bit and 15-bit exponent + xorb $0x80, %ah // invert sign bit (now 1 is "positive") + cmpl $0xc006, %eax // is num positive and exp >= 6 (number is >= 128.0)? + jae __expl@PLT // (if num is denormal, it is at least >= 64.0) + + fldt 8(%rsp) // x + fxam // Is NaN or +-Inf? + fstsw %ax + movb $0x45, %ch + andb %ah, %ch + cmpb $0x40, %ch + je 3f // If +-0, jump. + cmpb $0x05, %ch + je 2f // If +-Inf, jump. + + fldt MO(l2e) // log2(e) : x + fmulp // log2(e)*x + fld %st // log2(e)*x : log2(e)*x + frndint // int(log2(e)*x) : log2(e)*x + fsubr %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x) + fxch // fract(log2(e)*x) : int(log2(e)*x) + f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x) + fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x) + fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fscale // 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fsubrl MO(one) // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fstp %st(1) // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fsubrp %st, %st(1) // 2^(log2(e)*x)-1 + ret + +2: testl $0x200, %eax // Test sign. + jz 3f // If positive, jump. + fstp %st + fldl MO(minus1) // Set result to -1.0. +3: ret +END(__expm1l) +libm_hidden_def (__expm1l) +weak_alias (__expm1l, expm1l) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fabs.c b/src/system/libroot/posix/glibc/arch/x86_64/s_fabs.c new file mode 100644 index 0000000000..e5f70b7844 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fabs.c @@ -0,0 +1,27 @@ +/* Absolute value of floating point number. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +double +__fabs (double x) +{ + return __builtin_fabs (x); +} +weak_alias (__fabs, fabs) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fabsf.c b/src/system/libroot/posix/glibc/arch/x86_64/s_fabsf.c new file mode 100644 index 0000000000..5e58c11310 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fabsf.c @@ -0,0 +1,27 @@ +/* Absolute value of floating point number. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +float +__fabsf (float x) +{ + return __builtin_fabsf (x); +} +weak_alias (__fabsf, fabsf) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fabsl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_fabsl.S new file mode 100644 index 0000000000..3bee0f244e --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fabsl.S @@ -0,0 +1,28 @@ +/* Absolute value of floating point number. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__fabsl) + fldt 8(%rsp) + fabs + ret +END(__fabsl) +weak_alias (__fabsl, fabsl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fdiml.S b/src/system/libroot/posix/glibc/arch/x86_64/s_fdiml.S new file mode 100644 index 0000000000..d63ca00ef1 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fdiml.S @@ -0,0 +1,44 @@ +/* Compute positive difference. + Copyright (C) 1997, 1998, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__fdiml) + fldt 8(%rsp) // x + fldt 24(%rsp) // x : y + + fucomi %st(1), %st + jp 1f + + jc 3f + fstp %st(1) + fldz + jmp 2f + +3: fsubrp %st, %st(1) + ret + +1: fucomi %st(0), %st + fcmovnu %st(1), %st +2: fstp %st(1) + ret +END(__fdiml) +weak_alias (__fdiml, fdiml) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_finitel.S b/src/system/libroot/posix/glibc/arch/x86_64/s_finitel.S new file mode 100644 index 0000000000..9e49796901 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_finitel.S @@ -0,0 +1,16 @@ +/* + * Written by Joe Keane . + * Adopted for x86-64 by Andreas Jaeger . + */ + +#include + +ENTRY(__finitel) + movl 16(%rsp),%eax + orl $0xffff8000, %eax + incl %eax + shrl $31, %eax + ret +END (__finitel) +weak_alias (__finitel, finitel) +hidden_def (__finitel) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_floorl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_floorl.S new file mode 100644 index 0000000000..f9ecc388df --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_floorl.S @@ -0,0 +1,30 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper + * Changes for x86-64 by Andreas Jaeger =09 + * Public domain. + */ + +#include + +ENTRY(__floorl) + fldt 8(%rsp) + + fstcw -4(%rsp) /* store fpu control word */ + + /* We use here %edx although only the low 1 bits are defined. + But none of the operations should care and they are faster + than the 16 bit operations. */ + movl $0x400,%edx /* round towards -oo */ + orl -4(%rsp),%edx + andl $0xf7ff,%edx + movl %edx,-8(%rsp) + fldcw -8(%rsp) /* load modified control word */ + + frndint /* round */ + + fldcw -4(%rsp) /* restore original control word */ + + ret +END (__floorl) +weak_alias (__floorl, floorl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fmax.S b/src/system/libroot/posix/glibc/arch/x86_64/s_fmax.S new file mode 100644 index 0000000000..b55d6f84ce --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fmax.S @@ -0,0 +1,36 @@ +/* Compute maximum of two numbers, regarding NaN as missing argument. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__fmax) + ucomisd %xmm0, %xmm1 + jp 1f // jump if unordered + maxsd %xmm1, %xmm0 + jmp 2f + +1: ucomisd %xmm1, %xmm1 // Is xmm1 a NaN? + jp 2f // then return xmm0 + movsd %xmm1, %xmm0 // otherwise return xmm1 + +2: ret +END(__fmax) +weak_alias (__fmax, fmax) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fmaxf.S b/src/system/libroot/posix/glibc/arch/x86_64/s_fmaxf.S new file mode 100644 index 0000000000..20d6fdd065 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fmaxf.S @@ -0,0 +1,36 @@ +/* Compute maximum of two numbers, regarding NaN as missing argument. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__fmaxf) + ucomiss %xmm0, %xmm1 + jp 1f // jump if unordered + maxss %xmm1, %xmm0 + jmp 2f + +1: ucomiss %xmm1, %xmm1 // Is xmm1 a NaN? + jp 2f // then return xmm0 + movss %xmm1, %xmm0 // otherwise return xmm1 + +2: ret +END(__fmaxf) +weak_alias (__fmaxf, fmaxf) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fmaxl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_fmaxl.S new file mode 100644 index 0000000000..557ef3a17c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fmaxl.S @@ -0,0 +1,40 @@ +/* Compute maximum of two numbers, regarding NaN as missing argument. + Copyright (C) 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__fmaxl) + fldt 8(%rsp) // x + fldt 24(%rsp) // x : y + + fucomi %st(0), %st + fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise + + fxch + + fucomi %st(1), %st + fcmovb %st(1), %st + + fstp %st(1) + + ret +END(__fmaxl) +weak_alias (__fmaxl, fmaxl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fmin.S b/src/system/libroot/posix/glibc/arch/x86_64/s_fmin.S new file mode 100644 index 0000000000..37a3daaab2 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fmin.S @@ -0,0 +1,36 @@ +/* Compute minimum of two numbers, regarding NaN as missing argument. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__fmin) + ucomisd %xmm0, %xmm1 + jp 1f // jump if unordered + minsd %xmm1, %xmm0 + jmp 2f + +1: ucomisd %xmm1, %xmm1 // Is xmm1 a NaN? + jp 2f // then return xmm0 + movsd %xmm1, %xmm0 // otherwise return xmm1 + +2: ret +END(__fmin) +weak_alias (__fmin, fmin) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fminf.S b/src/system/libroot/posix/glibc/arch/x86_64/s_fminf.S new file mode 100644 index 0000000000..8e6f04bc08 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fminf.S @@ -0,0 +1,36 @@ +/* Compute minimum of two numbers, regarding NaN as missing argument. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__fminf) + ucomiss %xmm0, %xmm1 + jp 1f // jump if unordered + minss %xmm1, %xmm0 + jmp 2f + +1: ucomiss %xmm1, %xmm1 // Is xmm1 a NaN? + jp 2f // then return xmm0 + movss %xmm1, %xmm0 // otherwise return xmm1 + +2: ret +END(__fminf) +weak_alias (__fminf, fminf) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fminl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_fminl.S new file mode 100644 index 0000000000..cbe58f1b25 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fminl.S @@ -0,0 +1,38 @@ +/* Compute minimum of two numbers, regarding NaN as missing argument. + Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__fminl) + fldt 8(%rsp) // x + fldt 24(%rsp) // x : y + + fucomi %st(0), %st + fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise + + fucomi %st(1), %st + fcmovnb %st(1), %st + + fstp %st(1) + + ret +END(__fminl) +weak_alias (__fminl, fminl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_fpclassifyl.c b/src/system/libroot/posix/glibc/arch/x86_64/s_fpclassifyl.c new file mode 100644 index 0000000000..679e721d38 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_fpclassifyl.c @@ -0,0 +1,43 @@ +/* Return classification value corresponding to argument. + Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +int +__fpclassifyl (long double x) +{ + u_int32_t ex, hx, lx; + int retval = FP_NORMAL; + + GET_LDOUBLE_WORDS (ex, hx, lx, x); + ex &= 0x7fff; + if ((ex | lx | hx) == 0) + retval = FP_ZERO; + else if (ex == 0 && (hx & 0x80000000) == 0) + retval = FP_SUBNORMAL; + else if (ex == 0x7fff) + retval = ((hx & 0x7fffffff) | lx) != 0 ? FP_NAN : FP_INFINITE; + + return retval; +} +libm_hidden_def (__fpclassifyl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_ilogbl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_ilogbl.S new file mode 100644 index 0000000000..f59040c11e --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_ilogbl.S @@ -0,0 +1,35 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper + * Adapted for x86-64 by Andreas Jaeger . + * Public domain. + */ + +#include + +ENTRY(__ilogbl) + fldt 8(%rsp) +/* I added the following ugly construct because ilogb(+-Inf) is + required to return INT_MAX in ISO C99. + -- jakub@redhat.com. */ + fxam /* Is NaN or +-Inf? */ + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 1f /* Is +-Inf, jump. */ + + fxtract + fstp %st + + fistpl -4(%rsp) + fwait + movl -4(%rsp),%eax + + ret + +1: fstp %st + movl $0x7fffffff, %eax + ret +END (__ilogbl) +weak_alias (__ilogbl, ilogbl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_isinfl.c b/src/system/libroot/posix/glibc/arch/x86_64/s_isinfl.c new file mode 100644 index 0000000000..72e4ae8138 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_isinfl.c @@ -0,0 +1,37 @@ +/* + * Written by J.T. Conklin . + * Change for long double by Ulrich Drepper . + * Intel i387 specific version. + * Public domain. + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* + * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0; + * no branching! + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + int __isinfl(long double x) +#else + int __isinfl(x) + long double x; +#endif +{ + int32_t se,hx,lx; + GET_LDOUBLE_WORDS(se,hx,lx,x); + /* This additional ^ 0x80000000 is necessary because in Intel's + internal representation of the implicit one is explicit. */ + lx |= (hx ^ 0x80000000) | ((se & 0x7fff) ^ 0x7fff); + lx |= -lx; + se &= 0x8000; + return ~(lx >> 31) & (1 - (se >> 14)); +} +hidden_def (__isinfl) +weak_alias (__isinfl, isinfl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_isnanl.c b/src/system/libroot/posix/glibc/arch/x86_64/s_isnanl.c new file mode 100644 index 0000000000..aa459956e9 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_isnanl.c @@ -0,0 +1,48 @@ +/* s_isnanl.c -- long double version for i387 of s_isnan.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* + * isnanl(x) returns 1 is x is nan, else 0; + * no branching! + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + int __isnanl(long double x) +#else + int __isnanl(x) + long double x; +#endif +{ + int32_t se,hx,lx; + GET_LDOUBLE_WORDS(se,hx,lx,x); + se = (se & 0x7fff) << 1; + /* The additional & 0x7fffffff is required because Intel's + extended format has the normally implicit 1 explicit + present. Sigh! */ + lx |= hx & 0x7fffffff; + se |= (u_int32_t)(lx|(-lx))>>31; + se = 0xfffe - se; + return (int)((u_int32_t)(se))>>16; +} +hidden_def (__isnanl) +weak_alias (__isnanl, isnanl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_llrint.S b/src/system/libroot/posix/glibc/arch/x86_64/s_llrint.S new file mode 100644 index 0000000000..d496e4685c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_llrint.S @@ -0,0 +1,31 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__llrint) + cvtsd2si %xmm0,%rax + ret +END(__llrint) +weak_alias (__llrint, llrint) +strong_alias (__llrint, __lrint) +weak_alias (__llrint, lrint) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_llrintf.S b/src/system/libroot/posix/glibc/arch/x86_64/s_llrintf.S new file mode 100644 index 0000000000..2e818b70a1 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_llrintf.S @@ -0,0 +1,31 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__llrintf) + cvtss2si %xmm0,%rax + ret +END(__llrintf) +weak_alias (__llrintf, llrintf) +strong_alias (__llrintf, __lrintf) +weak_alias (__llrintf, lrintf) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_llrintl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_llrintl.S new file mode 100644 index 0000000000..2886dbe499 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_llrintl.S @@ -0,0 +1,34 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + .text +ENTRY(__llrintl) + fldt 8(%rsp) + fistpll -8(%rsp) + fwait + movq -8(%rsp),%rax + ret +END(__llrintl) +weak_alias (__llrintl, llrintl) +strong_alias (__llrintl, __lrintl) +weak_alias (__llrintl, lrintl) + diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_log1pl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_log1pl.S new file mode 100644 index 0000000000..ac2bd22a4f --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_log1pl.S @@ -0,0 +1,72 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $") + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + .align ALIGNARG(4) + /* The fyl2xp1 can only be used for values in + -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2 + 0.29 is a safe value. + */ +limit: .tfloat 0.29 + /* Please note: we use a double value here. Since 1.0 has + an exact representation this does not effect the accuracy + but it helps to optimize the code. */ +one: .double 1.0 + +/* + * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29, + * otherwise fyl2x with the needed extra computation. + */ +#ifdef PIC +#define MO(op) op##(%rip) +#else +#define MO(op) op +#endif + + .text +ENTRY(__log1pl) + fldln2 + + fldt 8(%rsp) + + fxam + fnstsw + fld %st + testb $1, %ah + jnz 3f // in case x is NaN or ±Inf +4: + fabs + fldt MO(limit) + fcompp + fnstsw + andb $1,%ah + jz 2f + + faddl MO(one) + fyl2x + ret + +2: fyl2xp1 + ret + +3: testb $4, %ah + jnz 4b // in case x is ±Inf + fstp %st(1) + fstp %st(1) + ret + +END (__log1pl) +weak_alias (__log1pl, log1pl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_logbl.c b/src/system/libroot/posix/glibc/arch/x86_64/s_logbl.c new file mode 100644 index 0000000000..34cfb01ecc --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_logbl.c @@ -0,0 +1,19 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper + * Public domain. + */ + +#include "math_private.h" + +long double +__logbl (long double x) +{ + long double res; + + asm ("fxtract\n" + "fstp %%st" : "=t" (res) : "0" (x)); + return res; +} + +weak_alias (__logbl, logbl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_lrint.S b/src/system/libroot/posix/glibc/arch/x86_64/s_lrint.S new file mode 100644 index 0000000000..dfc31359a0 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_lrint.S @@ -0,0 +1 @@ +/* Not needed, see s_llrint.S. */ diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_lrintf.S b/src/system/libroot/posix/glibc/arch/x86_64/s_lrintf.S new file mode 100644 index 0000000000..fcdc4dca9a --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_lrintf.S @@ -0,0 +1 @@ +/* Not needed, see s_llrintf.S. */ diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_lrintl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_lrintl.S new file mode 100644 index 0000000000..ef9c45d00d --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_lrintl.S @@ -0,0 +1 @@ +/* Not needed, see s_llrintl.S. */ diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_nearbyintl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_nearbyintl.S new file mode 100644 index 0000000000..dab2750a23 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_nearbyintl.S @@ -0,0 +1,21 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ +/* Adapted for use as nearbyint by Ulrich Drepper . */ + +#include + +ENTRY(__nearbyintl) + fldt 8(%rsp) + fnstcw -4(%rsp) + movl -4(%rsp), %eax + orl $0x20, %eax + movl %eax, -8(%rsp) + fldcw -8(%rsp) + frndint + fclex + fldcw -4(%rsp) + ret +END (__nearbyintl) +weak_alias (__nearbyintl, nearbyintl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_nextafterl.c b/src/system/libroot/posix/glibc/arch/x86_64/s_nextafterl.c new file mode 100644 index 0000000000..ed75406c0f --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_nextafterl.c @@ -0,0 +1,124 @@ +/* s_nextafterl.c -- long double version of s_nextafter.c. + * Special version for i387. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* IEEE functions + * nextafterl(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + long double __nextafterl(long double x, long double y) +#else + long double __nextafterl(x,y) + long double x,y; +#endif +{ + u_int32_t hx,hy,ix,iy; + u_int32_t lx,ly; + int32_t esx,esy; + + GET_LDOUBLE_WORDS(esx,hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = esx&0x7fff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + /* Intel's extended format has the normally implicit 1 explicit + present. Sigh! */ + if(((ix==0x7fff)&&(((hx&0x7fffffff)|lx)!=0)) || /* x is nan */ + ((iy==0x7fff)&&(((hy&0x7fffffff)|ly)!=0))) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if((ix|hx|lx)==0) { /* x == 0 */ + long double u; + SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; + } + if(esx>=0) { /* x > 0 */ + if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) { + /* x > y, x -= ulp */ + if(lx==0) { + if (hx <= 0x80000000) { + if (esx == 0) { + --hx; + } else { + esx -= 1; + hx = hx - 1; + if (esx > 0) + hx |= 0x80000000; + } + } else + hx -= 1; + } + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0 || (esx == 0 && hx == 0x80000000)) { + esx += 1; + hx |= 0x80000000; + } + } + } + } else { /* x < 0 */ + if(esy>=0||(esx>esy||((esx==esy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){ + /* x < y, x -= ulp */ + if(lx==0) { + if (hx <= 0x80000000) { + esx -= 1; + hx = hx - 1; + if ((esx&0x7fff) > 0) + hx |= 0x80000000; + } else + hx -= 1; + } + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0 || (esx == 0xffff8000 && hx == 0x80000000)) { + esx += 1; + hx |= 0x80000000; + } + } + } + } + esy = esx&0x7fff; + if(esy==0x7fff) return x+x; /* overflow */ + if(esy==0) { + long double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ + } + SET_LDOUBLE_WORDS(x,esx,hx,lx); + return x; +} +weak_alias (__nextafterl, nextafterl) +strong_alias (__nextafterl, __nexttowardl) +weak_alias (__nextafterl, nexttowardl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_nexttoward.c b/src/system/libroot/posix/glibc/arch/x86_64/s_nexttoward.c new file mode 100644 index 0000000000..529069c534 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_nexttoward.c @@ -0,0 +1,107 @@ +/* s_nexttoward.c + * Special i387 version + * Conversion from s_nextafter.c by Ulrich Drepper, Cygnus Support, + * drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* IEEE functions + * nexttoward(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include "math.h" +#include "math_private.h" +#include + +#ifdef __STDC__ + double __nexttoward(double x, long double y) +#else + double __nexttoward(x,y) + double x; + long double y; +#endif +{ + int32_t hx,ix,iy; + u_int32_t lx,hy,ly,esy; + + EXTRACT_WORDS(hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = hx&0x7fffffff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + /* Intel's extended format has the normally implicit 1 explicit + present. Sigh! */ + if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ + ((iy>=0x7fff)&&((hy&0x7fffffff)|ly)!=0)) /* y is nan */ + return x+y; + if((long double) x==y) return y; /* x=y, return y */ + if((ix|lx)==0) { /* x == 0 */ + double u; + INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; + } + if(hx>=0) { /* x > 0 */ + if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 + || (((ix>>20)&0x7ff)==iy-0x3c00 + && (((hx<<11)|(lx>>21))>(hy&0x7fffffff) + || (((hx<<11)|(lx>>21))==(hy&0x7fffffff) + && (lx<<11)>ly)))) { /* x > y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } else { /* x < 0 */ + if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00 + || (((ix>>20)&0x7ff)==iy-0x3c00 + && (((hx<<11)|(lx>>21))>(hy&0x7fffffff) + || (((hx<<11)|(lx>>21))==(hy&0x7fffffff) + && (lx<<11)>ly)))) {/* x < y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } + hy = hx&0x7ff00000; + if(hy>=0x7ff00000) { + x = x+x; /* overflow */ + if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) + /* Force conversion to double. */ + asm ("" : "+m"(x)); + return x; + } + if(hy<0x00100000) { + double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ + } + INSERT_WORDS(x,hx,lx); + return x; +} +weak_alias (__nexttoward, nexttoward) +#ifdef NO_LONG_DOUBLE +strong_alias (__nexttoward, __nexttowardl) +weak_alias (__nexttoward, nexttowardl) +#endif diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_nexttowardf.c b/src/system/libroot/posix/glibc/arch/x86_64/s_nexttowardf.c new file mode 100644 index 0000000000..87c44a827d --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_nexttowardf.c @@ -0,0 +1,87 @@ +/* s_nexttowardf.c -- float version of s_nextafter.c. + * Special i387 version. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +#include "math.h" +#include "math_private.h" +#include + +#ifdef __STDC__ + float __nexttowardf(float x, long double y) +#else + float __nexttowardf(x,y) + float x; + long double y; +#endif +{ + int32_t hx,ix,iy; + u_int32_t hy,ly,esy; + + GET_FLOAT_WORD(hx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = hx&0x7fffffff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + /* Intel's extended format has the normally implicit 1 explicit + present. Sigh! */ + if((ix>0x7f800000) || /* x is nan */ + (iy>=0x7fff&&(((hy&0x7fffffff)|ly)!=0))) /* y is nan */ + return x+y; + if((long double) x==y) return y; /* x=y, return y */ + if(ix==0) { /* x == 0 */ + float u; + SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; + } + if(hx>=0) { /* x > 0 */ + if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 + || (((ix>>23)&0xff)==iy-0x3f80 + && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x > y, x -= ulp */ + hx -= 1; + } else { /* x < y, x += ulp */ + hx += 1; + } + } else { /* x < 0 */ + if(esy<0x8000||((ix>>23)&0xff)>iy-0x3f80 + || (((ix>>23)&0xff)==iy-0x3f80 + && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x < y, x -= ulp */ + hx -= 1; + } else { /* x > y, x += ulp */ + hx += 1; + } + } + hy = hx&0x7f800000; + if(hy>=0x7f800000) { + x = x+x; /* overflow */ + if (FLT_EVAL_METHOD != 0) + /* Force conversion to float. */ + asm ("" : "+m"(x)); + return x; + } + if(hy<0x00800000) { + float u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ + } + SET_FLOAT_WORD(x,hx); + return x; +} +weak_alias (__nexttowardf, nexttowardf) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_rintl.c b/src/system/libroot/posix/glibc/arch/x86_64/s_rintl.c new file mode 100644 index 0000000000..874e32baf3 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_rintl.c @@ -0,0 +1,18 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper + * Public domain. + */ + +#include "math_private.h" + +long double +__rintl (long double x) +{ + long double res; + + asm ("frndint" : "=t" (res) : "0" (x)); + return res; +} + +weak_alias (__rintl, rintl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_scalbnl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_scalbnl.S new file mode 100644 index 0000000000..d0e9301eed --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_scalbnl.S @@ -0,0 +1,18 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper + * Changes for x86-64 by Andreas Jaeger =09 + * Public domain. + */ + +#include + +ENTRY(__scalbnl) + movl %edi,-4(%rsp) + fildl -4(%rsp) + fldt 8(%rsp) + fscale + fstp %st(1) + ret +END (__scalbnl) +weak_alias (__scalbnl, scalbnl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_significandl.c b/src/system/libroot/posix/glibc/arch/x86_64/s_significandl.c new file mode 100644 index 0000000000..22a29c67cb --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_significandl.c @@ -0,0 +1,19 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper + * Public domain. + */ + +#include "math_private.h" + +long double +__significandl (long double x) +{ + long double res; + + asm ("fxtract\n" + "fstp %%st(1)" : "=t" (res) : "0" (x)); + return res; +} + +weak_alias (__significandl, significandl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_sincos.S b/src/system/libroot/posix/glibc/arch/x86_64/s_sincos.S new file mode 100644 index 0000000000..9a33615340 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_sincos.S @@ -0,0 +1,61 @@ +/* Compute sine and cosine of argument. + Copyright (C) 1997, 2000, 2001, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE /* no space for saved regs */ +#define ANGLE PARMS +#define SINP ANGLE+12 +#define COSP SINP+PTR_SIZE + + .text +ENTRY (BP_SYM (__sincos)) + ENTER + + movsd %xmm0, -8(%rsp) + fldl -8(%rsp) + fsincos + fnstsw %ax + testl $0x400,%eax + jnz 1f + fstpl (%rsi) + fstpl (%rdi) + + LEAVE + retq + +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fnstsw %ax + testl $0x400,%eax + jnz 2b + fstp %st(1) + fsincos + fstpl (%rsi) + fstpl (%rdi) + + LEAVE + retq +END (BP_SYM (__sincos)) +weak_alias (BP_SYM (__sincos), BP_SYM (sincos)) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_sincosl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_sincosl.S new file mode 100644 index 0000000000..b17eabe767 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_sincosl.S @@ -0,0 +1,60 @@ +/* Compute sine and cosine of argument. + Copyright (C) 1997, 2000, 2001, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE /* no space for saved regs */ +#define ANGLE PARMS +#define SINP ANGLE+12 +#define COSP SINP+PTR_SIZE + + .text +ENTRY (BP_SYM (__sincosl)) + ENTER + + fldt 8(%rsp) + fsincos + fnstsw %ax + testl $0x400,%eax + jnz 1f + fstpt (%rsi) + fstpt (%rdi) + + LEAVE + retq + +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fnstsw %ax + testl $0x400,%eax + jnz 2b + fstp %st(1) + fsincos + fstpt (%rsi) + fstpt (%rdi) + + LEAVE + retq +END (BP_SYM (__sincosl)) +weak_alias (BP_SYM (__sincosl), BP_SYM (sincosl)) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_sinl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_sinl.S new file mode 100644 index 0000000000..54577b04d6 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_sinl.S @@ -0,0 +1,40 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + * Fixed errno handling by Ulrich Drepper . + */ + +#include + +ENTRY(__sinl) + fldt 8(%rsp) + fxam + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 3f +4: fsin + fnstsw %ax + testl $0x400,%eax + jnz 1f + ret + .align ALIGNARG(4) +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fnstsw %ax + testl $0x400,%eax + jnz 2b + fstp %st(1) + fsin + ret +3: //call __errno_location@PLT + //movl $EDOM, (%rax) + jmp 4b +END (__sinl) +weak_alias (__sinl, sinl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_tanl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_tanl.S new file mode 100644 index 0000000000..4a704203cd --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_tanl.S @@ -0,0 +1,43 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + * Fixed errno handling by Ulrich Drepper . + */ + +#include + +RCSID("$NetBSD: $") + +ENTRY(__tanl) + fldt 8(%rsp) + fxam + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 3f +4: fptan + fnstsw %ax + testl $0x400,%eax + jnz 1f + fstp %st(0) + ret +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fstsw %ax + testl $0x400,%eax + jnz 2b + fstp %st(1) + fptan + fstp %st(0) + ret +3: //call __errno_location@PLT + //movl $EDOM, (%rax) + jmp 4b +END (__tanl) +weak_alias (__tanl, tanl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/s_truncl.S b/src/system/libroot/posix/glibc/arch/x86_64/s_truncl.S new file mode 100644 index 0000000000..61acf9a250 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/s_truncl.S @@ -0,0 +1,34 @@ +/* Truncate long double value. + Copyright (C) 1997, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +ENTRY(__truncl) + fldt 8(%rsp) + fstcw -4(%rsp) + movl $0xc00, %edx + orl -4(%rsp), %edx + movl %edx, -8(%rsp) + fldcw -8(%rsp) + frndint + fldcw -4(%rsp) + ret +END(__truncl) +weak_alias (__truncl, truncl) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/sub_n.S b/src/system/libroot/posix/glibc/arch/x86_64/sub_n.S new file mode 100644 index 0000000000..48e1a2e0f4 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/sub_n.S @@ -0,0 +1,42 @@ +/* AMD64 __mpn_sub_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + The GNU MP Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY (__mpn_sub_n) + leaq (%rsi,%rcx,8), %rsi + leaq (%rdi,%rcx,8), %rdi + leaq (%rdx,%rcx,8), %rdx + negq %rcx + xorl %eax, %eax # clear cy + .p2align 2 +L(loop): + movq (%rsi,%rcx,8), %rax + movq (%rdx,%rcx,8), %r10 + sbbq %r10, %rax + movq %rax, (%rdi,%rcx,8) + incq %rcx + jne L(loop) + movq %rcx, %rax # zero %rax + adcq %rax, %rax + ret +END (__mpn_sub_n) diff --git a/src/system/libroot/posix/glibc/arch/x86_64/submul_1.S b/src/system/libroot/posix/glibc/arch/x86_64/submul_1.S new file mode 100644 index 0000000000..e94c9a7bee --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86_64/submul_1.S @@ -0,0 +1,46 @@ +/* AMD64 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract + the result from a second limb vector. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + The GNU MP Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY (__mpn_submul_1) + movq %rdx, %r11 + leaq (%rsi,%r11,8), %rsi + leaq (%rdi,%r11,8), %rdi + negq %r11 + xorl %r8d, %r8d + .p2align 3 +L(loop): + movq (%rsi,%r11,8), %rax + movq (%rdi,%r11,8), %r10 + mulq %rcx + subq %r8, %r10 + movl $0, %r8d + adcl %r8d, %r8d + subq %rax, %r10 + adcq %rdx, %r8 + movq %r10, (%rdi,%r11,8) + incq %r11 + jne L(loop) + movq %r8, %rax + ret +END (__mpn_submul_1) diff --git a/src/system/libroot/posix/glibc/include/arch/arm/bits/fenv.h b/src/system/libroot/posix/glibc/include/arch/arm/bits/fenv.h new file mode 100644 index 0000000000..7bd242385f --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/arm/bits/fenv.h @@ -0,0 +1,58 @@ +/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _FENV_H +# error "Never use directly; include instead." +#endif + +/* Define bits representing exceptions in the FPU status word. */ +enum + { + FE_INVALID = 1, +#define FE_INVALID FE_INVALID + FE_DIVBYZERO = 2, +#define FE_DIVBYZERO FE_DIVBYZERO + FE_OVERFLOW = 4, +#define FE_OVERFLOW FE_OVERFLOW + FE_UNDERFLOW = 8, +#define FE_UNDERFLOW FE_UNDERFLOW + }; + +/* Amount to shift by to convert an exception to a mask bit. */ +#define FE_EXCEPT_SHIFT 16 + +/* All supported exceptions. */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) + +/* The ARM FPU basically only supports round-to-nearest. Other rounding + modes exist, but you have to encode them in the actual instruction. */ +#define FE_TONEAREST 0 + +/* Type representing exception flags. */ +typedef unsigned long int fexcept_t; + +/* Type representing floating-point environment. */ +typedef struct + { + unsigned long int __cw; + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((fenv_t *) -1l) diff --git a/src/system/libroot/posix/glibc/include/arch/arm/bits/fenvinline.h b/src/system/libroot/posix/glibc/include/arch/arm/bits/fenvinline.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/system/libroot/posix/glibc/include/arch/arm/bits/mathdef.h b/src/system/libroot/posix/glibc/include/arch/arm/bits/mathdef.h index daca1102fc..5d9a3349cf 100644 --- a/src/system/libroot/posix/glibc/include/arch/arm/bits/mathdef.h +++ b/src/system/libroot/posix/glibc/include/arch/arm/bits/mathdef.h @@ -30,6 +30,12 @@ typedef float float_t; /* `float' expressions are evaluated as typedef double double_t; /* `double' expressions are evaluated as `double'. */ +/* Signal that both types are `long double'. */ +# define FLT_EVAL_METHOD 2 + +/* Define `INFINITY' as value of type `float'. */ +# define INFINITY HUGE_VALF + /* The values returned by `ilogb' for 0 and NaN respectively. */ # define FP_ILOGB0 (-2147483647) # define FP_ILOGBNAN (2147483647) @@ -41,3 +47,6 @@ typedef double double_t; /* `double' expressions are evaluated as declaration of all the `long double' function variants. */ # define __NO_LONG_DOUBLE_MATH 1 #endif + +/* Number of decimal digits for the `long double' type. */ +# define DECIMAL_DIG 21 diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/asm-syntax.h b/src/system/libroot/posix/glibc/include/arch/x86_64/asm-syntax.h new file mode 100644 index 0000000000..98eb26c121 --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/asm-syntax.h @@ -0,0 +1,24 @@ +/* Definitions for x86 syntax variations. + Copyright (C) 1992,1994,1995,1997,2000,2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in the GNU MP Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#undef ALIGN +#define ALIGN(log) .align 1< directly; include instead." +#endif + +#ifndef _BITS_BYTESWAP_H +#define _BITS_BYTESWAP_H 1 + +#include + +/* Swap bytes in 16 bit value. */ +#define __bswap_constant_16(x) \ + ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) + +#if defined __GNUC__ && __GNUC__ >= 2 +# define __bswap_16(x) \ + (__extension__ \ + ({ register unsigned short int __v, __x = (x); \ + if (__builtin_constant_p (__x)) \ + __v = __bswap_constant_16 (__x); \ + else \ + __asm__ ("rorw $8, %w0" \ + : "=r" (__v) \ + : "0" (__x) \ + : "cc"); \ + __v; })) +#else +/* This is better than nothing. */ +# define __bswap_16(x) \ + (__extension__ \ + ({ register unsigned short int __x = (x); __bswap_constant_16 (__x); })) +#endif + + +/* Swap bytes in 32 bit value. */ +#define __bswap_constant_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +#if defined __GNUC__ && __GNUC__ >= 2 +# if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \ + || defined __pentiumpro__ || defined __pentium4__ \ + || defined __k8__ || defined __athlon__ \ + || defined __k6__) +/* To swap the bytes in a word the i486 processors and up provide the + `bswap' opcode. On i386 we have to use three instructions. */ +# define __bswap_32(x) \ + (__extension__ \ + ({ register unsigned int __v, __x = (x); \ + if (__builtin_constant_p (__x)) \ + __v = __bswap_constant_32 (__x); \ + else \ + __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \ + __v; })) +# else +# define __bswap_32(x) \ + (__extension__ \ + ({ register unsigned int __v, __x = (x); \ + if (__builtin_constant_p (__x)) \ + __v = __bswap_constant_32 (__x); \ + else \ + __asm__ ("rorw $8, %w0;" \ + "rorl $16, %0;" \ + "rorw $8, %w0" \ + : "=r" (__v) \ + : "0" (__x) \ + : "cc"); \ + __v; })) +# endif +#else +# define __bswap_32(x) \ + (__extension__ \ + ({ register unsigned int __x = (x); __bswap_constant_32 (__x); })) +#endif + + +#if defined __GNUC__ && __GNUC__ >= 2 +/* Swap bytes in 64 bit value. */ +# define __bswap_constant_64(x) \ + ((((x) & 0xff00000000000000ull) >> 56) \ + | (((x) & 0x00ff000000000000ull) >> 40) \ + | (((x) & 0x0000ff0000000000ull) >> 24) \ + | (((x) & 0x000000ff00000000ull) >> 8) \ + | (((x) & 0x00000000ff000000ull) << 8) \ + | (((x) & 0x0000000000ff0000ull) << 24) \ + | (((x) & 0x000000000000ff00ull) << 40) \ + | (((x) & 0x00000000000000ffull) << 56)) + +# if __WORDSIZE == 64 +# define __bswap_64(x) \ + (__extension__ \ + ({ register unsigned long __v, __x = (x); \ + if (__builtin_constant_p (__x)) \ + __v = __bswap_constant_64 (__x); \ + else \ + __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); \ + __v; })) +# else +# define __bswap_64(x) \ + (__extension__ \ + ({ union { __extension__ unsigned long long int __ll; \ + unsigned int __l[2]; } __w, __r; \ + if (__builtin_constant_p (x)) \ + __r.__ll = __bswap_constant_64 (x); \ + else \ + { \ + __w.__ll = (x); \ + __r.__l[0] = __bswap_32 (__w.__l[1]); \ + __r.__l[1] = __bswap_32 (__w.__l[0]); \ + } \ + __r.__ll; })) +# endif +#endif + +#endif /* _BITS_BYTESWAP_H */ diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bits/endian.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/endian.h new file mode 100644 index 0000000000..2f59eada25 --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/endian.h @@ -0,0 +1,7 @@ +/* x86_64 is little-endian. */ + +#ifndef _ENDIAN_H +# error "Never use directly; include instead." +#endif + +#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bits/fenv.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/fenv.h new file mode 100644 index 0000000000..3b3254bdd3 --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/fenv.h @@ -0,0 +1,93 @@ +/* Copyright (C) 1997-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _FENV_H +# error "Never use directly; include instead." +#endif + +/* Define bits representing the exception. We use the bit positions + of the appropriate bits in the FPU control word. */ +enum + { + FE_INVALID = 0x01, +#define FE_INVALID FE_INVALID + __FE_DENORM = 0x02, + FE_DIVBYZERO = 0x04, +#define FE_DIVBYZERO FE_DIVBYZERO + FE_OVERFLOW = 0x08, +#define FE_OVERFLOW FE_OVERFLOW + FE_UNDERFLOW = 0x10, +#define FE_UNDERFLOW FE_UNDERFLOW + FE_INEXACT = 0x20 +#define FE_INEXACT FE_INEXACT + }; + +#define FE_ALL_EXCEPT \ + (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) + +/* The ix87 FPU supports all of the four defined rounding modes. We + use again the bit positions in the FPU control word as the values + for the appropriate macros. */ +enum + { + FE_TONEAREST = 0, +#define FE_TONEAREST FE_TONEAREST + FE_DOWNWARD = 0x400, +#define FE_DOWNWARD FE_DOWNWARD + FE_UPWARD = 0x800, +#define FE_UPWARD FE_UPWARD + FE_TOWARDZERO = 0xc00 +#define FE_TOWARDZERO FE_TOWARDZERO + }; + + +/* Type representing exception flags. */ +typedef unsigned short int fexcept_t; + + +/* Type representing floating-point environment. This structure + corresponds to the layout of the block written by the `fstenv' + instruction and has additional fields for the contents of the MXCSR + register as written by the `stmxcsr' instruction. */ +typedef struct + { + unsigned short int __control_word; + unsigned short int __unused1; + unsigned short int __status_word; + unsigned short int __unused2; + unsigned short int __tags; + unsigned short int __unused3; + unsigned int __eip; + unsigned short int __cs_selector; + unsigned int __opcode:11; + unsigned int __unused4:5; + unsigned int __data_offset; + unsigned short int __data_selector; + unsigned short int __unused5; +#ifdef __x86_64__ + unsigned int __mxcsr; +#endif + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exception is masked. */ +# define FE_NOMASK_ENV ((const fenv_t *) -2) +#endif diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bits/fenvinline.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/fenvinline.h new file mode 100644 index 0000000000..42f77b5618 --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/fenvinline.h @@ -0,0 +1,8 @@ +/* This file provides inline versions of floating-pint environment + handling functions. If there were any. */ + +#ifndef __NO_MATH_INLINES + +/* Here is where the code would go. */ + +#endif diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bits/huge_val.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/huge_val.h new file mode 100644 index 0000000000..f2bddf2874 --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/huge_val.h @@ -0,0 +1,40 @@ +/* Stub `HUGE_VAL' constant. + Used by and functions for overflow. + Copyright (C) 1992, 1996, 1997, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _MATH_H +# error "Never use directly; include instead." +#endif + +#if __GNUC_PREREQ(3,3) +# define HUGE_VAL (__builtin_huge_val()) +#else +# define HUGE_VAL 1e37 +#endif + +#if __GNUC_PREREQ(3,3) +# define HUGE_VALF (__builtin_huge_valf()) +#else +# define HUGE_VALF 1e37f +#endif + +#if __GNUC_PREREQ(3,3) +# define HUGE_VALL (__builtin_huge_vall()) +#else +# define HUGE_VALL ((long double) HUGE_VAL) +#endif diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bits/mathdef.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/mathdef.h new file mode 100644 index 0000000000..19d1fcaa7a --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/mathdef.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2001-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#if !defined _MATH_H && !defined _COMPLEX_H +# error "Never use directly; include instead" +#endif + +#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF +# define _MATH_H_MATHDEF 1 + +/* The x86-64 architecture computes values with the precission of the + used type. Similarly for -m32 -mfpmath=sse. */ +typedef float float_t; /* `float' expressions are evaluated as `float'. */ +typedef double double_t; /* `double' expressions are evaluated + as `double'. */ + +#define FLT_EVAL_METHOD 0 + +#if __GNUC_PREREQ(3,3) +# define INFINITY (__builtin_inff()) +#else +# define INFINITY HUGE_VALF +#endif + +/* The values returned by `ilogb' for 0 and NaN respectively. */ +# define FP_ILOGB0 (-2147483647 - 1) +# define FP_ILOGBNAN (-2147483647 - 1) + +/* The GCC 4.6 compiler will define __FP_FAST_FMA{,F,L} if the fma{,f,l} + builtins are supported. */ +# if __FP_FAST_FMA +# define FP_FAST_FMA 1 +# endif + +# if __FP_FAST_FMAF +# define FP_FAST_FMAF 1 +# endif + +# if __FP_FAST_FMAL +# define FP_FAST_FMAL 1 +# endif + +#endif /* ISO C99 */ diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bits/mathinline.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/mathinline.h new file mode 100644 index 0000000000..80f6d6453e --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/mathinline.h @@ -0,0 +1,970 @@ +/* Inline math functions for i387 and SSE. + Copyright (C) 1995-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _MATH_H +# error "Never use directly; include instead." +#endif + +#define __NTH(fct) __attribute__ ((__nothrow__)) fct + +#ifdef __cplusplus +# define __MATH_INLINE __inline +#else +# define __MATH_INLINE extern __inline +#endif + + +#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2 +/* GCC 2.97 and up have builtins that actually can be used. */ +# if !__GNUC_PREREQ (2,97) +/* ISO C99 defines some macros to perform unordered comparisons. The + ix87 FPU supports this with special opcodes and we should use them. + These must not be inline functions since we have to be able to handle + all floating-point types. */ +# undef isgreater +# undef isgreaterequal +# undef isless +# undef islessequal +# undef islessgreater +# undef isunordered +# ifdef __i686__ +/* For the PentiumPro and more recent processors we can provide + better code. */ +# define isgreater(x, y) \ + ({ register char __result; \ + __asm__ ("fucomip %%st(1), %%st; seta %%al" \ + : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \ + __result; }) +# define isgreaterequal(x, y) \ + ({ register char __result; \ + __asm__ ("fucomip %%st(1), %%st; setae %%al" \ + : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \ + __result; }) + +# define isless(x, y) \ + ({ register char __result; \ + __asm__ ("fucomip %%st(1), %%st; seta %%al" \ + : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \ + __result; }) + +# define islessequal(x, y) \ + ({ register char __result; \ + __asm__ ("fucomip %%st(1), %%st; setae %%al" \ + : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \ + __result; }) + +# define islessgreater(x, y) \ + ({ register char __result; \ + __asm__ ("fucomip %%st(1), %%st; setne %%al" \ + : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \ + __result; }) + +# define isunordered(x, y) \ + ({ register char __result; \ + __asm__ ("fucomip %%st(1), %%st; setp %%al" \ + : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \ + __result; }) +# else +/* This is the dumb, portable code for i386 and above. */ +# define isgreater(x, y) \ + ({ register char __result; \ + __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \ + : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \ + __result; }) + +# define isgreaterequal(x, y) \ + ({ register char __result; \ + __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \ + : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \ + __result; }) + +# define isless(x, y) \ + ({ register char __result; \ + __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \ + : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \ + __result; }) + +# define islessequal(x, y) \ + ({ register char __result; \ + __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \ + : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \ + __result; }) + +# define islessgreater(x, y) \ + ({ register char __result; \ + __asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al" \ + : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \ + __result; }) + +# define isunordered(x, y) \ + ({ register char __result; \ + __asm__ ("fucompp; fnstsw; sahf; setp %%al" \ + : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \ + __result; }) +# endif /* __i686__ */ +# endif /* GCC 2.97 */ + +/* The gcc, version 2.7 or below, has problems with all this inlining + code. So disable it for this version of the compiler. */ +# if __GNUC_PREREQ (2, 8) +__BEGIN_NAMESPACE_C99 + +/* Test for negative number. Used in the signbit() macro. */ +__MATH_INLINE int +__signbitf (float __x) +{ +# ifdef __SSE2_MATH__ + int __m; + __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x)); + return (__m & 0x8) != 0; +# else + __extension__ union { float __f; int __i; } __u = { __f: __x }; + return __u.__i < 0; +# endif +} +__MATH_INLINE int +__signbit (double __x) +{ +# ifdef __SSE2_MATH__ + int __m; + __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x)); + return (__m & 0x80) != 0; +# else + __extension__ union { double __d; int __i[2]; } __u = { __d: __x }; + return __u.__i[1] < 0; +# endif +} +__MATH_INLINE int +__signbitl (long double __x) +{ + __extension__ union { long double __l; int __i[3]; } __u = { __l: __x }; + return (__u.__i[2] & 0x8000) != 0; +} + +__END_NAMESPACE_C99 +# endif +#endif + + +/* The gcc, version 2.7 or below, has problems with all this inlining + code. So disable it for this version of the compiler. */ +#if __GNUC_PREREQ (2, 8) +# if !__GNUC_PREREQ (3, 4) && !defined __NO_MATH_INLINES \ + && defined __OPTIMIZE__ +/* GCC 3.4 introduced builtins for all functions below, so + there's no need to define any of these inline functions. */ + +# ifdef __USE_ISOC99 +__BEGIN_NAMESPACE_C99 + +/* Round to nearest integer. */ +# ifdef __SSE_MATH__ +__MATH_INLINE long int +__NTH (lrintf (float __x)) +{ + long int __res; + /* Mark as volatile since the result is dependent on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x)); + return __res; +} +# endif +# ifdef __SSE2_MATH__ +__MATH_INLINE long int +__NTH (lrint (double __x)) +{ + long int __res; + /* Mark as volatile since the result is dependent on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x)); + return __res; +} +# endif +# ifdef __x86_64__ +__MATH_INLINE long long int +__NTH (llrintf (float __x)) +{ + long long int __res; + /* Mark as volatile since the result is dependent on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x)); + return __res; +} +__MATH_INLINE long long int +__NTH (llrint (double __x)) +{ + long long int __res; + /* Mark as volatile since the result is dependent on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x)); + return __res; +} +# endif + +# if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0 \ + && defined __SSE2_MATH__ +/* Determine maximum of two values. */ +__MATH_INLINE float +__NTH (fmaxf (float __x, float __y)) +{ +# ifdef __AVX__ + float __res; + __asm ("vmaxss %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y)); + return __res; +# else + __asm ("maxss %1, %0" : "+x" (__x) : "xm" (__y)); + return __x; +# endif +} +__MATH_INLINE double +__NTH (fmax (double __x, double __y)) +{ +# ifdef __AVX__ + float __res; + __asm ("vmaxsd %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y)); + return __res; +# else + __asm ("maxsd %1, %0" : "+x" (__x) : "xm" (__y)); + return __x; +# endif +} + +/* Determine minimum of two values. */ +__MATH_INLINE float +__NTH (fminf (float __x, float __y)) +{ +# ifdef __AVX__ + float __res; + __asm ("vminss %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y)); + return __res; +# else + __asm ("minss %1, %0" : "+x" (__x) : "xm" (__y)); + return __x; +# endif +} +__MATH_INLINE double +__NTH (fmin (double __x, double __y)) +{ +# ifdef __AVX__ + float __res; + __asm ("vminsd %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y)); + return __res; +# else + __asm ("minsd %1, %0" : "+x" (__x) : "xm" (__y)); + return __x; +# endif +} +# endif + +__END_NAMESPACE_C99 +# endif + +# if defined __SSE4_1__ && defined __SSE2_MATH__ +# if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 +__BEGIN_NAMESPACE_C99 + +/* Round to nearest integer. */ +__MATH_INLINE double +__NTH (rint (double __x)) +{ + double __res; + /* Mark as volatile since the result is dependent on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("roundsd $4, %1, %0" : "=x" (__res) : "xm" (__x)); + return __res; +} +__MATH_INLINE float +__NTH (rintf (float __x)) +{ + float __res; + /* Mark as volatile since the result is dependent on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("roundss $4, %1, %0" : "=x" (__res) : "xm" (__x)); + return __res; +} + +# ifdef __USE_ISOC99 +/* Round to nearest integer without raising inexact exception. */ +__MATH_INLINE double +__NTH (nearbyint (double __x)) +{ + double __res; + /* Mark as volatile since the result is dependent on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("roundsd $0xc, %1, %0" : "=x" (__res) : "xm" (__x)); + return __res; +} +__MATH_INLINE float +__NTH (nearbyintf (float __x)) +{ + float __res; + /* Mark as volatile since the result is dependent on the state of + the SSE control register (the rounding mode). Otherwise GCC might + remove these assembler instructions since it does not know about + the rounding mode change and cannot currently be told. */ + __asm __volatile__ ("roundss $0xc, %1, %0" : "=x" (__res) : "xm" (__x)); + return __res; +} +# endif + +__END_NAMESPACE_C99 +# endif + +__BEGIN_NAMESPACE_STD +/* Smallest integral value not less than X. */ +__MATH_INLINE double +__NTH (ceil (double __x)) +{ + double __res; + __asm ("roundsd $2, %1, %0" : "=x" (__res) : "xm" (__x)); + return __res; +} +__END_NAMESPACE_STD + +__BEGIN_NAMESPACE_C99 +__MATH_INLINE float +__NTH (ceilf (float __x)) +{ + float __res; + __asm ("roundss $2, %1, %0" : "=x" (__res) : "xm" (__x)); + return __res; +} +__END_NAMESPACE_C99 + +__BEGIN_NAMESPACE_STD +/* Largest integer not greater than X. */ +__MATH_INLINE double +__NTH (floor (double __x)) +{ + double __res; + __asm ("roundsd $1, %1, %0" : "=x" (__res) : "xm" (__x)); + return __res; +} +__END_NAMESPACE_STD + +__BEGIN_NAMESPACE_C99 +__MATH_INLINE float +__NTH (floorf (float __x)) +{ + float __res; + __asm ("roundss $1, %1, %0" : "=x" (__res) : "xm" (__x)); + return __res; +} +__END_NAMESPACE_C99 +# endif +# endif +#endif + +#ifndef __x86_64__ +# if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \ + && defined __OPTIMIZE__) + +/* The inline functions do not set errno or raise necessarily the + correct exceptions. */ +# undef math_errhandling + +/* A macro to define float, double, and long double versions of various + math functions for the ix87 FPU. FUNC is the function name (which will + be suffixed with f and l for the float and long double version, + respectively). OP is the name of the FPU operation. + We define two sets of macros. The set with the additional NP + doesn't add a prototype declaration. */ + +# if defined __USE_MISC || defined __USE_ISOC99 +# define __inline_mathop(func, op) \ + __inline_mathop_ (double, func, op) \ + __inline_mathop_ (float, __CONCAT(func,f), op) \ + __inline_mathop_ (long double, __CONCAT(func,l), op) +# define __inline_mathopNP(func, op) \ + __inline_mathopNP_ (double, func, op) \ + __inline_mathopNP_ (float, __CONCAT(func,f), op) \ + __inline_mathopNP_ (long double, __CONCAT(func,l), op) +# else +# define __inline_mathop(func, op) \ + __inline_mathop_ (double, func, op) +# define __inline_mathopNP(func, op) \ + __inline_mathopNP_ (double, func, op) +# endif + +# define __inline_mathop_(float_type, func, op) \ + __inline_mathop_decl_ (float_type, func, op, "0" (__x)) +# define __inline_mathopNP_(float_type, func, op) \ + __inline_mathop_declNP_ (float_type, func, op, "0" (__x)) + + +# if defined __USE_MISC || defined __USE_ISOC99 +# define __inline_mathop_decl(func, op, params...) \ + __inline_mathop_decl_ (double, func, op, params) \ + __inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \ + __inline_mathop_decl_ (long double, __CONCAT(func,l), op, params) +# define __inline_mathop_declNP(func, op, params...) \ + __inline_mathop_declNP_ (double, func, op, params) \ + __inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \ + __inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params) +# else +# define __inline_mathop_decl(func, op, params...) \ + __inline_mathop_decl_ (double, func, op, params) +# define __inline_mathop_declNP(func, op, params...) \ + __inline_mathop_declNP_ (double, func, op, params) +# endif + +# define __inline_mathop_decl_(float_type, func, op, params...) \ + __MATH_INLINE float_type func (float_type) __THROW; \ + __inline_mathop_declNP_ (float_type, func, op, params) + +# define __inline_mathop_declNP_(float_type, func, op, params...) \ + __MATH_INLINE float_type __NTH (func (float_type __x)) \ + { \ + register float_type __result; \ + __asm __volatile__ (op : "=t" (__result) : params); \ + return __result; \ + } + + +# if defined __USE_MISC || defined __USE_ISOC99 +# define __inline_mathcode(func, arg, code) \ + __inline_mathcode_ (double, func, arg, code) \ + __inline_mathcode_ (float, __CONCAT(func,f), arg, code) \ + __inline_mathcode_ (long double, __CONCAT(func,l), arg, code) +# define __inline_mathcodeNP(func, arg, code) \ + __inline_mathcodeNP_ (double, func, arg, code) \ + __inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \ + __inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code) +# define __inline_mathcode2(func, arg1, arg2, code) \ + __inline_mathcode2_ (double, func, arg1, arg2, code) \ + __inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \ + __inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code) +# define __inline_mathcodeNP2(func, arg1, arg2, code) \ + __inline_mathcodeNP2_ (double, func, arg1, arg2, code) \ + __inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \ + __inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code) +# define __inline_mathcode3(func, arg1, arg2, arg3, code) \ + __inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \ + __inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \ + __inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code) +# define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \ + __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \ + __inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \ + __inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code) +# else +# define __inline_mathcode(func, arg, code) \ + __inline_mathcode_ (double, func, (arg), code) +# define __inline_mathcodeNP(func, arg, code) \ + __inline_mathcodeNP_ (double, func, (arg), code) +# define __inline_mathcode2(func, arg1, arg2, code) \ + __inline_mathcode2_ (double, func, arg1, arg2, code) +# define __inline_mathcodeNP2(func, arg1, arg2, code) \ + __inline_mathcodeNP2_ (double, func, arg1, arg2, code) +# define __inline_mathcode3(func, arg1, arg2, arg3, code) \ + __inline_mathcode3_ (double, func, arg1, arg2, arg3, code) +# define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \ + __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) +# endif + +# define __inline_mathcode_(float_type, func, arg, code) \ + __MATH_INLINE float_type func (float_type) __THROW; \ + __inline_mathcodeNP_(float_type, func, arg, code) + +# define __inline_mathcodeNP_(float_type, func, arg, code) \ + __MATH_INLINE float_type __NTH (func (float_type arg)) \ + { \ + code; \ + } + + +# define __inline_mathcode2_(float_type, func, arg1, arg2, code) \ + __MATH_INLINE float_type func (float_type, float_type) __THROW; \ + __inline_mathcodeNP2_ (float_type, func, arg1, arg2, code) + +# define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \ + __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2)) \ + { \ + code; \ + } + +# define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \ + __MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \ + __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) + +# define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \ + __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2, \ + float_type arg3)) \ + { \ + code; \ + } +# endif + + +# if !defined __NO_MATH_INLINES && defined __OPTIMIZE__ +/* Miscellaneous functions */ + +/* __FAST_MATH__ is defined by gcc -ffast-math. */ +# ifdef __FAST_MATH__ +# ifdef __USE_GNU +# define __sincos_code \ + register long double __cosr; \ + register long double __sinr; \ + register unsigned int __swtmp; \ + __asm __volatile__ \ + ("fsincos\n\t" \ + "fnstsw %w2\n\t" \ + "testl $0x400, %2\n\t" \ + "jz 1f\n\t" \ + "fldpi\n\t" \ + "fadd %%st(0)\n\t" \ + "fxch %%st(1)\n\t" \ + "2: fprem1\n\t" \ + "fnstsw %w2\n\t" \ + "testl $0x400, %2\n\t" \ + "jnz 2b\n\t" \ + "fstp %%st(1)\n\t" \ + "fsincos\n\t" \ + "1:" \ + : "=t" (__cosr), "=u" (__sinr), "=a" (__swtmp) : "0" (__x)); \ + *__sinx = __sinr; \ + *__cosx = __cosr + +__MATH_INLINE void +__NTH (__sincos (double __x, double *__sinx, double *__cosx)) +{ + __sincos_code; +} + +__MATH_INLINE void +__NTH (__sincosf (float __x, float *__sinx, float *__cosx)) +{ + __sincos_code; +} + +__MATH_INLINE void +__NTH (__sincosl (long double __x, long double *__sinx, long double *__cosx)) +{ + __sincos_code; +} +# endif + + +/* Optimized inline implementation, sometimes with reduced precision + and/or argument range. */ + +# if __GNUC_PREREQ (3, 5) +# define __expm1_code \ + register long double __temp; \ + __temp = __builtin_expm1l (__x); \ + return __temp ? __temp : __x +# else +# define __expm1_code \ + register long double __value; \ + register long double __exponent; \ + register long double __temp; \ + __asm __volatile__ \ + ("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \ + "fmul %%st(1) # x * log2(e)\n\t" \ + "fst %%st(1)\n\t" \ + "frndint # int(x * log2(e))\n\t" \ + "fxch\n\t" \ + "fsub %%st(1) # fract(x * log2(e))\n\t" \ + "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \ + "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \ + : "=t" (__value), "=u" (__exponent) : "0" (__x)); \ + __asm __volatile__ \ + ("fscale # 2^int(x * log2(e))\n\t" \ + : "=t" (__temp) : "0" (1.0), "u" (__exponent)); \ + __temp -= 1.0; \ + __temp += __value; \ + return __temp ? __temp : __x +# endif +__inline_mathcodeNP_ (long double, __expm1l, __x, __expm1_code) + +# if __GNUC_PREREQ (3, 4) +__inline_mathcodeNP_ (long double, __expl, __x, return __builtin_expl (__x)) +# else +# define __exp_code \ + register long double __value; \ + register long double __exponent; \ + __asm __volatile__ \ + ("fldl2e # e^x = 2^(x * log2(e))\n\t" \ + "fmul %%st(1) # x * log2(e)\n\t" \ + "fst %%st(1)\n\t" \ + "frndint # int(x * log2(e))\n\t" \ + "fxch\n\t" \ + "fsub %%st(1) # fract(x * log2(e))\n\t" \ + "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \ + : "=t" (__value), "=u" (__exponent) : "0" (__x)); \ + __value += 1.0; \ + __asm __volatile__ \ + ("fscale" \ + : "=t" (__value) : "0" (__value), "u" (__exponent)); \ + return __value +__inline_mathcodeNP (exp, __x, __exp_code) +__inline_mathcodeNP_ (long double, __expl, __x, __exp_code) +# endif + + +# if !__GNUC_PREREQ (3, 5) +__inline_mathcodeNP (tan, __x, \ + register long double __value; \ + register long double __value2 __attribute__ ((__unused__)); \ + __asm __volatile__ \ + ("fptan" \ + : "=t" (__value2), "=u" (__value) : "0" (__x)); \ + return __value) +# endif +# endif /* __FAST_MATH__ */ + + +# if __GNUC_PREREQ (3, 4) +__inline_mathcodeNP2_ (long double, __atan2l, __y, __x, + return __builtin_atan2l (__y, __x)) +# else +# define __atan2_code \ + register long double __value; \ + __asm __volatile__ \ + ("fpatan" \ + : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \ + return __value +# ifdef __FAST_MATH__ +__inline_mathcodeNP2 (atan2, __y, __x, __atan2_code) +# endif +__inline_mathcodeNP2_ (long double, __atan2l, __y, __x, __atan2_code) +# endif + + +# if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5) +__inline_mathcodeNP2 (fmod, __x, __y, \ + register long double __value; \ + __asm __volatile__ \ + ("1: fprem\n\t" \ + "fnstsw %%ax\n\t" \ + "sahf\n\t" \ + "jp 1b" \ + : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); \ + return __value) +# endif + + +# ifdef __FAST_MATH__ +# if !__GNUC_PREREQ (3,3) +__inline_mathopNP (sqrt, "fsqrt") +__inline_mathopNP_ (long double, __sqrtl, "fsqrt") +# define __libc_sqrtl(n) __sqrtl (n) +# else +# define __libc_sqrtl(n) __builtin_sqrtl (n) +# endif +# endif + +# if __GNUC_PREREQ (2, 8) +__inline_mathcodeNP_ (double, fabs, __x, return __builtin_fabs (__x)) +# if defined __USE_MISC || defined __USE_ISOC99 +__inline_mathcodeNP_ (float, fabsf, __x, return __builtin_fabsf (__x)) +__inline_mathcodeNP_ (long double, fabsl, __x, return __builtin_fabsl (__x)) +# endif +__inline_mathcodeNP_ (long double, __fabsl, __x, return __builtin_fabsl (__x)) +# else +__inline_mathop (fabs, "fabs") +__inline_mathop_ (long double, __fabsl, "fabs") +# endif + +# ifdef __FAST_MATH__ +# if !__GNUC_PREREQ (3, 4) +/* The argument range of this inline version is reduced. */ +__inline_mathopNP (sin, "fsin") +/* The argument range of this inline version is reduced. */ +__inline_mathopNP (cos, "fcos") + +__inline_mathop_declNP (log, "fldln2; fxch; fyl2x", "0" (__x) : "st(1)") +# endif + +# if !__GNUC_PREREQ (3, 5) +__inline_mathop_declNP (log10, "fldlg2; fxch; fyl2x", "0" (__x) : "st(1)") + +__inline_mathcodeNP (asin, __x, return __atan2l (__x, __libc_sqrtl (1.0 - __x * __x))) +__inline_mathcodeNP (acos, __x, return __atan2l (__libc_sqrtl (1.0 - __x * __x), __x)) +# endif + +# if !__GNUC_PREREQ (3, 4) +__inline_mathop_declNP (atan, "fld1; fpatan", "0" (__x) : "st(1)") +# endif +# endif /* __FAST_MATH__ */ + +__inline_mathcode_ (long double, __sgn1l, __x, \ + __extension__ union { long double __xld; unsigned int __xi[3]; } __n = \ + { __xld: __x }; \ + __n.__xi[2] = (__n.__xi[2] & 0x8000) | 0x3fff; \ + __n.__xi[1] = 0x80000000; \ + __n.__xi[0] = 0; \ + return __n.__xld) + + +# ifdef __FAST_MATH__ +/* The argument range of the inline version of sinhl is slightly reduced. */ +__inline_mathcodeNP (sinh, __x, \ + register long double __exm1 = __expm1l (__fabsl (__x)); \ + return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1l (__x)) + +__inline_mathcodeNP (cosh, __x, \ + register long double __ex = __expl (__x); \ + return 0.5 * (__ex + 1.0 / __ex)) + +__inline_mathcodeNP (tanh, __x, \ + register long double __exm1 = __expm1l (-__fabsl (__x + __x)); \ + return __exm1 / (__exm1 + 2.0) * __sgn1l (-__x)) +# endif + +__inline_mathcodeNP (floor, __x, \ + register long double __value; \ + register int __ignore; \ + unsigned short int __cw; \ + unsigned short int __cwtmp; \ + __asm __volatile ("fnstcw %3\n\t" \ + "movzwl %3, %1\n\t" \ + "andl $0xf3ff, %1\n\t" \ + "orl $0x0400, %1\n\t" /* rounding down */ \ + "movw %w1, %2\n\t" \ + "fldcw %2\n\t" \ + "frndint\n\t" \ + "fldcw %3" \ + : "=t" (__value), "=&q" (__ignore), "=m" (__cwtmp), \ + "=m" (__cw) \ + : "0" (__x)); \ + return __value) + +__inline_mathcodeNP (ceil, __x, \ + register long double __value; \ + register int __ignore; \ + unsigned short int __cw; \ + unsigned short int __cwtmp; \ + __asm __volatile ("fnstcw %3\n\t" \ + "movzwl %3, %1\n\t" \ + "andl $0xf3ff, %1\n\t" \ + "orl $0x0800, %1\n\t" /* rounding up */ \ + "movw %w1, %2\n\t" \ + "fldcw %2\n\t" \ + "frndint\n\t" \ + "fldcw %3" \ + : "=t" (__value), "=&q" (__ignore), "=m" (__cwtmp), \ + "=m" (__cw) \ + : "0" (__x)); \ + return __value) + +# ifdef __FAST_MATH__ +# define __ldexp_code \ + register long double __value; \ + __asm __volatile__ \ + ("fscale" \ + : "=t" (__value) : "0" (__x), "u" ((long double) __y)); \ + return __value + +__MATH_INLINE double +__NTH (ldexp (double __x, int __y)) +{ + __ldexp_code; +} +# endif + + +/* Optimized versions for some non-standardized functions. */ +# if defined __USE_ISOC99 || defined __USE_MISC + +# ifdef __FAST_MATH__ +__inline_mathcodeNP (expm1, __x, __expm1_code) + +/* We cannot rely on M_SQRT being defined. So we do it for ourself + here. */ +# define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */ + +# if !__GNUC_PREREQ (3, 5) +__inline_mathcodeNP (log1p, __x, \ + register long double __value; \ + if (__fabsl (__x) >= 1.0 - 0.5 * __M_SQRT2) \ + __value = logl (1.0 + __x); \ + else \ + __asm __volatile__ \ + ("fldln2\n\t" \ + "fxch\n\t" \ + "fyl2xp1" \ + : "=t" (__value) : "0" (__x) : "st(1)"); \ + return __value) +# endif + + +/* The argument range of the inline version of asinhl is slightly reduced. */ +__inline_mathcodeNP (asinh, __x, \ + register long double __y = __fabsl (__x); \ + return (log1pl (__y * __y / (__libc_sqrtl (__y * __y + 1.0) + 1.0) + __y) \ + * __sgn1l (__x))) + +__inline_mathcodeNP (acosh, __x, \ + return logl (__x + __libc_sqrtl (__x - 1.0) * __libc_sqrtl (__x + 1.0))) + +__inline_mathcodeNP (atanh, __x, \ + register long double __y = __fabsl (__x); \ + return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __sgn1l (__x)) + +/* The argument range of the inline version of hypotl is slightly reduced. */ +__inline_mathcodeNP2 (hypot, __x, __y, + return __libc_sqrtl (__x * __x + __y * __y)) + +# if !__GNUC_PREREQ (3, 5) +__inline_mathcodeNP(logb, __x, \ + register long double __value; \ + register long double __junk; \ + __asm __volatile__ \ + ("fxtract\n\t" \ + : "=t" (__junk), "=u" (__value) : "0" (__x)); \ + return __value) +# endif + +# endif +# endif + +# ifdef __USE_ISOC99 +# ifdef __FAST_MATH__ + +# if !__GNUC_PREREQ (3, 5) +__inline_mathop_declNP (log2, "fld1; fxch; fyl2x", "0" (__x) : "st(1)") +# endif + +__MATH_INLINE float +__NTH (ldexpf (float __x, int __y)) +{ + __ldexp_code; +} + +__MATH_INLINE long double +__NTH (ldexpl (long double __x, int __y)) +{ + __ldexp_code; +} + +__inline_mathopNP (rint, "frndint") +# endif /* __FAST_MATH__ */ + +# define __lrint_code \ + long int __lrintres; \ + __asm__ __volatile__ \ + ("fistpl %0" \ + : "=m" (__lrintres) : "t" (__x) : "st"); \ + return __lrintres +__MATH_INLINE long int +__NTH (lrintf (float __x)) +{ + __lrint_code; +} +__MATH_INLINE long int +__NTH (lrint (double __x)) +{ + __lrint_code; +} +__MATH_INLINE long int +__NTH (lrintl (long double __x)) +{ + __lrint_code; +} +# undef __lrint_code + +# define __llrint_code \ + long long int __llrintres; \ + __asm__ __volatile__ \ + ("fistpll %0" \ + : "=m" (__llrintres) : "t" (__x) : "st"); \ + return __llrintres +__MATH_INLINE long long int +__NTH (llrintf (float __x)) +{ + __llrint_code; +} +__MATH_INLINE long long int +__NTH (llrint (double __x)) +{ + __llrint_code; +} +__MATH_INLINE long long int +__NTH (llrintl (long double __x)) +{ + __llrint_code; +} +# undef __llrint_code + +# endif + + +# ifdef __USE_MISC + +# if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5) +__inline_mathcodeNP2 (drem, __x, __y, \ + register double __value; \ + register int __clobbered; \ + __asm __volatile__ \ + ("1: fprem1\n\t" \ + "fstsw %%ax\n\t" \ + "sahf\n\t" \ + "jp 1b" \ + : "=t" (__value), "=&a" (__clobbered) : "0" (__x), "u" (__y) : "cc"); \ + return __value) +# endif + + +/* This function is used in the `isfinite' macro. */ +__MATH_INLINE int +__NTH (__finite (double __x)) +{ + return (__extension__ + (((((union { double __d; int __i[2]; }) {__d: __x}).__i[1] + | 0x800fffffu) + 1) >> 31)); +} + +# endif /* __USE_MISC */ + +/* Undefine some of the large macros which are not used anymore. */ +# undef __atan2_code +# ifdef __FAST_MATH__ +# undef __expm1_code +# undef __exp_code +# undef __sincos_code +# endif /* __FAST_MATH__ */ + +# endif /* __NO_MATH_INLINES */ + + +/* This code is used internally in the GNU libc. */ +# ifdef __LIBC_INTERNAL_MATH_INLINES +__inline_mathop (__ieee754_sqrt, "fsqrt") +__inline_mathcode2 (__ieee754_atan2, __y, __x, + register long double __value; + __asm __volatile__ ("fpatan\n\t" + : "=t" (__value) + : "0" (__x), "u" (__y) : "st(1)"); + return __value;) +# endif + +#endif /* !__x86_64__ */ diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bits/nan.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/nan.h new file mode 100644 index 0000000000..00cb405f18 --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/nan.h @@ -0,0 +1,52 @@ +/* `NAN' constant for IEEE 754 machines. + Copyright (C) 1992,1996,1997,1999,2004,2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _MATH_H +# error "Never use directly; include instead." +#endif + + +/* IEEE Not A Number. */ + +#if __GNUC_PREREQ(3,3) + +# define NAN (__builtin_nanf ("")) + +#elif defined __GNUC__ + +# define NAN \ + (__extension__ \ + ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; }) \ + { __l: 0x7fc00000UL }).__d) + +#else + +# include + +# if __BYTE_ORDER == __BIG_ENDIAN +# define __nan_bytes { 0x7f, 0xc0, 0, 0 } +# endif +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define __nan_bytes { 0, 0, 0xc0, 0x7f } +# endif + +static union { unsigned char __c[4]; float __d; } __nan_union + __attribute_used__ = { __nan_bytes }; +# define NAN (__nan_union.__d) + +#endif /* GCC. */ diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bits/wordsize.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/wordsize.h new file mode 100644 index 0000000000..a40a0d816f --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bits/wordsize.h @@ -0,0 +1,8 @@ +/* Determine the wordsize from the preprocessor defines. */ + +#if defined __x86_64__ +# define __WORDSIZE 64 +# define __WORDSIZE_COMPAT32 1 +#else +# define __WORDSIZE 32 +#endif diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/bp-asm.h b/src/system/libroot/posix/glibc/include/arch/x86_64/bp-asm.h new file mode 100644 index 0000000000..ff140ce181 --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/bp-asm.h @@ -0,0 +1,141 @@ +/* Bounded-pointer definitions for x86-64 assembler. + Copyright (C) 2001 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _bp_asm_h_ +# define _bp_asm_h_ 1 + +# if __ASSEMBLER__ + +# if __BOUNDED_POINTERS__ + +/* Bounded pointers occupy three words. */ +# define PTR_SIZE 24 +/* Bounded pointer return values are passed back through a hidden + argument that points to caller-allocate space. The hidden arg + occupies one word on the stack. */ +# define RTN_SIZE 6 +/* Although the caller pushes the hidden arg, the callee is + responsible for popping it. */ +# define RET_PTR ret $RTN_SIZE +/* Maintain frame pointer chain in leaf assembler functions for the benefit + of debugging stack traces when bounds violations occur. */ +# define ENTER pushq %rbp; movq %rsp, %rbp +# define LEAVE movq %rbp, %rsp; popq %rbp +/* Stack space overhead of procedure-call linkage: return address and + frame pointer. */ +# define LINKAGE 16 +/* Stack offset of return address after calling ENTER. */ +# define PCOFF 8 + +/* Int 5 is the "bound range" exception also raised by the "bound" + instruction. */ +# define BOUNDS_VIOLATED int $5 + +# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) \ + cmpq 8+BP_MEM, VAL_REG; \ + jae 0f; /* continue if value >= low */ \ + BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) \ + cmpq 16+BP_MEM, VAL_REG; \ + Jcc 0f; /* continue if value < high */ \ + BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) \ + cmpq 8+BP_MEM, VAL_REG; \ + jb 1f; /* die if value < low */ \ + cmpq 16+BP_MEM, VAL_REG; \ + jb 0f; /* continue if value < high */ \ + 1: BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) \ + CHECK_BOUNDS_LOW(VAL_REG, BP_MEM); \ + addl LENGTH, VAL_REG; \ + cmpq 16+BP_MEM, VAL_REG; \ + jbe 0f; /* continue if value <= high */ \ + BOUNDS_VIOLATED; \ + 0: subq LENGTH, VAL_REG /* restore value */ + +/* Take bounds from BP_MEM and affix them to the pointer + value in %rax, stuffing all into memory at RTN(%esp). + Use %rdx as a scratch register. */ + +# define RETURN_BOUNDED_POINTER(BP_MEM) \ + movq RTN(%rsp), %rdx; \ + movq %rax, 0(%rdx); \ + movq 8+BP_MEM, %rax; \ + movq %rax, 4(%rdx); \ + movq 16+BP_MEM, %rax; \ + movq %rax, 8(%rdx) + +# define RETURN_NULL_BOUNDED_POINTER \ + movl RTN(%rsp), %rdx; \ + movl %rax, 0(%rdx); \ + movl %rax, 4(%rdx); \ + movl %rax, 8(%rdx) + +/* The caller of __errno_location is responsible for allocating space + for the three-word BP return-value and passing pushing its address + as an implicit first argument. */ +# define PUSH_ERRNO_LOCATION_RETURN \ + subl $16, %esp; \ + subl $8, %esp; \ + pushq %rsp + +/* __errno_location is responsible for popping the implicit first + argument, but we must pop the space for the BP itself. We also + dereference the return value in order to dig out the pointer value. */ +# define POP_ERRNO_LOCATION_RETURN \ + popq %rax; \ + addq $16, %rsp + +# else /* !__BOUNDED_POINTERS__ */ + +/* Unbounded pointers occupy one word. */ +# define PTR_SIZE 8 +/* Unbounded pointer return values are passed back in the register %rax. */ +# define RTN_SIZE 0 +/* Use simple return instruction for unbounded pointer values. */ +# define RET_PTR ret +/* Don't maintain frame pointer chain for leaf assembler functions. */ +# define ENTER +# define LEAVE +/* Stack space overhead of procedure-call linkage: return address only. */ +# define LINKAGE 8 +/* Stack offset of return address after calling ENTER. */ +# define PCOFF 0 + +# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) +# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) +# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) +# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) +# define RETURN_BOUNDED_POINTER(BP_MEM) + +# define RETURN_NULL_BOUNDED_POINTER + +# define PUSH_ERRNO_LOCATION_RETURN +# define POP_ERRNO_LOCATION_RETURN + +# endif /* !__BOUNDED_POINTERS__ */ + +# endif /* __ASSEMBLER__ */ + +#endif /* _bp_asm_h_ */ diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/config.h b/src/system/libroot/posix/glibc/include/arch/x86_64/config.h new file mode 100644 index 0000000000..8ac90aa35f --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/config.h @@ -0,0 +1,235 @@ +//#if !defined __ASSEMBLER__ && !defined _ISOMAC && !defined __OPTIMIZE__ +//# error "glibc cannot be compiled without optimization" +//#endif + +/* Another evil option when it comes to compiling the C library is + --ffast-math since it alters the ABI. */ +#if defined __FAST_MATH__ && !defined TEST_FAST_MATH +# error "glibc must not be compiled with -ffast-math" +#endif + +/* Define if using GNU ld, with support for weak symbols in a.out, + and for symbol set and warning messages extensions in a.out and ELF. + This implies HAVE_WEAK_SYMBOLS; set by --with-gnu-ld. */ +#define HAVE_GNU_LD 1 + +/* Define if using ELF, which supports weak symbols. + This implies HAVE_ASM_WEAK_DIRECTIVE and NO_UNDERSCORES; set by + --with-elf. */ +#define HAVE_ELF 1 + +/* Define if using XCOFF. Set by --with-xcoff. */ +#undef HAVE_XCOFF + +/* Define if C symbols are asm symbols. Don't define if C symbols + have a `_' prepended to make the asm symbol. */ +#define NO_UNDERSCORES 1 + +/* Define if weak symbols are available via the `.weak' directive. */ +#define HAVE_ASM_WEAK_DIRECTIVE 1 + +/* Define if weak symbols are available via the `.weakext' directive. */ +#undef HAVE_ASM_WEAKEXT_DIRECTIVE + +/* Define to the assembler line separator character for multiple + assembler instructions per line. Default is `;' */ +#undef ASM_LINE_SEP + +/* Define if not using ELF, but `.init' and `.fini' sections are available. */ +#undef HAVE_INITFINI + +/* Define if __attribute__((section("foo"))) puts quotes around foo. */ +#undef HAVE_SECTION_QUOTES + +/* Define if using the GNU assembler, gas. */ +#define HAVE_GNU_AS 1 + +/* Define if the assembler supports the `.set' directive. */ +#define HAVE_ASM_SET_DIRECTIVE 1 + +/* Define to the name of the assembler's directive for + declaring a symbol global (default `.globl'). */ +#define ASM_GLOBAL_DIRECTIVE .globl + +/* Define to the prefix before `object' or `function' in the + assembler's `.type' directive, if it has one. */ +#undef ASM_TYPE_DIRECTIVE_PREFIX + +/* Define a symbol_name as a global .symbol_name for ld. */ +#undef HAVE_ASM_GLOBAL_DOT_NAME + +/* Define if the assembler generates debugging information directly. */ +#undef HAVE_CPP_ASM_DEBUGINFO + +/* Define if _Unwind_Find_FDE should be exported from glibc. */ +#undef EXPORT_UNWIND_FIND_FDE + +/* Define to use GNU libio instead of GNU stdio. + This is defined by configure under --enable-libio. */ +#define USE_IN_LIBIO 1 + +/* Define if using ELF and the assembler supports the `.previous' + directive. */ +#define HAVE_ASM_PREVIOUS_DIRECTIVE 1 + +/* Define if using ELF and the assembler supports the `.popsection' + directive. */ +#undef HAVE_ASM_POPSECTION_DIRECTIVE + +/* Define if versioning of the library is wanted. */ +#undef DO_VERSIONING + +/* Defined to the oldest ABI we support, like 2.1. */ +#undef GLIBC_OLDEST_ABI + +/* Define if static NSS modules are wanted. */ +#undef DO_STATIC_NSS + +/* Define if gcc uses DWARF2 unwind information for exception support. */ +#define HAVE_DWARF2_UNWIND_INFO 1 + +/* Define if gcc uses DWARF2 unwind information for exception support + with static variable. */ +#define HAVE_DWARF2_UNWIND_INFO_STATIC 1 + +/* Define if the compiler supports __builtin_expect. */ +#define HAVE_BUILTIN_EXPECT 1 + +/* Define if the compiler supports __builtin_memset. */ +#undef HAVE_BUILTIN_MEMSET + +/* Define if the __thread keyword is supported. */ +#undef HAVE___THREAD + +/* Define if the compiler supports __attribute__((tls_model(""))). */ +#undef HAVE_TLS_MODEL_ATTRIBUTE + +/* Define if the regparm attribute shall be used for local functions + (gcc on ix86 only). */ +#undef USE_REGPARMS + +/* Defined on PowerPC if the GCC being used has a problem with clobbering + certain registers (CR0, MQ, CTR, LR) in asm statements. */ +#undef BROKEN_PPC_ASM_CR0 + +/* Defined on SPARC if ld doesn't handle R_SPARC_WDISP22 against .hidden + symbol. sysdeps/sparc/sparc32/elf/configure. */ +#undef BROKEN_SPARC_WDISP22 + +/* Define if the linker supports the -z combreloc option. */ +#undef HAVE_Z_COMBRELOC + +/* Define if the assembler supported .protected. */ +#undef HAVE_PROTECTED + +/* Define if the assembler supported .hidden. */ +#undef HAVE_HIDDEN + +/* Define if the compiler supports __attribute__ ((visibility (...))). */ +#define HAVE_VISIBILITY_ATTRIBUTE 1 + +/* Define if the compiler doesn't support __attribute__ ((visibility (...))) + together with __asm__ redirection properly. */ +#undef HAVE_BROKEN_VISIBILITY_ATTRIBUTE + +/* Define if the compiler doesn't support __attribute__ ((alias (...))) + together with __asm__ redirection properly. */ +#undef HAVE_BROKEN_ALIAS_ATTRIBUTE + +/* Define if _rtld_local structure should be forced into .sdata section. */ +#undef HAVE_SDATA_SECTION + +/* Define if binutils support TLS handling. */ +#undef HAVE_TLS_SUPPORT + +/* Define if the linker supports .preinit_array/.init_array/.fini_array + sections. */ +#undef HAVE_INITFINI_ARRAY + +/* Define if the access to static and hidden variables is position independent + and does not need relocations. */ +#undef PI_STATIC_AND_HIDDEN + +/* Define this to disable the `hidden_proto' et al macros in + include/libc-symbols.h that avoid PLT slots in the shared objects. */ +#undef NO_HIDDEN + + +/* Defined to some form of __attribute__ ((...)) if the compiler supports + a different, more efficient calling convention. */ +#if defined USE_REGPARMS && !defined PROF && !defined __BOUNDED_POINTERS__ +# define internal_function __attribute__ ((regparm (3), stdcall)) +#endif + +/* Linux specific: minimum supported kernel version. */ +#undef __LINUX_KERNEL_VERSION + +/* Override abi-tags ABI version if necessary. */ +#undef __ABI_TAG_VERSION + +/* An extension in gcc 2.96 and up allows the subtraction of two + local labels. */ +#undef HAVE_SUBTRACT_LOCAL_LABELS + +/* bash 2.0 introduced the _XXX_GNU_nonoption_argv_flags_ variable to help + getopt determine whether a parameter is a flag or not. This features + was disabled later since it caused trouble. We are by default therefore + disabling the support as well. */ +#undef USE_NONOPTION_FLAGS + +/* Mach/Hurd specific: define if mig supports the `retcode' keyword. */ +#undef HAVE_MIG_RETCODE + +/* Mach specific: define if the `host_page_size' RPC is available. */ +#undef HAVE_HOST_PAGE_SIZE + +/* Mach/i386 specific: define if the `i386_io_perm_*' RPCs are available. */ +#undef HAVE_I386_IO_PERM_MODIFY + +/* Mach/i386 specific: define if the `i386_set_gdt' RPC is available. */ +#undef HAVE_I386_SET_GDT + +/* + */ + +#ifndef _LIBC + +/* These symbols might be defined by some sysdeps configures. + They are used only in miscellaneous generator programs, not + in compiling libc itself. */ + +/* sysdeps/generic/configure.in */ +#undef HAVE_PSIGNAL + +/* sysdeps/unix/configure.in */ +#define HAVE_STRERROR + +/* sysdeps/unix/common/configure.in */ +#undef HAVE_SYS_SIGLIST +#undef HAVE__SYS_SIGLIST +#undef HAVE__CTYPE_ +#undef HAVE___CTYPE_ +#undef HAVE___CTYPE +#undef HAVE__CTYPE__ +#undef HAVE__CTYPE +#undef HAVE__LOCP + +#endif + +/* + */ + +#ifdef _LIBC + +/* The zic and zdump programs need these definitions. */ + +#define HAVE_STRERROR 1 + +/* The locale code needs these definitions. */ + +#define HAVE_REGEX 1 + +//#define HAVE_MMAP 1 +#undef HAVE_MMAP + +#endif diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/math_ldbl.h b/src/system/libroot/posix/glibc/include/arch/x86_64/math_ldbl.h new file mode 100644 index 0000000000..b9ff8dadaf --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/math_ldbl.h @@ -0,0 +1,79 @@ +#ifndef _MATH_PRIVATE_H_ +#error "Never use directly; include instead." +#endif + +/* A union which permits us to convert between a long double and + three 32 bit ints. */ + +typedef union +{ + long double value; + struct + { + u_int32_t lsw; + u_int32_t msw; + int sign_exponent:16; + unsigned int empty1:16; + unsigned int empty0:32; + } parts; +} ieee_long_double_shape_type; + +/* Get three 32 bit ints from a double. */ + +#define GET_LDOUBLE_WORDS(exp,ix0,ix1,d) \ +do { \ + ieee_long_double_shape_type ew_u; \ + ew_u.value = (d); \ + (exp) = ew_u.parts.sign_exponent; \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define SET_LDOUBLE_WORDS(d,exp,ix0,ix1) \ +do { \ + ieee_long_double_shape_type iw_u; \ + iw_u.parts.sign_exponent = (exp); \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Get the more significant 32 bits of a long double mantissa. */ + +#define GET_LDOUBLE_MSW(v,d) \ +do { \ + ieee_long_double_shape_type sh_u; \ + sh_u.value = (d); \ + (v) = sh_u.parts.msw; \ +} while (0) + +/* Set the more significant 32 bits of a long double mantissa from an int. */ + +#define SET_LDOUBLE_MSW(d,v) \ +do { \ + ieee_long_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Get int from the exponent of a long double. */ + +#define GET_LDOUBLE_EXP(exp,d) \ +do { \ + ieee_long_double_shape_type ge_u; \ + ge_u.value = (d); \ + (exp) = ge_u.parts.sign_exponent; \ +} while (0) + +/* Set exponent of a long double from an int. */ + +#define SET_LDOUBLE_EXP(d,exp) \ +do { \ + ieee_long_double_shape_type se_u; \ + se_u.value = (d); \ + se_u.parts.sign_exponent = (exp); \ + (d) = se_u.value; \ +} while (0) diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/stackinfo.h b/src/system/libroot/posix/glibc/include/arch/x86_64/stackinfo.h new file mode 100644 index 0000000000..60668d10b1 --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/stackinfo.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +/* On x86_64 the stack grows down. */ +#define _STACK_GROWS_DOWN 1 + +#endif /* stackinfo.h */ diff --git a/src/system/libroot/posix/glibc/include/arch/x86_64/sysdep.h b/src/system/libroot/posix/glibc/include/arch/x86_64/sysdep.h new file mode 100644 index 0000000000..156632493b --- /dev/null +++ b/src/system/libroot/posix/glibc/include/arch/x86_64/sysdep.h @@ -0,0 +1,131 @@ +/* Assembler macros for x86-64. + Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include_next + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +#define cfi_startproc .cfi_startproc +#define cfi_endproc .cfi_endproc +#define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off +#define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg +#define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off +#define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off +#define cfi_offset(reg, off) .cfi_offset reg, off +#define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off +#define cfi_register(r1, r2) .cfi_register r1, r2 +#define cfi_return_column(reg) .cfi_return_column reg +#define cfi_restore(reg) .cfi_restore reg +#define cfi_same_value(reg) .cfi_same_value reg +#define cfi_undefined(reg) .cfi_undefined reg +#define cfi_remember_state .cfi_remember_state +#define cfi_restore_state .cfi_restore_state +#define cfi_window_save .cfi_window_save + +#ifdef HAVE_ELF + +/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ +#define ALIGNARG(log2) 1<, 1997. @@ -89,6 +89,86 @@ ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c. */ #endif + +#ifdef __x86_64__ + +/* sysdeps/x86_64/fpu/printf_fphex.c */ + +#ifndef LONG_DOUBLE_DENORM_BIAS +# define LONG_DOUBLE_DENORM_BIAS (IEEE854_LONG_DOUBLE_BIAS - 1) +#endif + +#define PRINT_FPHEX_LONG_DOUBLE \ +do { \ + /* The "strange" 80 bit format on ix86 and m68k has an explicit \ + leading digit in the 64 bit mantissa. */ \ + unsigned long long int num; \ + \ + \ + num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \ + | fpnum.ldbl.ieee.mantissa1); \ + \ + zero_mantissa = num == 0; \ + \ + if (sizeof (unsigned long int) > 6) \ + { \ + numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, \ + info->spec == 'A'); \ + wnumstr = _itowa_word (num, \ + wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\ + 16, info->spec == 'A'); \ + } \ + else \ + { \ + numstr = _itoa (num, numbuf + sizeof numbuf, 16, info->spec == 'A');\ + wnumstr = _itowa (num, \ + wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \ + 16, info->spec == 'A'); \ + } \ + \ + /* Fill with zeroes. */ \ + while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \ + { \ + *--numstr = '0'; \ + *--wnumstr = L'0'; \ + } \ + \ + /* We use a full nibble for the leading digit. */ \ + leading = *numstr++; \ + \ + /* We have 3 bits from the mantissa in the leading nibble. \ + Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \ + exponent = fpnum.ldbl.ieee.exponent; \ + \ + if (exponent == 0) \ + { \ + if (zero_mantissa) \ + expnegative = 0; \ + else \ + { \ + /* This is a denormalized number. */ \ + expnegative = 1; \ + /* This is a hook for the m68k long double format, where the \ + exponent bias is the same for normalized and denormalized \ + numbers. */ \ + exponent = LONG_DOUBLE_DENORM_BIAS + 3; \ + } \ + } \ + else if (exponent >= IEEE854_LONG_DOUBLE_BIAS + 3) \ + { \ + expnegative = 0; \ + exponent -= IEEE854_LONG_DOUBLE_BIAS + 3; \ + } \ + else \ + { \ + expnegative = 1; \ + exponent = -(exponent - (IEEE854_LONG_DOUBLE_BIAS + 3)); \ + } \ +} while (0) + +#endif /* __x86_64__ */ + + int __printf_fphex (FILE *fp, const struct printf_info *info, @@ -338,8 +418,8 @@ __printf_fphex (FILE *fp, /* Look for trailing zeroes. */ if (! zero_mantissa) { - wnumend = wnumbuf + sizeof wnumbuf; - numend = numbuf + sizeof numbuf; + wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]]; + numend = &numbuf[sizeof numbuf / sizeof numbuf[0]]; while (wnumend[-1] == L'0') { --wnumend; @@ -399,12 +479,15 @@ __printf_fphex (FILE *fp, ++leading; else { - leading = 1; + leading = '1'; if (expnegative) { - exponent += 4; - if (exponent >= 0) - expnegative = 0; + exponent -= 4; + if (exponent <= 0) + { + exponent = -exponent; + expnegative = 0; + } } else exponent += 4; @@ -433,17 +516,13 @@ __printf_fphex (FILE *fp, + ((expbuf + sizeof expbuf) - expstr)); /* Exponent. */ - /* Count the decimal point. */ + /* Count the decimal point. + A special case when the mantissa or the precision is zero and the `#' + is not given. In this case we must not print the decimal point. */ if (precision > 0 || info->alt) width -= wide ? 1 : strlen (decimal); - /* A special case when the mantissa or the precision is zero and the `#' - is not given. In this case we must not print the decimal point. */ - if (precision == 0 && !info->alt) - ++width; /* This nihilates the +1 for the decimal-point - character in the following equation. */ - - if (!info->left && width > 0) + if (!info->left && info->pad != '0' && width > 0) PADN (' ', width); if (negative) @@ -458,6 +537,10 @@ __printf_fphex (FILE *fp, outchar (info->spec + ('x' - 'a')); else outchar (info->spec == 'A' ? 'X' : 'x'); + + if (!info->left && info->pad == '0' && width > 0) + PADN ('0', width); + outchar (leading); if (precision > 0 || info->alt) @@ -474,9 +557,6 @@ __printf_fphex (FILE *fp, PADN ('0', tofill); } - if (info->left && info->pad == '0' && width > 0) - PADN ('0', width); - if ('P' - 'A' == 'p' - 'a') outchar (info->spec + ('p' - 'a')); else diff --git a/src/system/libroot/posix/glibc/stdlib/jrand48_r.c b/src/system/libroot/posix/glibc/stdlib/jrand48_r.c index 2383ae129e..39e8d090a6 100644 --- a/src/system/libroot/posix/glibc/stdlib/jrand48_r.c +++ b/src/system/libroot/posix/glibc/stdlib/jrand48_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1997, 1998, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1997, 1998, 2001, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , August 1995. @@ -30,7 +30,7 @@ __jrand48_r (xsubi, buffer, result) return -1; /* Store the result. */ - *result = ((xsubi[2] << 16) | xsubi[1]) & 0xffffffffl; + *result = (int32_t) ((xsubi[2] << 16) | xsubi[1]); return 0; } diff --git a/src/system/libroot/posix/malloc/arch-specific.cpp b/src/system/libroot/posix/malloc/arch-specific.cpp index 8cb1f6723b..0bcaac8fcd 100644 --- a/src/system/libroot/posix/malloc/arch-specific.cpp +++ b/src/system/libroot/posix/malloc/arch-specific.cpp @@ -58,8 +58,13 @@ static const size_t kInitialHeapSize = 64 * B_PAGE_SIZE; static const size_t kHeapIncrement = 16 * B_PAGE_SIZE; // the steps in which to increase the heap size (must be a power of 2) +#if B_HAIKU_64_BIT +static const addr_t kHeapReservationBase = 0x1000000000; +static const addr_t kHeapReservationSize = 0x1000000000; +#else static const addr_t kHeapReservationBase = 0x18000000; static const addr_t kHeapReservationSize = 0x48000000; +#endif static area_id sHeapArea; static hoardLockType sHeapLock; @@ -76,8 +81,9 @@ init_after_fork(void) sHeapArea = area_for((void*)sFreeHeapBase); if (sHeapArea < 0) { // Where is it gone? - debug_printf("hoard: init_after_fork(): thread %ld, Heap area not " - "found! Base address: %p\n", find_thread(NULL), sHeapBase); + debug_printf("hoard: init_after_fork(): thread %" B_PRId32 ", Heap " + "area not found! Base address: %p\n", find_thread(NULL), + sHeapBase); exit(1); } } @@ -179,7 +185,7 @@ hoardSbrk(long size) if (chunk->size > (size_t)size + sizeof(free_chunk)) { // divide this chunk into smaller bits - uint32 newSize = chunk->size - size; + size_t newSize = chunk->size - size; free_chunk *next = chunk->next; chunk = (free_chunk *)((addr_t)chunk + size); diff --git a/src/system/libroot/posix/malloc/superblock.cpp b/src/system/libroot/posix/malloc/superblock.cpp index 05b6bc4380..5114ad8264 100644 --- a/src/system/libroot/posix/malloc/superblock.cpp +++ b/src/system/libroot/posix/malloc/superblock.cpp @@ -67,7 +67,7 @@ superblock::superblock(int numBlocks, // The number of blocks in the sb. // and insert the block pointers into the linked list. for (int i = 0; i < _numBlocks; i++) { // Make sure the block is on a double-word boundary. - assert(((unsigned int)b & hoardHeap::ALIGNMENT_MASK) == 0); + assert(((unsigned long)b & hoardHeap::ALIGNMENT_MASK) == 0); new(b) block(this); assert(b->getSuperblock() == this); b->setNext(_freeList); diff --git a/src/system/libroot/posix/malloc_debug/heap.cpp b/src/system/libroot/posix/malloc_debug/heap.cpp index 0753f674ec..074cada0e0 100644 --- a/src/system/libroot/posix/malloc_debug/heap.cpp +++ b/src/system/libroot/posix/malloc_debug/heap.cpp @@ -204,15 +204,16 @@ dump_page(heap_page *page) count++; printf("\t\tpage %p: bin_index: %u; free_count: %u; empty_index: %u; " - "free_list %p (%lu entr%s)\n", page, page->bin_index, page->free_count, - page->empty_index, page->free_list, count, count == 1 ? "y" : "ies"); + "free_list %p (%" B_PRIu32 " entr%s)\n", page, page->bin_index, + page->free_count, page->empty_index, page->free_list, count, + count == 1 ? "y" : "ies"); } static void dump_bin(heap_bin *bin) { - printf("\telement_size: %lu; max_free_count: %u; page_list %p;\n", + printf("\telement_size: %" B_PRIu32 "; max_free_count: %u; page_list %p;\n", bin->element_size, bin->max_free_count, bin->page_list); for (heap_page *temp = bin->page_list; temp != NULL; temp = temp->next) @@ -234,10 +235,11 @@ dump_allocator_areas(heap_allocator *heap) { heap_area *area = heap->all_areas; while (area) { - printf("\tarea %p: area: %ld; base: 0x%08lx; size: %lu; page_count: " - "%lu; free_pages: %p (%lu entr%s)\n", area, area->area, area->base, - area->size, area->page_count, area->free_pages, - area->free_page_count, area->free_page_count == 1 ? "y" : "ies"); + printf("\tarea %p: area: %" B_PRId32 "; base: 0x%08lx; size: %lu; " + "page_count: %" B_PRIu32 "; free_pages: %p (%" B_PRIu32 " entr%s)\n", + area, area->area, area->base, area->size, area->page_count, + area->free_pages, area->free_page_count, + area->free_page_count == 1 ? "y" : "ies"); area = area->all_next; } @@ -248,10 +250,11 @@ dump_allocator_areas(heap_allocator *heap) static void dump_allocator(heap_allocator *heap, bool areas, bool bins) { - printf("allocator %p: name: %s; page_size: %lu; bin_count: %lu; pages: " - "%lu; free_pages: %lu; empty_areas: %lu\n", heap, heap->name, - heap->page_size, heap->bin_count, heap->total_pages, - heap->total_free_pages, heap->empty_areas); + printf("allocator %p: name: %s; page_size: %" B_PRIu32 "; bin_count: %" + B_PRIu32 "; pages: %" B_PRIu32 "; free_pages: %" B_PRIu32 "; " + "empty_areas: %" B_PRIu32 "\n", heap, heap->name, heap->page_size, + heap->bin_count, heap->total_pages, heap->total_free_pages, + heap->empty_areas); if (areas) dump_allocator_areas(heap); @@ -304,8 +307,8 @@ dump_allocations(bool statsOnly, thread_id thread) if (thread == -1 || info->thread == thread) { // interesting... if (!statsOnly) { - printf("thread: % 6ld; address: 0x%08lx;" - " size: %lu bytes\n", info->thread, + printf("thread: % 6" B_PRId32 "; address: " + "0x%08lx; size: %lu bytes\n", info->thread, base, info->size); } @@ -330,7 +333,7 @@ dump_allocations(bool statsOnly, thread_id thread) if (thread == -1 || info->thread == thread) { // interesting... if (!statsOnly) { - printf("thread: % 6ld; address: 0x%08lx;" + printf("thread: % 6" B_PRId32 "; address: 0x%08lx;" " size: %lu bytes\n", info->thread, base, info->size); } @@ -348,7 +351,8 @@ dump_allocations(bool statsOnly, thread_id thread) } } - printf("total allocations: %lu; total bytes: %lu\n", totalCount, totalSize); + printf("total allocations: %" B_PRIu32 "; total bytes: %lu\n", totalCount, + totalSize); } @@ -1618,7 +1622,7 @@ heap_create_new_heap_area(heap_allocator *heap, const char *name, size_t size) static int32 heap_wall_checker(void *data) { - int msInterval = (int32)data; + int msInterval = (addr_t)data; while (!sStopWallChecking) { heap_validate_walls(); snooze(msInterval * 1000); @@ -1636,7 +1640,7 @@ heap_debug_start_wall_checking(int msInterval) { if (sWallCheckThread < 0) { sWallCheckThread = spawn_thread(heap_wall_checker, "heap wall checker", - B_LOW_PRIORITY, (void *)msInterval); + B_LOW_PRIORITY, (void *)(addr_t)msInterval); } if (sWallCheckThread < 0) diff --git a/src/system/libroot/posix/stdlib/pty.cpp b/src/system/libroot/posix/stdlib/pty.cpp index 2da52c50d6..78c43bcb99 100644 --- a/src/system/libroot/posix/stdlib/pty.cpp +++ b/src/system/libroot/posix/stdlib/pty.cpp @@ -37,8 +37,8 @@ ptsname(int masterFD) static char buffer[32]; char letter = 'p'; - snprintf(buffer, sizeof(buffer), "/dev/tt/%c%lx", char(letter + index / 16), - index % 16); + snprintf(buffer, sizeof(buffer), "/dev/tt/%c%" B_PRIx32, + char(letter + index / 16), index % 16); return buffer; } diff --git a/src/system/libroot/posix/stdlib/strtod.c b/src/system/libroot/posix/stdlib/strtod.c index 9ff1b400f6..1dc2e54dd3 100644 --- a/src/system/libroot/posix/stdlib/strtod.c +++ b/src/system/libroot/posix/stdlib/strtod.c @@ -126,7 +126,8 @@ #if defined(__i386__) || defined(__ia64__) || defined(__alpha__) || \ defined(__sparc64__) || defined(__powerpc__) || defined(__POWERPC__) || \ defined(__m68k__) || defined(__M68K__) || defined(__arm__) || \ - defined(__ARM__) || defined(__mipsel__) || defined(__MIPSEL__) + defined(__ARM__) || defined(__mipsel__) || defined(__MIPSEL__) || \ + defined(__x86_64__) # include # if BYTE_ORDER == BIG_ENDIAN # define IEEE_BIG_ENDIAN diff --git a/src/system/libroot/posix/string/arch/x86_64/Jamfile b/src/system/libroot/posix/string/arch/x86_64/Jamfile new file mode 100644 index 0000000000..1c3ac217c0 --- /dev/null +++ b/src/system/libroot/posix/string/arch/x86_64/Jamfile @@ -0,0 +1,8 @@ +SubDir HAIKU_TOP src system libroot posix string arch x86_64 ; + +UsePrivateSystemHeaders ; + +MergeObject posix_string_arch_$(TARGET_ARCH).o : + arch_string.S +; + diff --git a/src/system/libroot/posix/string/arch/x86_64/arch_string.S b/src/system/libroot/posix/string/arch/x86_64/arch_string.S new file mode 100644 index 0000000000..8bbadb31ca --- /dev/null +++ b/src/system/libroot/posix/string/arch/x86_64/arch_string.S @@ -0,0 +1,17 @@ +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include +#include + + +FUNCTION(memcpy): + jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMCPY * 8) +FUNCTION_END(memcpy) + + +FUNCTION(memset): + jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_X86_MEMSET * 8) +FUNCTION_END(memset) diff --git a/src/system/libroot/posix/sys/uname.c b/src/system/libroot/posix/sys/uname.c index 717f009fd0..120a95157d 100644 --- a/src/system/libroot/posix/sys/uname.c +++ b/src/system/libroot/posix/sys/uname.c @@ -41,7 +41,7 @@ uname(struct utsname *info) strlcat(info->version, systemInfo.kernel_build_date, sizeof(info->version)); strlcat(info->version, " ", sizeof(info->version)); strlcat(info->version, systemInfo.kernel_build_time, sizeof(info->version)); - snprintf(info->release, sizeof(info->release), "%lld", + snprintf(info->release, sizeof(info->release), "%" B_PRId64, systemInfo.kernel_version); // TODO: make this better @@ -55,6 +55,9 @@ uname(struct utsname *info) case B_AT_CLONE_PLATFORM: platform = "BePC"; break; + case B_64_BIT_PC_PLATFORM: + platform = "x86_64"; + break; default: platform = "unknown"; break; diff --git a/src/system/libroot/posix/syslog.cpp b/src/system/libroot/posix/syslog.cpp index 7ed66d97de..97d5b3c08f 100644 --- a/src/system/libroot/posix/syslog.cpp +++ b/src/system/libroot/posix/syslog.cpp @@ -95,7 +95,7 @@ message_to_console(syslog_context *context, const char *text, va_list args) if (context->ident[0]) fprintf(stderr, "'%s' ", context->ident); if (context->options & LOG_PID) - fprintf(stderr, "[%ld] ", find_thread(NULL)); + fprintf(stderr, "[%" B_PRId32 "] ", find_thread(NULL)); vfprintf(stderr, text, args); fputc('\n', stderr); diff --git a/src/system/runtime_loader/arch/x86_64/Jamfile b/src/system/runtime_loader/arch/x86_64/Jamfile new file mode 100644 index 0000000000..a894a0c1b5 --- /dev/null +++ b/src/system/runtime_loader/arch/x86_64/Jamfile @@ -0,0 +1,14 @@ +SubDir HAIKU_TOP src system runtime_loader arch x86_64 ; + +UsePrivateHeaders runtime_loader ; +UsePrivateSystemHeaders ; + +SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; + +StaticLibrary libruntime_loader_$(TARGET_ARCH).a : + arch_relocate.cpp + : + atomic.o + thread.o + arch_string.o +; diff --git a/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp b/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp new file mode 100644 index 0000000000..7148c2e23f --- /dev/null +++ b/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include "runtime_loader_private.h" + +#include + +#include +#include +#include + + +static status_t +relocate_rela(image_t* rootImage, image_t* image, Elf64_Rela* rel, + size_t relLength, SymbolLookupCache* cache) +{ + for (size_t i = 0; i < relLength / sizeof(Elf64_Rela); i++) { + int type = ELF64_R_TYPE(rel[i].r_info); + int symIndex = ELF64_R_SYM(rel[i].r_info); + Elf64_Addr symAddr = 0; + + // Resolve the symbol, if any. + if (symIndex != 0) { + Elf64_Sym* sym = SYMBOL(image, symIndex); + + status_t status = resolve_symbol(rootImage, image, sym, cache, + &symAddr); + if (status != B_OK) { + TRACE(("resolve symbol \"%s\" returned: %" B_PRId32 "\n", + SYMNAME(image, sym), status)); + printf("resolve symbol \"%s\" returned: %" B_PRId32 "\n", + SYMNAME(image, sym), status); + return status; + } + } + + // Address of the relocation. + Elf64_Addr relocAddr = image->regions[0].delta + rel[i].r_offset; + + // Calculate the relocation value. + Elf64_Addr relocValue; + switch(type) { + case R_X86_64_NONE: + continue; + case R_X86_64_64: + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: + relocValue = symAddr + rel[i].r_addend; + break; + case R_X86_64_PC32: + relocValue = symAddr + rel[i].r_addend - rel[i].r_offset; + break; + case R_X86_64_RELATIVE: + relocValue = image->regions[0].delta + rel[i].r_addend; + break; + default: + TRACE(("unhandled relocation type %d\n", type)); + return B_BAD_DATA; + } + + *(Elf64_Addr *)relocAddr = relocValue; + } + + return B_OK; +} + + +status_t +arch_relocate_image(image_t* rootImage, image_t* image, + SymbolLookupCache* cache) +{ + status_t status; + + // No REL on x86_64. + + // Perform RELA relocations. + if (image->rela) { + status = relocate_rela(rootImage, image, image->rela, image->rela_len, + cache); + if (status != B_OK) + return status; + } + + // PLT relocations (they are RELA on x86_64). + if (image->pltrel) { + status = relocate_rela(rootImage, image, (Elf64_Rela*)image->pltrel, + image->pltrel_len, cache); + if (status != B_OK) + return status; + } + + return B_OK; +} diff --git a/src/system/runtime_loader/elf.cpp b/src/system/runtime_loader/elf.cpp index 5d3c880d4a..9415d73b55 100644 --- a/src/system/runtime_loader/elf.cpp +++ b/src/system/runtime_loader/elf.cpp @@ -18,7 +18,6 @@ #include -#include #include #include @@ -70,7 +69,7 @@ static const char * find_dt_rpath(image_t *image) { int i; - struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr; + elf_dyn *d = (elf_dyn *)image->dynamic_ptr; for (i = 0; d[i].d_tag != DT_NULL; i++) { if (d[i].d_tag == DT_RPATH) @@ -84,7 +83,7 @@ find_dt_rpath(image_t *image) static status_t load_immediate_dependencies(image_t *image) { - struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr; + elf_dyn *d = (elf_dyn *)image->dynamic_ptr; bool reportErrors = report_errors(); status_t status = B_OK; uint32 i, j; @@ -670,7 +669,7 @@ get_nth_symbol(image_id imageID, int32 num, char *nameBuffer, // iterate through all the hash buckets until we've found the one for (i = 0; i < HASHTABSIZE(image); i++) { for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) { - struct Elf32_Sym *symbol = &image->syms[j]; + elf_sym *symbol = &image->syms[j]; if (count == num) { const char* symbolName = SYMNAME(image, symbol); @@ -680,9 +679,9 @@ get_nth_symbol(image_id imageID, int32 num, char *nameBuffer, void* location = (void*)(symbol->st_value + image->regions[0].delta); int32 type; - if (ELF32_ST_TYPE(symbol->st_info) == STT_FUNC) + if (symbol->Type() == STT_FUNC) type = B_SYMBOL_TYPE_TEXT; - else if (ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT) + else if (symbol->Type() == STT_OBJECT) type = B_SYMBOL_TYPE_DATA; else type = B_SYMBOL_TYPE_ANY; @@ -721,14 +720,14 @@ get_nearest_symbol_at_address(void* address, image_id* _imageID, return B_BAD_VALUE; } - struct Elf32_Sym* foundSymbol = NULL; + elf_sym* foundSymbol = NULL; addr_t foundLocation = (addr_t)NULL; bool found = false; for (uint32 i = 0; i < HASHTABSIZE(image) && !found; i++) { for (int32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) { - struct Elf32_Sym *symbol = &image->syms[j]; + elf_sym *symbol = &image->syms[j]; addr_t location = symbol->st_value + image->regions[0].delta; if (location <= (addr_t)address && location >= foundLocation) { @@ -753,9 +752,9 @@ get_nearest_symbol_at_address(void* address, image_id* _imageID, *_symbolName = SYMNAME(image, foundSymbol); if (_type != NULL) { - if (ELF32_ST_TYPE(foundSymbol->st_info) == STT_FUNC) + if (foundSymbol->Type() == STT_FUNC) *_type = B_SYMBOL_TYPE_TEXT; - else if (ELF32_ST_TYPE(foundSymbol->st_info) == STT_OBJECT) + else if (foundSymbol->Type() == STT_OBJECT) *_type = B_SYMBOL_TYPE_DATA; else *_type = B_SYMBOL_TYPE_ANY; @@ -831,14 +830,14 @@ get_library_symbol(void* handle, void* caller, const char* symbolName, if (handle == RTLD_DEFAULT || handle == RLD_GLOBAL_SCOPE) { // look in the default scope image_t* image; - Elf32_Sym* symbol = find_undefined_symbol_global(gProgramImage, + elf_sym* symbol = find_undefined_symbol_global(gProgramImage, gProgramImage, SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_ANY, NULL, LOOKUP_FLAG_DEFAULT_VERSION), &image); if (symbol != NULL) { *_location = (void*)(symbol->st_value + image->regions[0].delta); - int32 symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC + int32 symbolType = symbol->Type() == STT_FUNC ? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA; patch_defined_symbol(image, symbolName, _location, &symbolType); status = B_OK; @@ -864,7 +863,7 @@ get_library_symbol(void* handle, void* caller, const char* symbolName, bool hitCallerImage = false; set_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING); - Elf32_Sym* candidateSymbol = NULL; + elf_sym* candidateSymbol = NULL; image_t* candidateImage = NULL; image_t* image = get_loaded_images().head; @@ -883,14 +882,14 @@ get_library_symbol(void* handle, void* caller, const char* symbolName, continue; } - struct Elf32_Sym *symbol = find_symbol(image, + elf_sym *symbol = find_symbol(image, SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_TEXT, NULL, LOOKUP_FLAG_DEFAULT_VERSION)); if (symbol == NULL) continue; // found a symbol - bool isWeak = ELF32_ST_BIND(symbol->st_info) == STB_WEAK; + bool isWeak = symbol->Bind() == STB_WEAK; if (candidateImage == NULL || !isWeak) { candidateSymbol = symbol; candidateImage = image; @@ -932,7 +931,7 @@ status_t get_next_image_dependency(image_id id, uint32 *cookie, const char **_name) { uint32 i, j, searchIndex = *cookie; - struct Elf32_Dyn *dynamicSection; + elf_dyn *dynamicSection; image_t *image; if (_name == NULL) @@ -946,7 +945,7 @@ get_next_image_dependency(image_id id, uint32 *cookie, const char **_name) return B_BAD_IMAGE_ID; } - dynamicSection = (struct Elf32_Dyn *)image->dynamic_ptr; + dynamicSection = (elf_dyn *)image->dynamic_ptr; if (dynamicSection == NULL || image->num_needed <= searchIndex) { rld_unlock(); return B_ENTRY_NOT_FOUND; @@ -976,15 +975,14 @@ get_next_image_dependency(image_id id, uint32 *cookie, const char **_name) /*! Read and verify the ELF header */ status_t -elf_verify_header(void *header, int32 length) +elf_verify_header(void *header, size_t length) { int32 programSize, sectionSize; - if (length < (int32)sizeof(struct Elf32_Ehdr)) + if (length < sizeof(elf_ehdr)) return B_NOT_AN_EXECUTABLE; - return parse_elf_header((struct Elf32_Ehdr *)header, &programSize, - §ionSize); + return parse_elf_header((elf_ehdr *)header, &programSize, §ionSize); } @@ -1029,7 +1027,7 @@ rldelf_init(void) // create the debug area { - int32 size = TO_PAGE_SIZE(sizeof(runtime_loader_debug_area)); + size_t size = TO_PAGE_SIZE(sizeof(runtime_loader_debug_area)); runtime_loader_debug_area *area; area_id areaID = _kern_create_area(RUNTIME_LOADER_DEBUG_AREA_NAME, diff --git a/src/system/runtime_loader/elf_haiku_version.cpp b/src/system/runtime_loader/elf_haiku_version.cpp index 0646eb850f..75c01c8abe 100644 --- a/src/system/runtime_loader/elf_haiku_version.cpp +++ b/src/system/runtime_loader/elf_haiku_version.cpp @@ -20,7 +20,7 @@ static bool -analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader, +analyze_object_gcc_version(int fd, image_t* image, elf_ehdr& eheader, int32 sheaderSize, char* buffer, size_t bufferSize) { if (sheaderSize > (int)bufferSize) { @@ -38,8 +38,8 @@ analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader, } // load the string section - Elf32_Shdr* sectionHeader - = (Elf32_Shdr*)(buffer + eheader.e_shstrndx * eheader.e_shentsize); + elf_shdr* sectionHeader + = (elf_shdr*)(buffer + eheader.e_shstrndx * eheader.e_shentsize); if (sheaderSize + sectionHeader->sh_size > bufferSize) { FATAL("%s: Buffer not big enough for section string section\n", @@ -60,7 +60,7 @@ analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader, off_t commentOffset = 0; size_t commentSize = 0; for (uint32 i = 0; i < eheader.e_shnum; i++) { - sectionHeader = (Elf32_Shdr*)(buffer + i * eheader.e_shentsize); + sectionHeader = (elf_shdr*)(buffer + i * eheader.e_shentsize); const char* sectionName = sectionStrings + sectionHeader->sh_name; if (sectionHeader->sh_name != 0 && strcmp(sectionName, ".comment") == 0) { @@ -189,16 +189,16 @@ analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader, void -analyze_image_haiku_version_and_abi(int fd, image_t* image, Elf32_Ehdr& eheader, +analyze_image_haiku_version_and_abi(int fd, image_t* image, elf_ehdr& eheader, int32 sheaderSize, char* buffer, size_t bufferSize) { // Haiku API version - struct Elf32_Sym* symbol = find_symbol(image, + elf_sym* symbol = find_symbol(image, SymbolLookupInfo(B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME, B_SYMBOL_TYPE_DATA)); if (symbol != NULL && symbol->st_shndx != SHN_UNDEF && symbol->st_value > 0 - && ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT + && symbol->Type() == STT_OBJECT && symbol->st_size >= sizeof(uint32)) { image->api_version = *(uint32*)(symbol->st_value + image->regions[0].delta); @@ -211,7 +211,7 @@ analyze_image_haiku_version_and_abi(int fd, image_t* image, Elf32_Ehdr& eheader, B_SYMBOL_TYPE_DATA)); if (symbol != NULL && symbol->st_shndx != SHN_UNDEF && symbol->st_value > 0 - && ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT + && symbol->Type() == STT_OBJECT && symbol->st_size >= sizeof(uint32)) { image->abi = *(uint32*)(symbol->st_value + image->regions[0].delta); } else diff --git a/src/system/runtime_loader/elf_haiku_version.h b/src/system/runtime_loader/elf_haiku_version.h index 4c8353df4a..a24cc6055b 100644 --- a/src/system/runtime_loader/elf_haiku_version.h +++ b/src/system/runtime_loader/elf_haiku_version.h @@ -9,7 +9,7 @@ void analyze_image_haiku_version_and_abi(int fd, image_t* image, - Elf32_Ehdr& eheader, int32 sheaderSize, char* buffer, + elf_ehdr& eheader, int32 sheaderSize, char* buffer, size_t bufferSize); diff --git a/src/system/runtime_loader/elf_load_image.cpp b/src/system/runtime_loader/elf_load_image.cpp index d8286cea72..2ccabe46a9 100644 --- a/src/system/runtime_loader/elf_load_image.cpp +++ b/src/system/runtime_loader/elf_load_image.cpp @@ -36,12 +36,12 @@ get_program_path() static int32 count_regions(const char* imagePath, char const* buff, int phnum, int phentsize) { - struct Elf32_Phdr* pheaders; + elf_phdr* pheaders; int32 count = 0; int i; for (i = 0; i < phnum; i++) { - pheaders = (struct Elf32_Phdr*)(buff + i * phentsize); + pheaders = (elf_phdr*)(buff + i * phentsize); switch (pheaders->p_type) { case PT_NULL: @@ -78,7 +78,7 @@ count_regions(const char* imagePath, char const* buff, int phnum, int phentsize) // we don't use it break; default: - FATAL("%s: Unhandled pheader type in count 0x%lx\n", + FATAL("%s: Unhandled pheader type in count 0x%" B_PRIx32 "\n", imagePath, pheaders->p_type); break; } @@ -91,13 +91,13 @@ count_regions(const char* imagePath, char const* buff, int phnum, int phentsize) static status_t parse_program_headers(image_t* image, char* buff, int phnum, int phentsize) { - struct Elf32_Phdr* pheader; + elf_phdr* pheader; int regcount; int i; regcount = 0; for (i = 0; i < phnum; i++) { - pheader = (struct Elf32_Phdr*)(buff + i * phentsize); + pheader = (elf_phdr*)(buff + i * phentsize); switch (pheader->p_type) { case PT_NULL: @@ -194,7 +194,7 @@ parse_program_headers(image_t* image, char* buff, int phnum, int phentsize) // we don't use it break; default: - FATAL("%s: Unhandled pheader type in parse 0x%lx\n", + FATAL("%s: Unhandled pheader type in parse 0x%" B_PRIx32 "\n", image->path, pheader->p_type); return B_BAD_DATA; } @@ -227,7 +227,7 @@ assert_dynamic_loadable(image_t* image) static bool parse_dynamic_segment(image_t* image) { - struct Elf32_Dyn* d; + elf_dyn* d; int i; int sonameOffset = -1; @@ -235,7 +235,7 @@ parse_dynamic_segment(image_t* image) image->syms = 0; image->strtab = 0; - d = (struct Elf32_Dyn*)image->dynamic_ptr; + d = (elf_dyn*)image->dynamic_ptr; if (!d) return true; @@ -253,18 +253,18 @@ parse_dynamic_segment(image_t* image) = (char*)(d[i].d_un.d_ptr + image->regions[0].delta); break; case DT_SYMTAB: - image->syms = (struct Elf32_Sym*) + image->syms = (elf_sym*) (d[i].d_un.d_ptr + image->regions[0].delta); break; case DT_REL: - image->rel = (struct Elf32_Rel*) + image->rel = (elf_rel*) (d[i].d_un.d_ptr + image->regions[0].delta); break; case DT_RELSZ: image->rel_len = d[i].d_un.d_val; break; case DT_RELA: - image->rela = (struct Elf32_Rela*) + image->rela = (elf_rela*) (d[i].d_un.d_ptr + image->regions[0].delta); break; case DT_RELASZ: @@ -272,7 +272,7 @@ parse_dynamic_segment(image_t* image) break; case DT_JMPREL: // procedure linkage table relocations - image->pltrel = (struct Elf32_Rel*) + image->pltrel = (elf_rel*) (d[i].d_un.d_ptr + image->regions[0].delta); break; case DT_PLTRELSZ: @@ -290,18 +290,18 @@ parse_dynamic_segment(image_t* image) sonameOffset = d[i].d_un.d_val; break; case DT_VERSYM: - image->symbol_versions = (Elf32_Versym*) + image->symbol_versions = (elf_versym*) (d[i].d_un.d_ptr + image->regions[0].delta); break; case DT_VERDEF: - image->version_definitions = (Elf32_Verdef*) + image->version_definitions = (elf_verdef*) (d[i].d_un.d_ptr + image->regions[0].delta); break; case DT_VERDEFNUM: image->num_version_definitions = d[i].d_un.d_val; break; case DT_VERNEED: - image->needed_versions = (Elf32_Verneed*) + image->needed_versions = (elf_verneed*) (d[i].d_un.d_ptr + image->regions[0].delta); break; case DT_VERNEEDNUM: @@ -350,19 +350,19 @@ parse_dynamic_segment(image_t* image) status_t -parse_elf_header(struct Elf32_Ehdr* eheader, int32* _pheaderSize, +parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize, int32* _sheaderSize) { if (memcmp(eheader->e_ident, ELF_MAGIC, 4) != 0) return B_NOT_AN_EXECUTABLE; - if (eheader->e_ident[4] != ELFCLASS32) + if (eheader->e_ident[4] != ELF_CLASS) return B_NOT_AN_EXECUTABLE; if (eheader->e_phoff == 0) return B_NOT_AN_EXECUTABLE; - if (eheader->e_phentsize < sizeof(struct Elf32_Phdr)) + if (eheader->e_phentsize < sizeof(elf_phdr)) return B_NOT_AN_EXECUTABLE; *_pheaderSize = eheader->e_phentsize * eheader->e_phnum; @@ -389,7 +389,7 @@ load_image(char const* name, image_type type, const char* rpath, status_t status; int fd; - struct Elf32_Ehdr eheader; + elf_ehdr eheader; // Have we already loaded that image? Don't check for add-ons -- we always // reload them. @@ -480,8 +480,8 @@ load_image(char const* name, image_type type, const char* rpath, numRegions = count_regions(path, pheaderBuffer, eheader.e_phnum, eheader.e_phentsize); if (numRegions <= 0) { - FATAL("%s: Troubles parsing Program headers, numRegions = %ld\n", - path, numRegions); + FATAL("%s: Troubles parsing Program headers, numRegions = %" B_PRId32 + "\n", path, numRegions); status = B_BAD_DATA; goto err1; } diff --git a/src/system/runtime_loader/elf_load_image.h b/src/system/runtime_loader/elf_load_image.h index 3fec7ec485..e7c4e23367 100644 --- a/src/system/runtime_loader/elf_load_image.h +++ b/src/system/runtime_loader/elf_load_image.h @@ -8,7 +8,7 @@ #include "runtime_loader_private.h" -status_t parse_elf_header(struct Elf32_Ehdr* eheader, int32* _pheaderSize, +status_t parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize, int32* _sheaderSize); status_t load_image(char const* name, image_type type, const char* rpath, image_t** _image); diff --git a/src/system/runtime_loader/elf_symbol_lookup.cpp b/src/system/runtime_loader/elf_symbol_lookup.cpp index b2f6d16a04..1983197dc2 100644 --- a/src/system/runtime_loader/elf_symbol_lookup.cpp +++ b/src/system/runtime_loader/elf_symbol_lookup.cpp @@ -93,28 +93,28 @@ patch_undefined_symbol(image_t* rootImage, image_t* image, const char* name, } -Elf32_Sym* +elf_sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo) { if (image->dynamic_ptr == 0) return NULL; - Elf32_Sym* versionedSymbol = NULL; + elf_sym* versionedSymbol = NULL; uint32 versionedSymbolCount = 0; uint32 bucket = lookupInfo.hash % HASHTABSIZE(image); for (uint32 i = HASHBUCKETS(image)[bucket]; i != STN_UNDEF; i = HASHCHAINS(image)[i]) { - Elf32_Sym* symbol = &image->syms[i]; + elf_sym* symbol = &image->syms[i]; if (symbol->st_shndx != SHN_UNDEF - && ((ELF32_ST_BIND(symbol->st_info) == STB_GLOBAL) - || (ELF32_ST_BIND(symbol->st_info) == STB_WEAK)) + && ((symbol->Bind() == STB_GLOBAL) + || (symbol->Bind() == STB_WEAK)) && !strcmp(SYMNAME(image, symbol), lookupInfo.name)) { // check if the type matches - uint32 type = ELF32_ST_TYPE(symbol->st_info); + uint32 type = symbol->Type(); if ((lookupInfo.type == B_SYMBOL_TYPE_TEXT && type != STT_FUNC) || (lookupInfo.type == B_SYMBOL_TYPE_DATA && type != STT_OBJECT)) { @@ -219,7 +219,7 @@ find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo, void **_location) { // get the symbol in the image - Elf32_Sym* symbol = find_symbol(image, lookupInfo); + elf_sym* symbol = find_symbol(image, lookupInfo); if (symbol == NULL) return B_ENTRY_NOT_FOUND; @@ -244,16 +244,16 @@ find_symbol_breadth_first(image_t* image, const SymbolLookupInfo& lookupInfo, queue[count++] = image; image->flags |= RFLAG_VISITED; - Elf32_Sym* candidateSymbol = NULL; + elf_sym* candidateSymbol = NULL; image_t* candidateImage = NULL; while (index < count) { // pop next image image = queue[index++]; - Elf32_Sym* symbol = find_symbol(image, lookupInfo); + elf_sym* symbol = find_symbol(image, lookupInfo); if (symbol != NULL) { - bool isWeak = ELF32_ST_BIND(symbol->st_info) == STB_WEAK; + bool isWeak = symbol->Bind() == STB_WEAK; if (candidateImage == NULL || !isWeak) { candidateSymbol = symbol; candidateImage = image; @@ -294,7 +294,7 @@ find_symbol_breadth_first(image_t* image, const SymbolLookupInfo& lookupInfo, } -Elf32_Sym* +elf_sym* find_undefined_symbol_beos(image_t* rootImage, image_t* image, const SymbolLookupInfo& lookupInfo, image_t** foundInImage) { @@ -303,17 +303,17 @@ find_undefined_symbol_beos(image_t* rootImage, image_t* image, // symbol wasn't there. First we check whether the requesting symbol is // defined already -- then we can simply return it, since, due to symbolic // linking, that's the one we'd find anyway. - if (Elf32_Sym* symbol = lookupInfo.requestingSymbol) { + if (elf_sym* symbol = lookupInfo.requestingSymbol) { if (symbol->st_shndx != SHN_UNDEF - && ((ELF32_ST_BIND(symbol->st_info) == STB_GLOBAL) - || (ELF32_ST_BIND(symbol->st_info) == STB_WEAK))) { + && ((symbol->Bind() == STB_GLOBAL) + || (symbol->Bind() == STB_WEAK))) { *foundInImage = image; return symbol; } } // lookup in image - Elf32_Sym* symbol = find_symbol(image, lookupInfo); + elf_sym* symbol = find_symbol(image, lookupInfo); if (symbol != NULL) { *foundInImage = image; return symbol; @@ -334,7 +334,7 @@ find_undefined_symbol_beos(image_t* rootImage, image_t* image, } -Elf32_Sym* +elf_sym* find_undefined_symbol_global(image_t* rootImage, image_t* image, const SymbolLookupInfo& lookupInfo, image_t** _foundInImage) { @@ -342,7 +342,7 @@ find_undefined_symbol_global(image_t* rootImage, image_t* image, // the symbol in the order they have been loaded. We skip add-on images and // RTLD_LOCAL images though. image_t* candidateImage = NULL; - Elf32_Sym* candidateSymbol = NULL; + elf_sym* candidateSymbol = NULL; // If the requesting image is linked symbolically, look up the symbol there // first. @@ -350,7 +350,7 @@ find_undefined_symbol_global(image_t* rootImage, image_t* image, if (symbolic) { candidateSymbol = find_symbol(image, lookupInfo); if (candidateSymbol != NULL) { - if (ELF32_ST_BIND(candidateSymbol->st_info) != STB_WEAK) { + if (candidateSymbol->Bind() != STB_WEAK) { *_foundInImage = image; return candidateSymbol; } @@ -366,8 +366,8 @@ find_undefined_symbol_global(image_t* rootImage, image_t* image, : (otherImage->type != B_ADD_ON_IMAGE && (otherImage->flags & (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) != 0)) { - if (Elf32_Sym* symbol = find_symbol(otherImage, lookupInfo)) { - if (ELF32_ST_BIND(symbol->st_info) != STB_WEAK) { + if (elf_sym* symbol = find_symbol(otherImage, lookupInfo)) { + if (symbol->Bind() != STB_WEAK) { *_foundInImage = otherImage; return symbol; } @@ -388,7 +388,7 @@ find_undefined_symbol_global(image_t* rootImage, image_t* image, } -Elf32_Sym* +elf_sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image, const SymbolLookupInfo& lookupInfo, image_t** _foundInImage) { @@ -410,9 +410,9 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image, // weak symbols that must be resolved globally from those that should be // resolved within the add-on. if (rootImage == image) { - if (Elf32_Sym* symbol = lookupInfo.requestingSymbol) { + if (elf_sym* symbol = lookupInfo.requestingSymbol) { if (symbol->st_shndx != SHN_UNDEF - && (ELF32_ST_BIND(symbol->st_info) == STB_GLOBAL)) { + && (symbol->Bind() == STB_GLOBAL)) { *_foundInImage = image; return symbol; } @@ -420,7 +420,7 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image, } image_t* candidateImage = NULL; - Elf32_Sym* candidateSymbol = NULL; + elf_sym* candidateSymbol = NULL; // If the requesting image is linked symbolically, look up the symbol there // first. @@ -428,7 +428,7 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image, if (symbolic) { candidateSymbol = find_symbol(image, lookupInfo); if (candidateSymbol != NULL) { - if (ELF32_ST_BIND(candidateSymbol->st_info) != STB_WEAK) { + if (candidateSymbol->Bind() != STB_WEAK) { *_foundInImage = image; return candidateSymbol; } @@ -443,8 +443,8 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image, && otherImage->type != B_ADD_ON_IMAGE && (otherImage->flags & (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) != 0) { - if (Elf32_Sym* symbol = find_symbol(otherImage, lookupInfo)) { - if (ELF32_ST_BIND(symbol->st_info) != STB_WEAK) { + if (elf_sym* symbol = find_symbol(otherImage, lookupInfo)) { + if (symbol->Bind() != STB_WEAK) { *_foundInImage = otherImage; return symbol; } @@ -473,7 +473,7 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image, int -resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym, +resolve_symbol(image_t* rootImage, image_t* image, elf_sym* sym, SymbolLookupCache* cache, addr_t* symAddress) { uint32 index = sym - image->syms; @@ -484,18 +484,18 @@ resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym, return B_OK; } - struct Elf32_Sym* sharedSym; + elf_sym* sharedSym; image_t* sharedImage; const char* symName = SYMNAME(image, sym); // get the symbol type int32 type = B_SYMBOL_TYPE_ANY; - if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC) + if (sym->Type() == STT_FUNC) type = B_SYMBOL_TYPE_TEXT; - else if (ELF32_ST_TYPE(sym->st_info) == STT_OBJECT) + else if (sym->Type() == STT_OBJECT) type = B_SYMBOL_TYPE_DATA; - if (ELF32_ST_BIND(sym->st_info) == STB_LOCAL) { + if (sym->Bind() == STB_LOCAL) { // Local symbols references are always resolved to the given symbol. sharedImage = image; sharedSym = sym; @@ -526,14 +526,13 @@ resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym, // symbol not found at all lookupError = ERROR_NO_SYMBOL; sharedImage = NULL; - } else if (ELF32_ST_TYPE(sym->st_info) != STT_NOTYPE - && ELF32_ST_TYPE(sym->st_info) - != ELF32_ST_TYPE(sharedSym->st_info)) { + } else if (sym->Type() != STT_NOTYPE + && sym->Type() != sharedSym->Type()) { // symbol not of the requested type lookupError = ERROR_WRONG_TYPE; sharedImage = NULL; - } else if (ELF32_ST_BIND(sharedSym->st_info) != STB_GLOBAL - && ELF32_ST_BIND(sharedSym->st_info) != STB_WEAK) { + } else if (sharedSym->Bind() != STB_GLOBAL + && sharedSym->Bind() != STB_WEAK) { // symbol not exported lookupError = ERROR_NOT_EXPORTED; sharedImage = NULL; diff --git a/src/system/runtime_loader/elf_symbol_lookup.h b/src/system/runtime_loader/elf_symbol_lookup.h index 3f2791317f..5be9e542c7 100644 --- a/src/system/runtime_loader/elf_symbol_lookup.h +++ b/src/system/runtime_loader/elf_symbol_lookup.h @@ -25,11 +25,11 @@ struct SymbolLookupInfo { uint32 hash; uint32 flags; const elf_version_info* version; - Elf32_Sym* requestingSymbol; + elf_sym* requestingSymbol; SymbolLookupInfo(const char* name, int32 type, uint32 hash, const elf_version_info* version = NULL, uint32 flags = 0, - Elf32_Sym* requestingSymbol = NULL) + elf_sym* requestingSymbol = NULL) : name(name), type(type), @@ -42,7 +42,7 @@ struct SymbolLookupInfo { SymbolLookupInfo(const char* name, int32 type, const elf_version_info* version = NULL, uint32 flags = 0, - Elf32_Sym* requestingSymbol = NULL) + elf_sym* requestingSymbol = NULL) : name(name), type(type), @@ -115,17 +115,17 @@ void patch_undefined_symbol(image_t* rootImage, image_t* image, const char* name, image_t** foundInImage, void** symbol, int32* type); -Elf32_Sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo); +elf_sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo); status_t find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo, void** _location); status_t find_symbol_breadth_first(image_t* image, const SymbolLookupInfo& lookupInfo, image_t** _foundInImage, void** _location); -Elf32_Sym* find_undefined_symbol_beos(image_t* rootImage, image_t* image, +elf_sym* find_undefined_symbol_beos(image_t* rootImage, image_t* image, const SymbolLookupInfo& lookupInfo, image_t** foundInImage); -Elf32_Sym* find_undefined_symbol_global(image_t* rootImage, image_t* image, +elf_sym* find_undefined_symbol_global(image_t* rootImage, image_t* image, const SymbolLookupInfo& lookupInfo, image_t** foundInImage); -Elf32_Sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image, +elf_sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image, const SymbolLookupInfo& lookupInfo, image_t** foundInImage); diff --git a/src/system/runtime_loader/elf_versioning.cpp b/src/system/runtime_loader/elf_versioning.cpp index 756459aa68..9785d1d9f3 100644 --- a/src/system/runtime_loader/elf_versioning.cpp +++ b/src/system/runtime_loader/elf_versioning.cpp @@ -26,7 +26,7 @@ assert_defined_image_version(image_t* dependentImage, image_t* image, } // iterate through the defined versions to find the given one - Elf32_Verdef* definition = image->version_definitions; + elf_verdef* definition = image->version_definitions; for (uint32 i = 0; i < image->num_version_definitions; i++) { uint32 versionIndex = VER_NDX(definition->vd_ndx); elf_version_info& info = image->versions[versionIndex]; @@ -36,8 +36,7 @@ assert_defined_image_version(image_t* dependentImage, image_t* image, return B_OK; } - definition = (Elf32_Verdef*) - ((uint8*)definition + definition->vd_next); + definition = (elf_verdef*)((uint8*)definition + definition->vd_next); } // version not found -- fail, if not weak @@ -63,7 +62,7 @@ init_image_version_infos(image_t* image) uint32 maxIndex = 0; if (image->version_definitions != NULL) { - Elf32_Verdef* definition = image->version_definitions; + elf_verdef* definition = image->version_definitions; for (uint32 i = 0; i < image->num_version_definitions; i++) { if (definition->vd_version != 1) { FATAL("%s: Unsupported version definition revision: %u\n", @@ -75,13 +74,13 @@ init_image_version_infos(image_t* image) if (versionIndex > maxIndex) maxIndex = versionIndex; - definition = (Elf32_Verdef*) - ((uint8*)definition + definition->vd_next); + definition = (elf_verdef*) + ((uint8*)definition + definition->vd_next); } } if (image->needed_versions != NULL) { - Elf32_Verneed* needed = image->needed_versions; + elf_verneed* needed = image->needed_versions; for (uint32 i = 0; i < image->num_needed_versions; i++) { if (needed->vn_version != 1) { FATAL("%s: Unsupported version needed revision: %u\n", @@ -89,17 +88,17 @@ init_image_version_infos(image_t* image) return B_BAD_VALUE; } - Elf32_Vernaux* vernaux - = (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux); + elf_vernaux* vernaux + = (elf_vernaux*)((uint8*)needed + needed->vn_aux); for (uint32 k = 0; k < needed->vn_cnt; k++) { uint32 versionIndex = VER_NDX(vernaux->vna_other); if (versionIndex > maxIndex) maxIndex = versionIndex; - vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next); + vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next); } - needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next); + needed = (elf_verneed*)((uint8*)needed + needed->vn_next); } } @@ -119,12 +118,12 @@ init_image_version_infos(image_t* image) // version definitions if (image->version_definitions != NULL) { - Elf32_Verdef* definition = image->version_definitions; + elf_verdef* definition = image->version_definitions; for (uint32 i = 0; i < image->num_version_definitions; i++) { if (definition->vd_cnt > 0 && (definition->vd_flags & VER_FLG_BASE) == 0) { - Elf32_Verdaux* verdaux - = (Elf32_Verdaux*)((uint8*)definition + definition->vd_aux); + elf_verdaux* verdaux + = (elf_verdaux*)((uint8*)definition + definition->vd_aux); uint32 versionIndex = VER_NDX(definition->vd_ndx); elf_version_info& info = image->versions[versionIndex]; @@ -133,19 +132,19 @@ init_image_version_infos(image_t* image) info.file_name = NULL; } - definition = (Elf32_Verdef*) + definition = (elf_verdef*) ((uint8*)definition + definition->vd_next); } } // needed versions if (image->needed_versions != NULL) { - Elf32_Verneed* needed = image->needed_versions; + elf_verneed* needed = image->needed_versions; for (uint32 i = 0; i < image->num_needed_versions; i++) { const char* fileName = STRING(image, needed->vn_file); - Elf32_Vernaux* vernaux - = (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux); + elf_vernaux* vernaux + = (elf_vernaux*)((uint8*)needed + needed->vn_aux); for (uint32 k = 0; k < needed->vn_cnt; k++) { uint32 versionIndex = VER_NDX(vernaux->vna_other); elf_version_info& info = image->versions[versionIndex]; @@ -153,10 +152,10 @@ init_image_version_infos(image_t* image) info.name = STRING(image, vernaux->vna_name); info.file_name = fileName; - vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next); + vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next); } - needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next); + needed = (elf_verneed*)((uint8*)needed + needed->vn_next); } } @@ -170,7 +169,7 @@ check_needed_image_versions(image_t* image) if (image->needed_versions == NULL) return B_OK; - Elf32_Verneed* needed = image->needed_versions; + elf_verneed* needed = image->needed_versions; for (uint32 i = 0; i < image->num_needed_versions; i++) { const char* fileName = STRING(image, needed->vn_file); image_t* dependency = find_loaded_image_by_name(fileName, @@ -183,8 +182,8 @@ check_needed_image_versions(image_t* image) return B_FILE_NOT_FOUND; } - Elf32_Vernaux* vernaux - = (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux); + elf_vernaux* vernaux + = (elf_vernaux*)((uint8*)needed + needed->vn_aux); for (uint32 k = 0; k < needed->vn_cnt; k++) { uint32 versionIndex = VER_NDX(vernaux->vna_other); elf_version_info& info = image->versions[versionIndex]; @@ -194,10 +193,10 @@ check_needed_image_versions(image_t* image) if (error != B_OK) return error; - vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next); + vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next); } - needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next); + needed = (elf_verneed*)((uint8*)needed + needed->vn_next); } return B_OK; diff --git a/src/system/runtime_loader/heap.cpp b/src/system/runtime_loader/heap.cpp index 03346a978e..02dc286b02 100644 --- a/src/system/runtime_loader/heap.cpp +++ b/src/system/runtime_loader/heap.cpp @@ -35,11 +35,11 @@ static const size_t kInitialHeapSize = 65536; struct free_chunk { - uint32 size; + size_t size; free_chunk *next; - uint32 Size() const; - free_chunk *Split(uint32 splitSize); + size_t Size() const; + free_chunk *Split(size_t splitSize); bool IsTouching(free_chunk *link); free_chunk *Join(free_chunk *link); void Remove(free_chunk *previous = NULL); @@ -50,7 +50,7 @@ struct free_chunk { }; -static uint32 sAvailable; +static size_t sAvailable; static free_chunk sFreeAnchor; @@ -58,10 +58,10 @@ static free_chunk sFreeAnchor; * in this chunk. */ -uint32 +size_t free_chunk::Size() const { - return size - sizeof(uint32); + return size - sizeof(size_t); } @@ -70,13 +70,13 @@ free_chunk::Size() const */ free_chunk * -free_chunk::Split(uint32 splitSize) +free_chunk::Split(size_t splitSize) { - free_chunk *chunk = (free_chunk *)((uint8 *)this + sizeof(uint32) + splitSize); - chunk->size = size - splitSize - sizeof(uint32); + free_chunk *chunk = (free_chunk *)((uint8 *)this + sizeof(size_t) + splitSize); + chunk->size = size - splitSize - sizeof(size_t); chunk->next = next; - size = splitSize + sizeof(uint32); + size = splitSize + sizeof(size_t); return chunk; } @@ -167,7 +167,7 @@ free_chunk::AllocatedAddress() const free_chunk * free_chunk::SetToAllocated(void *allocated) { - return (free_chunk *)((uint8 *)allocated - sizeof(uint32)); + return (free_chunk *)((uint8 *)allocated - sizeof(size_t)); } @@ -183,7 +183,7 @@ add_area(size_t size) if (area < B_OK) return area; - sAvailable += size - sizeof(uint32); + sAvailable += size - sizeof(size_t); // declare the whole heap as one chunk, and add it // to the free list @@ -198,7 +198,7 @@ add_area(size_t size) static status_t -grow_heap(uint32 bytes) +grow_heap(size_t bytes) { // align the area size to an 32768 bytes boundary bytes = (bytes + 32767) & ~32767; @@ -295,10 +295,10 @@ restart: goto restart; } - if (chunk->Size() > size + sizeof(free_chunk) + 4) { + if (chunk->Size() > size + sizeof(free_chunk) + sizeof(size_t)) { // if this chunk is bigger than the requested size, // we split it to form two chunks (with a minimal - // size of 4 allocatable bytes). + // size of sizeof(size_t) allocatable bytes). free_chunk *freeChunk = chunk->Split(size); last->next = freeChunk; @@ -312,7 +312,7 @@ restart: last->next = chunk->next; } - sAvailable -= size + sizeof(uint32); + sAvailable -= size + sizeof(size_t); return chunk->AllocatedAddress(); } diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp index 0446b6d286..6c6c460285 100644 --- a/src/system/runtime_loader/images.cpp +++ b/src/system/runtime_loader/images.cpp @@ -23,8 +23,16 @@ #include "runtime_loader_private.h" -#define RLD_PROGRAM_BASE 0x00200000 - /* keep in sync with app ldscript */ +// keep in sync with app ldscript +#ifdef __x86_64__ + // runtime_loader potentially occupies 0x200000 - 0x600000 due to large + // page segment alignment. +# define RLD_PROGRAM_BASE 0x600000 +# define MAX_PAGE_SIZE 0x200000 +#else +# define RLD_PROGRAM_BASE 0x200000 +# define MAX_PAGE_SIZE B_PAGE_SIZE +#endif bool gInvalidImageIDs; @@ -50,7 +58,7 @@ update_image_id(image_t* image) } } - FATAL("Could not update image ID %ld after fork()!\n", image->id); + FATAL("Could not update image ID %" B_PRId32 " after fork()!\n", image->id); return B_ENTRY_NOT_FOUND; } @@ -319,7 +327,7 @@ map_image(int fd, char const* path, image_t* image, bool fixed) // Check whether the segments have an unreasonable amount of unused space // inbetween. - if (reservedSize > length + 8 * 1024) + if (reservedSize > length + MAX_PAGE_SIZE * 2) return B_BAD_DATA; // reserve that space and allocate the areas from that one @@ -330,7 +338,7 @@ map_image(int fd, char const* path, image_t* image, bool fixed) for (uint32 i = 0; i < image->num_regions; i++) { char regionName[B_OS_NAME_LENGTH]; - snprintf(regionName, sizeof(regionName), "%s_seg%lu%s", + snprintf(regionName, sizeof(regionName), "%s_seg%" B_PRIu32 "%s", baseName, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro"); get_image_region_load_address(image, i, diff --git a/src/system/runtime_loader/runtime_loader.cpp b/src/system/runtime_loader/runtime_loader.cpp index bbc9c45f0a..3389103901 100644 --- a/src/system/runtime_loader/runtime_loader.cpp +++ b/src/system/runtime_loader/runtime_loader.cpp @@ -9,7 +9,6 @@ #include "runtime_loader_private.h" -#include #include #include @@ -348,7 +347,7 @@ test_executable(const char *name, char *invoker) status = B_OK; } } else if (status == B_OK) { - struct Elf32_Ehdr *elfHeader = (struct Elf32_Ehdr *)buffer; + elf_ehdr *elfHeader = (elf_ehdr *)buffer; if (elfHeader->e_entry == 0) { // we don't like to open shared libraries status = B_NOT_AN_EXECUTABLE; diff --git a/src/system/runtime_loader/runtime_loader_private.h b/src/system/runtime_loader/runtime_loader_private.h index 3ac2d0dfab..f3f6dd38e0 100644 --- a/src/system/runtime_loader/runtime_loader_private.h +++ b/src/system/runtime_loader/runtime_loader_private.h @@ -73,11 +73,11 @@ status_t get_library_symbol(void* handle, void* caller, const char* symbolName, void** _location); status_t get_next_image_dependency(image_id id, uint32* cookie, const char** _name); -int resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym, +int resolve_symbol(image_t* rootImage, image_t* image, elf_sym* sym, SymbolLookupCache* cache, addr_t* sym_addr); -status_t elf_verify_header(void* header, int32 length); +status_t elf_verify_header(void* header, size_t length); void rldelf_init(void); void rldexport_init(void); status_t elf_reinit_after_fork(void); diff --git a/src/tests/kits/opengl/glinfo/Jamfile b/src/tests/kits/opengl/glinfo/Jamfile index e02567ed5e..c6c85deed3 100644 --- a/src/tests/kits/opengl/glinfo/Jamfile +++ b/src/tests/kits/opengl/glinfo/Jamfile @@ -1,5 +1,5 @@ SubDir HAIKU_TOP src tests kits opengl glinfo ; - +SubDirSysHdrs $(HAIKU_GLU_HEADERS) ; SubDirSysHdrs $(HAIKU_MESA_HEADERS) ; # For GCC2 @@ -24,11 +24,14 @@ Includes [ FGristFiles $(sources) ] : $(HAIKU_MESA_HEADERS_DEPENDENCY) ; # Dependency needed to trigger downloading/unzipping the package before # compiling the files. -Preference GLInfo - : $(sources) - : be GL translation libcolumnlistview.a $(HAIKU_LOCALE_LIBS) - $(TARGET_LIBSUPC++) - : GLInfo.rdef +Preference GLInfo : + $(sources) + : + be GL libglut.so + translation libcolumnlistview.a $(HAIKU_LOCALE_LIBS) + $(TARGET_LIBSUPC++) + : + GLInfo.rdef ; DoCatalogs GLInfo : diff --git a/src/tests/kits/opengl/glut/game_mode/Jamfile b/src/tests/kits/opengl/glut/game_mode/Jamfile index c01235fdad..ddcc55f5c2 100644 --- a/src/tests/kits/opengl/glut/game_mode/Jamfile +++ b/src/tests/kits/opengl/glut/game_mode/Jamfile @@ -18,5 +18,5 @@ Includes [ FGristFiles $(sources) ] : $(HAIKU_MESA_HEADERS_DEPENDENCY) ; SimpleTest GLUTGameMode : $(sources) - : be GL + : be GL libglut.so ; diff --git a/src/tests/servers/registrar/Jamfile b/src/tests/servers/registrar/Jamfile index 5a3cf21962..925515292e 100644 --- a/src/tests/servers/registrar/Jamfile +++ b/src/tests/servers/registrar/Jamfile @@ -1,7 +1,7 @@ SubDir HAIKU_TOP src tests servers registrar ; UsePublicHeaders [ FDirName add-ons registrar ] ; -UseArchHeaders $(TARGET_ARCH) ; +UseArchHeaders $(TARGET_KERNEL_ARCH) ; # some test programs diff --git a/src/tests/system/boot/loader/Jamfile b/src/tests/system/boot/loader/Jamfile index 3378873b0d..aec23cc9e7 100644 --- a/src/tests/system/boot/loader/Jamfile +++ b/src/tests/system/boot/loader/Jamfile @@ -5,7 +5,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ; UsePrivateHeaders [ FDirName kernel disk_device_manager ] ; UsePrivateHeaders [ FDirName kernel util ] ; UsePrivateHeaders kernel shared storage system ; -SubDirSysHdrs $(HAIKU_TOP) headers private kernel arch $(TARGET_ARCH) ; +SubDirSysHdrs $(HAIKU_TOP) headers private kernel arch $(TARGET_KERNEL_ARCH) ; SubDirSysHdrs $(HAIKU_TOP) headers private system arch $(TARGET_ARCH) ; SubDirSysHdrs $(HAIKU_TOP) src tests system boot loader ; SubDirHdrs $(HAIKU_TOP) src system boot loader ; diff --git a/src/tests/system/kernel/disk_device_manager/Jamfile b/src/tests/system/kernel/disk_device_manager/Jamfile index c25c21da12..e73a79f47f 100644 --- a/src/tests/system/kernel/disk_device_manager/Jamfile +++ b/src/tests/system/kernel/disk_device_manager/Jamfile @@ -10,7 +10,7 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits storage ] ; UsePrivateHeaders shared ; UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; UsePrivateHeaders [ FDirName kernel disk_device_manager ] ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] ; UsePrivateHeaders [ FDirName kernel fs ] ; UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel util ] ; diff --git a/src/tests/system/kernel/scheduler/Jamfile b/src/tests/system/kernel/scheduler/Jamfile index c7c4dcf295..b90549924c 100644 --- a/src/tests/system/kernel/scheduler/Jamfile +++ b/src/tests/system/kernel/scheduler/Jamfile @@ -3,7 +3,7 @@ SubDir HAIKU_TOP src tests system kernel scheduler ; #SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src system kernel util ] ; UsePrivateHeaders kernel ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] ; UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; #UseHeaders [ FDirName $(HAIKU_TOP) src system kernel cache ] ; diff --git a/src/tools/gensyscalls/Jamfile b/src/tools/gensyscalls/Jamfile index 02dbeb495b..156b9d78e3 100644 --- a/src/tools/gensyscalls/Jamfile +++ b/src/tools/gensyscalls/Jamfile @@ -42,7 +42,7 @@ rule PreprocessSyscalls local headers = [ on $(1) return $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ; local sysHeaders = $(TARGET_PRIVATE_SYSTEM_HEADERS) - [ ArchHeaders $(TARGET_ARCH) ] + [ ArchHeaders $(TARGET_KERNEL_ARCH) ] [ on $(1) return $(SUBDIRSYSHDRS) $(SYSHDRS) ] $(HAIKU_HDRS) ; diff --git a/src/tools/gensyscalls/arch/x86_64/arch_gensyscalls.h b/src/tools/gensyscalls/arch/x86_64/arch_gensyscalls.h new file mode 100644 index 0000000000..620802d3a9 --- /dev/null +++ b/src/tools/gensyscalls/arch/x86_64/arch_gensyscalls.h @@ -0,0 +1,2 @@ +#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE long +#define SYSCALL_PARAMETER_ALIGNMENT_TYPE long diff --git a/src/tools/set_haiku_revision.cpp b/src/tools/set_haiku_revision.cpp index 5022398448..acaa697204 100644 --- a/src/tools/set_haiku_revision.cpp +++ b/src/tools/set_haiku_revision.cpp @@ -39,6 +39,13 @@ typedef uint16_t Elf32_Half; typedef uint32_t Elf32_Off; typedef int32_t Elf32_Sword; typedef uint32_t Elf32_Word; +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; +typedef uint16_t Elf64_Half; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; // e_ident indices #define EI_MAG0 0 @@ -69,6 +76,23 @@ typedef struct { Elf32_Half e_shstrndx; } Elf32_Ehdr; +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} Elf64_Ehdr; + // e_ident EI_CLASS and EI_DATA values #define ELFCLASSNONE 0 #define ELFCLASS32 1 @@ -89,6 +113,17 @@ typedef struct { Elf32_Word p_align; } Elf32_Phdr; +typedef struct { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +} Elf64_Phdr; + // p_type #define PT_NULL 0 #define PT_LOAD 1 @@ -114,6 +149,19 @@ typedef struct { Elf32_Word sh_entsize; } Elf32_Shdr; +typedef struct { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +} Elf64_Shdr; + // sh_type values #define SHT_NULL 0 #define SHT_PROGBITS 1 @@ -135,7 +183,6 @@ typedef struct { // special section indexes #define SHN_UNDEF 0 -static const uint32_t kMaxELFHeaderSize = sizeof(Elf32_Ehdr) + 32; static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' }; @@ -168,8 +215,7 @@ print_usage(bool error) } // print_usage_and_exit -static -void +static void print_usage_and_exit(bool error) { print_usage(error); @@ -262,8 +308,8 @@ private: struct SectionInfo { uint32_t type; - uint32_t offset; - uint32_t size; + off_t offset; + size_t size; const char* name; }; @@ -307,82 +353,17 @@ public: if (fFileSize < 0) throw Exception("Failed to get the file size."); - // read ELF header - Elf32_Ehdr fileHeader; - Read(0, &fileHeader, sizeof(Elf32_Ehdr), "Failed to read ELF header."); + // Read identification information + unsigned char ident[EI_NIDENT]; + Read(0, ident, sizeof(ident), "Failed to read ELF identification."); + if (memcmp(ident, kELFFileMagic, sizeof(kELFFileMagic)) != 0) + throw Exception("Not a valid ELF file."); + fELFClass = ident[EI_CLASS]; - // check data encoding (endianess) - switch (fileHeader.e_ident[EI_DATA]) { - case ELFDATA2LSB: - fHostEndianess = (htonl(1) != 1); - break; - case ELFDATA2MSB: - fHostEndianess = (htonl(1) == 1); - break; - default: - case ELFDATANONE: - throw Exception(EIO, "Unsupported ELF data encoding."); - break; - } - - // get the header values - fELFHeaderSize = GetUInt16(fileHeader.e_ehsize); - fSectionHeaderTableOffset = GetUInt32(fileHeader.e_shoff); - fSectionHeaderSize = GetUInt16(fileHeader.e_shentsize); - fSectionHeaderCount = GetUInt16(fileHeader.e_shnum); - bool hasSectionHeaderTable = (fSectionHeaderTableOffset != 0); - - // check the sanity of the header values - // ELF header size - if (fELFHeaderSize < sizeof(Elf32_Ehdr) || fELFHeaderSize > kMaxELFHeaderSize) { - throw Exception(EIO, - "Invalid ELF header: invalid ELF header size: %lu.", - fELFHeaderSize); - } - - // section header table offset and entry count/size - uint32_t sectionHeaderTableSize = 0; - if (hasSectionHeaderTable) { - if (fSectionHeaderTableOffset < fELFHeaderSize - || fSectionHeaderTableOffset > fFileSize) { - throw Exception(EIO, "Invalid ELF header: invalid section " - "header table offset: %lu.", - fSectionHeaderTableOffset); - } - sectionHeaderTableSize = fSectionHeaderSize * fSectionHeaderCount; - if (fSectionHeaderSize < sizeof(Elf32_Shdr) - || fSectionHeaderTableOffset + sectionHeaderTableSize - > fFileSize) { - throw Exception(EIO, "Invalid ELF header: section header " - "table exceeds file: %lu.", - fSectionHeaderTableOffset - + sectionHeaderTableSize); - } - - - // load section header string section - uint16_t sectionHeaderStringSectionIndex - = GetUInt16(fileHeader.e_shstrndx); - if (sectionHeaderStringSectionIndex != SHN_UNDEF) { - if (sectionHeaderStringSectionIndex >= fSectionHeaderCount) { - throw Exception(EIO, "Invalid ELF header: invalid section " - "header string section index: %lu.", - sectionHeaderStringSectionIndex); - } - - // get the section info - SectionInfo info; - if (_ReadSectionHeader(sectionHeaderStringSectionIndex, - info)) { - fSectionHeaderStrings = new char[info.size + 1]; - Read(info.offset, fSectionHeaderStrings, info.size, - "Failed to read section header string section."); - fSectionHeaderStringsLength = info.size; - // null-terminate to be on the safe side - fSectionHeaderStrings[info.size] = '\0'; - } - } - } + if (fELFClass == ELFCLASS64) + _ParseELFHeader(); + else + _ParseELFHeader(); } bool FindSectionByName(const char* name, SectionInfo& foundInfo) @@ -392,9 +373,16 @@ public: return false; // iterate through the section headers - for (int32_t i = 0; i < (int32_t)fSectionHeaderCount; i++) { + for (size_t i = 0; i < fSectionHeaderCount; i++) { SectionInfo info; - if (_ReadSectionHeader(i, info)) { + + bool result; + if (fELFClass == ELFCLASS64) + result = _ReadSectionHeader(i, info); + else + result = _ReadSectionHeader(i, info); + + if (result) { //printf("section %3d: offset: %7d, size: %7d, name: %s\n", i, info.offset, info.size, info.name); if (strcmp(info.name, name) == 0) { foundInfo = info; @@ -457,44 +445,105 @@ public: return lseek(fFD, currentPos, SEEK_SET); } - // GetInt16 - int16_t GetInt16(int16_t value) - { - return (fHostEndianess ? value : _SwapUInt16(value)); - } - - // GetUInt16 - uint16_t GetUInt16(uint16_t value) - { - return (fHostEndianess ? value : _SwapUInt16(value)); - } - - // GetInt32 - int32_t GetInt32(int32_t value) - { - return (fHostEndianess ? value : _SwapUInt32(value)); - } - - // GetUInt32 - uint32_t GetUInt32(uint32_t value) - { - return (fHostEndianess ? value : _SwapUInt32(value)); - } + template + Type GetValue(Type& value); private: + template + void _ParseELFHeader() + { + // read ELF header + EhdrType fileHeader; + Read(0, &fileHeader, sizeof(EhdrType), "Failed to read ELF header."); + + // check data encoding (endianess) + switch (fileHeader.e_ident[EI_DATA]) { + case ELFDATA2LSB: + fHostEndianess = (htonl(1) != 1); + break; + case ELFDATA2MSB: + fHostEndianess = (htonl(1) == 1); + break; + default: + case ELFDATANONE: + throw Exception(EIO, "Unsupported ELF data encoding."); + break; + } + + // get the header values + fELFHeaderSize = GetValue(fileHeader.e_ehsize); + fSectionHeaderTableOffset = GetValue(fileHeader.e_shoff); + fSectionHeaderSize = GetValue(fileHeader.e_shentsize); + fSectionHeaderCount = GetValue(fileHeader.e_shnum); + bool hasSectionHeaderTable = (fSectionHeaderTableOffset != 0); + + // check the sanity of the header values + // ELF header size + if (fELFHeaderSize < sizeof(EhdrType)) { + throw Exception(EIO, + "Invalid ELF header: invalid ELF header size: %lu.", + fELFHeaderSize); + } + + // section header table offset and entry count/size + if (hasSectionHeaderTable) { + if (fSectionHeaderTableOffset < (off_t)fELFHeaderSize + || fSectionHeaderTableOffset > fFileSize) { + throw Exception(EIO, "Invalid ELF header: invalid section " + "header table offset: %llu.", + fSectionHeaderTableOffset); + } + size_t sectionHeaderTableSize + = fSectionHeaderSize * fSectionHeaderCount; + if (fSectionHeaderSize < (off_t)sizeof(ShdrType) + || fSectionHeaderTableOffset + (off_t)sectionHeaderTableSize + > fFileSize) { + throw Exception(EIO, "Invalid ELF header: section header " + "table exceeds file: %llu.", + fSectionHeaderTableOffset + + sectionHeaderTableSize); + } + + + // load section header string section + uint16_t sectionHeaderStringSectionIndex + = GetValue(fileHeader.e_shstrndx); + if (sectionHeaderStringSectionIndex != SHN_UNDEF) { + if (sectionHeaderStringSectionIndex >= fSectionHeaderCount) { + throw Exception(EIO, "Invalid ELF header: invalid section " + "header string section index: %u.", + sectionHeaderStringSectionIndex); + } + + // get the section info + SectionInfo info; + if (_ReadSectionHeader(sectionHeaderStringSectionIndex, + info)) { + fSectionHeaderStrings = new char[info.size + 1]; + Read(info.offset, fSectionHeaderStrings, info.size, + "Failed to read section header string section."); + fSectionHeaderStringsLength = info.size; + // null-terminate to be on the safe side + fSectionHeaderStrings[info.size] = '\0'; + } + } + } + } + + template bool _ReadSectionHeader(int index, SectionInfo& info) { - uint32_t shOffset = fSectionHeaderTableOffset + off_t shOffset = fSectionHeaderTableOffset + index * fSectionHeaderSize; - Elf32_Shdr sectionHeader; - Read(shOffset, §ionHeader, sizeof(Elf32_Shdr), + ShdrType sectionHeader; + Read(shOffset, §ionHeader, sizeof(ShdrType), "Failed to read ELF section header."); // get the header values - uint32_t type = GetUInt32(sectionHeader.sh_type); - uint32_t offset = GetUInt32(sectionHeader.sh_offset); - uint32_t size = GetUInt32(sectionHeader.sh_size); - uint32_t nameIndex = GetUInt32(sectionHeader.sh_name); + uint32_t type = GetValue(sectionHeader.sh_type); + off_t offset = GetValue(sectionHeader.sh_offset); + size_t size = GetValue(sectionHeader.sh_size); + uint32_t nameIndex = GetValue(sectionHeader.sh_name); // check the values // SHT_NULL marks the header unused, @@ -503,14 +552,14 @@ private: // SHT_NOBITS sections take no space in the file if (type != SHT_NOBITS) { - if (offset < fELFHeaderSize || offset > fFileSize) { + if (offset < (off_t)fELFHeaderSize || offset > fFileSize) { throw Exception(EIO, "Invalid ELF section header: " - "invalid section offset: %lu.", offset); + "invalid section offset: %llu.", offset); } - uint32_t sectionEnd = offset + size; + off_t sectionEnd = offset + size; if (sectionEnd > fFileSize) { throw Exception(EIO, "Invalid ELF section header: " - "section exceeds file: %lu.", sectionEnd); + "section exceeds file: %llu.", sectionEnd); } } @@ -546,19 +595,69 @@ private: | _SwapUInt16(uint16_t(value >> 16)); } + // _SwapUInt64 + static inline uint64_t _SwapUInt64(uint64_t value) + { + return ((uint64_t)_SwapUInt32(value & 0xffffffff) << 32) + | _SwapUInt32(uint32_t(value >> 32)); + } + private: int fFD; + uint8_t fELFClass; bool fHostEndianess; off_t fFileSize; - uint32_t fELFHeaderSize; - uint32_t fSectionHeaderTableOffset; - uint32_t fSectionHeaderSize; - uint32_t fSectionHeaderCount; + size_t fELFHeaderSize; + off_t fSectionHeaderTableOffset; + size_t fSectionHeaderSize; + size_t fSectionHeaderCount; char* fSectionHeaderStrings; - int fSectionHeaderStringsLength; + uint32_t fSectionHeaderStringsLength; }; +template<> +int16_t ELFObject::GetValue(int16_t& value) +{ + return (fHostEndianess ? value : _SwapUInt16(value)); +} + + +template<> +uint16_t ELFObject::GetValue(uint16_t& value) +{ + return (fHostEndianess ? value : _SwapUInt16(value)); +} + + +template<> +int32_t ELFObject::GetValue(int32_t& value) +{ + return (fHostEndianess ? value : _SwapUInt32(value)); +} + + +template<> +uint32_t ELFObject::GetValue(uint32_t& value) +{ + return (fHostEndianess ? value : _SwapUInt32(value)); +} + + +template<> +int64_t ELFObject::GetValue(int64_t& value) +{ + return (fHostEndianess ? value : _SwapUInt64(value)); +} + + +template<> +uint64_t ELFObject::GetValue(uint64_t& value) +{ + return (fHostEndianess ? value : _SwapUInt64(value)); +} + + // main int main(int argc, const char* const* argv)