summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Souza <luiz@netgate.com>2018-01-10 21:27:24 -0200
committerLuiz Souza <luiz@netgate.com>2018-01-10 21:27:24 -0200
commit890da90a7126ae0186b5d755b21bbcfec9827537 (patch)
tree945c22267eb68af6618737c4430abf0daba2e077
parent5c0d2d1eef0249c7d4dbfab048fd7811834c90c1 (diff)
parent413eb60eca725655270910c673c20bc94449e313 (diff)
downloadFreeBSD-src-890da90a7126ae0186b5d755b21bbcfec9827537.zip
FreeBSD-src-890da90a7126ae0186b5d755b21bbcfec9827537.tar.gz
Merge remote-tracking branch 'origin/stable/11' into devel-11
-rw-r--r--.gitattributes5
-rw-r--r--.gitignore18
-rw-r--r--COPYRIGHT2
-rw-r--r--Makefile.inc111
-rw-r--r--ObsoleteFiles.inc119
-rw-r--r--cddl/usr.bin/ctfconvert/Makefile5
-rw-r--r--cddl/usr.bin/ctfconvert/tests/Makefile5
-rw-r--r--cddl/usr.bin/ctfconvert/tests/ctfconvert_test.sh62
-rwxr-xr-xcddl/usr.sbin/dtrace/tests/tools/exclude.sh3
-rw-r--r--contrib/binutils/bfd/elflink.c4
-rw-r--r--contrib/binutils/include/obstack.h6
-rw-r--r--contrib/elftoolchain/elfcopy/binary.c4
-rw-r--r--contrib/libc++/include/algorithm5
-rw-r--r--contrib/libc++/include/deque5
-rw-r--r--contrib/libc++/include/functional36
-rw-r--r--contrib/libc++/include/list13
-rw-r--r--contrib/libc++/include/string12
-rw-r--r--contrib/libc++/include/type_traits7
-rw-r--r--contrib/libc++/include/vector17
-rw-r--r--contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h6
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h8
-rw-r--r--contrib/llvm/include/llvm/IR/AutoUpgrade.h2
-rw-r--r--contrib/llvm/include/llvm/Support/FormatVariadic.h17
-rw-r--r--contrib/llvm/lib/AsmParser/LLParser.cpp1
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp20
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h5
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp7
-rw-r--r--contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp10
-rw-r--r--contrib/llvm/lib/CodeGen/MachineRegisterInfo.cpp18
-rw-r--r--contrib/llvm/lib/CodeGen/MachineVerifier.cpp2
-rw-r--r--contrib/llvm/lib/IR/AutoUpgrade.cpp47
-rw-r--r--contrib/llvm/lib/IR/ConstantFold.cpp3
-rw-r--r--contrib/llvm/lib/Linker/IRMover.cpp4
-rw-r--r--contrib/llvm/lib/Linker/LinkModules.cpp14
-rw-r--r--contrib/llvm/lib/Support/Host.cpp1
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp112
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp19
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.td3
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp13
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMAsmPrinter.cpp2
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMCallLowering.cpp4
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp5
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMFastISel.cpp5
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp7
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMInstrInfo.td8
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp1
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMSubtarget.h11
-rw-r--r--contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp4
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp69
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp6
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRISelLowering.h5
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp18
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRInstrInfo.h6
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRInstrInfo.td74
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp2
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp2
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp20
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h2
-rw-r--r--contrib/llvm/lib/Target/BPF/BPFISelLowering.cpp8
-rw-r--r--contrib/llvm/lib/Target/BPF/BPFInstrInfo.td2
-rw-r--r--contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp234
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp8
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp15
-rw-r--r--contrib/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td7
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsDSPInstrInfo.td6
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp35
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsMTInstrFormats.td21
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsMTInstrInfo.td110
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp8
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp4
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsSchedule.td4
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsScheduleGeneric.td4
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h3
-rw-r--r--contrib/llvm/lib/Target/X86/X86ISelLowering.cpp17
-rw-r--r--contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp16
-rw-r--r--contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S3
-rw-r--r--contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S3
-rw-r--r--contrib/llvm/projects/libunwind/src/assembly.h15
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/Attr.td4
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td15
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def1
-rw-r--r--contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h1
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp24
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp11
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Version.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp11
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp35
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h4
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp13
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h6
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp5
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/Format/Format.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Headers/avx512fintrin.h9
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp26
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp3
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp23
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp1
-rw-r--r--contrib/llvm/tools/lld/ELF/Driver.cpp9
-rw-r--r--contrib/llvm/tools/lld/ELF/MarkLive.cpp7
-rw-r--r--contrib/llvm/tools/lld/ELF/Relocations.cpp26
-rw-r--r--contrib/llvm/tools/lld/ELF/SyntheticSections.cpp12
-rw-r--r--contrib/llvm/tools/lld/ELF/SyntheticSections.h3
-rw-r--r--contrib/llvm/tools/lld/ELF/Writer.cpp37
-rw-r--r--contrib/llvm/tools/lld/ELF/Writer.h1
-rw-r--r--contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h4
-rw-r--r--contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp4
-rw-r--r--contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp4
-rw-r--r--contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp4
-rw-r--r--contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp4
-rw-r--r--contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp57
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp3
-rw-r--r--contrib/tcpdump/CHANGES166
-rw-r--r--contrib/tcpdump/CONTRIBUTING62
-rw-r--r--contrib/tcpdump/CREDITS8
-rw-r--r--contrib/tcpdump/INSTALL.txt1
-rw-r--r--contrib/tcpdump/Makefile.in1
-rw-r--r--contrib/tcpdump/PLATFORMS21
-rw-r--r--contrib/tcpdump/README.md34
-rw-r--r--contrib/tcpdump/VERSION2
-rw-r--r--contrib/tcpdump/addrtoname.c80
-rw-r--r--contrib/tcpdump/addrtoname.h3
-rw-r--r--contrib/tcpdump/addrtostr.c17
-rw-r--r--contrib/tcpdump/af.c2
-rw-r--r--contrib/tcpdump/af.h2
-rw-r--r--contrib/tcpdump/checksum.c2
-rw-r--r--contrib/tcpdump/config.h.in3
-rwxr-xr-xcontrib/tcpdump/configure27
-rw-r--r--contrib/tcpdump/configure.in18
-rw-r--r--contrib/tcpdump/extract.h60
-rw-r--r--contrib/tcpdump/funcattrs.h122
-rw-r--r--contrib/tcpdump/gmpls.c2
-rw-r--r--contrib/tcpdump/gmpls.h2
-rw-r--r--contrib/tcpdump/ip6.h13
-rw-r--r--contrib/tcpdump/ipproto.c308
-rw-r--r--contrib/tcpdump/ipproto.h3
-rw-r--r--contrib/tcpdump/l2vpn.c2
-rw-r--r--contrib/tcpdump/l2vpn.h2
-rw-r--r--contrib/tcpdump/netdissect-stdinc.h5
-rw-r--r--contrib/tcpdump/netdissect.h16
-rw-r--r--contrib/tcpdump/nlpid.c2
-rw-r--r--contrib/tcpdump/nlpid.h2
-rw-r--r--contrib/tcpdump/oui.c2
-rw-r--r--contrib/tcpdump/oui.h2
-rw-r--r--contrib/tcpdump/print-802_11.c15
-rw-r--r--contrib/tcpdump/print-802_15_4.c240
-rw-r--r--contrib/tcpdump/print-aodv.c9
-rw-r--r--contrib/tcpdump/print-arp.c89
-rw-r--r--contrib/tcpdump/print-atm.c2
-rw-r--r--contrib/tcpdump/print-beep.c26
-rw-r--r--contrib/tcpdump/print-bfd.c2
-rw-r--r--contrib/tcpdump/print-bgp.c55
-rw-r--r--contrib/tcpdump/print-bootp.c1
-rw-r--r--contrib/tcpdump/print-cfm.c73
-rw-r--r--contrib/tcpdump/print-chdlc.c24
-rw-r--r--contrib/tcpdump/print-cnfp.c33
-rw-r--r--contrib/tcpdump/print-decnet.c2
-rw-r--r--contrib/tcpdump/print-dhcp6.c4
-rw-r--r--contrib/tcpdump/print-domain.c37
-rw-r--r--contrib/tcpdump/print-eap.c18
-rw-r--r--contrib/tcpdump/print-eigrp.c49
-rw-r--r--contrib/tcpdump/print-esp.c99
-rw-r--r--contrib/tcpdump/print-ether.c2
-rw-r--r--contrib/tcpdump/print-fr.c2
-rw-r--r--contrib/tcpdump/print-frag6.c5
-rw-r--r--contrib/tcpdump/print-gre.c2
-rw-r--r--contrib/tcpdump/print-hncp.c8
-rw-r--r--contrib/tcpdump/print-icmp.c18
-rw-r--r--contrib/tcpdump/print-icmp6.c3
-rw-r--r--contrib/tcpdump/print-ip.c39
-rw-r--r--contrib/tcpdump/print-ip6.c11
-rw-r--r--contrib/tcpdump/print-ip6opts.c4
-rw-r--r--contrib/tcpdump/print-isakmp.c231
-rw-r--r--contrib/tcpdump/print-isoclns.c534
-rw-r--r--contrib/tcpdump/print-juniper.c57
-rw-r--r--contrib/tcpdump/print-l2tp.c223
-rw-r--r--contrib/tcpdump/print-ldp.c2
-rw-r--r--contrib/tcpdump/print-llc.c2
-rw-r--r--contrib/tcpdump/print-lldp.c22
-rw-r--r--contrib/tcpdump/print-lmp.c434
-rw-r--r--contrib/tcpdump/print-lspping.c3
-rw-r--r--contrib/tcpdump/print-m3ua.c2
-rw-r--r--contrib/tcpdump/print-mobility.c46
-rw-r--r--contrib/tcpdump/print-mpcp.c2
-rw-r--r--contrib/tcpdump/print-mpls.c2
-rw-r--r--contrib/tcpdump/print-mptcp.c84
-rw-r--r--contrib/tcpdump/print-nfs.c25
-rw-r--r--contrib/tcpdump/print-null.c2
-rw-r--r--contrib/tcpdump/print-olsr.c23
-rw-r--r--contrib/tcpdump/print-ospf6.c4
-rw-r--r--contrib/tcpdump/print-pgm.c218
-rw-r--r--contrib/tcpdump/print-pim.c426
-rw-r--r--contrib/tcpdump/print-pktap.c6
-rw-r--r--contrib/tcpdump/print-ppp.c39
-rw-r--r--contrib/tcpdump/print-radius.c14
-rw-r--r--contrib/tcpdump/print-resp.c24
-rw-r--r--contrib/tcpdump/print-ripng.c71
-rw-r--r--contrib/tcpdump/print-rpki-rtr.c171
-rw-r--r--contrib/tcpdump/print-rsvp.c24
-rw-r--r--contrib/tcpdump/print-rt6.c8
-rw-r--r--contrib/tcpdump/print-rx.c36
-rw-r--r--contrib/tcpdump/print-sip.c2
-rw-r--r--contrib/tcpdump/print-sl.c25
-rw-r--r--contrib/tcpdump/print-slow.c2
-rw-r--r--contrib/tcpdump/print-stp.c2
-rw-r--r--contrib/tcpdump/print-syslog.c2
-rw-r--r--contrib/tcpdump/print-telnet.c1
-rw-r--r--contrib/tcpdump/print-tftp.c63
-rw-r--r--contrib/tcpdump/print-vqp.c14
-rw-r--r--contrib/tcpdump/print-vtp.c144
-rw-r--r--contrib/tcpdump/print-wb.c9
-rw-r--r--contrib/tcpdump/print-zephyr.c48
-rw-r--r--contrib/tcpdump/print.c27
-rw-r--r--contrib/tcpdump/signature.c2
-rw-r--r--contrib/tcpdump/signature.h2
-rw-r--r--contrib/tcpdump/smbutil.c1
-rw-r--r--contrib/tcpdump/tcpdump.1.in197
-rw-r--r--contrib/tcpdump/tcpdump.c39
-rw-r--r--contrib/tcpdump/util-print.c27
-rw-r--r--etc/defaults/rc.conf1
-rw-r--r--etc/mtree/BSD.debug.dist2
-rw-r--r--etc/mtree/BSD.tests.dist6
-rw-r--r--etc/mtree/BSD.usr.dist2
-rw-r--r--etc/rc.initdiskless7
-rw-r--r--etc/rc.subr2
-rw-r--r--lib/Makefile3
-rw-r--r--lib/clang/headers/Makefile2
-rw-r--r--lib/clang/include/clang/Basic/Version.inc8
-rw-r--r--lib/clang/include/clang/Config/config.h2
-rw-r--r--lib/clang/include/lld/Config/Version.inc6
-rw-r--r--lib/clang/include/llvm/Config/config.h8
-rw-r--r--lib/clang/include/llvm/Config/llvm-config.h4
-rw-r--r--lib/clang/include/llvm/Support/VCSRevision.h2
-rw-r--r--lib/libc/gen/isgreater.34
-rw-r--r--lib/libc/net/getaddrinfo.c3
-rw-r--r--lib/libclang_rt/Makefile.inc2
-rw-r--r--libexec/ftpd/ftpd.c2
-rw-r--r--release/tools/ec2.conf7
-rw-r--r--sbin/geom/class/mirror/gmirror.848
-rw-r--r--sbin/ifconfig/ifvxlan.c4
-rw-r--r--sbin/ipfw/ipfw2.c7
-rw-r--r--sbin/mdmfs/mdmfs.865
-rw-r--r--sbin/mdmfs/mdmfs.c163
-rw-r--r--share/man/man4/lm75.421
-rw-r--r--share/man/man4/md.446
-rw-r--r--share/man/man4/smp.47
-rw-r--r--share/man/man5/rc.conf.537
-rw-r--r--share/man/man7/build.718
-rw-r--r--share/man/man9/EVENTHANDLER.935
-rw-r--r--share/man/man9/atomic.9218
-rw-r--r--share/skel/dot.shrc2
-rw-r--r--sys/amd64/amd64/pmap.c2
-rw-r--r--sys/amd64/amd64/support.S11
-rw-r--r--sys/amd64/amd64/trap.c15
-rw-r--r--sys/amd64/include/atomic.h2
-rw-r--r--sys/amd64/vmm/io/vhpet.c2
-rw-r--r--sys/arm/allwinner/std.allwinner3
-rw-r--r--sys/arm/allwinner/std.allwinner_up3
-rw-r--r--sys/arm/altera/socfpga/std.socfpga3
-rw-r--r--sys/arm/arm/dump_machdep.c1
-rw-r--r--sys/arm/arm/elf_trampoline.c1
-rw-r--r--sys/arm/arm/genassym.c11
-rw-r--r--sys/arm/arm/locore-v6.S11
-rw-r--r--sys/arm/arm/machdep.c21
-rw-r--r--sys/arm/arm/machdep_boot.c1
-rw-r--r--sys/arm/arm/pmap-v6.c10
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_bsc.c346
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_bscreg.h6
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_bscvar.h12
-rw-r--r--sys/arm/broadcom/bcm2835/std.rpi2
-rw-r--r--sys/arm/conf/NOTES2
-rw-r--r--sys/arm/freescale/imx/imx6_hdmi.c60
-rw-r--r--sys/arm/freescale/imx/std.imx513
-rw-r--r--sys/arm/freescale/imx/std.imx533
-rw-r--r--sys/arm/freescale/imx/std.imx63
-rw-r--r--sys/arm/freescale/vybrid/std.vybrid3
-rw-r--r--sys/arm/include/atomic.h29
-rw-r--r--sys/arm/include/vmparam.h13
-rw-r--r--sys/arm/mv/armada38x/std.armada38x2
-rw-r--r--sys/arm/mv/armadaxp/std.armadaxp2
-rw-r--r--sys/arm/nvidia/tegra124/std.tegra1243
-rw-r--r--sys/arm/rockchip/std.rk30xx3
-rw-r--r--sys/arm/samsung/exynos/std.exynos52503
-rw-r--r--sys/arm/samsung/exynos/std.exynos54203
-rw-r--r--sys/arm/ti/am335x/std.am335x3
-rw-r--r--sys/arm/ti/omap4/std.omap43
-rw-r--r--sys/arm/ti/ti_pruss.c541
-rw-r--r--sys/arm/ti/ti_pruss.h21
-rw-r--r--sys/arm/xilinx/std.zynq73
-rw-r--r--sys/arm64/include/atomic.h2
-rw-r--r--sys/boot/arm/uboot/start.S32
-rw-r--r--sys/boot/fdt/dts/arm/bcm2835.dtsi2
-rw-r--r--sys/boot/fdt/dts/arm/bcm2836.dtsi2
-rw-r--r--sys/boot/uboot/lib/libuboot.h9
-rw-r--r--sys/cam/ata/ata_da.c2
-rw-r--r--sys/cam/ata/ata_pmp.c2
-rw-r--r--sys/cam/nvme/nvme_da.c2
-rw-r--r--sys/cam/scsi/scsi_cd.c2
-rw-r--r--sys/cam/scsi/scsi_da.c2
-rw-r--r--sys/cam/scsi/scsi_sa.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c7
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c10
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c57
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c25
-rw-r--r--sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c20
-rw-r--r--sys/cddl/dev/dtrace/amd64/dtrace_subr.c9
-rw-r--r--sys/cddl/dev/dtrace/i386/dtrace_subr.c9
-rw-r--r--sys/cddl/dev/sdt/sdt.c8
-rw-r--r--sys/conf/Makefile.arm5
-rw-r--r--sys/conf/NOTES3
-rw-r--r--sys/conf/dtb.mk1
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/ldscript.amd644
-rw-r--r--sys/conf/options1
-rw-r--r--sys/conf/options.arm1
-rw-r--r--sys/contrib/dev/acpica/changes.txt242
-rw-r--r--sys/contrib/dev/acpica/common/adfile.c4
-rw-r--r--sys/contrib/dev/acpica/common/adisasm.c4
-rw-r--r--sys/contrib/dev/acpica/common/ahtable.c2
-rw-r--r--sys/contrib/dev/acpica/common/dmswitch.c4
-rw-r--r--sys/contrib/dev/acpica/common/dmtable.c71
-rw-r--r--sys/contrib/dev/acpica/common/dmtables.c4
-rw-r--r--sys/contrib/dev/acpica/common/dmtbdump.c1028
-rw-r--r--sys/contrib/dev/acpica/common/dmtbinfo.c177
-rw-r--r--sys/contrib/dev/acpica/compiler/aslallocate.c303
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcache.c481
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcodegen.c19
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompile.c68
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompiler.h76
-rw-r--r--sys/contrib/dev/acpica/compiler/aslcompiler.l8
-rw-r--r--sys/contrib/dev/acpica/compiler/asldebug.c89
-rw-r--r--sys/contrib/dev/acpica/compiler/asldefine.h2
-rw-r--r--sys/contrib/dev/acpica/compiler/aslerror.c804
-rw-r--r--sys/contrib/dev/acpica/compiler/aslfiles.c9
-rw-r--r--sys/contrib/dev/acpica/compiler/aslhelp.c3
-rw-r--r--sys/contrib/dev/acpica/compiler/aslload.c30
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmain.c8
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmapenter.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmaputils.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmessages.c7
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmessages.h3
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmethod.c43
-rw-r--r--sys/contrib/dev/acpica/compiler/asloperands.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslopt.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/asloptions.c22
-rw-r--r--sys/contrib/dev/acpica/compiler/aslparseop.c61
-rw-r--r--sys/contrib/dev/acpica/compiler/aslprintf.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/aslresource.c8
-rw-r--r--sys/contrib/dev/acpica/compiler/aslrules.y3
-rw-r--r--sys/contrib/dev/acpica/compiler/aslstartup.c8
-rw-r--r--sys/contrib/dev/acpica/compiler/aslsupport.l22
-rw-r--r--sys/contrib/dev/acpica/compiler/asltree.c41
-rw-r--r--sys/contrib/dev/acpica/compiler/asltypes.h9
-rw-r--r--sys/contrib/dev/acpica/compiler/aslutils.c240
-rw-r--r--sys/contrib/dev/acpica/compiler/cvcompiler.c26
-rw-r--r--sys/contrib/dev/acpica/compiler/cvdisasm.c4
-rw-r--r--sys/contrib/dev/acpica/compiler/cvparser.c8
-rw-r--r--sys/contrib/dev/acpica/compiler/dtcompile.c20
-rw-r--r--sys/contrib/dev/acpica/compiler/dtcompiler.h37
-rw-r--r--sys/contrib/dev/acpica/compiler/dtexpress.c1
-rw-r--r--sys/contrib/dev/acpica/compiler/dtfield.c9
-rw-r--r--sys/contrib/dev/acpica/compiler/dtio.c5
-rw-r--r--sys/contrib/dev/acpica/compiler/dtparser.y18
-rw-r--r--sys/contrib/dev/acpica/compiler/dtsubtable.c3
-rw-r--r--sys/contrib/dev/acpica/compiler/dttable.c1
-rw-r--r--sys/contrib/dev/acpica/compiler/dttable1.c11
-rw-r--r--sys/contrib/dev/acpica/compiler/dttable2.c384
-rw-r--r--sys/contrib/dev/acpica/compiler/dttemplate.c3
-rw-r--r--sys/contrib/dev/acpica/compiler/dttemplate.h115
-rw-r--r--sys/contrib/dev/acpica/compiler/dtutils.c185
-rw-r--r--sys/contrib/dev/acpica/compiler/prexpress.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/prmacros.c2
-rw-r--r--sys/contrib/dev/acpica/compiler/prparser.y5
-rw-r--r--sys/contrib/dev/acpica/compiler/prscan.c3
-rw-r--r--sys/contrib/dev/acpica/compiler/prutils.c4
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbconvert.c4
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbexec.c124
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbfileio.c2
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbinput.c205
-rw-r--r--sys/contrib/dev/acpica/components/disassembler/dmresrc.c14
-rw-r--r--sys/contrib/dev/acpica/components/disassembler/dmwalk.c6
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dscontrol.c17
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dsfield.c27
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dsobject.c3
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dspkginit.c22
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dsutils.c3
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dswexec.c2
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dswload.c4
-rw-r--r--sys/contrib/dev/acpica/components/dispatcher/dswload2.c12
-rw-r--r--sys/contrib/dev/acpica/components/events/evgpe.c6
-rw-r--r--sys/contrib/dev/acpica/components/events/evregion.c11
-rw-r--r--sys/contrib/dev/acpica/components/executer/exconcat.c2
-rw-r--r--sys/contrib/dev/acpica/components/executer/exconvrt.c26
-rw-r--r--sys/contrib/dev/acpica/components/executer/exdump.c6
-rw-r--r--sys/contrib/dev/acpica/components/executer/exmisc.c2
-rw-r--r--sys/contrib/dev/acpica/components/executer/exresop.c2
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwgpe.c4
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwregs.c74
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwtimer.c37
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwvalid.c17
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwxface.c130
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsaccess.c14
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsconvert.c6
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsnames.c172
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nssearch.c1
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsxfeval.c18
-rw-r--r--sys/contrib/dev/acpica/components/parser/psargs.c2
-rw-r--r--sys/contrib/dev/acpica/components/parser/psobject.c9
-rw-r--r--sys/contrib/dev/acpica/components/parser/psutils.c10
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbxface.c9
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utdebug.c19
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utdecode.c11
-rw-r--r--sys/contrib/dev/acpica/components/utilities/uterror.c78
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utinit.c1
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utmath.c4
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utmutex.c7
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utnonansi.c13
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utosi.c2
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utstrsuppt.c621
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utstrtoul64.c472
-rw-r--r--sys/contrib/dev/acpica/components/utilities/uttrack.c5
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utxferror.c8
-rw-r--r--sys/contrib/dev/acpica/include/acapps.h3
-rw-r--r--sys/contrib/dev/acpica/include/acconfig.h4
-rw-r--r--sys/contrib/dev/acpica/include/acdebug.h6
-rw-r--r--sys/contrib/dev/acpica/include/acdisasm.h28
-rw-r--r--sys/contrib/dev/acpica/include/acexcep.h18
-rw-r--r--sys/contrib/dev/acpica/include/acglobal.h121
-rw-r--r--sys/contrib/dev/acpica/include/achware.h4
-rw-r--r--sys/contrib/dev/acpica/include/acinterp.h5
-rw-r--r--sys/contrib/dev/acpica/include/aclocal.h15
-rw-r--r--sys/contrib/dev/acpica/include/acmacros.h2
-rw-r--r--sys/contrib/dev/acpica/include/acnamesp.h5
-rw-r--r--sys/contrib/dev/acpica/include/acpixf.h6
-rw-r--r--sys/contrib/dev/acpica/include/actbl1.h209
-rw-r--r--sys/contrib/dev/acpica/include/actbl2.h16
-rw-r--r--sys/contrib/dev/acpica/include/actypes.h4
-rw-r--r--sys/contrib/dev/acpica/include/acutils.h78
-rw-r--r--sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c5
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c2
-rw-r--r--sys/dev/acpica/Osd/OsdSchedule.c3
-rw-r--r--sys/dev/acpica/acpi_cpu.c8
-rw-r--r--sys/dev/ahci/ahci_pci.c1
-rw-r--r--sys/dev/ffec/if_ffec.c187
-rw-r--r--sys/dev/ffec/if_ffecreg.h4
-rw-r--r--sys/dev/hpt27xx/hpt27xx_osm_bsd.c4
-rw-r--r--sys/dev/hptnr/hptnr_osm_bsd.c4
-rw-r--r--sys/dev/hptrr/hptrr_osm_bsd.c4
-rw-r--r--sys/dev/iicbus/ds3231.c20
-rw-r--r--sys/dev/md/md.c10
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_rx.c4
-rw-r--r--sys/dev/sdhci/fsl_sdhci.c31
-rw-r--r--sys/dev/sound/pci/hda/hdac.c4
-rw-r--r--sys/dev/txp/if_txp.c2
-rw-r--r--sys/dev/txp/if_txpreg.h5
-rw-r--r--sys/dev/usb/controller/xhci_pci.c4
-rw-r--r--sys/fs/devfs/devfs_vnops.c11
-rw-r--r--sys/fs/ext2fs/ext2_extattr.c22
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c6
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c9
-rw-r--r--sys/fs/procfs/procfs_map.c50
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c9
-rw-r--r--sys/geom/mirror/g_mirror.c137
-rw-r--r--sys/geom/mirror/g_mirror.h16
-rw-r--r--sys/i386/i386/trap.c13
-rw-r--r--sys/i386/include/atomic.h2
-rw-r--r--sys/kern/kern_dtrace.c2
-rw-r--r--sys/kern/kern_lockstat.c2
-rw-r--r--sys/kern/kern_mutex.c267
-rw-r--r--sys/kern/kern_proc.c33
-rw-r--r--sys/kern/kern_rwlock.c344
-rw-r--r--sys/kern/kern_sdt.c1
-rw-r--r--sys/kern/kern_switch.c27
-rw-r--r--sys/kern/kern_sx.c435
-rw-r--r--sys/kern/kern_sysctl.c22
-rw-r--r--sys/kern/kern_tc.c8
-rw-r--r--sys/kern/subr_bus.c8
-rw-r--r--sys/kern/subr_eventhandler.c22
-rw-r--r--sys/kern/subr_kdb.c2
-rw-r--r--sys/kern/subr_vmem.c4
-rw-r--r--sys/kern/vfs_bio.c10
-rw-r--r--sys/kern/vfs_cache.c430
-rw-r--r--sys/kern/vfs_extattr.c29
-rw-r--r--sys/mips/include/atomic.h19
-rw-r--r--sys/mips/mips/db_interface.c12
-rw-r--r--sys/mips/mips/support.S67
-rw-r--r--sys/modules/dtb/rpi/Makefile7
-rw-r--r--sys/net/if_vxlan.c35
-rw-r--r--sys/netinet/icmp6.h2
-rw-r--r--sys/netinet/tcp_input.c38
-rw-r--r--sys/netinet/tcp_output.c5
-rw-r--r--sys/netinet6/frag6.c2
-rw-r--r--sys/netinet6/icmp6.c4
-rw-r--r--sys/netinet6/in6.h1
-rw-r--r--sys/netinet6/ip6_id.c9
-rw-r--r--sys/netinet6/nd6_nbr.c8
-rw-r--r--sys/netinet6/nd6_rtr.c8
-rw-r--r--sys/powerpc/include/atomic.h2
-rw-r--r--sys/powerpc/powerpc/trap.c4
-rw-r--r--sys/riscv/include/atomic.h2
-rw-r--r--sys/security/audit/audit.c2
-rw-r--r--sys/sparc64/include/atomic.h7
-rw-r--r--sys/sys/atomic_common.h73
-rw-r--r--sys/sys/bus.h1
-rw-r--r--sys/sys/copyright.h4
-rw-r--r--sys/sys/dtrace_bsd.h5
-rw-r--r--sys/sys/eventhandler.h22
-rw-r--r--sys/sys/kdb.h2
-rw-r--r--sys/sys/lock.h11
-rw-r--r--sys/sys/mutex.h95
-rw-r--r--sys/sys/proc.h4
-rw-r--r--sys/sys/rwlock.h55
-rw-r--r--sys/sys/sdt.h10
-rw-r--r--sys/sys/sx.h33
-rw-r--r--sys/sys/systm.h1
-rw-r--r--sys/ufs/ffs/ffs_alloc.c16
-rw-r--r--sys/vm/uma_core.c2
-rw-r--r--sys/vm/vm_kern.c13
-rw-r--r--sys/vm/vm_page.c51
-rw-r--r--sys/vm/vm_page.h3
-rw-r--r--sys/vm/vm_pageout.c2
-rw-r--r--sys/vm/vm_pager.c2
-rw-r--r--sys/vm/vm_swapout.c90
-rw-r--r--sys/x86/include/specialreg.h2
-rw-r--r--sys/x86/x86/identcpu.c1
-rw-r--r--tests/sys/geom/class/geom_subr.sh11
-rwxr-xr-xtests/sys/geom/class/mirror/10_test.sh69
-rwxr-xr-xtests/sys/geom/class/mirror/11_test.sh84
-rwxr-xr-xtests/sys/geom/class/mirror/12_test.sh68
-rwxr-xr-xtests/sys/geom/class/mirror/13_test.sh81
-rw-r--r--tests/sys/geom/class/mirror/8_test.sh8
-rw-r--r--tests/sys/geom/class/mirror/9_test.sh12
-rw-r--r--tests/sys/geom/class/mirror/Makefile4
-rw-r--r--tests/sys/geom/class/mirror/conf.sh7
-rw-r--r--tests/sys/geom/class/nop/nop_test.sh11
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc229
-rw-r--r--usr.bin/Makefile2
-rw-r--r--usr.bin/ctlstat/ctlstat.c28
-rw-r--r--usr.bin/fold/Makefile5
-rw-r--r--usr.bin/fold/tests/Makefile5
-rw-r--r--usr.bin/fold/tests/fold_test.sh81
-rw-r--r--usr.bin/gzip/Makefile2
-rw-r--r--usr.bin/gzip/gzip.c2
-rw-r--r--usr.bin/gzip/zuncompress.c2
-rw-r--r--usr.bin/man/man.12
-rw-r--r--usr.bin/pathchk/pathchk.c2
-rw-r--r--usr.bin/rs/Makefile6
-rw-r--r--usr.bin/rs/tests/Makefile5
-rw-r--r--usr.bin/rs/tests/rs_test.sh278
-rw-r--r--usr.bin/su/su.c4
-rw-r--r--usr.bin/units/units.c2
-rw-r--r--usr.bin/xinstall/xinstall.c6
-rw-r--r--usr.sbin/acpi/acpidb/Makefile5
-rw-r--r--usr.sbin/acpi/iasl/Makefile45
-rw-r--r--usr.sbin/cpucontrol/intel.c20
-rw-r--r--usr.sbin/cpucontrol/via.c2
-rw-r--r--usr.sbin/diskinfo/diskinfo.c8
-rw-r--r--usr.sbin/fdformat/Makefile1
-rw-r--r--usr.sbin/fdformat/fdformat.8 (renamed from usr.sbin/fdformat/fdformat.1)4
-rw-r--r--usr.sbin/makefs/ffs.c2
-rw-r--r--usr.sbin/nandtool/nand_read.c2
-rw-r--r--usr.sbin/nandtool/nand_readoob.c2
-rw-r--r--usr.sbin/pw/psdate.c2
-rw-r--r--usr.sbin/pw/psdate.h1
-rw-r--r--usr.sbin/pw/pw.810
-rw-r--r--usr.sbin/pw/pw.h8
-rw-r--r--usr.sbin/pw/pw_conf.c8
-rw-r--r--usr.sbin/pw/pw_user.c77
-rw-r--r--usr.sbin/syslogd/syslogd.c5
576 files changed, 14801 insertions, 6075 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..d3452fd
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,5 @@
+*.c diff=cpp
+*.h diff=cpp
+*.cpp diff=cpp
+*.hpp diff=cpp
+*.py diff=python
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..26a1bb9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+_.tinderbox.*
+_.amd64.*
+_.arm.*
+_.arm64.*
+_.i386.*
+_.ia64.*
+_.mips.*
+_.pc98.*
+_.powerpc.*
+_.riscv.*
+_.sparc64.*
+_.sun4v.*
+GPATH
+GRTAGS
+GTAGS
+ID
+cscope.out
+?cscope.out
diff --git a/COPYRIGHT b/COPYRIGHT
index f35a1ef..f1dce1e 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -4,7 +4,7 @@
The compilation of software known as FreeBSD is distributed under the
following terms:
-Copyright (c) 1992-2017 The FreeBSD Project. All rights reserved.
+Copyright (c) 1992-2018 The FreeBSD Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
diff --git a/Makefile.inc1 b/Makefile.inc1
index 0f66b9a..f1970a6 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -260,10 +260,11 @@ SUBDIR+= tests
SUBDIR+=contrib/ofed
.endif
-# Local directories are last, since it is nice to at least get the base
-# system rebuilt before you do them.
+# Local directories are built in parallel with the base system directories.
+# Users may insert a .WAIT directive at the beginning or elsewhere within
+# the LOCAL_DIRS and LOCAL_LIB_DIRS lists as needed.
.for _DIR in ${LOCAL_DIRS}
-.if exists(${.CURDIR}/${_DIR}/Makefile)
+.if ${_DIR} == ".WAIT" || exists(${.CURDIR}/${_DIR}/Makefile)
SUBDIR+= ${_DIR}
.endif
.endfor
@@ -274,7 +275,7 @@ SUBDIR+= ${_DIR}
_REDUNDANT_LIB_DIRS+= ${LOCAL_LIB_DIRS:M${_DIR}*}
.endfor
.for _DIR in ${LOCAL_LIB_DIRS}
-.if empty(_REDUNDANT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile)
+.if ${_DIR} == ".WAIT" || (empty(_REDUNDANT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile))
SUBDIR+= ${_DIR}
.endif
.endfor
@@ -2146,7 +2147,7 @@ lib/liblzma__L: lib/libthr__L
_generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib ${_ofed_lib}
.for _DIR in ${LOCAL_LIB_DIRS}
-.if exists(${.CURDIR}/${_DIR}/Makefile) && empty(_generic_libs:M${_DIR})
+.if ${_DIR} == ".WAIT" || (empty(_generic_libs:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile))
_generic_libs+= ${_DIR}
.endif
.endfor
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index b9e1eca..cb3d5e4 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,6 +38,125 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20171226: new clang import which bumps version from 5.0.0 to 5.0.1.
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/allocator_interface.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/asan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/common_interface_defs.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/coverage_interface.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/dfsan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/esan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/linux_syscall_hooks.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/lsan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/msan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/tsan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/tsan_interface_atomic.h
+OLD_DIRS+=usr/lib/clang/5.0.0/include/sanitizer
+OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_builtin_vars.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_cmath.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_complex_builtins.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_intrinsics.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_math_forward_declares.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_runtime_wrapper.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/__stddef_max_align_t.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/__wmmintrin_aes.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/__wmmintrin_pclmul.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/adxintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/altivec.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/ammintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/arm_acle.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/arm_neon.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/armintr.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx2intrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512bwintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512cdintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512dqintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512erintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512fintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512ifmaintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512ifmavlintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512pfintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vbmiintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vbmivlintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlbwintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlcdintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vldqintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vpopcntdqintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/avxintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/bmi2intrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/bmiintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/clflushoptintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/clzerointrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/cpuid.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/emmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/f16cintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/fma4intrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/fmaintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/fxsrintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/htmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/htmxlintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/ia32intrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/immintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/lwpintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/lzcntintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/mm3dnow.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/mm_malloc.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/mmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/module.modulemap
+OLD_FILES+=usr/lib/clang/5.0.0/include/msa.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/mwaitxintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/nmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/opencl-c.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/pkuintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/pmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/popcntintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/prfchwintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/rdseedintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/rtmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/s390intrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/shaintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/smmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/tbmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/tmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/vadefs.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/vecintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/wmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/x86intrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/xmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/xopintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/xsavecintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/xsaveintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/xsaveoptintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/xsavesintrin.h
+OLD_FILES+=usr/lib/clang/5.0.0/include/xtestintrin.h
+OLD_DIRS+=usr/lib/clang/5.0.0/include
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-i386.so
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-x86_64.so
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-arm.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-armhf.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.safestack-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats_client-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a
+OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a
+OLD_DIRS+=usr/lib/clang/5.0.0/lib/freebsd
+OLD_DIRS+=usr/lib/clang/5.0.0/lib
+OLD_DIRS+=usr/lib/clang/5.0.0
+# 20171204: Move fdformat man page from volume 1 to volume 8.
+OLD_FILES+=usr/share/man/man1/fdformat.1.gz
# 20170926: new clang import which bumps version from 4.0.0 to 5.0.0.
OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/allocator_interface.h
OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/asan_interface.h
diff --git a/cddl/usr.bin/ctfconvert/Makefile b/cddl/usr.bin/ctfconvert/Makefile
index ce42381..42061c1 100644
--- a/cddl/usr.bin/ctfconvert/Makefile
+++ b/cddl/usr.bin/ctfconvert/Makefile
@@ -1,5 +1,7 @@
# $FreeBSD$
+.include <src.opts.mk>
+
.PATH: ${SRCTOP}/cddl/contrib/opensolaris/tools/ctf/common
.PATH: ${SRCTOP}/cddl/contrib/opensolaris/tools/ctf/cvt
@@ -36,4 +38,7 @@ CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris \
LIBADD= dwarf elf z pthread
+HAS_TESTS=
+SUBDIR.${MK_TESTS}+= tests
+
.include <bsd.prog.mk>
diff --git a/cddl/usr.bin/ctfconvert/tests/Makefile b/cddl/usr.bin/ctfconvert/tests/Makefile
new file mode 100644
index 0000000..431a1f2
--- /dev/null
+++ b/cddl/usr.bin/ctfconvert/tests/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+ATF_TESTS_SH+= ctfconvert_test
+
+.include <bsd.test.mk>
diff --git a/cddl/usr.bin/ctfconvert/tests/ctfconvert_test.sh b/cddl/usr.bin/ctfconvert/tests/ctfconvert_test.sh
new file mode 100644
index 0000000..04723fd
--- /dev/null
+++ b/cddl/usr.bin/ctfconvert/tests/ctfconvert_test.sh
@@ -0,0 +1,62 @@
+#
+# Copyright 2017 Shivansh
+# 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$
+#
+
+usage_output='Usage: ctfconvert'
+
+atf_test_case invalid_usage
+invalid_usage_head()
+{
+ atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
+}
+
+invalid_usage_body()
+{
+ atf_check -s not-exit:0 -e match:"$usage_output" ctfconvert -l
+ atf_check -s not-exit:0 -e match:"$usage_output" ctfconvert -L
+ atf_check -s not-exit:0 -e match:"$usage_output" ctfconvert -g
+ atf_check -s not-exit:0 -e match:"$usage_output" ctfconvert -i
+ atf_check -s not-exit:0 -e match:"$usage_output" ctfconvert -s
+ atf_check -s not-exit:0 -e match:"$usage_output" ctfconvert -o
+}
+
+atf_test_case no_arguments
+no_arguments_head()
+{
+ atf_set "descr" "Verify that ctfconvert(1) fails and generates a valid usage message when no arguments are supplied"
+}
+
+no_arguments_body()
+{
+ atf_check -s not-exit:0 -e match:"$usage_output" ctfconvert
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case invalid_usage
+ atf_add_test_case no_arguments
+}
diff --git a/cddl/usr.sbin/dtrace/tests/tools/exclude.sh b/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
index 0836b43..819f68f 100755
--- a/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
+++ b/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
@@ -175,6 +175,9 @@ exclude EXFAIL common/vars/tst.ucaller.ksh
exclude EXFAIL common/scripting/tst.projid.ksh
exclude EXFAIL common/scripting/tst.taskid.ksh
+# Depends on tst.chasestrings.exe being ELF32. See r326181 and r326285.
+exclude EXFAIL common/uctf/err.user64mode.ksh
+
# This test expects its test program to be installed without CTF data, but
# the rest of the programs for this feature need CTF data. Not yet sure how
# to build that.
diff --git a/contrib/binutils/bfd/elflink.c b/contrib/binutils/bfd/elflink.c
index 10d987c..2022b96 100644
--- a/contrib/binutils/bfd/elflink.c
+++ b/contrib/binutils/bfd/elflink.c
@@ -4815,7 +4815,7 @@ _bfd_elf_archive_symbol_lookup (bfd *abfd,
len = strlen (name);
copy = bfd_alloc (abfd, len);
if (copy == NULL)
- return (struct elf_link_hash_entry *) 0 - 1;
+ return (struct elf_link_hash_entry *)(intptr_t)-1;
first = p - name + 1;
memcpy (copy, name, first);
@@ -4927,7 +4927,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
}
h = archive_symbol_lookup (abfd, info, symdef->name);
- if (h == (struct elf_link_hash_entry *) 0 - 1)
+ if (h == (struct elf_link_hash_entry *)(intptr_t)-1)
goto error_return;
if (h == NULL)
diff --git a/contrib/binutils/include/obstack.h b/contrib/binutils/include/obstack.h
index 88c2a26..725b6cc 100644
--- a/contrib/binutils/include/obstack.h
+++ b/contrib/binutils/include/obstack.h
@@ -119,11 +119,11 @@ extern "C" {
may ignore the byte-within-word field of the pointer. */
#ifndef __PTR_TO_INT
-# define __PTR_TO_INT(P) ((P) - (char *) 0)
+# define __PTR_TO_INT(P) ((intptr_t)(P))
#endif
#ifndef __INT_TO_PTR
-# define __INT_TO_PTR(P) ((P) + (char *) 0)
+# define __INT_TO_PTR(P) ((void*)(intptr_t)(P))
#endif
/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is
@@ -427,7 +427,7 @@ __extension__ \
__o1->maybe_empty_object = 1; \
__o1->next_free \
= __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
- & ~ (__o1->alignment_mask)); \
+ & ~(intptr_t)(__o1->alignment_mask)); \
if (__o1->next_free - (char *)__o1->chunk \
> __o1->chunk_limit - (char *)__o1->chunk) \
__o1->next_free = __o1->chunk_limit; \
diff --git a/contrib/elftoolchain/elfcopy/binary.c b/contrib/elftoolchain/elfcopy/binary.c
index ad86a65..0b56ae0 100644
--- a/contrib/elftoolchain/elfcopy/binary.c
+++ b/contrib/elftoolchain/elfcopy/binary.c
@@ -101,10 +101,10 @@ create_binary(int ifd, int ofd)
sh.sh_size == 0)
continue;
(void) elf_errno();
- if ((d = elf_getdata(scn, NULL)) == NULL) {
+ if ((d = elf_rawdata(scn, NULL)) == NULL) {
elferr = elf_errno();
if (elferr != 0)
- warnx("elf_getdata failed: %s", elf_errmsg(-1));
+ warnx("elf_rawdata failed: %s", elf_errmsg(-1));
continue;
}
if (d->d_buf == NULL || d->d_size == 0)
diff --git a/contrib/libc++/include/algorithm b/contrib/libc++/include/algorithm
index 4542275..00db6d7 100644
--- a/contrib/libc++/include/algorithm
+++ b/contrib/libc++/include/algorithm
@@ -3013,6 +3013,7 @@ template<class _Engine, class _UIntType>
_UIntType
__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
{
+ const size_t _WRt = numeric_limits<result_type>::digits;
result_type _Sp = 0;
for (size_t __k = 0; __k < __n0_; ++__k)
{
@@ -3021,7 +3022,7 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
{
__u = __e_() - _Engine::min();
} while (__u >= __y0_);
- if (__w0_ < _WDt)
+ if (__w0_ < _WRt)
_Sp <<= __w0_;
else
_Sp = 0;
@@ -3034,7 +3035,7 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
{
__u = __e_() - _Engine::min();
} while (__u >= __y1_);
- if (__w0_ < _WDt - 1)
+ if (__w0_ < _WRt - 1)
_Sp <<= __w0_ + 1;
else
_Sp = 0;
diff --git a/contrib/libc++/include/deque b/contrib/libc++/include/deque
index f795b48..fee7561 100644
--- a/contrib/libc++/include/deque
+++ b/contrib/libc++/include/deque
@@ -1356,7 +1356,6 @@ public:
iterator insert(const_iterator __p, initializer_list<value_type> __il)
{return insert(__p, __il.begin(), __il.end());}
#endif // _LIBCPP_CXX03_LANG
-
iterator insert(const_iterator __p, const value_type& __v);
iterator insert(const_iterator __p, size_type __n, const value_type& __v);
template <class _InputIter>
@@ -2224,7 +2223,11 @@ deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
!__is_forward_iterator<_InpIter>::value>::type*)
{
for (; __f != __l; ++__f)
+#ifdef _LIBCPP_CXX03_LANG
push_back(*__f);
+#else
+ emplace_back(*__f);
+#endif
}
template <class _Tp, class _Allocator>
diff --git a/contrib/libc++/include/functional b/contrib/libc++/include/functional
index 83a2e5a..f73c3ca 100644
--- a/contrib/libc++/include/functional
+++ b/contrib/libc++/include/functional
@@ -1597,9 +1597,11 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
return reinterpret_cast<__base*>(p);
}
- template <class _Fp, bool = !is_same<_Fp, function>::value &&
- __invokable<_Fp&, _ArgTypes...>::value>
- struct __callable;
+ template <class _Fp, bool = __lazy_and<
+ integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>,
+ __invokable<_Fp&, _ArgTypes...>
+ >::value>
+ struct __callable;
template <class _Fp>
struct __callable<_Fp, true>
{
@@ -1612,6 +1614,9 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
{
static const bool value = false;
};
+
+ template <class _Fp>
+ using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type;
public:
typedef _Rp result_type;
@@ -1622,9 +1627,7 @@ public:
function(nullptr_t) _NOEXCEPT : __f_(0) {}
function(const function&);
function(function&&) _NOEXCEPT;
- template<class _Fp, class = typename enable_if<
- __callable<_Fp>::value && !is_same<_Fp, function>::value
- >::type>
+ template<class _Fp, class = _EnableIfCallable<_Fp>>
function(_Fp);
#if _LIBCPP_STD_VER <= 14
@@ -1638,21 +1641,15 @@ public:
function(allocator_arg_t, const _Alloc&, const function&);
template<class _Alloc>
function(allocator_arg_t, const _Alloc&, function&&);
- template<class _Fp, class _Alloc, class = typename enable_if<__callable<_Fp>::value>::type>
+ template<class _Fp, class _Alloc, class = _EnableIfCallable<_Fp>>
function(allocator_arg_t, const _Alloc& __a, _Fp __f);
#endif
function& operator=(const function&);
function& operator=(function&&) _NOEXCEPT;
function& operator=(nullptr_t) _NOEXCEPT;
- template<class _Fp>
- typename enable_if
- <
- __callable<typename decay<_Fp>::type>::value &&
- !is_same<typename remove_reference<_Fp>::type, function>::value,
- function&
- >::type
- operator=(_Fp&&);
+ template<class _Fp, class = _EnableIfCallable<_Fp>>
+ function& operator=(_Fp&&);
~function();
@@ -1854,13 +1851,8 @@ function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
}
template<class _Rp, class ..._ArgTypes>
-template <class _Fp>
-typename enable_if
-<
- function<_Rp(_ArgTypes...)>::template __callable<typename decay<_Fp>::type>::value &&
- !is_same<typename remove_reference<_Fp>::type, function<_Rp(_ArgTypes...)>>::value,
- function<_Rp(_ArgTypes...)>&
->::type
+template <class _Fp, class>
+function<_Rp(_ArgTypes...)>&
function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
{
function(_VSTD::forward<_Fp>(__f)).swap(*this);
diff --git a/contrib/libc++/include/list b/contrib/libc++/include/list
index 20a66c3..9c70fff 100644
--- a/contrib/libc++/include/list
+++ b/contrib/libc++/include/list
@@ -992,6 +992,15 @@ public:
void push_front(const value_type& __x);
void push_back(const value_type& __x);
+#ifndef _LIBCPP_CXX03_LANG
+ template <class _Arg>
+ _LIBCPP_INLINE_VISIBILITY
+ void __emplace_back(_Arg&& __arg) { emplace_back(_VSTD::forward<_Arg>(__arg)); }
+#else
+ _LIBCPP_INLINE_VISIBILITY
+ void __emplace_back(value_type const& __arg) { push_back(__arg); }
+#endif
+
iterator insert(const_iterator __p, const value_type& __x);
iterator insert(const_iterator __p, size_type __n, const value_type& __x);
template <class _InpIter>
@@ -1189,7 +1198,7 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
__get_db()->__insert_c(this);
#endif
for (; __f != __l; ++__f)
- push_back(*__f);
+ __emplace_back(*__f);
}
template <class _Tp, class _Alloc>
@@ -1202,7 +1211,7 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,
__get_db()->__insert_c(this);
#endif
for (; __f != __l; ++__f)
- push_back(*__f);
+ __emplace_back(*__f);
}
template <class _Tp, class _Alloc>
diff --git a/contrib/libc++/include/string b/contrib/libc++/include/string
index 610f19e..7775587 100644
--- a/contrib/libc++/include/string
+++ b/contrib/libc++/include/string
@@ -259,7 +259,7 @@ public:
size_type find(value_type c, size_type pos = 0) const noexcept;
size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
- size_type ffind(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
+ size_type rfind(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;
size_type rfind(const value_type* s, size_type pos = npos) const noexcept;
size_type rfind(value_type c, size_type pos = npos) const noexcept;
@@ -271,7 +271,7 @@ public:
size_type find_first_of(value_type c, size_type pos = 0) const noexcept;
size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
- size_type find_last_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
+ size_type find_last_of(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;
size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;
size_type find_last_of(value_type c, size_type pos = npos) const noexcept;
@@ -283,7 +283,7 @@ public:
size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;
size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
- size_type find_last_not_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
+ size_type find_last_not_of(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;
size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;
@@ -1147,7 +1147,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
- size_type rfind(__self_view __sv, size_type __pos = 0) const _NOEXCEPT;
+ size_type rfind(__self_view __sv, size_type __pos = npos) const _NOEXCEPT;
size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
@@ -1166,7 +1166,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
- size_type find_last_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT;
+ size_type find_last_of(__self_view __sv, size_type __pos = npos) const _NOEXCEPT;
size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
@@ -1186,7 +1186,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
- size_type find_last_not_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT;
+ size_type find_last_not_of(__self_view __sv, size_type __pos = npos) const _NOEXCEPT;
size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
diff --git a/contrib/libc++/include/type_traits b/contrib/libc++/include/type_traits
index 9db4d66..6c111ab 100644
--- a/contrib/libc++/include/type_traits
+++ b/contrib/libc++/include/type_traits
@@ -4339,8 +4339,8 @@ struct __invokable_r
using _Result = decltype(
_VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...));
- static const bool value =
- conditional<
+ using type =
+ typename conditional<
!is_same<_Result, __nat>::value,
typename conditional<
is_void<_Ret>::value,
@@ -4348,7 +4348,8 @@ struct __invokable_r
is_convertible<_Result, _Ret>
>::type,
false_type
- >::type::value;
+ >::type;
+ static const bool value = type::value;
};
template <class _Fp, class ..._Args>
diff --git a/contrib/libc++/include/vector b/contrib/libc++/include/vector
index 6e9920a..b2f8f09 100644
--- a/contrib/libc++/include/vector
+++ b/contrib/libc++/include/vector
@@ -674,6 +674,17 @@ public:
const value_type* data() const _NOEXCEPT
{return _VSTD::__to_raw_pointer(this->__begin_);}
+#ifdef _LIBCPP_CXX03_LANG
+ _LIBCPP_INLINE_VISIBILITY
+ void __emplace_back(const value_type& __x) { push_back(__x); }
+#else
+ template <class _Arg>
+ _LIBCPP_INLINE_VISIBILITY
+ void __emplace_back(_Arg&& __arg) {
+ emplace_back(_VSTD::forward<_Arg>(__arg));
+ }
+#endif
+
_LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
#ifndef _LIBCPP_CXX03_LANG
@@ -1128,7 +1139,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first,
__get_db()->__insert_c(this);
#endif
for (; __first != __last; ++__first)
- push_back(*__first);
+ __emplace_back(*__first);
}
template <class _Tp, class _Allocator>
@@ -1145,7 +1156,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, c
__get_db()->__insert_c(this);
#endif
for (; __first != __last; ++__first)
- push_back(*__first);
+ __emplace_back(*__first);
}
template <class _Tp, class _Allocator>
@@ -1365,7 +1376,7 @@ vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
{
clear();
for (; __first != __last; ++__first)
- push_back(*__first);
+ __emplace_back(*__first);
}
template <class _Tp, class _Allocator>
diff --git a/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 0b07fe9..9bbda71 100644
--- a/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -652,6 +652,12 @@ public:
auto GTI = gep_type_begin(PointeeType, Operands);
Type *TargetType;
+
+ // Handle the case where the GEP instruction has a single operand,
+ // the basis, therefore TargetType is a nullptr.
+ if (Operands.empty())
+ return !BaseGV ? TTI::TCC_Free : TTI::TCC_Basic;
+
for (auto I = Operands.begin(); I != Operands.end(); ++I, ++GTI) {
TargetType = GTI.getIndexedType();
// We assume that the cost of Scalar GEP with constant index and the
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 8347f00..5ef0ac9 100644
--- a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -807,6 +807,14 @@ public:
return getReservedRegs().test(PhysReg);
}
+ /// Returns true when the given register unit is considered reserved.
+ ///
+ /// Register units are considered reserved when for at least one of their
+ /// root registers, the root register and all super registers are reserved.
+ /// This currently iterates the register hierarchy and may be slower than
+ /// expected.
+ bool isReservedRegUnit(unsigned Unit) const;
+
/// isAllocatable - Returns true when PhysReg belongs to an allocatable
/// register class and it hasn't been reserved.
///
diff --git a/contrib/llvm/include/llvm/IR/AutoUpgrade.h b/contrib/llvm/include/llvm/IR/AutoUpgrade.h
index b42a3d3..3f406f0 100644
--- a/contrib/llvm/include/llvm/IR/AutoUpgrade.h
+++ b/contrib/llvm/include/llvm/IR/AutoUpgrade.h
@@ -51,6 +51,8 @@ namespace llvm {
/// module is modified.
bool UpgradeModuleFlags(Module &M);
+ void UpgradeSectionAttributes(Module &M);
+
/// If the given TBAA tag uses the scalar TBAA format, create a new node
/// corresponding to the upgrade to the struct-path aware TBAA format.
/// Otherwise return the \p TBAANode itself.
diff --git a/contrib/llvm/include/llvm/Support/FormatVariadic.h b/contrib/llvm/include/llvm/Support/FormatVariadic.h
index c1153e8..408c6d8 100644
--- a/contrib/llvm/include/llvm/Support/FormatVariadic.h
+++ b/contrib/llvm/include/llvm/Support/FormatVariadic.h
@@ -94,6 +94,15 @@ public:
Adapters.reserve(ParamCount);
}
+ formatv_object_base(formatv_object_base const &rhs) = delete;
+
+ formatv_object_base(formatv_object_base &&rhs)
+ : Fmt(std::move(rhs.Fmt)),
+ Adapters(), // Adapters are initialized by formatv_object
+ Replacements(std::move(rhs.Replacements)) {
+ Adapters.reserve(rhs.Adapters.size());
+ };
+
void format(raw_ostream &S) const {
for (auto &R : Replacements) {
if (R.Type == ReplacementType::Empty)
@@ -149,6 +158,14 @@ public:
Parameters(std::move(Params)) {
Adapters = apply_tuple(create_adapters(), Parameters);
}
+
+ formatv_object(formatv_object const &rhs) = delete;
+
+ formatv_object(formatv_object &&rhs)
+ : formatv_object_base(std::move(rhs)),
+ Parameters(std::move(rhs.Parameters)) {
+ Adapters = apply_tuple(create_adapters(), Parameters);
+ }
};
// \brief Format text given a format string and replacement parameters.
diff --git a/contrib/llvm/lib/AsmParser/LLParser.cpp b/contrib/llvm/lib/AsmParser/LLParser.cpp
index 13679ce..234805a 100644
--- a/contrib/llvm/lib/AsmParser/LLParser.cpp
+++ b/contrib/llvm/lib/AsmParser/LLParser.cpp
@@ -240,6 +240,7 @@ bool LLParser::ValidateEndOfModule() {
UpgradeDebugInfo(*M);
UpgradeModuleFlags(*M);
+ UpgradeSectionAttributes(*M);
if (!Slots)
return false;
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 2b4970a..048e367 100644
--- a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -264,7 +264,7 @@ Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) {
if (convertToString(Record, 0, S))
return error("Invalid record");
// Check for the i386 and other (x86_64, ARM) conventions
- if (S.find("__DATA, __objc_catlist") != std::string::npos ||
+ if (S.find("__DATA,__objc_catlist") != std::string::npos ||
S.find("__OBJC,__category") != std::string::npos)
return true;
break;
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 676c48f..333d14a 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -621,6 +621,7 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
auto *SP = cast<DISubprogram>(Scope->getScopeNode());
DIE *ContextDIE;
+ DwarfCompileUnit *ContextCU = this;
if (includeMinimalInlineScopes())
ContextDIE = &getUnitDie();
@@ -631,18 +632,23 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
else if (auto *SPDecl = SP->getDeclaration()) {
ContextDIE = &getUnitDie();
getOrCreateSubprogramDIE(SPDecl);
- } else
+ } else {
ContextDIE = getOrCreateContextDIE(resolve(SP->getScope()));
+ // The scope may be shared with a subprogram that has already been
+ // constructed in another CU, in which case we need to construct this
+ // subprogram in the same CU.
+ ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
+ }
// Passing null as the associated node because the abstract definition
// shouldn't be found by lookup.
- AbsDef = &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
- applySubprogramAttributesToDefinition(SP, *AbsDef);
+ AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
+ ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
- if (!includeMinimalInlineScopes())
- addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
- if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef))
- addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
+ if (!ContextCU->includeMinimalInlineScopes())
+ ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
+ if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
+ ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
}
DIE *DwarfCompileUnit::constructImportedEntityDIE(
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 5dfe06c..78ee9a1 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -283,7 +283,7 @@ class DwarfDebug : public DebugHandlerBase {
// 0, referencing the comp_dir of all the type units that use it.
MCDwarfDwoLineTable SplitTypeUnitFileTable;
/// @}
-
+
/// True iff there are multiple CUs in this module.
bool SingleCU;
bool IsDarwin;
@@ -562,6 +562,9 @@ public:
bool isLexicalScopeDIENull(LexicalScope *Scope);
bool hasDwarfPubSections(bool includeMinimalInlineScopes) const;
+
+ /// Find the matching DwarfCompileUnit for the given CU DIE.
+ DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Die); }
};
} // End of namespace llvm
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index fe38ee8..3a8568c 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -131,13 +131,12 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// Intersection between the bits we already emitted and the bits
// covered by this subregister.
- SmallBitVector Intersection(RegSize, false);
- Intersection.set(Offset, Offset + Size);
- Intersection ^= Coverage;
+ SmallBitVector CurSubReg(RegSize, false);
+ CurSubReg.set(Offset, Offset + Size);
// If this sub-register has a DWARF number and we haven't covered
// its range, emit a DWARF piece for it.
- if (Reg >= 0 && Intersection.any()) {
+ if (Reg >= 0 && CurSubReg.test(Coverage)) {
// Emit a piece for any gap in the coverage.
if (Offset > CurPos)
DwarfRegs.push_back({-1, Offset - CurPos, nullptr});
diff --git a/contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
index 471dcea..0e240f4 100644
--- a/contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/contrib/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -269,8 +269,9 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) {
// may share super-registers. That's OK because createDeadDefs() is
// idempotent. It is very rare for a register unit to have multiple roots, so
// uniquing super-registers is probably not worthwhile.
- bool IsReserved = true;
+ bool IsReserved = false;
for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
+ bool IsRootReserved = true;
for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
Super.isValid(); ++Super) {
unsigned Reg = *Super;
@@ -279,9 +280,12 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) {
// A register unit is considered reserved if all its roots and all their
// super registers are reserved.
if (!MRI->isReserved(Reg))
- IsReserved = false;
+ IsRootReserved = false;
}
+ IsReserved |= IsRootReserved;
}
+ assert(IsReserved == MRI->isReservedRegUnit(Unit) &&
+ "reserved computation mismatch");
// Now extend LR to reach all uses.
// Ignore uses of reserved registers. We only track defs of those.
@@ -924,7 +928,7 @@ public:
// kill flags. This is wasteful. Eventually, LiveVariables will strip all kill
// flags, and postRA passes will use a live register utility instead.
LiveRange *getRegUnitLI(unsigned Unit) {
- if (UpdateFlags)
+ if (UpdateFlags && !MRI.isReservedRegUnit(Unit))
return &LIS.getRegUnit(Unit);
return LIS.getCachedRegUnit(Unit);
}
diff --git a/contrib/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/contrib/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 9a92ee2..be06053 100644
--- a/contrib/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -601,3 +601,21 @@ void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
UpdatedCSRs.push_back(0);
IsUpdatedCSRsInitialized = true;
}
+
+bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
+ const TargetRegisterInfo *TRI = getTargetRegisterInfo();
+ for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
+ bool IsRootReserved = true;
+ for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
+ Super.isValid(); ++Super) {
+ unsigned Reg = *Super;
+ if (!isReserved(Reg)) {
+ IsRootReserved = false;
+ break;
+ }
+ }
+ if (IsRootReserved)
+ return true;
+ }
+ return false;
+}
diff --git a/contrib/llvm/lib/CodeGen/MachineVerifier.cpp b/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
index fcb5448..c50a95a 100644
--- a/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1316,6 +1316,8 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
// Check the cached regunit intervals.
if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) {
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
+ if (MRI->isReservedRegUnit(*Units))
+ continue;
if (const LiveRange *LR = LiveInts->getCachedRegUnit(*Units))
checkLivenessAtUse(MO, MONum, UseIdx, *LR, *Units);
}
diff --git a/contrib/llvm/lib/IR/AutoUpgrade.cpp b/contrib/llvm/lib/IR/AutoUpgrade.cpp
index a501799..80640de 100644
--- a/contrib/llvm/lib/IR/AutoUpgrade.cpp
+++ b/contrib/llvm/lib/IR/AutoUpgrade.cpp
@@ -2271,6 +2271,24 @@ bool llvm::UpgradeModuleFlags(Module &M) {
}
}
}
+ // Upgrade Objective-C Image Info Section. Removed the whitespce in the
+ // section name so that llvm-lto will not complain about mismatching
+ // module flags that is functionally the same.
+ if (ID->getString() == "Objective-C Image Info Section") {
+ if (auto *Value = dyn_cast_or_null<MDString>(Op->getOperand(2))) {
+ SmallVector<StringRef, 4> ValueComp;
+ Value->getString().split(ValueComp, " ");
+ if (ValueComp.size() != 1) {
+ std::string NewValue;
+ for (auto &S : ValueComp)
+ NewValue += S.str();
+ Metadata *Ops[3] = {Op->getOperand(0), Op->getOperand(1),
+ MDString::get(M.getContext(), NewValue)};
+ ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
+ Changed = true;
+ }
+ }
+ }
}
// "Objective-C Class Properties" is recently added for Objective-C. We
@@ -2287,6 +2305,35 @@ bool llvm::UpgradeModuleFlags(Module &M) {
return Changed;
}
+void llvm::UpgradeSectionAttributes(Module &M) {
+ auto TrimSpaces = [](StringRef Section) -> std::string {
+ SmallVector<StringRef, 5> Components;
+ Section.split(Components, ',');
+
+ SmallString<32> Buffer;
+ raw_svector_ostream OS(Buffer);
+
+ for (auto Component : Components)
+ OS << ',' << Component.trim();
+
+ return OS.str().substr(1);
+ };
+
+ for (auto &GV : M.globals()) {
+ if (!GV.hasSection())
+ continue;
+
+ StringRef Section = GV.getSection();
+
+ if (!Section.startswith("__DATA, __objc_catlist"))
+ continue;
+
+ // __DATA, __objc_catlist, regular, no_dead_strip
+ // __DATA,__objc_catlist,regular,no_dead_strip
+ GV.setSection(TrimSpaces(Section));
+ }
+}
+
static bool isOldLoopArgument(Metadata *MD) {
auto *T = dyn_cast_or_null<MDTuple>(MD);
if (!T)
diff --git a/contrib/llvm/lib/IR/ConstantFold.cpp b/contrib/llvm/lib/IR/ConstantFold.cpp
index 311b0a7..996331e 100644
--- a/contrib/llvm/lib/IR/ConstantFold.cpp
+++ b/contrib/llvm/lib/IR/ConstantFold.cpp
@@ -2199,6 +2199,9 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
Unknown = true;
continue;
}
+ if (!isa<ConstantInt>(Idxs[i - 1]))
+ // FIXME: add the support of cosntant vector index.
+ continue;
if (InRangeIndex && i == *InRangeIndex + 1) {
// If an index is marked inrange, we cannot apply this canonicalization to
// the following index, as that will cause the inrange index to point to
diff --git a/contrib/llvm/lib/Linker/IRMover.cpp b/contrib/llvm/lib/Linker/IRMover.cpp
index f486e52..ee067a9 100644
--- a/contrib/llvm/lib/Linker/IRMover.cpp
+++ b/contrib/llvm/lib/Linker/IRMover.cpp
@@ -640,6 +640,10 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
} else {
if (ForDefinition)
NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV));
+ else if (SGV->getValueType()->isFunctionTy())
+ NewGV =
+ Function::Create(cast<FunctionType>(TypeMap.get(SGV->getValueType())),
+ GlobalValue::ExternalLinkage, SGV->getName(), &DstM);
else
NewGV = new GlobalVariable(
DstM, TypeMap.get(SGV->getValueType()),
diff --git a/contrib/llvm/lib/Linker/LinkModules.cpp b/contrib/llvm/lib/Linker/LinkModules.cpp
index c0ce4bf..25f31a3 100644
--- a/contrib/llvm/lib/Linker/LinkModules.cpp
+++ b/contrib/llvm/lib/Linker/LinkModules.cpp
@@ -329,8 +329,18 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
GlobalValue *DGV = getLinkedToGlobal(&GV);
- if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration()))
- return false;
+ if (shouldLinkOnlyNeeded()) {
+ // Always import variables with appending linkage.
+ if (!GV.hasAppendingLinkage()) {
+ // Don't import globals unless they are referenced by the destination
+ // module.
+ if (!DGV)
+ return false;
+ // Don't import globals that are already defined in the destination module
+ if (!DGV->isDeclaration())
+ return false;
+ }
+ }
if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) {
auto *DGVar = dyn_cast<GlobalVariable>(DGV);
diff --git a/contrib/llvm/lib/Support/Host.cpp b/contrib/llvm/lib/Support/Host.cpp
index 5cf0316..f1c0d3a 100644
--- a/contrib/llvm/lib/Support/Host.cpp
+++ b/contrib/llvm/lib/Support/Host.cpp
@@ -208,6 +208,7 @@ StringRef sys::detail::getHostCPUNameForARM(
.Case("0x06f", "krait") // APQ8064
.Case("0x201", "kryo")
.Case("0x205", "kryo")
+ .Case("0xc00", "falkor")
.Default("generic");
return "generic";
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp b/contrib/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp
index c0e2235..2c887a9 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp
+++ b/contrib/llvm/lib/Target/AArch64/AArch64FalkorHWPFFix.cpp
@@ -220,27 +220,27 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
default:
return None;
+ case AArch64::LD1i64:
+ case AArch64::LD2i64:
+ DestRegIdx = 0;
+ BaseRegIdx = 3;
+ OffsetIdx = -1;
+ IsPrePost = false;
+ break;
+
case AArch64::LD1i8:
case AArch64::LD1i16:
case AArch64::LD1i32:
- case AArch64::LD1i64:
case AArch64::LD2i8:
case AArch64::LD2i16:
case AArch64::LD2i32:
- case AArch64::LD2i64:
case AArch64::LD3i8:
case AArch64::LD3i16:
case AArch64::LD3i32:
+ case AArch64::LD3i64:
case AArch64::LD4i8:
case AArch64::LD4i16:
case AArch64::LD4i32:
- DestRegIdx = 0;
- BaseRegIdx = 3;
- OffsetIdx = -1;
- IsPrePost = false;
- break;
-
- case AArch64::LD3i64:
case AArch64::LD4i64:
DestRegIdx = -1;
BaseRegIdx = 3;
@@ -264,23 +264,16 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
case AArch64::LD1Rv4s:
case AArch64::LD1Rv8h:
case AArch64::LD1Rv16b:
- case AArch64::LD1Twov1d:
- case AArch64::LD1Twov2s:
- case AArch64::LD1Twov4h:
- case AArch64::LD1Twov8b:
- case AArch64::LD2Twov2s:
- case AArch64::LD2Twov4s:
- case AArch64::LD2Twov8b:
- case AArch64::LD2Rv1d:
- case AArch64::LD2Rv2s:
- case AArch64::LD2Rv4s:
- case AArch64::LD2Rv8b:
DestRegIdx = 0;
BaseRegIdx = 1;
OffsetIdx = -1;
IsPrePost = false;
break;
+ case AArch64::LD1Twov1d:
+ case AArch64::LD1Twov2s:
+ case AArch64::LD1Twov4h:
+ case AArch64::LD1Twov8b:
case AArch64::LD1Twov2d:
case AArch64::LD1Twov4s:
case AArch64::LD1Twov8h:
@@ -301,10 +294,17 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
case AArch64::LD1Fourv4s:
case AArch64::LD1Fourv8h:
case AArch64::LD1Fourv16b:
+ case AArch64::LD2Twov2s:
+ case AArch64::LD2Twov4s:
+ case AArch64::LD2Twov8b:
case AArch64::LD2Twov2d:
case AArch64::LD2Twov4h:
case AArch64::LD2Twov8h:
case AArch64::LD2Twov16b:
+ case AArch64::LD2Rv1d:
+ case AArch64::LD2Rv2s:
+ case AArch64::LD2Rv4s:
+ case AArch64::LD2Rv8b:
case AArch64::LD2Rv2d:
case AArch64::LD2Rv4h:
case AArch64::LD2Rv8h:
@@ -345,32 +345,32 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
IsPrePost = false;
break;
+ case AArch64::LD1i64_POST:
+ case AArch64::LD2i64_POST:
+ DestRegIdx = 1;
+ BaseRegIdx = 4;
+ OffsetIdx = 5;
+ IsPrePost = true;
+ break;
+
case AArch64::LD1i8_POST:
case AArch64::LD1i16_POST:
case AArch64::LD1i32_POST:
- case AArch64::LD1i64_POST:
case AArch64::LD2i8_POST:
case AArch64::LD2i16_POST:
case AArch64::LD2i32_POST:
- case AArch64::LD2i64_POST:
case AArch64::LD3i8_POST:
case AArch64::LD3i16_POST:
case AArch64::LD3i32_POST:
+ case AArch64::LD3i64_POST:
case AArch64::LD4i8_POST:
case AArch64::LD4i16_POST:
case AArch64::LD4i32_POST:
- DestRegIdx = 1;
- BaseRegIdx = 4;
- OffsetIdx = 5;
- IsPrePost = false;
- break;
-
- case AArch64::LD3i64_POST:
case AArch64::LD4i64_POST:
DestRegIdx = -1;
BaseRegIdx = 4;
OffsetIdx = 5;
- IsPrePost = false;
+ IsPrePost = true;
break;
case AArch64::LD1Onev1d_POST:
@@ -389,23 +389,16 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
case AArch64::LD1Rv4s_POST:
case AArch64::LD1Rv8h_POST:
case AArch64::LD1Rv16b_POST:
- case AArch64::LD1Twov1d_POST:
- case AArch64::LD1Twov2s_POST:
- case AArch64::LD1Twov4h_POST:
- case AArch64::LD1Twov8b_POST:
- case AArch64::LD2Twov2s_POST:
- case AArch64::LD2Twov4s_POST:
- case AArch64::LD2Twov8b_POST:
- case AArch64::LD2Rv1d_POST:
- case AArch64::LD2Rv2s_POST:
- case AArch64::LD2Rv4s_POST:
- case AArch64::LD2Rv8b_POST:
DestRegIdx = 1;
BaseRegIdx = 2;
OffsetIdx = 3;
- IsPrePost = false;
+ IsPrePost = true;
break;
+ case AArch64::LD1Twov1d_POST:
+ case AArch64::LD1Twov2s_POST:
+ case AArch64::LD1Twov4h_POST:
+ case AArch64::LD1Twov8b_POST:
case AArch64::LD1Twov2d_POST:
case AArch64::LD1Twov4s_POST:
case AArch64::LD1Twov8h_POST:
@@ -426,10 +419,17 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
case AArch64::LD1Fourv4s_POST:
case AArch64::LD1Fourv8h_POST:
case AArch64::LD1Fourv16b_POST:
+ case AArch64::LD2Twov2s_POST:
+ case AArch64::LD2Twov4s_POST:
+ case AArch64::LD2Twov8b_POST:
case AArch64::LD2Twov2d_POST:
case AArch64::LD2Twov4h_POST:
case AArch64::LD2Twov8h_POST:
case AArch64::LD2Twov16b_POST:
+ case AArch64::LD2Rv1d_POST:
+ case AArch64::LD2Rv2s_POST:
+ case AArch64::LD2Rv4s_POST:
+ case AArch64::LD2Rv8b_POST:
case AArch64::LD2Rv2d_POST:
case AArch64::LD2Rv4h_POST:
case AArch64::LD2Rv8h_POST:
@@ -467,7 +467,7 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
DestRegIdx = -1;
BaseRegIdx = 2;
OffsetIdx = 3;
- IsPrePost = false;
+ IsPrePost = true;
break;
case AArch64::LDRBBroW:
@@ -572,8 +572,12 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
IsPrePost = true;
break;
- case AArch64::LDPDi:
+ case AArch64::LDNPDi:
+ case AArch64::LDNPQi:
+ case AArch64::LDNPSi:
case AArch64::LDPQi:
+ case AArch64::LDPDi:
+ case AArch64::LDPSi:
DestRegIdx = -1;
BaseRegIdx = 2;
OffsetIdx = 3;
@@ -581,7 +585,6 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
break;
case AArch64::LDPSWi:
- case AArch64::LDPSi:
case AArch64::LDPWi:
case AArch64::LDPXi:
DestRegIdx = 0;
@@ -592,18 +595,18 @@ static Optional<LoadInfo> getLoadInfo(const MachineInstr &MI) {
case AArch64::LDPQpost:
case AArch64::LDPQpre:
+ case AArch64::LDPDpost:
+ case AArch64::LDPDpre:
+ case AArch64::LDPSpost:
+ case AArch64::LDPSpre:
DestRegIdx = -1;
BaseRegIdx = 3;
OffsetIdx = 4;
IsPrePost = true;
break;
- case AArch64::LDPDpost:
- case AArch64::LDPDpre:
case AArch64::LDPSWpost:
case AArch64::LDPSWpre:
- case AArch64::LDPSpost:
- case AArch64::LDPSpre:
case AArch64::LDPWpost:
case AArch64::LDPWpre:
case AArch64::LDPXpost:
@@ -687,9 +690,14 @@ void FalkorHWPFFix::runOnLoop(MachineLoop &L, MachineFunction &Fn) {
if (!TII->isStridedAccess(MI))
continue;
- LoadInfo LdI = *getLoadInfo(MI);
- unsigned OldTag = *getTag(TRI, MI, LdI);
- auto &OldCollisions = TagMap[OldTag];
+ Optional<LoadInfo> OptLdI = getLoadInfo(MI);
+ if (!OptLdI)
+ continue;
+ LoadInfo LdI = *OptLdI;
+ Optional<unsigned> OptOldTag = getTag(TRI, MI, LdI);
+ if (!OptOldTag)
+ continue;
+ auto &OldCollisions = TagMap[*OptOldTag];
if (OldCollisions.size() <= 1)
continue;
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 9d87988..9c57926 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9347,11 +9347,20 @@ static SDValue replaceZeroVectorStore(SelectionDAG &DAG, StoreSDNode &St) {
return SDValue();
}
- // Use WZR/XZR here to prevent DAGCombiner::MergeConsecutiveStores from
- // undoing this transformation.
- SDValue SplatVal = VT.getVectorElementType().getSizeInBits() == 32
- ? DAG.getRegister(AArch64::WZR, MVT::i32)
- : DAG.getRegister(AArch64::XZR, MVT::i64);
+ // Use a CopyFromReg WZR/XZR here to prevent
+ // DAGCombiner::MergeConsecutiveStores from undoing this transformation.
+ SDLoc DL(&St);
+ unsigned ZeroReg;
+ EVT ZeroVT;
+ if (VT.getVectorElementType().getSizeInBits() == 32) {
+ ZeroReg = AArch64::WZR;
+ ZeroVT = MVT::i32;
+ } else {
+ ZeroReg = AArch64::XZR;
+ ZeroVT = MVT::i64;
+ }
+ SDValue SplatVal =
+ DAG.getCopyFromReg(DAG.getEntryNode(), DL, ZeroReg, ZeroVT);
return splitStoreSplat(DAG, St, SplatVal, NumVecElts);
}
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 5049a39..5971997 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/contrib/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -441,8 +441,7 @@ def MSRpstateImm1 : MSRpstateImm0_1;
def MSRpstateImm4 : MSRpstateImm0_15;
// The thread pointer (on Linux, at least, where this has been implemented) is
-// TPIDR_EL0. Add pseudo op so we can mark it as not having any side effects.
-let hasSideEffects = 0 in
+// TPIDR_EL0.
def MOVbaseTLS : Pseudo<(outs GPR64:$dst), (ins),
[(set GPR64:$dst, AArch64threadpointer)]>, Sched<[WriteSys]>;
diff --git a/contrib/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/contrib/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
index cd9e7fb..025397b 100644
--- a/contrib/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
@@ -218,12 +218,17 @@ void GCNHazardRecognizer::RecedeCycle() {
int GCNHazardRecognizer::getWaitStatesSince(
function_ref<bool(MachineInstr *)> IsHazard) {
- int WaitStates = -1;
+ int WaitStates = 0;
for (MachineInstr *MI : EmittedInstrs) {
+ if (MI) {
+ if (IsHazard(MI))
+ return WaitStates;
+
+ unsigned Opcode = MI->getOpcode();
+ if (Opcode == AMDGPU::DBG_VALUE || Opcode == AMDGPU::IMPLICIT_DEF)
+ continue;
+ }
++WaitStates;
- if (!MI || !IsHazard(MI))
- continue;
- return WaitStates;
}
return std::numeric_limits<int>::max();
}
diff --git a/contrib/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/contrib/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index 582153d..b24d342 100644
--- a/contrib/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1276,6 +1276,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Add 's' bit operand (always reg0 for this)
.addReg(0));
+ assert(Subtarget->hasV4TOps());
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
.addReg(MI->getOperand(0).getReg()));
return;
@@ -1896,6 +1897,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
.addImm(ARMCC::AL)
.addReg(0));
+ assert(Subtarget->hasV4TOps());
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
.addReg(ScratchReg)
// Predicate.
diff --git a/contrib/llvm/lib/Target/ARM/ARMCallLowering.cpp b/contrib/llvm/lib/Target/ARM/ARMCallLowering.cpp
index 051827a..a1a31e1 100644
--- a/contrib/llvm/lib/Target/ARM/ARMCallLowering.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMCallLowering.cpp
@@ -251,7 +251,9 @@ bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
const Value *Val, unsigned VReg) const {
assert(!Val == !VReg && "Return value without a vreg");
- auto Ret = MIRBuilder.buildInstrNoInsert(ARM::BX_RET).add(predOps(ARMCC::AL));
+ auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
+ unsigned Opcode = ST.getReturnOpcode();
+ auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
return false;
diff --git a/contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index 46d8f0d..3767277 100644
--- a/contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -1030,8 +1030,11 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
if (STI->isThumb())
MIB.add(predOps(ARMCC::AL));
} else if (RetOpcode == ARM::TCRETURNri) {
+ unsigned Opcode =
+ STI->isThumb() ? ARM::tTAILJMPr
+ : (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4);
BuildMI(MBB, MBBI, dl,
- TII.get(STI->isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr))
+ TII.get(Opcode))
.addReg(JumpTarget.getReg(), RegState::Kill);
}
diff --git a/contrib/llvm/lib/Target/ARM/ARMFastISel.cpp b/contrib/llvm/lib/Target/ARM/ARMFastISel.cpp
index bf00ef6..5dc9373 100644
--- a/contrib/llvm/lib/Target/ARM/ARMFastISel.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMFastISel.cpp
@@ -1332,6 +1332,8 @@ bool ARMFastISel::SelectIndirectBr(const Instruction *I) {
if (AddrReg == 0) return false;
unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX;
+ assert(isThumb2 || Subtarget->hasV4TOps());
+
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc)).addReg(AddrReg));
@@ -2168,9 +2170,8 @@ bool ARMFastISel::SelectRet(const Instruction *I) {
RetRegs.push_back(VA.getLocReg());
}
- unsigned RetOpc = isThumb2 ? ARM::tBX_RET : ARM::BX_RET;
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(RetOpc));
+ TII.get(Subtarget->getReturnOpcode()));
AddOptionalDefs(MIB);
for (unsigned R : RetRegs)
MIB.addReg(R, RegState::Implicit);
diff --git a/contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 16b54e8..00b788a 100644
--- a/contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -479,7 +479,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
if (DPRCSSize > 0) {
// Since vpush register list cannot have gaps, there may be multiple vpush
// instructions in the prologue.
- while (MBBI->getOpcode() == ARM::VSTMDDB_UPD) {
+ while (MBBI != MBB.end() && MBBI->getOpcode() == ARM::VSTMDDB_UPD) {
DefCFAOffsetCandidates.addInst(MBBI, sizeOfSPAdjustment(*MBBI));
LastPush = MBBI++;
}
@@ -2397,9 +2397,8 @@ void ARMFrameLowering::adjustForSegmentedStacks(
BuildMI(AllocMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
- // bx lr - Return from this function.
- Opcode = Thumb ? ARM::tBX_RET : ARM::BX_RET;
- BuildMI(AllocMBB, DL, TII.get(Opcode)).add(predOps(ARMCC::AL));
+ // Return from this function.
+ BuildMI(AllocMBB, DL, TII.get(ST->getReturnOpcode())).add(predOps(ARMCC::AL));
// Restore SR0 and SR1 in case of __morestack() was not called.
// pop {SR0, SR1}
diff --git a/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td b/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td
index 7206083..c488cd3 100644
--- a/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -2425,7 +2425,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in {
def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst),
4, IIC_Br, [],
(BX GPR:$dst)>, Sched<[WriteBr]>,
- Requires<[IsARM]>;
+ Requires<[IsARM, HasV4T]>;
}
// Secure Monitor Call is a system instruction.
@@ -5589,6 +5589,12 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
(MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>;
+let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in
+ def TAILJMPr4 : ARMPseudoExpand<(outs), (ins GPR:$dst),
+ 4, IIC_Br, [],
+ (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
+ Requires<[IsARM, NoV4T]>, Sched<[WriteBr]>;
+
// Large immediate handling.
// 32-bit immediate using two piece mod_imms or movw + movt.
diff --git a/contrib/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/contrib/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 7a452d4..5d57b68 100644
--- a/contrib/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -1909,6 +1909,7 @@ bool ARMLoadStoreOpt::CombineMovBx(MachineBasicBlock &MBB) {
for (auto Use : Prev->uses())
if (Use.isKill()) {
+ assert(STI->hasV4TOps());
BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(ARM::tBX))
.addReg(Use.getReg(), RegState::Kill)
.add(predOps(ARMCC::AL))
diff --git a/contrib/llvm/lib/Target/ARM/ARMSubtarget.h b/contrib/llvm/lib/Target/ARM/ARMSubtarget.h
index e15b175..9d74953 100644
--- a/contrib/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/contrib/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -729,6 +729,17 @@ public:
/// True if fast-isel is used.
bool useFastISel() const;
+
+ /// Returns the correct return opcode for the current feature set.
+ /// Use BX if available to allow mixing thumb/arm code, but fall back
+ /// to plain mov pc,lr on ARMv4.
+ unsigned getReturnOpcode() const {
+ if (isThumb())
+ return ARM::tBX_RET;
+ if (hasV4TOps())
+ return ARM::BX_RET;
+ return ARM::MOVPCLR;
+ }
};
} // end namespace llvm
diff --git a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
index b8a8b1f..2ab7bfe 100644
--- a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
+++ b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
@@ -142,9 +142,9 @@ std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
if (isThumb) {
if (ARMArchFeature.empty())
- ARMArchFeature = "+thumb-mode";
+ ARMArchFeature = "+thumb-mode,+v4t";
else
- ARMArchFeature += ",+thumb-mode";
+ ARMArchFeature += ",+thumb-mode,+v4t";
}
if (TT.isOSNaCl()) {
diff --git a/contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 540e05a..d6f85ed 100644
--- a/contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -583,8 +583,8 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
unsigned TmpReg = 0; // 0 for no temporary register
unsigned SrcReg = MI.getOperand(1).getReg();
bool SrcIsKill = MI.getOperand(1).isKill();
- OpLo = AVR::LDRdPtr;
- OpHi = AVR::LDDRdPtrQ;
+ OpLo = AVR::LDRdPtrPi;
+ OpHi = AVR::LDRdPtr;
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
// Use a temporary register if src and dst registers are the same.
@@ -597,6 +597,7 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
// Load low byte.
auto MIBLO = buildMI(MBB, MBBI, OpLo)
.addReg(CurDstLoReg, RegState::Define)
+ .addReg(SrcReg, RegState::Define)
.addReg(SrcReg);
// Push low byte onto stack if necessary.
@@ -606,8 +607,7 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
// Load high byte.
auto MIBHI = buildMI(MBB, MBBI, OpHi)
.addReg(CurDstHiReg, RegState::Define)
- .addReg(SrcReg, getKillRegState(SrcIsKill))
- .addImm(1);
+ .addReg(SrcReg, getKillRegState(SrcIsKill));
if (TmpReg) {
// Move the high byte into the final destination.
@@ -699,7 +699,9 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
OpHi = AVR::LDDRdPtrQ;
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
- assert(Imm <= 63 && "Offset is out of range");
+ // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
+ // allowed for the instruction, 62 is the limit here.
+ assert(Imm <= 62 && "Offset is out of range");
// Use a temporary register if src and dst registers are the same.
if (DstReg == SrcReg)
@@ -741,7 +743,50 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
template <>
bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
- llvm_unreachable("wide LPM is unimplemented");
+ MachineInstr &MI = *MBBI;
+ unsigned OpLo, OpHi, DstLoReg, DstHiReg;
+ unsigned DstReg = MI.getOperand(0).getReg();
+ unsigned TmpReg = 0; // 0 for no temporary register
+ unsigned SrcReg = MI.getOperand(1).getReg();
+ bool SrcIsKill = MI.getOperand(1).isKill();
+ OpLo = AVR::LPMRdZPi;
+ OpHi = AVR::LPMRdZ;
+ TRI->splitReg(DstReg, DstLoReg, DstHiReg);
+
+ // Use a temporary register if src and dst registers are the same.
+ if (DstReg == SrcReg)
+ TmpReg = scavengeGPR8(MI);
+
+ unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
+ unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
+
+ // Load low byte.
+ auto MIBLO = buildMI(MBB, MBBI, OpLo)
+ .addReg(CurDstLoReg, RegState::Define)
+ .addReg(SrcReg);
+
+ // Push low byte onto stack if necessary.
+ if (TmpReg)
+ buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
+
+ // Load high byte.
+ auto MIBHI = buildMI(MBB, MBBI, OpHi)
+ .addReg(CurDstHiReg, RegState::Define)
+ .addReg(SrcReg, getKillRegState(SrcIsKill));
+
+ if (TmpReg) {
+ // Move the high byte into the final destination.
+ buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
+
+ // Move the low byte from the scratch space into the final destination.
+ buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
+ }
+
+ MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
+ MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
+
+ MI.eraseFromParent();
+ return true;
}
template <>
@@ -1074,7 +1119,9 @@ bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
OpHi = AVR::STDPtrQRr;
TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
- assert(Imm <= 63 && "Offset is out of range");
+ // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
+ // allowed for the instruction, 62 is the limit here.
+ assert(Imm <= 62 && "Offset is out of range");
auto MIBLO = buildMI(MBB, MBBI, OpLo)
.addReg(DstReg)
@@ -1104,7 +1151,9 @@ bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) {
OpHi = AVR::INRdA;
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
- assert(Imm <= 63 && "Address is out of range");
+ // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
+ // allowed for the instruction, 62 is the limit here.
+ assert(Imm <= 62 && "Address is out of range");
auto MIBLO = buildMI(MBB, MBBI, OpLo)
.addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
@@ -1132,7 +1181,9 @@ bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) {
OpHi = AVR::OUTARr;
TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
- assert(Imm <= 63 && "Address is out of range");
+ // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
+ // allowed for the instruction, 62 is the limit here.
+ assert(Imm <= 62 && "Address is out of range");
// 16 bit I/O writes need the high byte first
auto MIBHI = buildMI(MBB, MBBI, OpHi)
diff --git a/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp b/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
index 7d3faac..d8e8bc1 100644
--- a/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -1469,8 +1469,10 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
}
const BasicBlock *LLVM_BB = BB->getBasicBlock();
- MachineFunction::iterator I = BB->getParent()->begin();
- ++I;
+
+ MachineFunction::iterator I;
+ for (I = F->begin(); I != F->end() && &(*I) != BB; ++I);
+ if (I != F->end()) ++I;
// Create loop block.
MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
diff --git a/contrib/llvm/lib/Target/AVR/AVRISelLowering.h b/contrib/llvm/lib/Target/AVR/AVRISelLowering.h
index b44c62a..85f9552 100644
--- a/contrib/llvm/lib/Target/AVR/AVRISelLowering.h
+++ b/contrib/llvm/lib/Target/AVR/AVRISelLowering.h
@@ -75,6 +75,11 @@ public:
MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override {
return MVT::i8;
}
+
+ MVT::SimpleValueType getCmpLibcallReturnType() const override {
+ return MVT::i8;
+ }
+
const char *getTargetNodeName(unsigned Opcode) const override;
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
diff --git a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp
index 744aa72..1a89a13 100644
--- a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp
@@ -537,8 +537,7 @@ bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
llvm_unreachable("unexpected opcode!");
case AVR::JMPk:
case AVR::CALLk:
- assert(BrOffset >= 0 && "offset must be absolute address");
- return isUIntN(16, BrOffset);
+ return true;
case AVR::RCALLk:
case AVR::RJMPk:
return isIntN(13, BrOffset);
@@ -556,5 +555,20 @@ bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
}
}
+unsigned AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock &NewDestBB,
+ const DebugLoc &DL,
+ int64_t BrOffset,
+ RegScavenger *RS) const {
+ // This method inserts a *direct* branch (JMP), despite its name.
+ // LLVM calls this method to fixup unconditional branches; it never calls
+ // insertBranch or some hypothetical "insertDirectBranch".
+ // See lib/CodeGen/RegisterRelaxation.cpp for details.
+ // We end up here when a jump is too long for a RJMP instruction.
+ auto &MI = *BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB);
+
+ return getInstSizeInBytes(MI);
+}
+
} // end of namespace llvm
diff --git a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.h b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.h
index f42d34f..eee8a92 100644
--- a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.h
+++ b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.h
@@ -107,6 +107,12 @@ public:
bool isBranchOffsetInRange(unsigned BranchOpc,
int64_t BrOffset) const override;
+
+ unsigned insertIndirectBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock &NewDestBB,
+ const DebugLoc &DL,
+ int64_t BrOffset,
+ RegScavenger *RS) const override;
private:
const AVRRegisterInfo RI;
};
diff --git a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
index 184e4d5..7d1bfc8 100644
--- a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -1152,10 +1152,10 @@ isReMaterializable = 1 in
//
// Expands to:
// ld Rd, P+
- // ld Rd+1, P+
+ // ld Rd+1, P
let Constraints = "@earlyclobber $reg" in
def LDWRdPtr : Pseudo<(outs DREGS:$reg),
- (ins PTRDISPREGS:$ptrreg),
+ (ins PTRREGS:$ptrreg),
"ldw\t$reg, $ptrreg",
[(set i16:$reg, (load i16:$ptrreg))]>,
Requires<[HasSRAM]>;
@@ -1164,7 +1164,7 @@ isReMaterializable = 1 in
// Indirect loads (with postincrement or predecrement).
let mayLoad = 1,
hasSideEffects = 0,
-Constraints = "$ptrreg = $base_wb,@earlyclobber $reg,@earlyclobber $base_wb" in
+Constraints = "$ptrreg = $base_wb,@earlyclobber $reg" in
{
def LDRdPtrPi : FSTLD<0,
0b01,
@@ -1238,35 +1238,55 @@ isReMaterializable = 1 in
Requires<[HasSRAM]>;
}
-class AtomicLoad<PatFrag Op, RegisterClass DRC> :
- Pseudo<(outs DRC:$rd), (ins PTRREGS:$rr), "atomic_op",
+class AtomicLoad<PatFrag Op, RegisterClass DRC,
+ RegisterClass PTRRC> :
+ Pseudo<(outs DRC:$rd), (ins PTRRC:$rr), "atomic_op",
[(set DRC:$rd, (Op i16:$rr))]>;
-class AtomicStore<PatFrag Op, RegisterClass DRC> :
- Pseudo<(outs), (ins PTRDISPREGS:$rd, DRC:$rr), "atomic_op",
+class AtomicStore<PatFrag Op, RegisterClass DRC,
+ RegisterClass PTRRC> :
+ Pseudo<(outs), (ins PTRRC:$rd, DRC:$rr), "atomic_op",
[(Op i16:$rd, DRC:$rr)]>;
-class AtomicLoadOp<PatFrag Op, RegisterClass DRC> :
- Pseudo<(outs DRC:$rd), (ins PTRREGS:$rr, DRC:$operand),
+class AtomicLoadOp<PatFrag Op, RegisterClass DRC,
+ RegisterClass PTRRC> :
+ Pseudo<(outs DRC:$rd), (ins PTRRC:$rr, DRC:$operand),
"atomic_op",
[(set DRC:$rd, (Op i16:$rr, DRC:$operand))]>;
-def AtomicLoad8 : AtomicLoad<atomic_load_8, GPR8>;
-def AtomicLoad16 : AtomicLoad<atomic_load_16, DREGS>;
-
-def AtomicStore8 : AtomicStore<atomic_store_8, GPR8>;
-def AtomicStore16 : AtomicStore<atomic_store_16, DREGS>;
-
-def AtomicLoadAdd8 : AtomicLoadOp<atomic_load_add_8, GPR8>;
-def AtomicLoadAdd16 : AtomicLoadOp<atomic_load_add_16, DREGS>;
-def AtomicLoadSub8 : AtomicLoadOp<atomic_load_sub_8, GPR8>;
-def AtomicLoadSub16 : AtomicLoadOp<atomic_load_sub_16, DREGS>;
-def AtomicLoadAnd8 : AtomicLoadOp<atomic_load_and_8, GPR8>;
-def AtomicLoadAnd16 : AtomicLoadOp<atomic_load_and_16, DREGS>;
-def AtomicLoadOr8 : AtomicLoadOp<atomic_load_or_8, GPR8>;
-def AtomicLoadOr16 : AtomicLoadOp<atomic_load_or_16, DREGS>;
-def AtomicLoadXor8 : AtomicLoadOp<atomic_load_xor_8, GPR8>;
-def AtomicLoadXor16 : AtomicLoadOp<atomic_load_xor_16, DREGS>;
+// FIXME: I think 16-bit atomic binary ops need to mark
+// r0 as clobbered.
+
+// Atomic instructions
+// ===================
+//
+// These are all expanded by AVRExpandPseudoInsts
+//
+// 8-bit operations can use any pointer register because
+// they are expanded directly into an LD/ST instruction.
+//
+// 16-bit operations use 16-bit load/store postincrement instructions,
+// which require PTRDISPREGS.
+
+def AtomicLoad8 : AtomicLoad<atomic_load_8, GPR8, PTRREGS>;
+def AtomicLoad16 : AtomicLoad<atomic_load_16, DREGS, PTRDISPREGS>;
+
+def AtomicStore8 : AtomicStore<atomic_store_8, GPR8, PTRREGS>;
+def AtomicStore16 : AtomicStore<atomic_store_16, DREGS, PTRDISPREGS>;
+
+class AtomicLoadOp8<PatFrag Op> : AtomicLoadOp<Op, GPR8, PTRREGS>;
+class AtomicLoadOp16<PatFrag Op> : AtomicLoadOp<Op, DREGS, PTRDISPREGS>;
+
+def AtomicLoadAdd8 : AtomicLoadOp8<atomic_load_add_8>;
+def AtomicLoadAdd16 : AtomicLoadOp16<atomic_load_add_16>;
+def AtomicLoadSub8 : AtomicLoadOp8<atomic_load_sub_8>;
+def AtomicLoadSub16 : AtomicLoadOp16<atomic_load_sub_16>;
+def AtomicLoadAnd8 : AtomicLoadOp8<atomic_load_and_8>;
+def AtomicLoadAnd16 : AtomicLoadOp16<atomic_load_and_16>;
+def AtomicLoadOr8 : AtomicLoadOp8<atomic_load_or_8>;
+def AtomicLoadOr16 : AtomicLoadOp16<atomic_load_or_16>;
+def AtomicLoadXor8 : AtomicLoadOp8<atomic_load_xor_8>;
+def AtomicLoadXor16 : AtomicLoadOp16<atomic_load_xor_16>;
def AtomicFence : Pseudo<(outs), (ins), "atomic_fence",
[(atomic_fence imm, imm)]>;
@@ -1397,6 +1417,7 @@ def STDWPtrQRr : Pseudo<(outs),
// Load program memory operations.
let canFoldAsLoad = 1,
isReMaterializable = 1,
+mayLoad = 1,
hasSideEffects = 0 in
{
let Defs = [R0],
@@ -1417,8 +1438,7 @@ hasSideEffects = 0 in
Requires<[HasLPMX]>;
// Load program memory, while postincrementing the Z register.
- let mayLoad = 1,
- Defs = [R31R30] in
+ let Defs = [R31R30] in
{
def LPMRdZPi : FLPMX<0,
1,
diff --git a/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp b/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
index 249dc55..7099b29 100644
--- a/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
@@ -203,7 +203,7 @@ void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// If the offset is too big we have to adjust and restore the frame pointer
// to materialize a valid load/store with displacement.
//:TODO: consider using only one adiw/sbiw chain for more than one frame index
- if (Offset > 63) {
+ if (Offset > 62) {
unsigned AddOpc = AVR::ADIWRdK, SubOpc = AVR::SBIWRdK;
int AddOffset = Offset - 63 + 1;
diff --git a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
index a9d61ff..e698b6e 100644
--- a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
@@ -25,7 +25,7 @@
namespace llvm {
-static const char *AVRDataLayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-n8";
+static const char *AVRDataLayout = "e-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8";
/// Processes a CPU name.
static StringRef getCPU(StringRef CPU) {
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp
index a2d8c16..2b45d9a 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.cpp
@@ -13,6 +13,8 @@
#include "AVRTargetStreamer.h"
+#include "llvm/MC/MCContext.h"
+
namespace llvm {
AVRTargetStreamer::AVRTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
@@ -20,5 +22,23 @@ AVRTargetStreamer::AVRTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
AVRTargetAsmStreamer::AVRTargetAsmStreamer(MCStreamer &S)
: AVRTargetStreamer(S) {}
+void AVRTargetStreamer::finish() {
+ MCStreamer &OS = getStreamer();
+ MCContext &Context = OS.getContext();
+
+ MCSymbol *DoCopyData = Context.getOrCreateSymbol("__do_copy_data");
+ MCSymbol *DoClearBss = Context.getOrCreateSymbol("__do_clear_bss");
+
+ // FIXME: We can disable __do_copy_data if there are no static RAM variables.
+
+ OS.emitRawComment(" Declaring this symbol tells the CRT that it should");
+ OS.emitRawComment("copy all variables from program memory to RAM on startup");
+ OS.EmitSymbolAttribute(DoCopyData, MCSA_Global);
+
+ OS.emitRawComment(" Declaring this symbol tells the CRT that it should");
+ OS.emitRawComment("clear the zeroed data section on startup");
+ OS.EmitSymbolAttribute(DoClearBss, MCSA_Global);
+}
+
} // end namespace llvm
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h
index 99a5366..815088b 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRTargetStreamer.h
@@ -19,6 +19,8 @@ class MCStreamer;
class AVRTargetStreamer : public MCTargetStreamer {
public:
explicit AVRTargetStreamer(MCStreamer &S);
+
+ void finish() override;
};
/// A target streamer for textual AVR assembly code.
diff --git a/contrib/llvm/lib/Target/BPF/BPFISelLowering.cpp b/contrib/llvm/lib/Target/BPF/BPFISelLowering.cpp
index 81b0aa7..5740b49 100644
--- a/contrib/llvm/lib/Target/BPF/BPFISelLowering.cpp
+++ b/contrib/llvm/lib/Target/BPF/BPFISelLowering.cpp
@@ -578,11 +578,15 @@ BPFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
.addReg(LHS)
.addReg(MI.getOperand(2).getReg())
.addMBB(Copy1MBB);
- else
+ else {
+ int64_t imm32 = MI.getOperand(2).getImm();
+ // sanity check before we build J*_ri instruction.
+ assert (isInt<32>(imm32));
BuildMI(BB, DL, TII.get(NewCC))
.addReg(LHS)
- .addImm(MI.getOperand(2).getImm())
+ .addImm(imm32)
.addMBB(Copy1MBB);
+ }
// Copy0MBB:
// %FalseValue = ...
diff --git a/contrib/llvm/lib/Target/BPF/BPFInstrInfo.td b/contrib/llvm/lib/Target/BPF/BPFInstrInfo.td
index f683578..59e92f8 100644
--- a/contrib/llvm/lib/Target/BPF/BPFInstrInfo.td
+++ b/contrib/llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -464,7 +464,7 @@ let usesCustomInserter = 1 in {
(ins GPR:$lhs, i64imm:$rhs, i64imm:$imm, GPR:$src, GPR:$src2),
"# Select PSEUDO $dst = $lhs $imm $rhs ? $src : $src2",
[(set i64:$dst,
- (BPFselectcc i64:$lhs, (i64 imm:$rhs), (i64 imm:$imm), i64:$src, i64:$src2))]>;
+ (BPFselectcc i64:$lhs, (i64 i64immSExt32:$rhs), (i64 imm:$imm), i64:$src, i64:$src2))]>;
}
// load 64-bit global addr into register
diff --git a/contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index e12188e..a294004 100644
--- a/contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -304,6 +304,9 @@ class MipsAsmParser : public MCTargetAsmParser {
bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
+ bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI);
+
bool reportParseError(Twine ErrorMsg);
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
@@ -2511,6 +2514,16 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::SEQIMacro:
return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
+ case Mips::MFTC0: case Mips::MTTC0:
+ case Mips::MFTGPR: case Mips::MTTGPR:
+ case Mips::MFTLO: case Mips::MTTLO:
+ case Mips::MFTHI: case Mips::MTTHI:
+ case Mips::MFTACX: case Mips::MTTACX:
+ case Mips::MFTDSP: case Mips::MTTDSP:
+ case Mips::MFTC1: case Mips::MTTC1:
+ case Mips::MFTHC1: case Mips::MTTHC1:
+ case Mips::CFTC1: case Mips::CTTC1:
+ return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
}
}
@@ -4882,6 +4895,212 @@ bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return false;
}
+// Map the DSP accumulator and control register to the corresponding gpr
+// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
+// do not map the DSP registers contigously to gpr registers.
+static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
+ switch (Inst.getOpcode()) {
+ case Mips::MFTLO:
+ case Mips::MTTLO:
+ switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
+ case Mips::AC0:
+ return Mips::ZERO;
+ case Mips::AC1:
+ return Mips::A0;
+ case Mips::AC2:
+ return Mips::T0;
+ case Mips::AC3:
+ return Mips::T4;
+ default:
+ llvm_unreachable("Unknown register for 'mttr' alias!");
+ }
+ case Mips::MFTHI:
+ case Mips::MTTHI:
+ switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
+ case Mips::AC0:
+ return Mips::AT;
+ case Mips::AC1:
+ return Mips::A1;
+ case Mips::AC2:
+ return Mips::T1;
+ case Mips::AC3:
+ return Mips::T5;
+ default:
+ llvm_unreachable("Unknown register for 'mttr' alias!");
+ }
+ case Mips::MFTACX:
+ case Mips::MTTACX:
+ switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
+ case Mips::AC0:
+ return Mips::V0;
+ case Mips::AC1:
+ return Mips::A2;
+ case Mips::AC2:
+ return Mips::T2;
+ case Mips::AC3:
+ return Mips::T6;
+ default:
+ llvm_unreachable("Unknown register for 'mttr' alias!");
+ }
+ case Mips::MFTDSP:
+ case Mips::MTTDSP:
+ return Mips::S0;
+ default:
+ llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
+ }
+}
+
+// Map the floating point register operand to the corresponding register
+// operand.
+static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
+ switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
+ case Mips::F0: return Mips::ZERO;
+ case Mips::F1: return Mips::AT;
+ case Mips::F2: return Mips::V0;
+ case Mips::F3: return Mips::V1;
+ case Mips::F4: return Mips::A0;
+ case Mips::F5: return Mips::A1;
+ case Mips::F6: return Mips::A2;
+ case Mips::F7: return Mips::A3;
+ case Mips::F8: return Mips::T0;
+ case Mips::F9: return Mips::T1;
+ case Mips::F10: return Mips::T2;
+ case Mips::F11: return Mips::T3;
+ case Mips::F12: return Mips::T4;
+ case Mips::F13: return Mips::T5;
+ case Mips::F14: return Mips::T6;
+ case Mips::F15: return Mips::T7;
+ case Mips::F16: return Mips::S0;
+ case Mips::F17: return Mips::S1;
+ case Mips::F18: return Mips::S2;
+ case Mips::F19: return Mips::S3;
+ case Mips::F20: return Mips::S4;
+ case Mips::F21: return Mips::S5;
+ case Mips::F22: return Mips::S6;
+ case Mips::F23: return Mips::S7;
+ case Mips::F24: return Mips::T8;
+ case Mips::F25: return Mips::T9;
+ case Mips::F26: return Mips::K0;
+ case Mips::F27: return Mips::K1;
+ case Mips::F28: return Mips::GP;
+ case Mips::F29: return Mips::SP;
+ case Mips::F30: return Mips::FP;
+ case Mips::F31: return Mips::RA;
+ default: llvm_unreachable("Unknown register for mttc1 alias!");
+ }
+}
+
+// Map the coprocessor operand the corresponding gpr register operand.
+static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
+ switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
+ case Mips::COP00: return Mips::ZERO;
+ case Mips::COP01: return Mips::AT;
+ case Mips::COP02: return Mips::V0;
+ case Mips::COP03: return Mips::V1;
+ case Mips::COP04: return Mips::A0;
+ case Mips::COP05: return Mips::A1;
+ case Mips::COP06: return Mips::A2;
+ case Mips::COP07: return Mips::A3;
+ case Mips::COP08: return Mips::T0;
+ case Mips::COP09: return Mips::T1;
+ case Mips::COP010: return Mips::T2;
+ case Mips::COP011: return Mips::T3;
+ case Mips::COP012: return Mips::T4;
+ case Mips::COP013: return Mips::T5;
+ case Mips::COP014: return Mips::T6;
+ case Mips::COP015: return Mips::T7;
+ case Mips::COP016: return Mips::S0;
+ case Mips::COP017: return Mips::S1;
+ case Mips::COP018: return Mips::S2;
+ case Mips::COP019: return Mips::S3;
+ case Mips::COP020: return Mips::S4;
+ case Mips::COP021: return Mips::S5;
+ case Mips::COP022: return Mips::S6;
+ case Mips::COP023: return Mips::S7;
+ case Mips::COP024: return Mips::T8;
+ case Mips::COP025: return Mips::T9;
+ case Mips::COP026: return Mips::K0;
+ case Mips::COP027: return Mips::K1;
+ case Mips::COP028: return Mips::GP;
+ case Mips::COP029: return Mips::SP;
+ case Mips::COP030: return Mips::FP;
+ case Mips::COP031: return Mips::RA;
+ default: llvm_unreachable("Unknown register for mttc0 alias!");
+ }
+}
+
+/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
+/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
+bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI) {
+ MipsTargetStreamer &TOut = getTargetStreamer();
+ unsigned rd = 0;
+ unsigned u = 1;
+ unsigned sel = 0;
+ unsigned h = 0;
+ bool IsMFTR = false;
+ switch (Inst.getOpcode()) {
+ case Mips::MFTC0:
+ IsMFTR = true;
+ LLVM_FALLTHROUGH;
+ case Mips::MTTC0:
+ u = 0;
+ rd = getRegisterForMxtrC0(Inst, IsMFTR);
+ sel = Inst.getOperand(2).getImm();
+ break;
+ case Mips::MFTGPR:
+ IsMFTR = true;
+ LLVM_FALLTHROUGH;
+ case Mips::MTTGPR:
+ rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
+ break;
+ case Mips::MFTLO:
+ case Mips::MFTHI:
+ case Mips::MFTACX:
+ case Mips::MFTDSP:
+ IsMFTR = true;
+ LLVM_FALLTHROUGH;
+ case Mips::MTTLO:
+ case Mips::MTTHI:
+ case Mips::MTTACX:
+ case Mips::MTTDSP:
+ rd = getRegisterForMxtrDSP(Inst, IsMFTR);
+ sel = 1;
+ break;
+ case Mips::MFTHC1:
+ h = 1;
+ LLVM_FALLTHROUGH;
+ case Mips::MFTC1:
+ IsMFTR = true;
+ rd = getRegisterForMxtrFP(Inst, IsMFTR);
+ sel = 2;
+ break;
+ case Mips::MTTHC1:
+ h = 1;
+ LLVM_FALLTHROUGH;
+ case Mips::MTTC1:
+ rd = getRegisterForMxtrFP(Inst, IsMFTR);
+ sel = 2;
+ break;
+ case Mips::CFTC1:
+ IsMFTR = true;
+ LLVM_FALLTHROUGH;
+ case Mips::CTTC1:
+ rd = getRegisterForMxtrFP(Inst, IsMFTR);
+ sel = 3;
+ break;
+ }
+ unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
+ unsigned Op1 =
+ IsMFTR ? rd
+ : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
+ : Inst.getOperand(0).getReg());
+
+ TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
+ STI);
+ return false;
+}
+
unsigned
MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
const OperandVector &Operands) {
@@ -5793,14 +6012,21 @@ OperandMatchResultTy
MipsAsmParser::parseInvNum(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
const MCExpr *IdVal;
- // If the first token is '$' we may have register operand.
- if (Parser.getTok().is(AsmToken::Dollar))
- return MatchOperand_NoMatch;
+ // If the first token is '$' we may have register operand. We have to reject
+ // cases where it is not a register. Complicating the matter is that
+ // register names are not reserved across all ABIs.
+ // Peek past the dollar to see if it's a register name for this ABI.
SMLoc S = Parser.getTok().getLoc();
+ if (Parser.getTok().is(AsmToken::Dollar)) {
+ return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
+ ? MatchOperand_ParseFail
+ : MatchOperand_NoMatch;
+ }
if (getParser().parseExpression(IdVal))
return MatchOperand_ParseFail;
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
- assert(MCE && "Unexpected MCExpr type.");
+ if (!MCE)
+ return MatchOperand_NoMatch;
int64_t Val = MCE->getValue();
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Operands.push_back(MipsOperand::CreateImm(
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
index aad6bf3..0bddba7 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
@@ -246,8 +246,6 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
break;
case MEK_CALL_HI16:
case MEK_CALL_LO16:
- case MEK_DTPREL_HI:
- case MEK_DTPREL_LO:
case MEK_GOT:
case MEK_GOT_CALL:
case MEK_GOT_DISP:
@@ -263,14 +261,16 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
case MEK_NEG:
case MEK_PCREL_HI16:
case MEK_PCREL_LO16:
- case MEK_TLSLDM:
// If we do have nested target-specific expressions, they will be in
// a consecutive chain.
if (const MipsMCExpr *E = dyn_cast<const MipsMCExpr>(getSubExpr()))
E->fixELFSymbolsInTLSFixups(Asm);
break;
- case MEK_GOTTPREL:
+ case MEK_DTPREL_HI:
+ case MEK_DTPREL_LO:
+ case MEK_TLSLDM:
case MEK_TLSGD:
+ case MEK_GOTTPREL:
case MEK_TPREL_HI:
case MEK_TPREL_LO:
fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 2907b77..7caeb08 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -193,6 +193,21 @@ void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1,
emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
}
+void MipsTargetStreamer::emitRRIII(unsigned Opcode, unsigned Reg0,
+ unsigned Reg1, int16_t Imm0, int16_t Imm1,
+ int16_t Imm2, SMLoc IDLoc,
+ const MCSubtargetInfo *STI) {
+ MCInst TmpInst;
+ TmpInst.setOpcode(Opcode);
+ TmpInst.addOperand(MCOperand::createReg(Reg0));
+ TmpInst.addOperand(MCOperand::createReg(Reg1));
+ TmpInst.addOperand(MCOperand::createImm(Imm0));
+ TmpInst.addOperand(MCOperand::createImm(Imm1));
+ TmpInst.addOperand(MCOperand::createImm(Imm2));
+ TmpInst.setLoc(IDLoc);
+ getStreamer().EmitInstruction(TmpInst, *STI);
+}
+
void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg,
unsigned TrgReg, bool Is64Bit,
const MCSubtargetInfo *STI) {
diff --git a/contrib/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td b/contrib/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td
index f82f82f..20c1ab5 100644
--- a/contrib/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td
+++ b/contrib/llvm/lib/Target/Mips/MicroMipsDSPInstrInfo.td
@@ -415,6 +415,13 @@ class BITREV_MM_DESC : ABSQ_S_PH_MM_R2_DESC_BASE<"bitrev", int_mips_bitrev,
class BPOSGE32_MM_DESC : BPOSGE32_DESC_BASE<"bposge32", brtarget_mm,
NoItinerary>;
+let DecoderNamespace = "MicroMipsDSP", Arch = "mmdsp",
+ AdditionalPredicates = [HasDSP, InMicroMips] in {
+ def LWDSP_MM : Load<"lw", DSPROpnd, null_frag, II_LW>, DspMMRel,
+ LW_FM_MM<0x3f>;
+ def SWDSP_MM : Store<"sw", DSPROpnd, null_frag, II_SW>, DspMMRel,
+ LW_FM_MM<0x3e>;
+}
// Instruction defs.
// microMIPS DSP Rev 1
def ADDQ_PH_MM : DspMMRel, ADDQ_PH_MM_ENC, ADDQ_PH_DESC;
diff --git a/contrib/llvm/lib/Target/Mips/MipsDSPInstrInfo.td b/contrib/llvm/lib/Target/Mips/MipsDSPInstrInfo.td
index c238a65..2595333 100644
--- a/contrib/llvm/lib/Target/Mips/MipsDSPInstrInfo.td
+++ b/contrib/llvm/lib/Target/Mips/MipsDSPInstrInfo.td
@@ -1284,6 +1284,12 @@ let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
def STORE_CCOND_DSP : Store<"store_ccond_dsp", DSPCC>;
}
+let DecoderNamespace = "MipsDSP", Arch = "dsp",
+ AdditionalPredicates = [HasDSP] in {
+ def LWDSP : Load<"lw", DSPROpnd, null_frag, II_LW>, DspMMRel, LW_FM<0x23>;
+ def SWDSP : Store<"sw", DSPROpnd, null_frag, II_SW>, DspMMRel, LW_FM<0x2b>;
+}
+
// Pseudo CMP and PICK instructions.
class PseudoCMP<Instruction RealInst> :
PseudoDSP<(outs DSPCC:$cmp), (ins DSPROpnd:$rs, DSPROpnd:$rt), []>,
diff --git a/contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp
index ef05166..27a8597 100644
--- a/contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp
@@ -107,38 +107,31 @@ bool MipsFrameLowering::hasBP(const MachineFunction &MF) const {
return MFI.hasVarSizedObjects() && TRI->needsStackRealignment(MF);
}
+// Estimate the size of the stack, including the incoming arguments. We need to
+// account for register spills, local objects, reserved call frame and incoming
+// arguments. This is required to determine the largest possible positive offset
+// from $sp so that it can be determined if an emergency spill slot for stack
+// addresses is required.
uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
- int64_t Offset = 0;
+ int64_t Size = 0;
- // Iterate over fixed sized objects.
+ // Iterate over fixed sized objects which are incoming arguments.
for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
- Offset = std::max(Offset, -MFI.getObjectOffset(I));
+ if (MFI.getObjectOffset(I) > 0)
+ Size += MFI.getObjectSize(I);
// Conservatively assume all callee-saved registers will be saved.
for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) {
- unsigned Size = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R));
- Offset = alignTo(Offset + Size, Size);
+ unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R));
+ Size = alignTo(Size + RegSize, RegSize);
}
- unsigned MaxAlign = MFI.getMaxAlignment();
-
- // Check that MaxAlign is not zero if there is a stack object that is not a
- // callee-saved spill.
- assert(!MFI.getObjectIndexEnd() || MaxAlign);
-
- // Iterate over other objects.
- for (unsigned I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I)
- Offset = alignTo(Offset + MFI.getObjectSize(I), MaxAlign);
-
- // Call frame.
- if (MFI.adjustsStack() && hasReservedCallFrame(MF))
- Offset = alignTo(Offset + MFI.getMaxCallFrameSize(),
- std::max(MaxAlign, getStackAlignment()));
-
- return alignTo(Offset, getStackAlignment());
+ // Get the size of the rest of the frame objects and any possible reserved
+ // call frame, accounting for alignment.
+ return Size + MFI.estimateStackSize(MF);
}
// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
diff --git a/contrib/llvm/lib/Target/Mips/MipsMTInstrFormats.td b/contrib/llvm/lib/Target/Mips/MipsMTInstrFormats.td
index 64bee5b..edc0981 100644
--- a/contrib/llvm/lib/Target/Mips/MipsMTInstrFormats.td
+++ b/contrib/llvm/lib/Target/Mips/MipsMTInstrFormats.td
@@ -35,6 +35,8 @@ class FIELD5<bits<5> Val> {
def FIELD5_1_DMT_EMT : FIELD5<0b00001>;
def FIELD5_2_DMT_EMT : FIELD5<0b01111>;
def FIELD5_1_2_DVPE_EVPE : FIELD5<0b00000>;
+def FIELD5_MFTR : FIELD5<0b01000>;
+def FIELD5_MTTR : FIELD5<0b01100>;
class COP0_MFMC0_MT<FIELD5 Op1, FIELD5 Op2, OPCODE1 sc> : MipsMTInst {
bits<32> Inst;
@@ -50,6 +52,25 @@ class COP0_MFMC0_MT<FIELD5 Op1, FIELD5 Op2, OPCODE1 sc> : MipsMTInst {
let Inst{2-0} = 0b001;
}
+class COP0_MFTTR_MT<FIELD5 Op> : MipsMTInst {
+ bits<32> Inst;
+
+ bits<5> rt;
+ bits<5> rd;
+ bits<1> u;
+ bits<1> h;
+ bits<3> sel;
+ let Inst{31-26} = 0b010000; // COP0
+ let Inst{25-21} = Op.Value; // MFMC0
+ let Inst{20-16} = rt;
+ let Inst{15-11} = rd;
+ let Inst{10-6} = 0b00000; // rx - currently unsupported.
+ let Inst{5} = u;
+ let Inst{4} = h;
+ let Inst{3} = 0b0;
+ let Inst{2-0} = sel;
+}
+
class SPECIAL3_MT_FORK : MipsMTInst {
bits<32> Inst;
diff --git a/contrib/llvm/lib/Target/Mips/MipsMTInstrInfo.td b/contrib/llvm/lib/Target/Mips/MipsMTInstrInfo.td
index ab6693f..72e626c 100644
--- a/contrib/llvm/lib/Target/Mips/MipsMTInstrInfo.td
+++ b/contrib/llvm/lib/Target/Mips/MipsMTInstrInfo.td
@@ -6,6 +6,13 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// This file describes the MIPS MT ASE as defined by MD00378 1.12.
+//
+// TODO: Add support for the microMIPS encodings for the MT ASE and add the
+// instruction mappings.
+//
+//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MIPS MT Instruction Encodings
@@ -27,6 +34,10 @@ class FORK_ENC : SPECIAL3_MT_FORK;
class YIELD_ENC : SPECIAL3_MT_YIELD;
+class MFTR_ENC : COP0_MFTTR_MT<FIELD5_MFTR>;
+
+class MTTR_ENC : COP0_MFTTR_MT<FIELD5_MTTR>;
+
//===----------------------------------------------------------------------===//
// MIPS MT Instruction Descriptions
//===----------------------------------------------------------------------===//
@@ -39,6 +50,22 @@ class MT_1R_DESC_BASE<string instr_asm, InstrItinClass Itin = NoItinerary> {
InstrItinClass Itinerary = Itin;
}
+class MFTR_DESC {
+ dag OutOperandList = (outs GPR32Opnd:$rd);
+ dag InOperandList = (ins GPR32Opnd:$rt, uimm1:$u, uimm3:$sel, uimm1:$h);
+ string AsmString = "mftr\t$rd, $rt, $u, $sel, $h";
+ list<dag> Pattern = [];
+ InstrItinClass Itinerary = II_MFTR;
+}
+
+class MTTR_DESC {
+ dag OutOperandList = (outs GPR32Opnd:$rd);
+ dag InOperandList = (ins GPR32Opnd:$rt, uimm1:$u, uimm3:$sel, uimm1:$h);
+ string AsmString = "mttr\t$rt, $rd, $u, $sel, $h";
+ list<dag> Pattern = [];
+ InstrItinClass Itinerary = II_MTTR;
+}
+
class FORK_DESC {
dag OutOperandList = (outs GPR32Opnd:$rs, GPR32Opnd:$rd);
dag InOperandList = (ins GPR32Opnd:$rt);
@@ -79,9 +106,74 @@ let hasSideEffects = 1, isNotDuplicable = 1,
def FORK : FORK_ENC, FORK_DESC, ASE_MT;
def YIELD : YIELD_ENC, YIELD_DESC, ASE_MT;
+
+ def MFTR : MFTR_ENC, MFTR_DESC, ASE_MT;
+
+ def MTTR : MTTR_ENC, MTTR_DESC, ASE_MT;
}
//===----------------------------------------------------------------------===//
+// MIPS MT Pseudo Instructions - used to support mtfr & mttr aliases.
+//===----------------------------------------------------------------------===//
+def MFTC0 : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins COP0Opnd:$rt,
+ uimm3:$sel),
+ "mftc0 $rd, $rt, $sel">, ASE_MT;
+
+def MFTGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rt,
+ uimm3:$sel),
+ "mftgpr $rd, $rt">, ASE_MT;
+
+def MFTLO : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac),
+ "mftlo $rt, $ac">, ASE_MT;
+
+def MFTHI : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac),
+ "mfthi $rt, $ac">, ASE_MT;
+
+def MFTACX : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac),
+ "mftacx $rt, $ac">, ASE_MT;
+
+def MFTDSP : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins),
+ "mftdsp $rt">, ASE_MT;
+
+def MFTC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGR32Opnd:$ft),
+ "mftc1 $rt, $ft">, ASE_MT;
+
+def MFTHC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGR32Opnd:$ft),
+ "mfthc1 $rt, $ft">, ASE_MT;
+
+def CFTC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGRCCOpnd:$ft),
+ "cftc1 $rt, $ft">, ASE_MT;
+
+
+def MTTC0 : MipsAsmPseudoInst<(outs COP0Opnd:$rd), (ins GPR32Opnd:$rt,
+ uimm3:$sel),
+ "mttc0 $rt, $rd, $sel">, ASE_MT;
+
+def MTTGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins GPR32Opnd:$rd),
+ "mttgpr $rd, $rt">, ASE_MT;
+
+def MTTLO : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt),
+ "mttlo $rt, $ac">, ASE_MT;
+
+def MTTHI : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt),
+ "mtthi $rt, $ac">, ASE_MT;
+
+def MTTACX : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt),
+ "mttacx $rt, $ac">, ASE_MT;
+
+def MTTDSP : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rt),
+ "mttdsp $rt">, ASE_MT;
+
+def MTTC1 : MipsAsmPseudoInst<(outs FGR32Opnd:$ft), (ins GPR32Opnd:$rt),
+ "mttc1 $rt, $ft">, ASE_MT;
+
+def MTTHC1 : MipsAsmPseudoInst<(outs FGR32Opnd:$ft), (ins GPR32Opnd:$rt),
+ "mtthc1 $rt, $ft">, ASE_MT;
+
+def CTTC1 : MipsAsmPseudoInst<(outs FGRCCOpnd:$ft), (ins GPR32Opnd:$rt),
+ "cttc1 $rt, $ft">, ASE_MT;
+
+//===----------------------------------------------------------------------===//
// MIPS MT Instruction Definitions
//===----------------------------------------------------------------------===//
@@ -95,4 +187,22 @@ let AdditionalPredicates = [NotInMicroMips] in {
def : MipsInstAlias<"evpe", (EVPE ZERO), 1>, ASE_MT;
def : MipsInstAlias<"yield $rs", (YIELD ZERO, GPR32Opnd:$rs), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mftc0 $rd, $rt", (MFTC0 GPR32Opnd:$rd, COP0Opnd:$rt, 0),
+ 1>, ASE_MT;
+
+ def : MipsInstAlias<"mftlo $rt", (MFTLO GPR32Opnd:$rt, AC0), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mfthi $rt", (MFTHI GPR32Opnd:$rt, AC0), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mftacx $rt", (MFTACX GPR32Opnd:$rt, AC0), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mttc0 $rd, $rt", (MTTC0 COP0Opnd:$rt, GPR32Opnd:$rd, 0),
+ 1>, ASE_MT;
+
+ def : MipsInstAlias<"mttlo $rt", (MTTLO AC0, GPR32Opnd:$rt), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mtthi $rt", (MTTHI AC0, GPR32Opnd:$rt), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mttacx $rt", (MTTACX AC0, GPR32Opnd:$rt), 1>, ASE_MT;
}
diff --git a/contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
index 102ebb2..735461c 100644
--- a/contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
@@ -894,10 +894,12 @@ void MipsSEFrameLowering::determineCalleeSaves(MachineFunction &MF,
}
// Set scavenging frame index if necessary.
- uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() +
- estimateStackSize(MF);
+ uint64_t MaxSPOffset = estimateStackSize(MF);
- if (isInt<16>(MaxSPOffset))
+ // MSA has a minimum offset of 10 bits signed. If there is a variable
+ // sized object on the stack, the estimation cannot account for it.
+ if (isIntN(STI.hasMSA() ? 10 : 16, MaxSPOffset) &&
+ !MF.getFrameInfo().hasVarSizedObjects())
return;
const TargetRegisterClass &RC =
diff --git a/contrib/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/contrib/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index ee07479..d2c2169 100644
--- a/contrib/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -226,6 +226,8 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
Opc = Mips::SW;
else if (Mips::HI64RegClass.hasSubClassEq(RC))
Opc = Mips::SD;
+ else if (Mips::DSPRRegClass.hasSubClassEq(RC))
+ Opc = Mips::SWDSP;
// Hi, Lo are normally caller save but they are callee save
// for interrupt handling.
@@ -302,6 +304,8 @@ loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
Opc = Mips::LW;
else if (Mips::LO64RegClass.hasSubClassEq(RC))
Opc = Mips::LD;
+ else if (Mips::DSPRRegClass.hasSubClassEq(RC))
+ Opc = Mips::LWDSP;
assert(Opc && "Register class not handled!");
diff --git a/contrib/llvm/lib/Target/Mips/MipsSchedule.td b/contrib/llvm/lib/Target/Mips/MipsSchedule.td
index c2947bb..8ec55ab 100644
--- a/contrib/llvm/lib/Target/Mips/MipsSchedule.td
+++ b/contrib/llvm/lib/Target/Mips/MipsSchedule.td
@@ -226,6 +226,7 @@ def II_MFC1 : InstrItinClass;
def II_MFHC1 : InstrItinClass;
def II_MFC2 : InstrItinClass;
def II_MFHI_MFLO : InstrItinClass; // mfhi and mflo
+def II_MFTR : InstrItinClass;
def II_MOD : InstrItinClass;
def II_MODU : InstrItinClass;
def II_MOVE : InstrItinClass;
@@ -255,6 +256,7 @@ def II_MTC1 : InstrItinClass;
def II_MTHC1 : InstrItinClass;
def II_MTC2 : InstrItinClass;
def II_MTHI_MTLO : InstrItinClass; // mthi and mtlo
+def II_MTTR : InstrItinClass;
def II_MUL : InstrItinClass;
def II_MUH : InstrItinClass;
def II_MUHU : InstrItinClass;
@@ -664,12 +666,14 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
InstrItinData<II_MFHC0 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MFC1 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MFC2 , [InstrStage<2, [ALU]>]>,
+ InstrItinData<II_MFTR , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTC0 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTHC0 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTC1 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTC2 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MFHC1 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTHC1 , [InstrStage<2, [ALU]>]>,
+ InstrItinData<II_MTTR , [InstrStage<2, [ALU]>]>,
InstrItinData<II_CACHE , [InstrStage<1, [ALU]>]>,
InstrItinData<II_PREF , [InstrStage<1, [ALU]>]>,
InstrItinData<II_CACHEE , [InstrStage<1, [ALU]>]>,
diff --git a/contrib/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/contrib/llvm/lib/Target/Mips/MipsScheduleGeneric.td
index 89cda67..e4c52a4 100644
--- a/contrib/llvm/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/contrib/llvm/lib/Target/Mips/MipsScheduleGeneric.td
@@ -268,9 +268,11 @@ def : ItinRW<[GenericWriteLoad], [II_LWLE, II_LWRE]>;
// MIPS MT instructions
// ====================
-def : ItinRW<[GenericWriteMove], [II_DMT, II_DVPE, II_EMT, II_EVPE]>;
+def : ItinRW<[GenericWriteMove], [II_DMT, II_DVPE, II_EMT, II_EVPE, II_MFTR,
+ II_MTTR]>;
def : ItinRW<[GenericReadWriteCOP0Long], [II_YIELD]>;
+
def : ItinRW<[GenericWriteCOP0Short], [II_FORK]>;
// MIPS32R6 and MIPS16e
diff --git a/contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h b/contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h
index 7d9f99c..af24838 100644
--- a/contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h
+++ b/contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h
@@ -119,6 +119,9 @@ public:
SMLoc IDLoc, const MCSubtargetInfo *STI);
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
SMLoc IDLoc, const MCSubtargetInfo *STI);
+ void emitRRIII(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm0,
+ int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
+ const MCSubtargetInfo *STI);
void emitAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, bool Is64Bit,
const MCSubtargetInfo *STI);
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
diff --git a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
index 957b46c40..607bc45 100644
--- a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -7026,6 +7026,18 @@ X86TargetLowering::LowerBUILD_VECTORvXi1(SDValue Op, SelectionDAG &DAG) const {
return DAG.getTargetConstant(1, dl, VT);
if (ISD::isBuildVectorOfConstantSDNodes(Op.getNode())) {
+ if (VT == MVT::v64i1 && !Subtarget.is64Bit()) {
+ // Split the pieces.
+ SDValue Lower =
+ DAG.getBuildVector(MVT::v32i1, dl, Op.getNode()->ops().slice(0, 32));
+ SDValue Upper =
+ DAG.getBuildVector(MVT::v32i1, dl, Op.getNode()->ops().slice(32, 32));
+ // We have to manually lower both halves so getNode doesn't try to
+ // reassemble the build_vector.
+ Lower = LowerBUILD_VECTORvXi1(Lower, DAG);
+ Upper = LowerBUILD_VECTORvXi1(Upper, DAG);
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v64i1, Lower, Upper);
+ }
SDValue Imm = ConvertI1VectorToInteger(Op, DAG);
if (Imm.getValueSizeInBits() == VT.getSizeInBits())
return DAG.getBitcast(VT, Imm);
@@ -34733,6 +34745,11 @@ static SDValue combineVectorSizedSetCCEquality(SDNode *SetCC, SelectionDAG &DAG,
if (!OpVT.isScalarInteger() || OpSize < 128 || isNullConstant(Y))
return SDValue();
+ // Bail out if we know that this is not really just an oversized integer.
+ if (peekThroughBitcasts(X).getValueType() == MVT::f128 ||
+ peekThroughBitcasts(Y).getValueType() == MVT::f128)
+ return SDValue();
+
// TODO: Use PXOR + PTEST for SSE4.1 or later?
// TODO: Add support for AVX-512.
EVT VT = SetCC->getValueType(0);
diff --git a/contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp b/contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 9d01856..8ac1034 100644
--- a/contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/contrib/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -586,8 +586,8 @@ public:
private:
// Expression handling.
const Expression *createExpression(Instruction *) const;
- const Expression *createBinaryExpression(unsigned, Type *, Value *,
- Value *) const;
+ const Expression *createBinaryExpression(unsigned, Type *, Value *, Value *,
+ Instruction *) const;
PHIExpression *createPHIExpression(Instruction *, bool &HasBackEdge,
bool &OriginalOpsConstant) const;
const DeadExpression *createDeadExpression() const;
@@ -902,8 +902,8 @@ bool NewGVN::setBasicExpressionInfo(Instruction *I, BasicExpression *E) const {
}
const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
- Value *Arg1,
- Value *Arg2) const {
+ Value *Arg1, Value *Arg2,
+ Instruction *I) const {
auto *E = new (ExpressionAllocator) BasicExpression(2);
E->setType(T);
@@ -921,7 +921,7 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
E->op_push_back(lookupOperandLeader(Arg2));
Value *V = SimplifyBinOp(Opcode, E->getOperand(0), E->getOperand(1), SQ);
- if (const Expression *SimplifiedE = checkSimplificationResults(E, nullptr, V))
+ if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
return SimplifiedE;
return E;
}
@@ -1699,8 +1699,9 @@ NewGVN::performSymbolicAggrValueEvaluation(Instruction *I) const {
// expression.
assert(II->getNumArgOperands() == 2 &&
"Expect two args for recognised intrinsics.");
- return createBinaryExpression(
- Opcode, EI->getType(), II->getArgOperand(0), II->getArgOperand(1));
+ return createBinaryExpression(Opcode, EI->getType(),
+ II->getArgOperand(0),
+ II->getArgOperand(1), I);
}
}
}
@@ -1933,6 +1934,7 @@ void NewGVN::touchAndErase(Map &M, const KeyType &Key) {
}
void NewGVN::addAdditionalUsers(Value *To, Value *User) const {
+ assert(User && To != User);
if (isa<Instruction>(To))
AdditionalUsers[To].insert(User);
}
diff --git a/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S b/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S
index d916695..884cc05 100644
--- a/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S
+++ b/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S
@@ -484,4 +484,5 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
#endif
- .section .note.GNU-stack,"",@progbits
+NO_EXEC_STACK_DIRECTIVE
+
diff --git a/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S b/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S
index cebcd76..98c8c4f 100644
--- a/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S
+++ b/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S
@@ -470,4 +470,5 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
#endif
- .section .note.GNU-stack,"",@progbits
+NO_EXEC_STACK_DIRECTIVE
+
diff --git a/contrib/llvm/projects/libunwind/src/assembly.h b/contrib/llvm/projects/libunwind/src/assembly.h
index f46a24d..06b29b3 100644
--- a/contrib/llvm/projects/libunwind/src/assembly.h
+++ b/contrib/llvm/projects/libunwind/src/assembly.h
@@ -35,19 +35,34 @@
#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
#if defined(__APPLE__)
+
#define SYMBOL_IS_FUNC(name)
+#define NO_EXEC_STACK_DIRECTIVE
+
#elif defined(__ELF__)
+
#if defined(__arm__)
#define SYMBOL_IS_FUNC(name) .type name,%function
#else
#define SYMBOL_IS_FUNC(name) .type name,@function
#endif
+
+#if defined(__GNU__) || defined(__ANDROID__) || defined(__FreeBSD__)
+#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
+#else
+#define NO_EXEC_STACK_DIRECTIVE
+#endif
+
#else
+
#define SYMBOL_IS_FUNC(name) \
.def name SEPARATOR \
.scl 2 SEPARATOR \
.type 32 SEPARATOR \
.endef
+
+#define NO_EXEC_STACK_DIRECTIVE
+
#endif
#define DEFINE_LIBUNWIND_FUNCTION(name) \
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td
index f13e13b..5c69635 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td
+++ b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td
@@ -2459,9 +2459,9 @@ def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
let Documentation = [DLLImportDocs];
}
-def SelectAny : InheritableAttr, TargetSpecificAttr<TargetWindows> {
+def SelectAny : InheritableAttr {
let Spellings = [Declspec<"selectany">, GCC<"selectany">];
- let Documentation = [Undocumented];
+ let Documentation = [SelectAnyDocs];
}
def Thread : Attr {
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td b/contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td
index 33ef3ea..567c7a3 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td
+++ b/contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td
@@ -3106,3 +3106,18 @@ This attribute can be added to an Objective-C ``@interface`` declaration to
ensure that this class cannot be subclassed.
}];
}
+
+
+def SelectAnyDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{
+This attribute appertains to a global symbol, causing it to have a weak
+definition (
+`linkonce <https://llvm.org/docs/LangRef.html#linkage-types>`_
+), allowing the linker to select any definition.
+
+For more information see
+`gcc documentation <https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Microsoft-Windows-Variable-Attributes.html>`_
+or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_.
+}];
+}
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def
index 6d3a478..2f8f891 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def
+++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def
@@ -976,7 +976,6 @@ TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "", "avx512f")
diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6456913..8dc6e7b 100644
--- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8830,7 +8830,7 @@ def err_omp_firstprivate_distribute_in_teams_reduction : Error<
def err_omp_depend_clause_thread_simd : Error<
"'depend' clauses cannot be mixed with '%0' clause">;
def err_omp_depend_sink_expected_loop_iteration : Error<
- "expected %0 loop iteration variable">;
+ "expected%select{| %1}0 loop iteration variable">;
def err_omp_depend_sink_unexpected_expr : Error<
"unexpected expression: number of expressions is larger than the number of associated loops">;
def err_omp_depend_sink_expected_plus_minus : Error<
diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h
index 4251fa6..215f30a 100644
--- a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h
+++ b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h
@@ -560,6 +560,7 @@ public:
void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
VarDecl *getVariable() const {
+ assert(isVariableCapture());
return VarAndNestedAndThis.getPointer();
}
diff --git a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp
index a26b608..792e8cc 100644
--- a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp
@@ -537,7 +537,7 @@ namespace {
/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can
/// evaluate the expression regardless of what the RHS is, but C only allows
/// certain things in certain situations.
- struct LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) EvalInfo {
+ struct EvalInfo {
ASTContext &Ctx;
/// EvalStatus - Contains information about the evaluation.
@@ -977,24 +977,22 @@ namespace {
/// RAII object used to optionally suppress diagnostics and side-effects from
/// a speculative evaluation.
class SpeculativeEvaluationRAII {
- /// Pair of EvalInfo, and a bit that stores whether or not we were
- /// speculatively evaluating when we created this RAII.
- llvm::PointerIntPair<EvalInfo *, 1, bool> InfoAndOldSpecEval;
- Expr::EvalStatus Old;
+ EvalInfo *Info = nullptr;
+ Expr::EvalStatus OldStatus;
+ bool OldIsSpeculativelyEvaluating;
void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
- InfoAndOldSpecEval = Other.InfoAndOldSpecEval;
- Old = Other.Old;
- Other.InfoAndOldSpecEval.setPointer(nullptr);
+ Info = Other.Info;
+ OldStatus = Other.OldStatus;
+ Other.Info = nullptr;
}
void maybeRestoreState() {
- EvalInfo *Info = InfoAndOldSpecEval.getPointer();
if (!Info)
return;
- Info->EvalStatus = Old;
- Info->IsSpeculativelyEvaluating = InfoAndOldSpecEval.getInt();
+ Info->EvalStatus = OldStatus;
+ Info->IsSpeculativelyEvaluating = OldIsSpeculativelyEvaluating;
}
public:
@@ -1002,8 +1000,8 @@ namespace {
SpeculativeEvaluationRAII(
EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag = nullptr)
- : InfoAndOldSpecEval(&Info, Info.IsSpeculativelyEvaluating),
- Old(Info.EvalStatus) {
+ : Info(&Info), OldStatus(Info.EvalStatus),
+ OldIsSpeculativelyEvaluating(Info.IsSpeculativelyEvaluating) {
Info.EvalStatus.Diag = NewDiag;
Info.IsSpeculativelyEvaluating = true;
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index 5d75aa5..b33ab13 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -2169,7 +2169,7 @@ class AMDGPUTargetInfo final : public TargetInfo {
public:
AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: TargetInfo(Triple) ,
- GPU(isAMDGCN(Triple) ? GK_GFX6 : GK_R600),
+ GPU(isAMDGCN(Triple) ? GK_GFX6 : parseR600Name(Opts.CPU)),
hasFP64(false),
hasFMAF(false),
hasLDEXPF(false),
@@ -2179,6 +2179,12 @@ public:
hasFMAF = true;
hasLDEXPF = true;
}
+ if (getTriple().getArch() == llvm::Triple::r600) {
+ if (GPU == GK_EVERGREEN_DOUBLE_OPS || GPU == GK_CAYMAN) {
+ hasFMAF = true;
+ }
+ }
+
auto IsGenericZero = isGenericZero(Triple);
resetDataLayout(getTriple().getArch() == llvm::Triple::amdgcn ?
(IsGenericZero ? DataLayoutStringSIGenericIsZero :
@@ -9350,8 +9356,7 @@ public:
WIntType = SignedInt;
Char32Type = UnsignedLong;
SigAtomicType = SignedChar;
- resetDataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
- "-f32:32:32-f64:64:64-n8");
+ resetDataLayout("e-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8");
}
void getTargetDefines(const LangOptions &Opts,
diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp
index 509c4a9..2c569ff 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Version.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Version.cpp
@@ -36,7 +36,7 @@ std::string getClangRepositoryPath() {
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
// pick up a tag in an SVN export, for example.
- StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_500/final/lib/Basic/Version.cpp $");
+ StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_501/final/lib/Basic/Version.cpp $");
if (URL.empty()) {
URL = SVNRepository.slice(SVNRepository.find(':'),
SVNRepository.find("/lib/Basic"));
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
index 9572bd3..63c7b3d 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
@@ -3309,12 +3309,7 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
bool IsLowerBound) {
- QualType BaseTy;
- if (auto *ASE =
- dyn_cast<OMPArraySectionExpr>(E->getBase()->IgnoreParenImpCasts()))
- BaseTy = OMPArraySectionExpr::getBaseOriginalType(ASE);
- else
- BaseTy = E->getBase()->getType();
+ QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(E->getBase());
QualType ResultExprTy;
if (auto *AT = getContext().getAsArrayType(BaseTy))
ResultExprTy = AT->getElementType();
@@ -3619,8 +3614,9 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
getFieldAlignmentSource(BaseInfo.getAlignmentSource());
LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias());
+ QualType type = field->getType();
const RecordDecl *rec = field->getParent();
- if (rec->isUnion() || rec->hasAttr<MayAliasAttr>())
+ if (rec->isUnion() || rec->hasAttr<MayAliasAttr>() || type->isVectorType())
FieldBaseInfo.setMayAlias(true);
bool mayAlias = FieldBaseInfo.getMayAlias();
@@ -3645,7 +3641,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo);
}
- QualType type = field->getType();
Address addr = base.getAddress();
unsigned cvr = base.getVRQualifiers();
bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA;
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index d488bd4..9f8aa6c 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -264,6 +264,13 @@ public:
return nullptr;
}
+ /// \brief Get an LValue for the current ThreadID variable.
+ LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override {
+ if (OuterRegionInfo)
+ return OuterRegionInfo->getThreadIDVariableLValue(CGF);
+ llvm_unreachable("No LValue for inlined OpenMP construct");
+ }
+
/// \brief Get the name of the capture helper.
StringRef getHelperName() const override {
if (auto *OuterRegionInfo = getOldCSI())
@@ -771,7 +778,8 @@ static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
/// \param Init Initial expression of array.
/// \param SrcAddr Address of the original array.
static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
- QualType Type, const Expr *Init,
+ QualType Type, bool EmitDeclareReductionInit,
+ const Expr *Init,
const OMPDeclareReductionDecl *DRD,
Address SrcAddr = Address::invalid()) {
// Perform element-by-element initialization.
@@ -825,7 +833,7 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
// Emit copy.
{
CodeGenFunction::RunCleanupsScope InitScope(CGF);
- if (DRD && (DRD->getInitializer() || !Init)) {
+ if (EmitDeclareReductionInit) {
emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
SrcElementCurrent, ElementTy);
} else
@@ -883,8 +891,12 @@ void ReductionCodeGen::emitAggregateInitialization(
// captured region.
auto *PrivateVD =
cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
+ bool EmitDeclareReductionInit =
+ DRD && (DRD->getInitializer() || !PrivateVD->hasInit());
EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(),
- DRD ? ClausesData[N].ReductionOp : PrivateVD->getInit(),
+ EmitDeclareReductionInit,
+ EmitDeclareReductionInit ? ClausesData[N].ReductionOp
+ : PrivateVD->getInit(),
DRD, SharedLVal.getAddress());
}
@@ -4244,9 +4256,20 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
// Build type kmp_routine_entry_t (if not built yet).
emitKmpRoutineEntryT(KmpInt32Ty);
// Build type kmp_task_t (if not built yet).
- if (KmpTaskTQTy.isNull()) {
- KmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
- CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
+ if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) {
+ if (SavedKmpTaskloopTQTy.isNull()) {
+ SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl(
+ CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
+ }
+ KmpTaskTQTy = SavedKmpTaskloopTQTy;
+ } else if (D.getDirectiveKind() == OMPD_task) {
+ assert(D.getDirectiveKind() == OMPD_task &&
+ "Expected taskloop or task directive");
+ if (SavedKmpTaskTQTy.isNull()) {
+ SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
+ CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
+ }
+ KmpTaskTQTy = SavedKmpTaskTQTy;
}
auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
// Build particular struct kmp_task_t for the given task.
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
index 5dcf999..185c01d 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -313,6 +313,10 @@ private:
/// deconstructors of firstprivate C++ objects */
/// } kmp_task_t;
QualType KmpTaskTQTy;
+ /// Saved kmp_task_t for task directive.
+ QualType SavedKmpTaskTQTy;
+ /// Saved kmp_task_t for taskloop-based directive.
+ QualType SavedKmpTaskloopTQTy;
/// \brief Type typedef struct kmp_depend_info {
/// kmp_intptr_t base_addr;
/// size_t len;
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 6135cf3..cf430f8 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1210,12 +1210,14 @@ void CodeGenFunction::EmitOMPInnerLoop(
EmitBlock(LoopExit.getBlock());
}
-void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
+bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
if (!HaveInsertPoint())
- return;
+ return false;
// Emit inits for the linear variables.
+ bool HasLinears = false;
for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
for (auto *Init : C->inits()) {
+ HasLinears = true;
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
if (auto *Ref = dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) {
AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
@@ -1240,6 +1242,7 @@ void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
EmitIgnoredExpr(CS);
}
}
+ return HasLinears;
}
void CodeGenFunction::EmitOMPLinearClauseFinal(
@@ -1529,7 +1532,7 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
CGF.EmitOMPSimdInit(S);
emitAlignedClause(CGF, S);
- CGF.EmitOMPLinearClauseInit(S);
+ (void)CGF.EmitOMPLinearClauseInit(S);
{
OMPPrivateScope LoopScope(CGF);
CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
@@ -2147,7 +2150,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(
llvm::DenseSet<const Expr *> EmittedFinals;
emitAlignedClause(*this, S);
- EmitOMPLinearClauseInit(S);
+ bool HasLinears = EmitOMPLinearClauseInit(S);
// Emit helper vars inits.
std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S);
@@ -2161,7 +2164,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(
// Emit 'then' code.
{
OMPPrivateScope LoopScope(*this);
- if (EmitOMPFirstprivateClause(S, LoopScope)) {
+ if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables and post-update of
// lastprivate variables.
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
index 753dd92..6a1fa48 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
@@ -1116,7 +1116,7 @@ private:
auto IP = CGF.Builder.saveAndClearIP();
CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
CodeGen(CGF);
- CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
+ CGF.EmitBranch(Stack.back().ContBlock.getBlock());
CGF.Builder.restoreIP(IP);
Stack.back().HasBeenEmitted = true;
}
@@ -2761,7 +2761,9 @@ public:
/// and initializes them with the values according to OpenMP standard.
///
/// \param D Directive (possibly) with the 'linear' clause.
- void EmitOMPLinearClauseInit(const OMPLoopDirective &D);
+ /// \return true if at least one linear variable is found that should be
+ /// initialized with the value of the original variable, false otherwise.
+ bool EmitOMPLinearClauseInit(const OMPLoopDirective &D);
typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/,
llvm::Value * /*OutlinedFn*/,
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
index 9a858df..12afb18 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp
@@ -74,11 +74,6 @@ ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
: D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)),
EffectiveTriple() {
- if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
- if (!isThreadModelSupported(A->getValue()))
- D.Diag(diag::err_drv_invalid_thread_model_for_target)
- << A->getValue() << A->getAsString(Args);
-
std::string CandidateLibPath = getArchSpecificLibPath();
if (getVFS().exists(CandidateLibPath))
getFilePaths().push_back(CandidateLibPath);
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp
index 5dc6dfa..28e4f5b 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -65,14 +65,6 @@ Tool *BareMetal::buildLinker() const {
return new tools::baremetal::Linker(*this);
}
-std::string BareMetal::getThreadModel() const {
- return "single";
-}
-
-bool BareMetal::isThreadModelSupported(const StringRef Model) const {
- return Model == "single";
-}
-
std::string BareMetal::getRuntimesDir() const {
SmallString<128> Dir(getDriver().ResourceDir);
llvm::sys::path::append(Dir, "lib", "baremetal");
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h
index 4b74899..5e9fd9b 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains/BareMetal.h
@@ -38,8 +38,6 @@ public:
bool isPICDefaultForced() const override { return false; }
bool SupportsProfiling() const override { return false; }
bool SupportsObjCGC() const override { return false; }
- std::string getThreadModel() const override;
- bool isThreadModelSupported(const StringRef Model) const override;
RuntimeLibType GetDefaultRuntimeLibType() const override {
return ToolChain::RLT_CompilerRT;
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
index 6a6b90f..497f0b4 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2227,8 +2227,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
CmdArgs.push_back("-mthread-model");
- if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
+ if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) {
+ if (!getToolChain().isThreadModelSupported(A->getValue()))
+ D.Diag(diag::err_drv_invalid_thread_model_for_target)
+ << A->getValue() << A->getAsString(Args);
CmdArgs.push_back(A->getValue());
+ }
else
CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel()));
diff --git a/contrib/llvm/tools/clang/lib/Format/Format.cpp b/contrib/llvm/tools/clang/lib/Format/Format.cpp
index aa4ed8c..6fe5be2 100644
--- a/contrib/llvm/tools/clang/lib/Format/Format.cpp
+++ b/contrib/llvm/tools/clang/lib/Format/Format.cpp
@@ -506,7 +506,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
Expanded.BraceWrapping.AfterFunction = true;
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterUnion = true;
- Expanded.BraceWrapping.SplitEmptyFunction = false;
+ Expanded.BraceWrapping.SplitEmptyFunction = true;
Expanded.BraceWrapping.SplitEmptyRecord = false;
break;
case FormatStyle::BS_Stroustrup:
diff --git a/contrib/llvm/tools/clang/lib/Headers/avx512fintrin.h b/contrib/llvm/tools/clang/lib/Headers/avx512fintrin.h
index 4ce6945..4b66acc02 100644
--- a/contrib/llvm/tools/clang/lib/Headers/avx512fintrin.h
+++ b/contrib/llvm/tools/clang/lib/Headers/avx512fintrin.h
@@ -267,21 +267,16 @@ _mm512_maskz_set1_epi32(__mmask16 __M, int __A)
__M);
}
+#ifdef __x86_64__
static __inline __m512i __DEFAULT_FN_ATTRS
_mm512_maskz_set1_epi64(__mmask8 __M, long long __A)
{
-#ifdef __x86_64__
return (__m512i) __builtin_ia32_pbroadcastq512_gpr_mask (__A,
(__v8di)
_mm512_setzero_si512 (),
__M);
-#else
- return (__m512i) __builtin_ia32_pbroadcastq512_mem_mask (__A,
- (__v8di)
- _mm512_setzero_si512 (),
- __M);
-#endif
}
+#endif
static __inline __m512 __DEFAULT_FN_ATTRS
_mm512_setzero_ps(void)
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
index 692a77e..59c1012 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
@@ -1603,7 +1603,24 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
if (D->isInvalidDecl())
return false;
- if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>() ||
+ bool Referenced = false;
+ if (auto *DD = dyn_cast<DecompositionDecl>(D)) {
+ // For a decomposition declaration, warn if none of the bindings are
+ // referenced, instead of if the variable itself is referenced (which
+ // it is, by the bindings' expressions).
+ for (auto *BD : DD->bindings()) {
+ if (BD->isReferenced()) {
+ Referenced = true;
+ break;
+ }
+ }
+ } else if (!D->getDeclName()) {
+ return false;
+ } else if (D->isReferenced() || D->isUsed()) {
+ Referenced = true;
+ }
+
+ if (Referenced || D->hasAttr<UnusedAttr>() ||
D->hasAttr<ObjCPreciseLifetimeAttr>())
return false;
@@ -1726,7 +1743,7 @@ void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {
else
DiagID = diag::warn_unused_variable;
- Diag(D->getLocation(), DiagID) << D->getDeclName() << Hint;
+ Diag(D->getLocation(), DiagID) << D << Hint;
}
static void CheckPoppedLabel(LabelDecl *L, Sema &S) {
@@ -1756,8 +1773,6 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
NamedDecl *D = cast<NamedDecl>(TmpD);
- if (!D->getDeclName()) continue;
-
// Diagnose unused variables in this scope.
if (!S->hasUnrecoverableErrorOccurred()) {
DiagnoseUnusedDecl(D);
@@ -1765,6 +1780,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
DiagnoseUnusedNestedTypedefs(RD);
}
+ if (!D->getDeclName()) continue;
+
// If this was a forward reference to a label, verify it was defined.
if (LabelDecl *LD = dyn_cast<LabelDecl>(D))
CheckPoppedLabel(LD, *this);
@@ -6155,7 +6172,6 @@ NamedDecl *Sema::ActOnVariableDeclarator(
IdentifierInfo *II = Name.getAsIdentifierInfo();
if (D.isDecompositionDeclarator()) {
- AddToScope = false;
// Take the name of the first declarator as our name for diagnostic
// purposes.
auto &Decomp = D.getDecompositionDeclarator();
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
index c05e5f0..48f698c 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
@@ -826,7 +826,10 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
NamedDecl *New =
ActOnVariableDeclarator(S, D, DC, TInfo, Previous,
MultiTemplateParamsArg(), AddToScope, Bindings);
- CurContext->addHiddenDecl(New);
+ if (AddToScope) {
+ S->AddDecl(New);
+ CurContext->addHiddenDecl(New);
+ }
if (isInOpenMPDeclareTargetContext())
checkDeclIsAllowedInOpenMPTarget(nullptr, New);
@@ -12997,7 +13000,8 @@ bool Sema::CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl) {
StringRef LiteralName
= FnDecl->getDeclName().getCXXLiteralIdentifier()->getName();
- if (LiteralName[0] != '_') {
+ if (LiteralName[0] != '_' &&
+ !getSourceManager().isInSystemHeader(FnDecl->getLocation())) {
// C++11 [usrlit.suffix]p1:
// Literal suffix identifiers that do not start with an underscore
// are reserved for future standardization.
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
index 46f2ba3..b0b7e64 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
@@ -1469,6 +1469,9 @@ void Sema::DiagnoseUnusedLambdaCapture(const LambdaScopeInfo::Capture &From) {
if (CaptureHasSideEffects(From))
return;
+ if (From.isVLATypeCapture())
+ return;
+
auto diag = Diag(From.getLocation(), diag::warn_unused_lambda_capture);
if (From.isThisCapture())
diag << "'this'";
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp
index 01f574b..1ae6f9d 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp
@@ -3111,8 +3111,8 @@ bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
if (!NewStep->isValueDependent()) {
// Check that the step is integer expression.
SourceLocation StepLoc = NewStep->getLocStart();
- ExprResult Val =
- SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
+ ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
+ StepLoc, getExprAsWritten(NewStep));
if (Val.isInvalid())
return true;
NewStep = Val.get();
@@ -8858,7 +8858,8 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
PrevD = D;
}
}
- if (Ty->isDependentType() || Ty->isInstantiationDependentType() ||
+ if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
+ Ty->isInstantiationDependentType() ||
Ty->containsUnexpandedParameterPack() ||
filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool {
return !D->isInvalidDecl() &&
@@ -10226,9 +10227,14 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
if (!CurContext->isDependentContext() &&
DSAStack->getParentOrderedRegionParam() &&
DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
- Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
- << DSAStack->getParentLoopControlVariable(
- DepCounter.getZExtValue());
+ ValueDecl* VD = DSAStack->getParentLoopControlVariable(
+ DepCounter.getZExtValue());
+ if (VD) {
+ Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
+ << 1 << VD;
+ } else {
+ Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
+ }
continue;
}
OpsOffs.push_back({RHS, OOK});
@@ -10258,8 +10264,9 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
TotalDepCount > VarList.size() &&
- DSAStack->getParentOrderedRegionParam()) {
- Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
+ DSAStack->getParentOrderedRegionParam() &&
+ DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
+ Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1
<< DSAStack->getParentLoopControlVariable(VarList.size() + 1);
}
if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 6fee23a..4a26efc 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -677,6 +677,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Decl *TemplateDeclInstantiator::VisitBindingDecl(BindingDecl *D) {
auto *NewBD = BindingDecl::Create(SemaRef.Context, Owner, D->getLocation(),
D->getIdentifier());
+ NewBD->setReferenced(D->isReferenced());
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewBD);
return NewBD;
}
diff --git a/contrib/llvm/tools/lld/ELF/Driver.cpp b/contrib/llvm/tools/lld/ELF/Driver.cpp
index 458016f..1ff2d29 100644
--- a/contrib/llvm/tools/lld/ELF/Driver.cpp
+++ b/contrib/llvm/tools/lld/ELF/Driver.cpp
@@ -1010,6 +1010,15 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
if (Args.hasArg(OPT_exclude_libs))
excludeLibs(Args, Files);
+ // Create ElfHeader early. We need a dummy section in
+ // addReservedSymbols to mark the created symbols as not absolute.
+ Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
+ Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
+
+ // We need to create some reserved symbols such as _end. Create them.
+ if (!Config->Relocatable)
+ addReservedSymbols<ELFT>();
+
// Apply version scripts.
Symtab.scanVersionScript();
diff --git a/contrib/llvm/tools/lld/ELF/MarkLive.cpp b/contrib/llvm/tools/lld/ELF/MarkLive.cpp
index bde3eef..ab216cf 100644
--- a/contrib/llvm/tools/lld/ELF/MarkLive.cpp
+++ b/contrib/llvm/tools/lld/ELF/MarkLive.cpp
@@ -73,12 +73,13 @@ static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
std::function<void(ResolvedReloc)> Fn) {
SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
if (auto *D = dyn_cast<DefinedRegular>(&B)) {
- if (!D->Section)
+ auto *RelSec = dyn_cast_or_null<InputSectionBase>(D->Section);
+ if (!RelSec)
return;
typename ELFT::uint Offset = D->Value;
if (D->isSection())
Offset += getAddend<ELFT>(Sec, Rel);
- Fn({cast<InputSectionBase>(D->Section), Offset});
+ Fn({RelSec, Offset});
} else if (auto *U = dyn_cast<Undefined>(&B)) {
for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
Fn({Sec, 0});
@@ -220,7 +221,7 @@ template <class ELFT> void elf::markLive() {
auto MarkSymbol = [&](const SymbolBody *Sym) {
if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
- if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
+ if (auto *IS = dyn_cast_or_null<InputSectionBase>(D->Section))
Enqueue({IS, D->Value});
};
diff --git a/contrib/llvm/tools/lld/ELF/Relocations.cpp b/contrib/llvm/tools/lld/ELF/Relocations.cpp
index e5fcb2d..ce8ec6f 100644
--- a/contrib/llvm/tools/lld/ELF/Relocations.cpp
+++ b/contrib/llvm/tools/lld/ELF/Relocations.cpp
@@ -790,13 +790,31 @@ static void addGotEntry(SymbolBody &Sym, bool Preemptible) {
DynType = Target->GotRel;
}
- bool Constant = !Preemptible && !(Config->Pic && !isAbsolute(Sym));
- if (!Constant)
+ // If a GOT slot value can be calculated at link-time, which is now,
+ // we can just fill that out.
+ //
+ // (We don't actually write a value to a GOT slot right now, but we
+ // add a static relocation to a Relocations vector so that
+ // InputSection::relocate will do the work for us. We may be able
+ // to just write a value now, but it is a TODO.)
+ bool IsLinkTimeConstant = !Preemptible && (!Config->Pic || isAbsolute(Sym));
+ if (IsLinkTimeConstant) {
+ InX::Got->Relocations.push_back({Expr, DynType, Off, 0, &Sym});
+ } else {
+ // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that
+ // the GOT slot will be fixed at load-time.
In<ELFT>::RelaDyn->addReloc(
{DynType, InX::Got, Off, !Preemptible, &Sym, 0});
- if (Constant || (!Config->IsRela && !Preemptible))
- InX::Got->Relocations.push_back({Expr, DynType, Off, 0, &Sym});
+ // REL type relocations don't have addend fields unlike RELAs, and
+ // their addends are stored to the section to which they are applied.
+ // So, store addends if we need to.
+ //
+ // This is ugly -- the difference between REL and RELA should be
+ // handled in a better way. It's a TODO.
+ if (!Config->IsRela && !Preemptible)
+ InX::Got->Relocations.push_back({R_ABS, Target->GotRel, Off, 0, &Sym});
+ }
}
// The reason we have to do this early scan is as follows
diff --git a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
index 4bbec4a..a67b039 100644
--- a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
+++ b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
@@ -427,10 +427,11 @@ CieRecord *EhFrameSection<ELFT>::addCie(EhSectionPiece &Piece,
&Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]);
// Search for an existing CIE by CIE contents/relocation target pair.
- CieRecord *Cie = &CieMap[{Piece.data(), Personality}];
+ CieRecord *&Cie = CieMap[{Piece.data(), Personality}];
// If not found, create a new one.
- if (Cie->Piece == nullptr) {
+ if (!Cie) {
+ Cie = make<CieRecord>();
Cie->Piece = &Piece;
Cies.push_back(Cie);
}
@@ -522,9 +523,14 @@ template <class ELFT>
static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) {
memcpy(Buf, D.data(), D.size());
+ size_t Aligned = alignTo(D.size(), sizeof(typename ELFT::uint));
+
+ // Zero-clear trailing padding if it exists.
+ memset(Buf + D.size(), 0, Aligned - D.size());
+
// Fix the size field. -4 since size does not include the size field itself.
const endianness E = ELFT::TargetEndianness;
- write32<E>(Buf, alignTo(D.size(), sizeof(typename ELFT::uint)) - 4);
+ write32<E>(Buf, Aligned - 4);
}
template <class ELFT> void EhFrameSection<ELFT>::finalizeContents() {
diff --git a/contrib/llvm/tools/lld/ELF/SyntheticSections.h b/contrib/llvm/tools/lld/ELF/SyntheticSections.h
index ddd8ca9..ccf021e 100644
--- a/contrib/llvm/tools/lld/ELF/SyntheticSections.h
+++ b/contrib/llvm/tools/lld/ELF/SyntheticSections.h
@@ -103,7 +103,8 @@ private:
std::vector<CieRecord *> Cies;
// CIE records are uniquified by their contents and personality functions.
- llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap;
+ llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord *>
+ CieMap;
};
class GotSection : public SyntheticSection {
diff --git a/contrib/llvm/tools/lld/ELF/Writer.cpp b/contrib/llvm/tools/lld/ELF/Writer.cpp
index 1853f99..8cc678d 100644
--- a/contrib/llvm/tools/lld/ELF/Writer.cpp
+++ b/contrib/llvm/tools/lld/ELF/Writer.cpp
@@ -50,7 +50,6 @@ private:
void createSyntheticSections();
void copyLocalSymbols();
void addSectionSymbols();
- void addReservedSymbols();
void createSections();
void forEachRelSec(std::function<void(InputSectionBase &)> Fn);
void sortSections();
@@ -168,10 +167,6 @@ template <class ELFT> void Writer<ELFT>::run() {
if (!Config->Relocatable)
combineEhFrameSections<ELFT>();
- // We need to create some reserved symbols such as _end. Create them.
- if (!Config->Relocatable)
- addReservedSymbols();
-
// Create output sections.
if (Script->Opt.HasSections) {
// If linker script contains SECTIONS commands, let it create sections.
@@ -286,8 +281,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
InX::ShStrTab = make<StringTableSection>(".shstrtab", false);
- Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
- Out::ElfHeader->Size = sizeof(Elf_Ehdr);
Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
Out::ProgramHeaders->updateAlignment(Config->Wordsize);
@@ -796,7 +789,7 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
// The linker is expected to define some symbols depending on
// the linking result. This function defines such symbols.
-template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
+template <class ELFT> void elf::addReservedSymbols() {
if (Config->EMachine == EM_MIPS) {
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
// so that it points to an absolute address which by default is relative
@@ -820,20 +813,8 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
Symtab<ELFT>::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL);
}
- // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
- // be at some offset from the base of the .got section, usually 0 or the end
- // of the .got
- InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
- : cast<InputSection>(InX::Got);
ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>(
- "_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff);
-
- // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
- // static linking the linker is required to optimize away any references to
- // __tls_get_addr, so it's not defined anywhere. Create a hidden definition
- // to avoid the undefined symbol error.
- if (!InX::DynSymTab)
- Symtab<ELFT>::X->addIgnored("__tls_get_addr");
+ "_GLOBAL_OFFSET_TABLE_", Out::ElfHeader, Target->GotBaseSymOff);
// __ehdr_start is the location of ELF file headers. Note that we define
// this symbol unconditionally even when using a linker script, which
@@ -1721,6 +1702,15 @@ static uint16_t getELFType() {
// to each section. This function fixes some predefined
// symbol values that depend on section address and size.
template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
+ if (ElfSym::GlobalOffsetTable) {
+ // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
+ // be at some offset from the base of the .got section, usually 0 or the end
+ // of the .got
+ InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
+ : cast<InputSection>(InX::Got);
+ ElfSym::GlobalOffsetTable->Section = GotSection;
+ }
+
// _etext is the first location after the last read-only loadable segment.
// _edata is the first location after the last read-write loadable segment.
// _end is the first location after the uninitialized data region.
@@ -1911,3 +1901,8 @@ template void elf::writeResult<ELF32LE>();
template void elf::writeResult<ELF32BE>();
template void elf::writeResult<ELF64LE>();
template void elf::writeResult<ELF64BE>();
+
+template void elf::addReservedSymbols<ELF32LE>();
+template void elf::addReservedSymbols<ELF32BE>();
+template void elf::addReservedSymbols<ELF64LE>();
+template void elf::addReservedSymbols<ELF64BE>();
diff --git a/contrib/llvm/tools/lld/ELF/Writer.h b/contrib/llvm/tools/lld/ELF/Writer.h
index 7fa56be..0317dde 100644
--- a/contrib/llvm/tools/lld/ELF/Writer.h
+++ b/contrib/llvm/tools/lld/ELF/Writer.h
@@ -47,6 +47,7 @@ struct PhdrEntry {
bool HasLMA = false;
};
+template <class ELFT> void addReservedSymbols();
llvm::StringRef getOutputSectionName(llvm::StringRef Name);
template <class ELFT> uint32_t getMipsEFlags();
diff --git a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h
index 70a63bd..6028006 100644
--- a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h
+++ b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h
@@ -112,6 +112,10 @@ public:
/// info in final executables.
virtual bool isLazyPointer(const Reference &);
+ /// Reference from an __stub_helper entry to the required offset of the
+ /// lazy bind commands.
+ virtual Reference::KindValue lazyImmediateLocationKind() = 0;
+
/// Returns true if the specified relocation is paired to the next relocation.
virtual bool isPairedReloc(const normalized::Relocation &) = 0;
diff --git a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
index 7d15448..2f663c6 100644
--- a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
+++ b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
@@ -67,6 +67,10 @@ public:
return invalid;
}
+ Reference::KindValue lazyImmediateLocationKind() override {
+ return lazyImmediateLocation;
+ }
+
Reference::KindValue pointerKind() override {
return invalid;
}
diff --git a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
index 10360b5..b9c815c 100644
--- a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
+++ b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
@@ -127,6 +127,10 @@ public:
return pointer64;
}
+ Reference::KindValue lazyImmediateLocationKind() override {
+ return lazyImmediateLocation;
+ }
+
uint32_t dwarfCompactUnwindType() override {
return 0x03000000;
}
diff --git a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
index 2272bff..a2c6809 100644
--- a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
+++ b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
@@ -70,6 +70,10 @@ public:
return delta32;
}
+ Reference::KindValue lazyImmediateLocationKind() override {
+ return lazyImmediateLocation;
+ }
+
Reference::KindValue unwindRefToEhFrameKind() override {
return invalid;
}
diff --git a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
index d687ca5..aee9959 100644
--- a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
+++ b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
@@ -116,6 +116,10 @@ public:
return unwindFDEToFunction;
}
+ Reference::KindValue lazyImmediateLocationKind() override {
+ return lazyImmediateLocation;
+ }
+
Reference::KindValue unwindRefToEhFrameKind() override {
return unwindInfoToEhFrame;
}
diff --git a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index e58e3d2..f2e5ed7 100644
--- a/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -172,6 +172,8 @@ private:
SymbolScope &symbolScope);
void appendSection(SectionInfo *si, NormalizedFile &file);
uint32_t sectionIndexForAtom(const Atom *atom);
+ void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
+ NormalizedFile &file);
typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
@@ -1423,6 +1425,8 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
uint8_t segmentIndex;
uint64_t segmentStartAddr;
+ uint32_t offsetInBindInfo = 0;
+
for (SectionInfo *sect : _sectionInfos) {
segIndexForSection(sect, segmentIndex, segmentStartAddr);
for (const AtomInfo &info : sect->atomsAndOffsets) {
@@ -1467,6 +1471,59 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
bind.symbolName = targ->name();
bind.addend = ref->addend();
nFile.lazyBindingInfo.push_back(bind);
+
+ // Now that we know the segmentOffset and the ordinal attribute,
+ // we can fix the helper's code
+
+ fixLazyReferenceImm(atom, offsetInBindInfo, nFile);
+
+ // 5 bytes for opcodes + variable sizes (target name + \0 and offset
+ // encode's size)
+ offsetInBindInfo +=
+ 6 + targ->name().size() + llvm::getULEB128Size(bind.segOffset);
+ if (bind.ordinal > BIND_IMMEDIATE_MASK)
+ offsetInBindInfo += llvm::getULEB128Size(bind.ordinal);
+ }
+ }
+ }
+ }
+}
+
+void Util::fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
+ NormalizedFile &file) {
+ for (const auto &ref : *atom) {
+ const DefinedAtom *da = dyn_cast<DefinedAtom>(ref->target());
+ if (da == nullptr)
+ return;
+
+ const Reference *helperRef = nullptr;
+ for (const Reference *hr : *da) {
+ if (hr->kindValue() == _archHandler.lazyImmediateLocationKind()) {
+ helperRef = hr;
+ break;
+ }
+ }
+ if (helperRef == nullptr)
+ continue;
+
+ // TODO: maybe get the fixed atom content from _archHandler ?
+ for (SectionInfo *sectInfo : _sectionInfos) {
+ for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) {
+ if (atomInfo.atom == helperRef->target()) {
+ auto sectionContent =
+ file.sections[sectInfo->normalizedSectionIndex].content;
+ uint8_t *rawb =
+ file.ownedAllocations.Allocate<uint8_t>(sectionContent.size());
+ llvm::MutableArrayRef<uint8_t> newContent{rawb,
+ sectionContent.size()};
+ std::copy(sectionContent.begin(), sectionContent.end(),
+ newContent.begin());
+ llvm::support::ulittle32_t *loc =
+ reinterpret_cast<llvm::support::ulittle32_t *>(
+ &newContent[atomInfo.offsetInSection +
+ helperRef->offsetInAtom()]);
+ *loc = offset;
+ file.sections[sectInfo->normalizedSectionIndex].content = newContent;
}
}
}
diff --git a/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp
index e31483f..363e6fe 100644
--- a/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp
@@ -282,8 +282,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
.setMCJITMemoryManager(
std::unique_ptr<MemoryManager>(new MemoryManager(*this)))
.setCodeModel(codeModel)
- .setOptLevel(llvm::CodeGenOpt::Less)
- .setUseOrcMCJITReplacement(true);
+ .setOptLevel(llvm::CodeGenOpt::Less);
llvm::StringRef mArch;
llvm::StringRef mCPU;
diff --git a/contrib/tcpdump/CHANGES b/contrib/tcpdump/CHANGES
index 7c4be17..09acbb2 100644
--- a/contrib/tcpdump/CHANGES
+++ b/contrib/tcpdump/CHANGES
@@ -1,10 +1,119 @@
+Sunday September 3, 2017 denis@ovsienko.info
+ Summary for 4.9.2 tcpdump release
+ Do not use getprotobynumber() for protocol name resolution. Do not do
+ any protocol name resolution if -n is specified.
+ Improve errors detection in the test scripts.
+ Fix a segfault with OpenSSL 1.1 and improve OpenSSL usage.
+ Clean up IS-IS printing.
+ Fix buffer overflow vulnerabilities:
+ CVE-2017-11543 (SLIP)
+ CVE-2017-13011 (bittok2str_internal)
+ Fix infinite loop vulnerabilities:
+ CVE-2017-12989 (RESP)
+ CVE-2017-12990 (ISAKMP)
+ CVE-2017-12995 (DNS)
+ CVE-2017-12997 (LLDP)
+ Fix buffer over-read vulnerabilities:
+ CVE-2017-11541 (safeputs)
+ CVE-2017-11542 (PIMv1)
+ CVE-2017-12893 (SMB/CIFS)
+ CVE-2017-12894 (lookup_bytestring)
+ CVE-2017-12895 (ICMP)
+ CVE-2017-12896 (ISAKMP)
+ CVE-2017-12897 (ISO CLNS)
+ CVE-2017-12898 (NFS)
+ CVE-2017-12899 (DECnet)
+ CVE-2017-12900 (tok2strbuf)
+ CVE-2017-12901 (EIGRP)
+ CVE-2017-12902 (Zephyr)
+ CVE-2017-12985 (IPv6)
+ CVE-2017-12986 (IPv6 routing headers)
+ CVE-2017-12987 (IEEE 802.11)
+ CVE-2017-12988 (telnet)
+ CVE-2017-12991 (BGP)
+ CVE-2017-12992 (RIPng)
+ CVE-2017-12993 (Juniper)
+ CVE-2017-11542 (PIMv1)
+ CVE-2017-11541 (safeputs)
+ CVE-2017-12994 (BGP)
+ CVE-2017-12996 (PIMv2)
+ CVE-2017-12998 (ISO IS-IS)
+ CVE-2017-12999 (ISO IS-IS)
+ CVE-2017-13000 (IEEE 802.15.4)
+ CVE-2017-13001 (NFS)
+ CVE-2017-13002 (AODV)
+ CVE-2017-13003 (LMP)
+ CVE-2017-13004 (Juniper)
+ CVE-2017-13005 (NFS)
+ CVE-2017-13006 (L2TP)
+ CVE-2017-13007 (Apple PKTAP)
+ CVE-2017-13008 (IEEE 802.11)
+ CVE-2017-13009 (IPv6 mobility)
+ CVE-2017-13010 (BEEP)
+ CVE-2017-13012 (ICMP)
+ CVE-2017-13013 (ARP)
+ CVE-2017-13014 (White Board)
+ CVE-2017-13015 (EAP)
+ CVE-2017-11543 (SLIP)
+ CVE-2017-13016 (ISO ES-IS)
+ CVE-2017-13017 (DHCPv6)
+ CVE-2017-13018 (PGM)
+ CVE-2017-13019 (PGM)
+ CVE-2017-13020 (VTP)
+ CVE-2017-13021 (ICMPv6)
+ CVE-2017-13022 (IP)
+ CVE-2017-13023 (IPv6 mobility)
+ CVE-2017-13024 (IPv6 mobility)
+ CVE-2017-13025 (IPv6 mobility)
+ CVE-2017-13026 (ISO IS-IS)
+ CVE-2017-13027 (LLDP)
+ CVE-2017-13028 (BOOTP)
+ CVE-2017-13029 (PPP)
+ CVE-2017-13030 (PIM)
+ CVE-2017-13031 (IPv6 fragmentation header)
+ CVE-2017-13032 (RADIUS)
+ CVE-2017-13033 (VTP)
+ CVE-2017-13034 (PGM)
+ CVE-2017-13035 (ISO IS-IS)
+ CVE-2017-13036 (OSPFv3)
+ CVE-2017-13037 (IP)
+ CVE-2017-13038 (PPP)
+ CVE-2017-13039 (ISAKMP)
+ CVE-2017-13040 (MPTCP)
+ CVE-2017-13041 (ICMPv6)
+ CVE-2017-13042 (HNCP)
+ CVE-2017-13043 (BGP)
+ CVE-2017-13044 (HNCP)
+ CVE-2017-13045 (VQP)
+ CVE-2017-13046 (BGP)
+ CVE-2017-13047 (ISO ES-IS)
+ CVE-2017-13048 (RSVP)
+ CVE-2017-13049 (Rx)
+ CVE-2017-13050 (RPKI-Router)
+ CVE-2017-13051 (RSVP)
+ CVE-2017-13052 (CFM)
+ CVE-2017-13053 (BGP)
+ CVE-2017-13054 (LLDP)
+ CVE-2017-13055 (ISO IS-IS)
+ CVE-2017-13687 (Cisco HDLC)
+ CVE-2017-13688 (OLSR)
+ CVE-2017-13689 (IKEv1)
+ CVE-2017-13690 (IKEv2)
+ CVE-2017-13725 (IPv6 routing headers)
+
+Sunday July 23, 2017 denis@ovsienko.info
+ Summary for 4.9.1 tcpdump release
+ CVE-2017-11108/Fix bounds checking for STP.
+ Make assorted documentation updates and fix a few typos in tcpdump output.
+ Fixup -C for file size >2GB (GH #488).
+ Show AddressSanitizer presence in version output.
+ Fix a bug in test scripts (exposed in GH #613).
+ On FreeBSD adjust Capsicum capabilities for netmap.
+ On Linux fix a use-after-free when the requested interface does not exist.
+
Wednesday January 18, 2017 devel.fx.lebail@orange.fr
Summary for 4.9.0 tcpdump release
General updates:
- Improve separation frontend/backend (tcpdump/libnetdissect)
- Don't require IPv6 library support in order to support IPv6 addresses
- Introduce data types to use for integral values in packet structures
- Fix display of timestamps with -tt, -ttt and -ttttt options
Fix some heap overflows found with American Fuzzy Lop by Hanno Boeck and others
(More information in the log with CVE-2016-* and CVE-2017-*)
Change the way protocols print link-layer addresses (Fix heap overflows
@@ -35,14 +144,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
Don't drop CAP_SYS_CHROOT before chrooting
Fixes issue where statistics not reported when -G and -W options used
- New printers supporting:
- Generic Protocol Extension for VXLAN (VXLAN-GPE)
- Home Networking Control Protocol (HNCP), RFCs 7787 and 7788
- Locator/Identifier Separation Protocol (LISP), type 3 and type 4 packets
- Marvell Extended Distributed Switch Architecture header (MEDSA)
- Network Service Header (NSH)
- REdis Serialization Protocol (RESP)
-
Updated printers:
802.11: Beginnings of 11ac radiotap support
802.11: Check the Protected bit for management frames
@@ -61,7 +162,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
ATM: Fix an incorrect bounds check
BFD: Update specification from draft to RFC 5880
BFD: Update to print optional authentication field
- BGP: Add decoding of ADD-PATH capability
BGP: Add support for the AIGP attribute (RFC7311)
BGP: Print LARGE_COMMUNITY Path Attribute
BGP: Update BGP numbers from IANA; Print minor values for FSM notification
@@ -78,7 +178,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
DTP: Improve packet integrity checks
EGP: Fix bounds checks
ESP: Don't use OpenSSL_add_all_algorithms() in OpenSSL 1.1.0 or later
- ESP: Handle OpenSSL 1.1.x
Ethernet: Add some bounds checking before calling isoclns_print (Fix a heap overflow)
Ethernet: Print the Length/Type field as length when needed
FDDI: Fix -e output for FDDI
@@ -87,7 +186,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
Geneve: Fix error message with invalid option length; Update list option classes
HNCP: Fix incorrect time interval format. Fix handling of IPv4 prefixes
ICMP6: Fetch a 32-bit big-endian quantity with EXTRACT_32BITS()
- ICMP6: dagid is always an IPv6 address, not an opaque 128-bit string
IGMP: Add a length check
IP: Add a bounds check (Fix a heap overflow)
IP: Check before fetching the protocol version (Fix a heap overflow)
@@ -115,7 +213,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
MPLS LSP ping: Update printing for RFC 4379, bug fixes, more bounds checks
MPLS: "length" is now the *remaining* packet length
MPLS: Add bounds and length checks (Fix a heap overflow)
- NFS: Add a test that makes unaligned accesses
NFS: Don't assume the ONC RPC header is nicely aligned
NFS: Don't overflow the Opaque_Handle buffer (Fix a segmentation fault)
NFS: Don't run past the end of an NFSv3 file handle
@@ -130,7 +227,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
PGM: Print the formatted IP address, not the raw binary address, as a string
PIM: Add some bounds checking (Fix a heap overflow)
PIMv2: Fix checksumming of Register messages
- PPI: Pass an adjusted struct pcap_pkthdr to the sub-printer
PPP: Add some bounds checks (Fix a heap overflow)
PPP: Report invalid PAP AACK/ANAK packets
Q.933: Add a missing bounds check
@@ -171,16 +267,46 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
UDLD: Fix an infinite loop
UDP: Add a bounds check (Fix a heap overflow)
UDP: Check against the packet length first
- UDP: Don't do the DDP-over-UDP heuristic check up front
VAT: Add some bounds checks
VTP: Add a test on Mgmt Domain Name length
VTP: Add bounds checks and filter out non-printable characters
VXLAN: Add a bound check and a test case
ZeroMQ: Fix an infinite loop
-Tuesday April 14, 2015 guy@alum.mit.edu
- Summary for 4.8.0 tcpdump release
+Tuesday October 25, 2016 mcr@sandelman.ca
+ Summary for 4.8.1 tcpdump release
Fix "-x" for Apple PKTAP and PPI packets
+ Improve separation frontend/backend (tcpdump/libnetdissect)
+ Fix display of timestamps with -tt, -ttt and -ttttt options
+ Add support for the Marvell Extended Distributed Switch Architecture header
+ Use PRIx64 to print a 64-bit number in hex.
+ Printer for HNCP (RFCs 7787 and 7788).
+ dagid is always an IPv6 address, not an opaque 128-bit string, and other fixes to RPL printer.
+ RSVP: Add bounds and length checks
+ OSPF: Do more bounds checking
+ Handle OpenSSL 1.1.x.
+ Initial support for the REdis Serialization Protocol known as RESP.
+ Add printing function for Generic Protocol Extension for VXLAN
+ draft-ietf-nvo3-vxlan-gpe-01
+ Network Service Header: draft-ietf-sfc-nsh-01
+ Don't recompile the filter if the new file has the same DLT.
+ Pass an adjusted struct pcap_pkthdr to the sub-printer.
+ Add three test cases for already fixed CVEs
+ CVE-2014-8767: OLSR
+ CVE-2014-8768: Geonet
+ CVE-2014-8769: AODV
+ Don't do the DDP-over-UDP heuristic first: GitHub issue #499.
+ Use the new debugging routines in libpcap.
+ Harmonize TCP source or destination ports tests with UDP ones
+ Introduce data types to use for integral values in packet structures.
+ RSVP: Fix an infinite loop
+ Support of Type 3 and Type 4 LISP packets.
+ Don't require IPv6 library support in order to support IPv6 addresses.
+ Many many changes to support libnetdissect usage.
+ Add a test that makes unaligned accesses: GitHub issue #478.
+ add a DNSSEC test case: GH #445 and GH #467.
+ BGP: add decoding of ADD-PATH capability
+ fixes to LLC header printing, and RFC948-style IP packets
Friday April 10, 2015 guy@alum.mit.edu
Summary for 4.7.4 tcpdump release
diff --git a/contrib/tcpdump/CONTRIBUTING b/contrib/tcpdump/CONTRIBUTING
index 5d3b46e..186583e 100644
--- a/contrib/tcpdump/CONTRIBUTING
+++ b/contrib/tcpdump/CONTRIBUTING
@@ -3,6 +3,44 @@ Some Information for Contributors
You want to contribute to Tcpdump, Thanks!
Please, read these lines.
+
+How to report bugs and other problems
+-------------------------------------
+To report a security issue (segfault, buffer overflow, infinite loop, arbitrary
+code execution etc) please send an e-mail to security@tcpdump.org, do not use
+the bug tracker!
+
+To report a non-security problem (failure to compile, incorrect output in the
+protocol printout, missing support for a particular protocol etc) please check
+first that it reproduces with the latest stable release of tcpdump and the latest
+stable release of libpcap. If it does, please check that the problem reproduces
+with the current git master branch of tcpdump and the current git master branch of
+libpcap. If it does (and it is not a security-related problem, otherwise see
+above), please navigate to https://github.com/the-tcpdump-group/tcpdump/issues
+and check if the problem has already been reported. If it has not, please open
+a new issue and provide the following details:
+
+* tcpdump and libpcap version (tcpdump --version)
+* operating system name and version and any other details that may be relevant
+ (uname -a, compiler name and version, CPU type etc.)
+* configure flags if any were used
+* statement of the problem
+* steps to reproduce
+
+Please note that if you know exactly how to solve the problem and the solution
+would not be too intrusive, it would be best to contribute some development time
+and open a pull request instead as discussed below.
+
+Still not sure how to do? Feel free to [subscribe](http://www.tcpdump.org/#mailing-lists)
+to the mailing list tcpdump-workers@lists.tcpdump.org and ask!
+
+
+How to add new code and to update existing code
+-----------------------------------------------
+
+0) Check that there isn't a pull request already opened for the changes you
+ intend to make.
+
1) Fork the Tcpdump repository on GitHub from
https://github.com/the-tcpdump-group/tcpdump
(See https://help.github.com/articles/fork-a-repo/)
@@ -12,8 +50,11 @@ Please, read these lines.
on Linux and OSX before sending pull requests.
(See http://docs.travis-ci.com/user/getting-started/)
-3) Clone your repository
+3) Setup your git working copy
git clone https://github.com/<username>/tcpdump.git
+ cd tcpdump
+ git remote add upstream https://github.com/the-tcpdump-group/tcpdump
+ git fetch upstream
4) Do a 'touch .devel' in your working directory.
Currently, the effect is
@@ -47,19 +88,26 @@ Please, read these lines.
7) Test with 'make check'
Don't send a pull request if 'make check' gives failed tests.
-8) Rebase your commits against upstream/master
- (To keep linearity)
+8) Try to rebase your commits to keep the history simple.
+ git rebase upstream/master
+ (If the rebase fails and you cannot resolve, issue "git rebase --abort"
+ and ask for help in the pull request comment.)
-9) Initiate and send a pull request
+9) Once 100% happy, put your work into your forked repository.
+ git push
+
+10) Initiate and send a pull request
(See https://help.github.com/articles/using-pull-requests/)
-Some remarks
-------------
+
+Code style and generic remarks
+------------------------------
a) A thorough reading of some other printers code is useful.
b) Put the normative reference if any as comments (RFC, etc.).
-c) Put the format of packets/headers/options as comments.
+c) Put the format of packets/headers/options as comments if there is no
+ published normative reference.
d) The printer may receive incomplete packet in the buffer, truncated at any
random position, for example by capturing with '-s size' option.
diff --git a/contrib/tcpdump/CREDITS b/contrib/tcpdump/CREDITS
index 5242967..85ee5f4 100644
--- a/contrib/tcpdump/CREDITS
+++ b/contrib/tcpdump/CREDITS
@@ -5,7 +5,7 @@ The current maintainers:
Denis Ovsienko <denis at ovsienko dot info>
Fulvio Risso <risso at polito dot it>
Guy Harris <guy at alum dot mit dot edu>
- Hannes Gredler <hannes at juniper dot net>
+ Hannes Gredler <hannes at gredler dot at>
Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
Francois-Xavier Le Bail <fx dot lebail at yahoo dot com>
@@ -39,6 +39,7 @@ Additional people who have contributed patches:
Bjoern A. Zeeb <bzeeb at Zabbadoz dot NeT>
Bram <tcpdump at mail dot wizbit dot be>
Brent L. Bates <blbates at vigyan dot com>
+ Brian Carpenter <brian dot carpenter at gmail dot com>
Brian Ginsbach <ginsbach at cray dot com>
Bruce M. Simpson <bms at spc dot org>
Carles Kishimoto Bisbe <ckishimo at ac dot upc dot es>
@@ -54,6 +55,7 @@ Additional people who have contributed patches:
Craig Rodrigues <rodrigc at mediaone dot net>
Crist J. Clark <cjclark at alum dot mit dot edu>
Daniel Hagerty <hag at ai dot mit dot edu>
+ Daniel Lee <Longinus00 at gmail dot com>
Darren Reed <darrenr at reed dot wattle dot id dot au>
David Binderman <d dot binderman at virgin dot net>
David Horn <dhorn2000 at gmail dot com>
@@ -85,6 +87,7 @@ Additional people who have contributed patches:
Greg Stark <gsstark at mit dot edu>
Hank Leininger <tcpdump-workers at progressive-comp dot com>
Hannes Viertel <hviertel at juniper dot net>
+ Hanno Böck <hanno at hboeck dot de>
Harry Raaymakers <harryr at connect dot com dot au>
Heinz-Ado Arnolds <Ado dot Arnolds at dhm-systems dot de>
Hendrik Scholz <hendrik at scholz dot net>
@@ -111,6 +114,7 @@ Additional people who have contributed patches:
Juliusz Chroboczek <jch at pps dot jussieu dot fr>
Kaarthik Sivakumar <kaarthik at torrentnet dot com>
Kaladhar Musunuru <kaladharm at sourceforge dot net>
+ Kamil Frankowicz <kontakt at frankowicz dot me>
Karl Norby <karl-norby at sourceforge dot net>
Kazushi Sugyo <sugyo at pb dot jp dot nec dot com>
Kelly Carmichael <kcarmich at ipapp dot com>
@@ -123,7 +127,6 @@ Additional people who have contributed patches:
Larry Lile <lile at stdio dot com>
Lennert Buytenhek <buytenh at gnu dot org>
Loganaden Velvindron <logan at elandsys dot com>
- Daniel Lee <Longinus00 at gmail dot com>
Loris Degioanni <loris at netgroup-serv dot polito dot it>
Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
Lucas C. Villa Real <lucasvr at us dot ibm dot com>
@@ -166,6 +169,7 @@ Additional people who have contributed patches:
Paolo Abeni <paolo dot abeni at email dot it>
Pascal Hennequin <pascal dot hennequin at int-evry dot fr>
Pasvorn Boonmark <boonmark at juniper dot net>
+ Patrik Lundquist <patrik dot lundquist at gmail dot com>
Paul Ferrell <pflarr at sourceforge dot net>
Paul Mundt <lethal at linux-sh dot org>
Paul S. Traina <pst at freebsd dot org>
diff --git a/contrib/tcpdump/INSTALL.txt b/contrib/tcpdump/INSTALL.txt
index f91d004..57d4a45 100644
--- a/contrib/tcpdump/INSTALL.txt
+++ b/contrib/tcpdump/INSTALL.txt
@@ -37,6 +37,7 @@ Please see "PLATFORMS" for notes about tested platforms.
FILES
-----
CHANGES - description of differences between releases
+CONTRIBUTING - guidelines for contributing
CREDITS - people that have helped tcpdump along
INSTALL.txt - this file
LICENSE - the license under which tcpdump is distributed
diff --git a/contrib/tcpdump/Makefile.in b/contrib/tcpdump/Makefile.in
index c18d5ed..0941f0e 100644
--- a/contrib/tcpdump/Makefile.in
+++ b/contrib/tcpdump/Makefile.in
@@ -263,6 +263,7 @@ HDR = \
ether.h \
ethertype.h \
extract.h \
+ funcattrs.h \
getopt_long.h \
gmpls.h \
gmt2local.h \
diff --git a/contrib/tcpdump/PLATFORMS b/contrib/tcpdump/PLATFORMS
index ec85e59..4f11c51 100644
--- a/contrib/tcpdump/PLATFORMS
+++ b/contrib/tcpdump/PLATFORMS
@@ -1,9 +1,16 @@
-== Tested platforms ==
-NetBSD 5.1/i386 (mcr - 2012/4/1)
-Debian Linux (squeeze/i386) (mcr - 2012/4/1)
-
----
-RedHat Linux 6.1/i386 (assar)
-FreeBSD 2.2.8/i386 (itojun)
+In many operating systems tcpdump is available as a native package or port,
+which simplifies installation of updates and long-term maintenance. However,
+the native packages are sometimes a few versions behind and to try a more
+recent snapshot it will take to compile tcpdump from the source code.
+tcpdump compiles and works on at least the following platforms:
+* AIX
+* FreeBSD
+* HP-UX 11i
+* Linux (any) with glibc (usually just works)
+* Linux (any) with musl libc (sometimes fails to compile, please report any bugs)
+* Mac OS X / macOS
+* NetBSD
+* OpenWrt
+* Solaris
diff --git a/contrib/tcpdump/README.md b/contrib/tcpdump/README.md
index c83ffab..a1fba9b 100644
--- a/contrib/tcpdump/README.md
+++ b/contrib/tcpdump/README.md
@@ -3,25 +3,21 @@
[![Build
Status](https://travis-ci.org/the-tcpdump-group/tcpdump.png)](https://travis-ci.org/the-tcpdump-group/tcpdump)
-TCPDUMP 4.x.y
-Now maintained by "The Tcpdump Group"
-See www.tcpdump.org
+To report a security issue please send an e-mail to security@tcpdump.org.
-Please send inquiries/comments/reports to:
+To report bugs and other problems, contribute patches, request a
+feature, provide generic feedback etc please see the file
+CONTRIBUTING in the tcpdump source tree root.
-* tcpdump-workers@lists.tcpdump.org
+TCPDUMP 4.x.y
+Now maintained by "The Tcpdump Group"
+See www.tcpdump.org
Anonymous Git is available via:
git clone git://bpf.tcpdump.org/tcpdump
-Please submit patches by forking the branch on GitHub at:
-
-* http://github.com/the-tcpdump-group/tcpdump/tree/master
-
-and issuing a pull request.
-
-formerly from Lawrence Berkeley National Laboratory
+formerly from Lawrence Berkeley National Laboratory
Network Research Group <tcpdump@ee.lbl.gov>
ftp://ftp.ee.lbl.gov/old/tcpdump.tar.Z (3.4)
@@ -71,20 +67,6 @@ It is a program that can be used to extract portions of tcpdump binary
trace files. See the above distribution for further details and
documentation.
-Problems, bugs, questions, desirable enhancements, etc. should be sent
-to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support
-requests, and feature requests may also be submitted on the GitHub issue
-tracker for tcpdump at:
-
-* https://github.com/the-tcpdump-group/tcpdump/issues
-
-Source code contributions, etc. should be sent to the email address
-above or submitted by forking the branch on GitHub at:
-
-* http://github.com/the-tcpdump-group/tcpdump/tree/master
-
-and issuing a pull request.
-
Current versions can be found at www.tcpdump.org.
- The TCPdump team
diff --git a/contrib/tcpdump/VERSION b/contrib/tcpdump/VERSION
index 6ed7776..dad10c7 100644
--- a/contrib/tcpdump/VERSION
+++ b/contrib/tcpdump/VERSION
@@ -1 +1 @@
-4.9.0
+4.9.2
diff --git a/contrib/tcpdump/addrtoname.c b/contrib/tcpdump/addrtoname.c
index 85cbf7b..88af3c8 100644
--- a/contrib/tcpdump/addrtoname.c
+++ b/contrib/tcpdump/addrtoname.c
@@ -150,13 +150,23 @@ struct enamemem {
u_short e_addr2;
const char *e_name;
u_char *e_nsap; /* used only for nsaptable[] */
-#define e_bs e_nsap /* for bytestringtable */
struct enamemem *e_nxt;
};
static struct enamemem enametable[HASHNAMESIZE];
static struct enamemem nsaptable[HASHNAMESIZE];
-static struct enamemem bytestringtable[HASHNAMESIZE];
+
+struct bsnamemem {
+ u_short bs_addr0;
+ u_short bs_addr1;
+ u_short bs_addr2;
+ const char *bs_name;
+ u_char *bs_bytes;
+ unsigned int bs_nbytes;
+ struct bsnamemem *bs_nxt;
+};
+
+static struct bsnamemem bytestringtable[HASHNAMESIZE];
struct protoidmem {
uint32_t p_oui;
@@ -342,7 +352,7 @@ getname6(netdissect_options *ndo, const u_char *ap)
return (p->name);
}
-static const char hex[] = "0123456789abcdef";
+static const char hex[16] = "0123456789abcdef";
/* Find the hash node that corresponds the ether address 'ep' */
@@ -380,11 +390,11 @@ lookup_emem(netdissect_options *ndo, const u_char *ep)
* with length 'nlen'
*/
-static inline struct enamemem *
+static inline struct bsnamemem *
lookup_bytestring(netdissect_options *ndo, register const u_char *bs,
const unsigned int nlen)
{
- struct enamemem *tp;
+ struct bsnamemem *tp;
register u_int i, j, k;
if (nlen >= 6) {
@@ -399,26 +409,28 @@ lookup_bytestring(netdissect_options *ndo, register const u_char *bs,
i = j = k = 0;
tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
- while (tp->e_nxt)
- if (tp->e_addr0 == i &&
- tp->e_addr1 == j &&
- tp->e_addr2 == k &&
- memcmp((const char *)bs, (const char *)(tp->e_bs), nlen) == 0)
+ while (tp->bs_nxt)
+ if (nlen == tp->bs_nbytes &&
+ tp->bs_addr0 == i &&
+ tp->bs_addr1 == j &&
+ tp->bs_addr2 == k &&
+ memcmp((const char *)bs, (const char *)(tp->bs_bytes), nlen) == 0)
return tp;
else
- tp = tp->e_nxt;
+ tp = tp->bs_nxt;
- tp->e_addr0 = i;
- tp->e_addr1 = j;
- tp->e_addr2 = k;
+ tp->bs_addr0 = i;
+ tp->bs_addr1 = j;
+ tp->bs_addr2 = k;
- tp->e_bs = (u_char *) calloc(1, nlen + 1);
- if (tp->e_bs == NULL)
+ tp->bs_bytes = (u_char *) calloc(1, nlen);
+ if (tp->bs_bytes == NULL)
(*ndo->ndo_error)(ndo, "lookup_bytestring: calloc");
- memcpy(tp->e_bs, bs, nlen);
- tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
- if (tp->e_nxt == NULL)
+ memcpy(tp->bs_bytes, bs, nlen);
+ tp->bs_nbytes = nlen;
+ tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp));
+ if (tp->bs_nxt == NULL)
(*ndo->ndo_error)(ndo, "lookup_bytestring: calloc");
return tp;
@@ -445,11 +457,11 @@ lookup_nsap(netdissect_options *ndo, register const u_char *nsap,
tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
while (tp->e_nxt)
- if (tp->e_addr0 == i &&
+ if (nsap_length == tp->e_nsap[0] &&
+ tp->e_addr0 == i &&
tp->e_addr1 == j &&
tp->e_addr2 == k &&
- tp->e_nsap[0] == nsap_length &&
- memcmp((const char *)&(nsap[1]),
+ memcmp((const char *)nsap,
(char *)&(tp->e_nsap[1]), nsap_length) == 0)
return tp;
else
@@ -549,12 +561,12 @@ le64addr_string(netdissect_options *ndo, const u_char *ep)
const unsigned int len = 8;
register u_int i;
register char *cp;
- register struct enamemem *tp;
+ register struct bsnamemem *tp;
char buf[BUFSIZE];
tp = lookup_bytestring(ndo, ep, len);
- if (tp->e_name)
- return (tp->e_name);
+ if (tp->bs_name)
+ return (tp->bs_name);
cp = buf;
for (i = len; i > 0 ; --i) {
@@ -566,11 +578,11 @@ le64addr_string(netdissect_options *ndo, const u_char *ep)
*cp = '\0';
- tp->e_name = strdup(buf);
- if (tp->e_name == NULL)
+ tp->bs_name = strdup(buf);
+ if (tp->bs_name == NULL)
(*ndo->ndo_error)(ndo, "le64addr_string: strdup(buf)");
- return (tp->e_name);
+ return (tp->bs_name);
}
const char *
@@ -579,7 +591,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
{
register u_int i;
register char *cp;
- register struct enamemem *tp;
+ register struct bsnamemem *tp;
if (len == 0)
return ("<empty>");
@@ -591,11 +603,11 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
return (q922_string(ndo, ep, len));
tp = lookup_bytestring(ndo, ep, len);
- if (tp->e_name)
- return (tp->e_name);
+ if (tp->bs_name)
+ return (tp->bs_name);
- tp->e_name = cp = (char *)malloc(len*3);
- if (tp->e_name == NULL)
+ tp->bs_name = cp = (char *)malloc(len*3);
+ if (tp->bs_name == NULL)
(*ndo->ndo_error)(ndo, "linkaddr_string: malloc");
*cp++ = hex[*ep >> 4];
*cp++ = hex[*ep++ & 0xf];
@@ -605,7 +617,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
*cp++ = hex[*ep++ & 0xf];
}
*cp = '\0';
- return (tp->e_name);
+ return (tp->bs_name);
}
const char *
diff --git a/contrib/tcpdump/addrtoname.h b/contrib/tcpdump/addrtoname.h
index 72e5ef1..fe8b6bb 100644
--- a/contrib/tcpdump/addrtoname.h
+++ b/contrib/tcpdump/addrtoname.h
@@ -33,7 +33,8 @@ enum {
LINKADDR_ETHER,
LINKADDR_FRELAY,
LINKADDR_IEEE1394,
- LINKADDR_ATM
+ LINKADDR_ATM,
+ LINKADDR_OTHER
};
#define BUFSIZE 128
diff --git a/contrib/tcpdump/addrtostr.c b/contrib/tcpdump/addrtostr.c
index fd331a3..6b06767 100644
--- a/contrib/tcpdump/addrtostr.c
+++ b/contrib/tcpdump/addrtostr.c
@@ -110,25 +110,24 @@ addrtostr6 (const void *src, char *dst, size_t size)
size_t space_left, added_space;
int snprintfed;
struct {
- long base;
- long len;
+ int base;
+ int len;
} best, cur;
- u_long words [IN6ADDRSZ / INT16SZ];
+ uint16_t words [IN6ADDRSZ / INT16SZ];
int i;
/* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
- memset (words, 0, sizeof(words));
- for (i = 0; i < IN6ADDRSZ; i++)
- words[i/2] |= (srcaddr[i] << ((1 - (i % 2)) << 3));
+ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+ words[i] = (srcaddr[2*i] << 8) | srcaddr[2*i + 1];
best.len = 0;
best.base = -1;
cur.len = 0;
cur.base = -1;
- for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+ for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++)
{
if (words[i] == 0)
{
@@ -161,7 +160,7 @@ addrtostr6 (const void *src, char *dst, size_t size)
*dp++ = c; \
space_left--; \
}
- for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+ for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++)
{
/* Are we inside the best run of 0x00's?
*/
@@ -192,7 +191,7 @@ addrtostr6 (const void *src, char *dst, size_t size)
space_left -= added_space;
break;
}
- snprintfed = snprintf (dp, space_left, "%lx", words[i]);
+ snprintfed = snprintf (dp, space_left, "%x", words[i]);
if (snprintfed < 0)
return (NULL);
if ((size_t) snprintfed >= space_left)
diff --git a/contrib/tcpdump/af.c b/contrib/tcpdump/af.c
index 539ede5..704e2f0 100644
--- a/contrib/tcpdump/af.c
+++ b/contrib/tcpdump/af.c
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/contrib/tcpdump/af.h b/contrib/tcpdump/af.h
index 1bde577..6365b12 100644
--- a/contrib/tcpdump/af.h
+++ b/contrib/tcpdump/af.h
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok af_values[];
diff --git a/contrib/tcpdump/checksum.c b/contrib/tcpdump/checksum.c
index 0829fbe..a48a147 100644
--- a/contrib/tcpdump/checksum.c
+++ b/contrib/tcpdump/checksum.c
@@ -14,7 +14,7 @@
*
* miscellaneous checksumming routines
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/contrib/tcpdump/config.h.in b/contrib/tcpdump/config.h.in
index 27ba4b10..40aacda 100644
--- a/contrib/tcpdump/config.h.in
+++ b/contrib/tcpdump/config.h.in
@@ -34,6 +34,9 @@
/* Define to 1 if you have the `ether_ntohost' function. */
#undef HAVE_ETHER_NTOHOST
+/* Define to 1 if you have the `EVP_CipherInit_ex' function. */
+#undef HAVE_EVP_CIPHERINIT_EX
+
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
#undef HAVE_EVP_CIPHER_CTX_NEW
diff --git a/contrib/tcpdump/configure b/contrib/tcpdump/configure
index 03c69c5..7124f6f 100755
--- a/contrib/tcpdump/configure
+++ b/contrib/tcpdump/configure
@@ -5801,7 +5801,7 @@ if test "x$ac_cv_func_pcap_loop" = xyes; then :
else
- as_fn_error $? "Report this to tcpdump-workers@lists.tcpdump.org, and include the
+ as_fn_error $? "This is a bug, please follow the guidelines in CONTRIBUTING and include the
config.log file in your report. If you have downloaded libpcap from
tcpdump.org, and built it yourself, please also include the config.log
file from the libpcap source directory, the Makefile from the libpcap
@@ -8116,17 +8116,32 @@ fi
done
#
- # OK, do we have EVP_CIPHER_CTX_new?
+ # OK, then:
+ #
+ # 1) do we have EVP_CIPHER_CTX_new?
# If so, we use it to allocate an
# EVP_CIPHER_CTX, as EVP_CIPHER_CTX may be
# opaque; otherwise, we allocate it ourselves.
#
- for ac_func in EVP_CIPHER_CTX_new
+ # 2) do we have EVP_CipherInit_ex()?
+ # If so, we use it, because we need to be
+ # able to make two "initialize the cipher"
+ # calls, one with the cipher and key, and
+ # one with the IV, and, as of OpenSSL 1.1,
+ # You Can't Do That with EVP_CipherInit(),
+ # because a call to EVP_CipherInit() will
+ # unconditionally clear the context, and
+ # if you don't supply a cipher, it'll
+ # clear the cipher, rendering the context
+ # unusable and causing a crash.
+ #
+ for ac_func in EVP_CIPHER_CTX_new EVP_CipherInit_ex
do :
- ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_new" "ac_cv_func_EVP_CIPHER_CTX_new"
-if test "x$ac_cv_func_EVP_CIPHER_CTX_new" = xyes; then :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define HAVE_EVP_CIPHER_CTX_NEW 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
diff --git a/contrib/tcpdump/configure.in b/contrib/tcpdump/configure.in
index a78a126..b2305a5 100644
--- a/contrib/tcpdump/configure.in
+++ b/contrib/tcpdump/configure.in
@@ -935,12 +935,26 @@ if test "$want_libcrypto" != "no"; then
if test "$ac_cv_lib_crypto_DES_cbc_encrypt" = "yes"; then
AC_CHECK_HEADERS(openssl/evp.h)
#
- # OK, do we have EVP_CIPHER_CTX_new?
+ # OK, then:
+ #
+ # 1) do we have EVP_CIPHER_CTX_new?
# If so, we use it to allocate an
# EVP_CIPHER_CTX, as EVP_CIPHER_CTX may be
# opaque; otherwise, we allocate it ourselves.
#
- AC_CHECK_FUNCS(EVP_CIPHER_CTX_new)
+ # 2) do we have EVP_CipherInit_ex()?
+ # If so, we use it, because we need to be
+ # able to make two "initialize the cipher"
+ # calls, one with the cipher and key, and
+ # one with the IV, and, as of OpenSSL 1.1,
+ # You Can't Do That with EVP_CipherInit(),
+ # because a call to EVP_CipherInit() will
+ # unconditionally clear the context, and
+ # if you don't supply a cipher, it'll
+ # clear the cipher, rendering the context
+ # unusable and causing a crash.
+ #
+ AC_CHECK_FUNCS(EVP_CIPHER_CTX_new EVP_CipherInit_ex)
fi
])
fi
diff --git a/contrib/tcpdump/extract.h b/contrib/tcpdump/extract.h
index 23623c2..5969c22 100644
--- a/contrib/tcpdump/extract.h
+++ b/contrib/tcpdump/extract.h
@@ -20,8 +20,48 @@
*/
/*
- * Macros to extract possibly-unaligned big-endian integral values.
+ * For 8-bit values; provided for the sake of completeness. Byte order
+ * isn't relevant, and alignment isn't an issue.
*/
+#define EXTRACT_8BITS(p) (*(p))
+#define EXTRACT_LE_8BITS(p) (*(p))
+
+/*
+ * Inline functions or macros to extract possibly-unaligned big-endian
+ * integral values.
+ */
+#include "funcattrs.h"
+
+/*
+ * If we have versions of GCC or Clang that support an __attribute__
+ * to say "if we're building with unsigned behavior sanitization,
+ * don't complain about undefined behavior in this function", we
+ * label these functions with that attribute - we *know* it's undefined
+ * in the C standard, but we *also* know it does what we want with
+ * the ISA we're targeting and the compiler we're using.
+ *
+ * For GCC 4.9.0 and later, we use __attribute__((no_sanitize_undefined));
+ * pre-5.0 GCC doesn't have __has_attribute, and I'm not sure whether
+ * GCC or Clang first had __attribute__((no_sanitize(XXX)).
+ *
+ * For Clang, we check for __attribute__((no_sanitize(XXX)) with
+ * __has_attribute, as there are versions of Clang that support
+ * __attribute__((no_sanitize("undefined")) but don't support
+ * __attribute__((no_sanitize_undefined)).
+ *
+ * We define this here, rather than in funcattrs.h, because we
+ * only want it used here, we don't want it to be broadly used.
+ * (Any printer will get this defined, but this should at least
+ * make it harder for people to find.)
+ */
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409)
+#define UNALIGNED_OK __attribute__((no_sanitize_undefined))
+#elif __has_attribute(no_sanitize)
+#define UNALIGNED_OK __attribute__((no_sanitize("undefined")))
+#else
+#define UNALIGNED_OK
+#endif
+
#ifdef LBL_ALIGN
/*
* The processor doesn't natively handle unaligned loads.
@@ -31,7 +71,7 @@
defined(__mips) || defined(__mips__))
/*
- * This is a GCC-compatible compiler and we have __attribute__, which
+* This is a GCC-compatible compiler and we have __attribute__, which
* we assume that mean we have __attribute__((packed)), and this is
* MIPS or Alpha, which has instructions that can help when doing
* unaligned loads.
@@ -88,19 +128,19 @@ typedef struct {
uint32_t val;
} __attribute__((packed)) unaligned_uint32_t;
-static inline uint16_t
+UNALIGNED_OK static inline uint16_t
EXTRACT_16BITS(const void *p)
{
return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val));
}
-static inline uint32_t
+UNALIGNED_OK static inline uint32_t
EXTRACT_32BITS(const void *p)
{
return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val));
}
-static inline uint64_t
+UNALIGNED_OK static inline uint64_t
EXTRACT_64BITS(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 |
@@ -138,19 +178,19 @@ EXTRACT_64BITS(const void *p)
* The processor natively handles unaligned loads, so we can just
* cast the pointer and fetch through it.
*/
-static inline uint16_t
+static inline uint16_t UNALIGNED_OK
EXTRACT_16BITS(const void *p)
{
return ((uint16_t)ntohs(*(const uint16_t *)(p)));
}
-static inline uint32_t
+static inline uint32_t UNALIGNED_OK
EXTRACT_32BITS(const void *p)
{
return ((uint32_t)ntohl(*(const uint32_t *)(p)));
}
-static inline uint64_t
+static inline uint64_t UNALIGNED_OK
EXTRACT_64BITS(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
@@ -193,7 +233,6 @@ EXTRACT_64BITS(const void *p)
* Macros to extract possibly-unaligned little-endian integral values.
* XXX - do loads on little-endian machines that support unaligned loads?
*/
-#define EXTRACT_LE_8BITS(p) (*(p))
#define EXTRACT_LE_16BITS(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
@@ -242,3 +281,6 @@ EXTRACT_64BITS(const void *p)
#define ND_TTEST_64BITS(p) ND_TTEST2(*(p), 8)
#define ND_TCHECK_64BITS(p) ND_TCHECK2(*(p), 8)
+
+#define ND_TTEST_128BITS(p) ND_TTEST2(*(p), 16)
+#define ND_TCHECK_128BITS(p) ND_TCHECK2(*(p), 16)
diff --git a/contrib/tcpdump/funcattrs.h b/contrib/tcpdump/funcattrs.h
new file mode 100644
index 0000000..63d3f56
--- /dev/null
+++ b/contrib/tcpdump/funcattrs.h
@@ -0,0 +1,122 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory 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.
+ */
+
+#ifndef lib_funcattrs_h
+#define lib_funcattrs_h
+
+/*
+ * Attributes to apply to functions and their arguments, using various
+ * compiler-specific extensions.
+ */
+
+/*
+ * This was introduced by Clang:
+ *
+ * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
+ *
+ * in some version (which version?); it has been picked up by GCC 5.0.
+ */
+#ifndef __has_attribute
+ /*
+ * It's a macro, so you can check whether it's defined to check
+ * whether it's supported.
+ *
+ * If it's not, define it to always return 0, so that we move on to
+ * the fallback checks.
+ */
+ #define __has_attribute(x) 0
+#endif
+
+/*
+ * NORETURN, before a function declaration, means "this function
+ * never returns". (It must go before the function declaration, e.g.
+ * "extern NORETURN func(...)" rather than after the function
+ * declaration, as the MSVC version has to go before the declaration.)
+ */
+#if __has_attribute(noreturn) \
+ || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
+ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
+ || (defined(__xlC__) && __xlC__ >= 0x0A01) \
+ || (defined(__HP_aCC) && __HP_aCC >= 61000)
+ /*
+ * Compiler with support for __attribute((noreturn)), or GCC 2.5 and
+ * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
+ * and later (do any earlier versions of XL C support this?), or
+ * HP aCC A.06.10 and later.
+ */
+ #define NORETURN __attribute((noreturn))
+#elif defined(_MSC_VER)
+ /*
+ * MSVC.
+ */
+ #define NORETURN __declspec(noreturn)
+#else
+ #define NORETURN
+#endif
+
+/*
+ * PRINTFLIKE(x,y), after a function declaration, means "this function
+ * does printf-style formatting, with the xth argument being the format
+ * string and the yth argument being the first argument for the format
+ * string".
+ */
+#if __has_attribute(__format__) \
+ || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
+ || (defined(__xlC__) && __xlC__ >= 0x0A01) \
+ || (defined(__HP_aCC) && __HP_aCC >= 61000)
+ /*
+ * Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1
+ * and later (do any earlier versions of XL C support this?),
+ * or HP aCC A.06.10 and later.
+ */
+ #define PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
+#else
+ #define PRINTFLIKE(x,y)
+#endif
+
+/*
+ * For flagging arguments as format strings in MSVC.
+ */
+#if _MSC_VER >= 1400
+ #include <sal.h>
+ #if _MSC_VER > 1400
+ #define FORMAT_STRING(p) _Printf_format_string_ p
+ #else
+ #define FORMAT_STRING(p) __format_string p
+ #endif
+#else
+ #define FORMAT_STRING(p) p
+#endif
+
+#endif /* lib_funcattrs_h */
diff --git a/contrib/tcpdump/gmpls.c b/contrib/tcpdump/gmpls.c
index 23515e9..e527540 100644
--- a/contrib/tcpdump/gmpls.c
+++ b/contrib/tcpdump/gmpls.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/contrib/tcpdump/gmpls.h b/contrib/tcpdump/gmpls.h
index 8b44f94..32fa811 100644
--- a/contrib/tcpdump/gmpls.h
+++ b/contrib/tcpdump/gmpls.h
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#define GMPLS_PSC1 1
diff --git a/contrib/tcpdump/ip6.h b/contrib/tcpdump/ip6.h
index 2ea1d0a..9a24ef1 100644
--- a/contrib/tcpdump/ip6.h
+++ b/contrib/tcpdump/ip6.h
@@ -178,14 +178,13 @@ struct ip6_rthdr {
/* Type 0 Routing header */
/* Also used for Type 2 */
struct ip6_rthdr0 {
- uint8_t ip6r0_nxt; /* next header */
- uint8_t ip6r0_len; /* length in units of 8 octets */
- uint8_t ip6r0_type; /* always zero */
- uint8_t ip6r0_segleft; /* segments left */
- uint8_t ip6r0_reserved; /* reserved field */
- uint8_t ip6r0_slmap[3]; /* strict/loose bit map */
+ nd_uint8_t ip6r0_nxt; /* next header */
+ nd_uint8_t ip6r0_len; /* length in units of 8 octets */
+ nd_uint8_t ip6r0_type; /* always zero */
+ nd_uint8_t ip6r0_segleft; /* segments left */
+ nd_uint32_t ip6r0_reserved; /* reserved field */
struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */
-} UNALIGNED;
+};
/* Fragment header */
struct ip6_frag {
diff --git a/contrib/tcpdump/ipproto.c b/contrib/tcpdump/ipproto.c
index a702acd..6eca06b 100644
--- a/contrib/tcpdump/ipproto.c
+++ b/contrib/tcpdump/ipproto.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
@@ -55,3 +55,309 @@ const struct tok ipproto_values[] = {
{ 0, NULL }
};
+/*
+ * For completeness the number space in the array below comes from IANA:
+ * https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
+ * However, the spelling tries to match that of /etc/protocols to achieve as
+ * much consistency as possible with the previously implemented behaviour,
+ * which was based on getprotobynumber (3).
+ */
+static const char *netdb_protocol_names[256] = {
+ "hopopt", /* 0 (IPPROTO_HOPOPTS, IPv6 Hop-by-Hop Option) */
+ "icmp", /* 1 (IPPROTO_ICMP, Internet Control Message) */
+ "igmp", /* 2 (IPPROTO_IGMP, Internet Group Management) */
+ "ggp", /* 3 (Gateway-to-Gateway) */
+ "ipencap", /* 4 (IPPROTO_IPV4, IPv4 encapsulation) */
+ "st", /* 5 (Stream, ST datagram mode) */
+ "tcp", /* 6 (IPPROTO_TCP, Transmission Control) */
+ "cbt", /* 7 (CBT) */
+ "egp", /* 8 (IPPROTO_EGP, Exterior Gateway Protocol) */
+ "igp", /* 9 (IPPROTO_PIGP, "any private interior gateway
+ * (used by Cisco for their IGRP)")
+ */
+ "bbn-rcc-mon", /* 10 (BBN RCC Monitoring) */
+ "nvp-ii", /* 11 (Network Voice Protocol) */
+ "pup", /* 12 (PARC universal packet protocol) */
+ "argus", /* 13 (ARGUS) */
+ "emcon", /* 14 (EMCON) */
+ "xnet", /* 15 (Cross Net Debugger) */
+ "chaos", /* 16 (Chaos) */
+ "udp", /* 17 (IPPROTO_UDP, User Datagram) */
+ "mux", /* 18 (Multiplexing) */
+ "dcn-meas", /* 19 (DCN Measurement Subsystems) */
+ "hmp", /* 20 (Host Monitoring) */
+ "prm", /* 21 (Packet Radio Measurement) */
+ "xns-idp", /* 22 (XEROX NS IDP) */
+ "trunk-1", /* 23 (Trunk-1) */
+ "trunk-2", /* 24 (Trunk-2) */
+ "leaf-1", /* 25 (Leaf-1) */
+ "leaf-2", /* 26 (Leaf-2) */
+ "rdp", /* 27 (Reliable Data Protocol) */
+ "irtp", /* 28 (Internet Reliable Transaction) */
+ "iso-tp4", /* 29 (ISO Transport Protocol Class 4) */
+ "netblt", /* 30 (Bulk Data Transfer Protocol) */
+ "mfe-nsp", /* 31 (MFE Network Services Protocol) */
+ "merit-inp", /* 32 (MERIT Internodal Protocol) */
+ "dccp", /* 33 (IPPROTO_DCCP, Datagram Congestion
+ * Control Protocol)
+ */
+ "3pc", /* 34 (Third Party Connect Protocol) */
+ "idpr", /* 35 (Inter-Domain Policy Routing Protocol) */
+ "xtp", /* 36 (Xpress Transfer Protocol) */
+ "ddp", /* 37 (Datagram Delivery Protocol) */
+ "idpr-cmtp", /* 38 (IDPR Control Message Transport Proto) */
+ "tp++", /* 39 (TP++ Transport Protocol) */
+ "il", /* 40 (IL Transport Protocol) */
+ "ipv6", /* 41 (IPPROTO_IPV6, IPv6 encapsulation) */
+ "sdrp", /* 42 (Source Demand Routing Protocol) */
+ "ipv6-route", /* 43 (IPPROTO_ROUTING, Routing Header for IPv6) */
+ "ipv6-frag", /* 44 (IPPROTO_FRAGMENT, Fragment Header for
+ * IPv6)
+ */
+ "idrp", /* 45 (Inter-Domain Routing Protocol) */
+ "rsvp", /* 46 (IPPROTO_RSVP, Reservation Protocol) */
+ "gre", /* 47 (IPPROTO_GRE, Generic Routing
+ * Encapsulation)
+ */
+ "dsr", /* 48 (Dynamic Source Routing Protocol) */
+ "bna", /* 49 (BNA) */
+ "esp", /* 50 (IPPROTO_ESP, Encap Security Payload) */
+ "ah", /* 51 (IPPROTO_AH, Authentication Header) */
+ "i-nlsp", /* 52 (Integrated Net Layer Security TUBA) */
+ "swipe", /* 53 (IP with Encryption) */
+ "narp", /* 54 (NBMA Address Resolution Protocol) */
+ "mobile", /* 55 (IPPROTO_MOBILE, IP Mobility) */
+ "tlsp", /* 56 (Transport Layer Security Protocol using
+ * Kryptonet key management)
+ */
+ "skip", /* 57 (SKIP) */
+ "ipv6-icmp", /* 58 (IPPROTO_ICMPV6, ICMP for IPv6) */
+ "ipv6-nonxt", /* 59 (IPPROTO_NONE, No Next Header for IPv6) */
+ "ipv6-opts", /* 60 (IPPROTO_DSTOPTS, Destination Options for
+ * IPv6)
+ */
+ NULL, /* 61 (any host internal protocol) */
+ "cftp", /* 62 (IPPROTO_MOBILITY_OLD, CFTP, see the note
+ * in ipproto.h)
+ */
+ NULL, /* 63 (any local network) */
+ "sat-expak", /* 64 (SATNET and Backroom EXPAK) */
+ "kryptolan", /* 65 (Kryptolan) */
+ "rvd", /* 66 (MIT Remote Virtual Disk Protocol) */
+ "ippc", /* 67 (Internet Pluribus Packet Core) */
+ NULL, /* 68 (any distributed file system) */
+ "sat-mon", /* 69 (SATNET Monitoring) */
+ "visa", /* 70 (VISA Protocol) */
+ "ipcv", /* 71 (Internet Packet Core Utility) */
+ "cpnx", /* 72 (Computer Protocol Network Executive) */
+ "rspf", /* 73 (Radio Shortest Path First, CPHB -- Computer
+ * Protocol Heart Beat -- in IANA)
+ */
+ "wsn", /* 74 (Wang Span Network) */
+ "pvp", /* 75 (Packet Video Protocol) */
+ "br-sat-mon", /* 76 (Backroom SATNET Monitoring) */
+ "sun-nd", /* 77 (IPPROTO_ND, SUN ND PROTOCOL-Temporary) */
+ "wb-mon", /* 78 (WIDEBAND Monitoring) */
+ "wb-expak", /* 79 (WIDEBAND EXPAK) */
+ "iso-ip", /* 80 (ISO Internet Protocol) */
+ "vmtp", /* 81 (Versatile Message Transport) */
+ "secure-vmtp", /* 82 (Secure VMTP) */
+ "vines", /* 83 (VINES) */
+ "ttp", /* 84 (Transaction Transport Protocol, also IPTM --
+ * Internet Protocol Traffic Manager)
+ */
+ "nsfnet-igp", /* 85 (NSFNET-IGP) */
+ "dgp", /* 86 (Dissimilar Gateway Protocol) */
+ "tcf", /* 87 (TCF) */
+ "eigrp", /* 88 (IPPROTO_EIGRP, Cisco EIGRP) */
+ "ospf", /* 89 (IPPROTO_OSPF, Open Shortest Path First
+ * IGP)
+ */
+ "sprite-rpc", /* 90 (Sprite RPC Protocol) */
+ "larp", /* 91 (Locus Address Resolution Protocol) */
+ "mtp", /* 92 (Multicast Transport Protocol) */
+ "ax.25", /* 93 (AX.25 Frames) */
+ "ipip", /* 94 (IP-within-IP Encapsulation Protocol) */
+ "micp", /* 95 (Mobile Internetworking Control Pro.) */
+ "scc-sp", /* 96 (Semaphore Communications Sec. Pro.) */
+ "etherip", /* 97 (Ethernet-within-IP Encapsulation) */
+ "encap", /* 98 (Encapsulation Header) */
+ NULL, /* 99 (any private encryption scheme) */
+ "gmtp", /* 100 (GMTP) */
+ "ifmp", /* 101 (Ipsilon Flow Management Protocol) */
+ "pnni", /* 102 (PNNI over IP) */
+ "pim", /* 103 (IPPROTO_PIM, Protocol Independent
+ * Multicast)
+ */
+ "aris", /* 104 (ARIS) */
+ "scps", /* 105 (SCPS) */
+ "qnx", /* 106 (QNX) */
+ "a/n", /* 107 (Active Networks) */
+ "ipcomp", /* 108 (IPPROTO_IPCOMP, IP Payload Compression
+ * Protocol)
+ */
+ "snp", /* 109 (Sitara Networks Protocol) */
+ "compaq-peer", /* 110 (Compaq Peer Protocol) */
+ "ipx-in-ip", /* 111 (IPX in IP) */
+ "vrrp", /* 112 (IPPROTO_VRRP, Virtual Router Redundancy
+ * Protocol)
+ */
+ "pgm", /* 113 (IPPROTO_PGM, PGM Reliable Transport
+ * Protocol)
+ */
+ NULL, /* 114 (any 0-hop protocol) */
+ "l2tp", /* 115 (Layer Two Tunneling Protocol) */
+ "ddx", /* 116 (D-II Data Exchange (DDX)) */
+ "iatp", /* 117 (Interactive Agent Transfer Protocol) */
+ "stp", /* 118 (Schedule Transfer Protocol) */
+ "srp", /* 119 (SpectraLink Radio Protocol) */
+ "uti", /* 120 (UTI) */
+ "smp", /* 121 (Simple Message Protocol) */
+ "sm", /* 122 (Simple Multicast Protocol) */
+ "ptp", /* 123 (Performance Transparency Protocol) */
+ "isis", /* 124 (ISIS over IPv4) */
+ "fire", /* 125 (FIRE) */
+ "crtp", /* 126 (Combat Radio Transport Protocol) */
+ "crudp", /* 127 (Combat Radio User Datagram) */
+ "sscopmce", /* 128 (SSCOPMCE) */
+ "iplt", /* 129 (IPLT) */
+ "sps", /* 130 (Secure Packet Shield) */
+ "pipe", /* 131 (Private IP Encapsulation within IP) */
+ "sctp", /* 132 (IPPROTO_SCTP, Stream Control Transmission
+ * Protocol)
+ */
+ "fc", /* 133 (Fibre Channel) */
+ "rsvp-e2e-ignore", /* 134 (RSVP-E2E-IGNORE) */
+ "mobility-header", /* 135 (IPPROTO_MOBILITY, Mobility Header) */
+ "udplite", /* 136 (UDPLite) */
+ "mpls-in-ip", /* 137 (MPLS-in-IP) */
+ "manet", /* 138 (MANET Protocols) */
+ "hip", /* 139 (Host Identity Protocol) */
+ "shim6", /* 140 (Shim6 Protocol) */
+ "wesp", /* 141 (Wrapped Encapsulating Security Payload) */
+ "rohc", /* 142 (Robust Header Compression) */
+ NULL, /* 143 (unassigned) */
+ NULL, /* 144 (unassigned) */
+ NULL, /* 145 (unassigned) */
+ NULL, /* 146 (unassigned) */
+ NULL, /* 147 (unassigned) */
+ NULL, /* 148 (unassigned) */
+ NULL, /* 149 (unassigned) */
+ NULL, /* 150 (unassigned) */
+ NULL, /* 151 (unassigned) */
+ NULL, /* 152 (unassigned) */
+ NULL, /* 153 (unassigned) */
+ NULL, /* 154 (unassigned) */
+ NULL, /* 155 (unassigned) */
+ NULL, /* 156 (unassigned) */
+ NULL, /* 157 (unassigned) */
+ NULL, /* 158 (unassigned) */
+ NULL, /* 159 (unassigned) */
+ NULL, /* 160 (unassigned) */
+ NULL, /* 161 (unassigned) */
+ NULL, /* 162 (unassigned) */
+ NULL, /* 163 (unassigned) */
+ NULL, /* 164 (unassigned) */
+ NULL, /* 165 (unassigned) */
+ NULL, /* 166 (unassigned) */
+ NULL, /* 167 (unassigned) */
+ NULL, /* 168 (unassigned) */
+ NULL, /* 169 (unassigned) */
+ NULL, /* 170 (unassigned) */
+ NULL, /* 171 (unassigned) */
+ NULL, /* 172 (unassigned) */
+ NULL, /* 173 (unassigned) */
+ NULL, /* 174 (unassigned) */
+ NULL, /* 175 (unassigned) */
+ NULL, /* 176 (unassigned) */
+ NULL, /* 177 (unassigned) */
+ NULL, /* 178 (unassigned) */
+ NULL, /* 179 (unassigned) */
+ NULL, /* 180 (unassigned) */
+ NULL, /* 181 (unassigned) */
+ NULL, /* 182 (unassigned) */
+ NULL, /* 183 (unassigned) */
+ NULL, /* 184 (unassigned) */
+ NULL, /* 185 (unassigned) */
+ NULL, /* 186 (unassigned) */
+ NULL, /* 187 (unassigned) */
+ NULL, /* 188 (unassigned) */
+ NULL, /* 189 (unassigned) */
+ NULL, /* 190 (unassigned) */
+ NULL, /* 191 (unassigned) */
+ NULL, /* 192 (unassigned) */
+ NULL, /* 193 (unassigned) */
+ NULL, /* 194 (unassigned) */
+ NULL, /* 195 (unassigned) */
+ NULL, /* 196 (unassigned) */
+ NULL, /* 197 (unassigned) */
+ NULL, /* 198 (unassigned) */
+ NULL, /* 199 (unassigned) */
+ NULL, /* 200 (unassigned) */
+ NULL, /* 201 (unassigned) */
+ NULL, /* 202 (unassigned) */
+ NULL, /* 203 (unassigned) */
+ NULL, /* 204 (unassigned) */
+ NULL, /* 205 (unassigned) */
+ NULL, /* 206 (unassigned) */
+ NULL, /* 207 (unassigned) */
+ NULL, /* 208 (unassigned) */
+ NULL, /* 209 (unassigned) */
+ NULL, /* 210 (unassigned) */
+ NULL, /* 211 (unassigned) */
+ NULL, /* 212 (unassigned) */
+ NULL, /* 213 (unassigned) */
+ NULL, /* 214 (unassigned) */
+ NULL, /* 215 (unassigned) */
+ NULL, /* 216 (unassigned) */
+ NULL, /* 217 (unassigned) */
+ NULL, /* 218 (unassigned) */
+ NULL, /* 219 (unassigned) */
+ NULL, /* 220 (unassigned) */
+ NULL, /* 221 (unassigned) */
+ NULL, /* 222 (unassigned) */
+ NULL, /* 223 (unassigned) */
+ NULL, /* 224 (unassigned) */
+ NULL, /* 225 (unassigned) */
+ NULL, /* 226 (unassigned) */
+ NULL, /* 227 (unassigned) */
+ NULL, /* 228 (unassigned) */
+ NULL, /* 229 (unassigned) */
+ NULL, /* 230 (unassigned) */
+ NULL, /* 231 (unassigned) */
+ NULL, /* 232 (unassigned) */
+ NULL, /* 233 (unassigned) */
+ NULL, /* 234 (unassigned) */
+ NULL, /* 235 (unassigned) */
+ NULL, /* 236 (unassigned) */
+ NULL, /* 237 (unassigned) */
+ NULL, /* 238 (unassigned) */
+ NULL, /* 239 (unassigned) */
+ NULL, /* 240 (unassigned) */
+ NULL, /* 241 (unassigned) */
+ NULL, /* 242 (unassigned) */
+ NULL, /* 243 (unassigned) */
+ NULL, /* 244 (unassigned) */
+ NULL, /* 245 (unassigned) */
+ NULL, /* 246 (unassigned) */
+ NULL, /* 247 (unassigned) */
+ NULL, /* 248 (unassigned) */
+ NULL, /* 249 (unassigned) */
+ NULL, /* 250 (unassigned) */
+ NULL, /* 251 (unassigned) */
+ NULL, /* 252 (unassigned) */
+ "exptest-253", /* 253 (Use for experimentation and testing,
+ * RFC 3692)
+ */
+ "exptest-254", /* 254 (Use for experimentation and testing,
+ * RFC 3692)
+ */
+ "reserved", /* 255 (reserved) */
+};
+
+/* The function enforces the array index to be 8-bit. */
+const char *
+netdb_protoname (const nd_uint8_t protoid)
+{
+ return netdb_protocol_names[protoid];
+}
diff --git a/contrib/tcpdump/ipproto.h b/contrib/tcpdump/ipproto.h
index dfc4f46..6bc9e1a 100644
--- a/contrib/tcpdump/ipproto.h
+++ b/contrib/tcpdump/ipproto.h
@@ -36,6 +36,7 @@
*/
extern const struct tok ipproto_values[];
+extern const char *netdb_protoname (const nd_uint8_t);
#ifndef IPPROTO_IP
#define IPPROTO_IP 0 /* dummy for IP */
@@ -109,7 +110,7 @@ extern const struct tok ipproto_values[];
* It appears that 62 used to be used, even though that's assigned to
* a protocol called CFTP; however, the only reference for CFTP is a
* Network Message from BBN back in 1982, so, for now, we support 62,
- * aas well as 135, as a protocol number for mobility headers.
+ * as well as 135, as a protocol number for mobility headers.
*/
#define IPPROTO_MOBILITY_OLD 62
#endif
diff --git a/contrib/tcpdump/l2vpn.c b/contrib/tcpdump/l2vpn.c
index 3f3639f..b0f6682 100644
--- a/contrib/tcpdump/l2vpn.c
+++ b/contrib/tcpdump/l2vpn.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/contrib/tcpdump/l2vpn.h b/contrib/tcpdump/l2vpn.h
index d93abf1..98b6fcc 100644
--- a/contrib/tcpdump/l2vpn.h
+++ b/contrib/tcpdump/l2vpn.h
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok l2vpn_encaps_values[];
diff --git a/contrib/tcpdump/netdissect-stdinc.h b/contrib/tcpdump/netdissect-stdinc.h
index c7070f0..8282c58 100644
--- a/contrib/tcpdump/netdissect-stdinc.h
+++ b/contrib/tcpdump/netdissect-stdinc.h
@@ -394,6 +394,11 @@ struct in6_addr {
* end of Apple deprecation workaround macros
*/
+/*
+ * Function attributes, for various compilers.
+ */
+#include "funcattrs.h"
+
#ifndef min
#define min(a,b) ((a)>(b)?(b):(a))
#endif
diff --git a/contrib/tcpdump/netdissect.h b/contrib/tcpdump/netdissect.h
index d691ad1..286b176 100644
--- a/contrib/tcpdump/netdissect.h
+++ b/contrib/tcpdump/netdissect.h
@@ -82,19 +82,13 @@ extern int32_t thiszone; /* seconds offset from gmt to local time */
extern const char istr[];
#if !defined(HAVE_SNPRINTF)
-int snprintf (char *str, size_t sz, const char *format, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 3, 4)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+int snprintf (char *str, size_t sz, FORMAT_STRING(const char *format), ...)
+ PRINTFLIKE(3, 4);
#endif /* !defined(HAVE_SNPRINTF) */
#if !defined(HAVE_VSNPRINTF)
-int vsnprintf (char *str, size_t sz, const char *format, va_list ap)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 3, 0)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+int vsnprintf (char *str, size_t sz, FORMAT_STRING(const char *format),
+ va_list ap) PRINTFLIKE(3, 0);
#endif /* !defined(HAVE_VSNPRINTF) */
#ifndef HAVE_STRLCAT
@@ -532,7 +526,7 @@ extern void ipx_netbios_print(netdissect_options *, const u_char *, u_int);
extern void ipx_print(netdissect_options *, const u_char *, u_int);
extern void isakmp_print(netdissect_options *, const u_char *, u_int, const u_char *);
extern void isakmp_rfc3948_print(netdissect_options *, const u_char *, u_int, const u_char *);
-extern void isoclns_print(netdissect_options *, const u_char *, u_int, u_int);
+extern void isoclns_print(netdissect_options *, const u_char *, u_int);
extern void krb_print(netdissect_options *, const u_char *);
extern void l2tp_print(netdissect_options *, const u_char *, u_int);
extern void lane_print(netdissect_options *, const u_char *, u_int, u_int);
diff --git a/contrib/tcpdump/nlpid.c b/contrib/tcpdump/nlpid.c
index 4b44ee1..991ea3c 100644
--- a/contrib/tcpdump/nlpid.c
+++ b/contrib/tcpdump/nlpid.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/contrib/tcpdump/nlpid.h b/contrib/tcpdump/nlpid.h
index 63a2e70..a3a6905 100644
--- a/contrib/tcpdump/nlpid.h
+++ b/contrib/tcpdump/nlpid.h
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok nlpid_values[];
diff --git a/contrib/tcpdump/oui.c b/contrib/tcpdump/oui.c
index 71425de..56cd127 100644
--- a/contrib/tcpdump/oui.c
+++ b/contrib/tcpdump/oui.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/contrib/tcpdump/oui.h b/contrib/tcpdump/oui.h
index a85f883..a9f732a 100644
--- a/contrib/tcpdump/oui.h
+++ b/contrib/tcpdump/oui.h
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok oui_values[];
diff --git a/contrib/tcpdump/print-802_11.c b/contrib/tcpdump/print-802_11.c
index 3db98ea..f066c91 100644
--- a/contrib/tcpdump/print-802_11.c
+++ b/contrib/tcpdump/print-802_11.c
@@ -1039,10 +1039,6 @@ parse_elements(netdissect_options *ndo,
if (ssid.length != 0) {
if (ssid.length > sizeof(ssid.ssid) - 1)
return 0;
- if (!ND_TTEST2(*(p + offset), ssid.length))
- return 0;
- if (length < ssid.length)
- return 0;
memcpy(&ssid.ssid, p + offset, ssid.length);
offset += ssid.length;
length -= ssid.length;
@@ -1068,10 +1064,6 @@ parse_elements(netdissect_options *ndo,
if (challenge.length >
sizeof(challenge.text) - 1)
return 0;
- if (!ND_TTEST2(*(p + offset), challenge.length))
- return 0;
- if (length < challenge.length)
- return 0;
memcpy(&challenge.text, p + offset,
challenge.length);
offset += challenge.length;
@@ -1097,10 +1089,6 @@ parse_elements(netdissect_options *ndo,
if (rates.length != 0) {
if (rates.length > sizeof rates.rate)
return 0;
- if (!ND_TTEST2(*(p + offset), rates.length))
- return 0;
- if (length < rates.length)
- return 0;
memcpy(&rates.rate, p + offset, rates.length);
offset += rates.length;
length -= rates.length;
@@ -1189,8 +1177,7 @@ parse_elements(netdissect_options *ndo,
offset += 3;
length -= 3;
- memcpy(tim.bitmap, p + (tim.length - 3),
- (tim.length - 3));
+ memcpy(tim.bitmap, p + offset, tim.length - 3);
offset += tim.length - 3;
length -= tim.length - 3;
/*
diff --git a/contrib/tcpdump/print-802_15_4.c b/contrib/tcpdump/print-802_15_4.c
index 6fe6d35..1c77da8 100644
--- a/contrib/tcpdump/print-802_15_4.c
+++ b/contrib/tcpdump/print-802_15_4.c
@@ -38,144 +38,186 @@ static const char *ftypes[] = {
"Data", /* 1 */
"ACK", /* 2 */
"Command", /* 3 */
- "Reserved", /* 4 */
- "Reserved", /* 5 */
- "Reserved", /* 6 */
- "Reserved", /* 7 */
+ "Reserved (0x4)", /* 4 */
+ "Reserved (0x5)", /* 5 */
+ "Reserved (0x6)", /* 6 */
+ "Reserved (0x7)", /* 7 */
};
-static int
-extract_header_length(uint16_t fc)
-{
- int len = 0;
-
- switch ((fc >> 10) & 0x3) {
- case 0x00:
- if (fc & (1 << 6)) /* intra-PAN with none dest addr */
- return -1;
- break;
- case 0x01:
- return -1;
- case 0x02:
- len += 4;
- break;
- case 0x03:
- len += 10;
- break;
- }
-
- switch ((fc >> 14) & 0x3) {
- case 0x00:
- break;
- case 0x01:
- return -1;
- case 0x02:
- len += 4;
- break;
- case 0x03:
- len += 10;
- break;
- }
-
- if (fc & (1 << 6)) {
- if (len < 2)
- return -1;
- len -= 2;
- }
-
- return len;
-}
-
+/*
+ * Frame Control subfields.
+ */
+#define FC_FRAME_TYPE(fc) ((fc) & 0x7)
+#define FC_SECURITY_ENABLED 0x0008
+#define FC_FRAME_PENDING 0x0010
+#define FC_ACK_REQUEST 0x0020
+#define FC_PAN_ID_COMPRESSION 0x0040
+#define FC_DEST_ADDRESSING_MODE(fc) (((fc) >> 10) & 0x3)
+#define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3)
+#define FC_SRC_ADDRESSING_MODE(fc) (((fc) >> 14) & 0x3)
+
+#define FC_ADDRESSING_MODE_NONE 0x00
+#define FC_ADDRESSING_MODE_RESERVED 0x01
+#define FC_ADDRESSING_MODE_SHORT 0x02
+#define FC_ADDRESSING_MODE_LONG 0x03
u_int
ieee802_15_4_if_print(netdissect_options *ndo,
const struct pcap_pkthdr *h, const u_char *p)
{
u_int caplen = h->caplen;
- int hdrlen;
+ u_int hdrlen;
uint16_t fc;
uint8_t seq;
+ uint16_t panid = 0;
if (caplen < 3) {
- ND_PRINT((ndo, "[|802.15.4] %x", caplen));
+ ND_PRINT((ndo, "[|802.15.4]"));
return caplen;
}
+ hdrlen = 3;
fc = EXTRACT_LE_16BITS(p);
- hdrlen = extract_header_length(fc);
-
seq = EXTRACT_LE_8BITS(p + 2);
p += 3;
caplen -= 3;
- ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[fc & 0x7]));
+ ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[FC_FRAME_TYPE(fc)]));
if (ndo->ndo_vflag)
ND_PRINT((ndo,"seq %02x ", seq));
- if (hdrlen == -1) {
- ND_PRINT((ndo,"invalid! "));
- return caplen;
- }
-
-
- if (!ndo->ndo_vflag) {
- p+= hdrlen;
- caplen -= hdrlen;
- } else {
- uint16_t panid = 0;
- switch ((fc >> 10) & 0x3) {
- case 0x00:
+ /*
+ * Destination address and PAN ID, if present.
+ */
+ switch (FC_DEST_ADDRESSING_MODE(fc)) {
+ case FC_ADDRESSING_MODE_NONE:
+ if (fc & FC_PAN_ID_COMPRESSION) {
+ /*
+ * PAN ID compression; this requires that both
+ * the source and destination addresses be present,
+ * but the destination address is missing.
+ */
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"none "));
- break;
- case 0x01:
+ break;
+ case FC_ADDRESSING_MODE_RESERVED:
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"reserved destination addressing mode"));
- return 0;
- case 0x02:
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
+ return hdrlen;
+ case FC_ADDRESSING_MODE_SHORT:
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
- p += 2;
- break;
- case 0x03:
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
- ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
- p += 8;
- break;
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ break;
+ case FC_ADDRESSING_MODE_LONG:
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ if (caplen < 8) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
}
+ if (ndo->ndo_vflag)
+ ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
+ p += 8;
+ caplen -= 8;
+ hdrlen += 8;
+ break;
+ }
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"< "));
- switch ((fc >> 14) & 0x3) {
- case 0x00:
+ /*
+ * Source address and PAN ID, if present.
+ */
+ switch (FC_SRC_ADDRESSING_MODE(fc)) {
+ case FC_ADDRESSING_MODE_NONE:
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"none "));
- break;
- case 0x01:
+ break;
+ case FC_ADDRESSING_MODE_RESERVED:
+ if (ndo->ndo_vflag)
ND_PRINT((ndo,"reserved source addressing mode"));
- return 0;
- case 0x02:
- if (!(fc & (1 << 6))) {
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
+ return 0;
+ case FC_ADDRESSING_MODE_SHORT:
+ if (!(fc & FC_PAN_ID_COMPRESSION)) {
+ /*
+ * The source PAN ID is not compressed out, so
+ * fetch it. (Otherwise, we'll use the destination
+ * PAN ID, fetched above.)
+ */
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
}
- ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
+ panid = EXTRACT_LE_16BITS(p);
p += 2;
- break;
- case 0x03:
- if (!(fc & (1 << 6))) {
- panid = EXTRACT_LE_16BITS(p);
- p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ }
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ break;
+ case FC_ADDRESSING_MODE_LONG:
+ if (!(fc & FC_PAN_ID_COMPRESSION)) {
+ /*
+ * The source PAN ID is not compressed out, so
+ * fetch it. (Otherwise, we'll use the destination
+ * PAN ID, fetched above.)
+ */
+ if (caplen < 2) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
}
- ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
- p += 8;
- break;
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
}
-
- caplen -= hdrlen;
+ if (caplen < 8) {
+ ND_PRINT((ndo, "[|802.15.4]"));
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
+ p += 8;
+ caplen -= 8;
+ hdrlen += 8;
+ break;
}
if (!ndo->ndo_suppress_default_print)
ND_DEFAULTPRINT(p, caplen);
- return 0;
+ return hdrlen;
}
diff --git a/contrib/tcpdump/print-aodv.c b/contrib/tcpdump/print-aodv.c
index 6cd0c9e..fe75db8 100644
--- a/contrib/tcpdump/print-aodv.c
+++ b/contrib/tcpdump/print-aodv.c
@@ -42,7 +42,9 @@
#include "addrtoname.h"
#include "extract.h"
-
+/*
+ * RFC 3561
+ */
struct aodv_rreq {
uint8_t rreq_type; /* AODV message type (1) */
uint8_t rreq_flags; /* various flags */
@@ -178,12 +180,17 @@ aodv_extension(netdissect_options *ndo,
{
const struct aodv_hello *ah;
+ ND_TCHECK(*ep);
switch (ep->type) {
case AODV_EXT_HELLO:
ah = (const struct aodv_hello *)(const void *)ep;
ND_TCHECK(*ah);
if (length < sizeof(struct aodv_hello))
goto trunc;
+ if (ep->length < 4) {
+ ND_PRINT((ndo, "\n\text HELLO - bad length %u", ep->length));
+ break;
+ }
ND_PRINT((ndo, "\n\text HELLO %ld ms",
(unsigned long)EXTRACT_32BITS(&ah->interval)));
break;
diff --git a/contrib/tcpdump/print-arp.c b/contrib/tcpdump/print-arp.c
index eff97c4..96727fa 100644
--- a/contrib/tcpdump/print-arp.c
+++ b/contrib/tcpdump/print-arp.c
@@ -78,7 +78,7 @@ struct arp_pkthdr {
u_char ar_tha[]; /* target hardware address */
u_char ar_tpa[]; /* target protocol address */
#endif
-#define ar_sha(ap) (((const u_char *)((ap)+1))+0)
+#define ar_sha(ap) (((const u_char *)((ap)+1))+ 0)
#define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln)
#define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln)
#define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln)
@@ -190,6 +190,30 @@ isnonzero(const u_char *a, size_t len)
}
static void
+tpaddr_print_ip(netdissect_options *ndo,
+ const struct arp_pkthdr *ap, u_short pro)
+{
+ if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ ND_PRINT((ndo, "<wrong proto type>"));
+ else if (PROTO_LEN(ap) != 4)
+ ND_PRINT((ndo, "<wrong len>"));
+ else
+ ND_PRINT((ndo, "%s", ipaddr_string(ndo, TPA(ap))));
+}
+
+static void
+spaddr_print_ip(netdissect_options *ndo,
+ const struct arp_pkthdr *ap, u_short pro)
+{
+ if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ ND_PRINT((ndo, "<wrong proto type>"));
+ else if (PROTO_LEN(ap) != 4)
+ ND_PRINT((ndo, "<wrong len>"));
+ else
+ ND_PRINT((ndo, "%s", ipaddr_string(ndo, SPA(ap))));
+}
+
+static void
atmarp_addr_print(netdissect_options *ndo,
const u_char *ha, u_int ha_len, const u_char *srca,
u_int srca_len)
@@ -205,6 +229,30 @@ atmarp_addr_print(netdissect_options *ndo,
}
static void
+atmarp_tpaddr_print(netdissect_options *ndo,
+ const struct atmarp_pkthdr *ap, u_short pro)
+{
+ if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ ND_PRINT((ndo, "<wrong proto type>"));
+ else if (ATMTPROTO_LEN(ap) != 4)
+ ND_PRINT((ndo, "<wrong tplen>"));
+ else
+ ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMTPA(ap))));
+}
+
+static void
+atmarp_spaddr_print(netdissect_options *ndo,
+ const struct atmarp_pkthdr *ap, u_short pro)
+{
+ if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ ND_PRINT((ndo, "<wrong proto type>"));
+ else if (ATMSPROTO_LEN(ap) != 4)
+ ND_PRINT((ndo, "<wrong splen>"));
+ else
+ ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMSPA(ap))));
+}
+
+static void
atmarp_print(netdissect_options *ndo,
const u_char *bp, u_int length, u_int caplen)
{
@@ -252,18 +300,21 @@ atmarp_print(netdissect_options *ndo,
switch (op) {
case ARPOP_REQUEST:
- ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, ATMTPA(ap))));
+ ND_PRINT((ndo, "who-has "));
+ atmarp_tpaddr_print(ndo, ap, pro);
if (ATMTHRD_LEN(ap) != 0) {
ND_PRINT((ndo, " ("));
atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap),
ATMTSA(ap), ATMTSLN(ap));
ND_PRINT((ndo, ")"));
}
- ND_PRINT((ndo, "tell %s", ipaddr_string(ndo, ATMSPA(ap))));
+ ND_PRINT((ndo, " tell "));
+ atmarp_spaddr_print(ndo, ap, pro);
break;
case ARPOP_REPLY:
- ND_PRINT((ndo, "%s is-at ", ipaddr_string(ndo, ATMSPA(ap))));
+ atmarp_spaddr_print(ndo, ap, pro);
+ ND_PRINT((ndo, " is-at "));
atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
ATMSSLN(ap));
break;
@@ -280,11 +331,13 @@ atmarp_print(netdissect_options *ndo,
case ARPOP_INVREPLY:
atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
ATMSSLN(ap));
- ND_PRINT((ndo, "at %s", ipaddr_string(ndo, ATMSPA(ap))));
+ ND_PRINT((ndo, "at "));
+ atmarp_spaddr_print(ndo, ap, pro);
break;
case ARPOP_NAK:
- ND_PRINT((ndo, "for %s", ipaddr_string(ndo, ATMSPA(ap))));
+ ND_PRINT((ndo, "for "));
+ atmarp_spaddr_print(ndo, ap, pro);
break;
default:
@@ -332,7 +385,7 @@ arp_print(netdissect_options *ndo,
break;
}
- if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) {
+ if (!ND_TTEST2(*TPA(ap), PROTO_LEN(ap))) {
ND_PRINT((ndo, "%s", tstr));
ND_DEFAULTPRINT((const u_char *)ap, length);
return;
@@ -367,16 +420,18 @@ arp_print(netdissect_options *ndo,
switch (op) {
case ARPOP_REQUEST:
- ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, TPA(ap))));
+ ND_PRINT((ndo, "who-has "));
+ tpaddr_print_ip(ndo, ap, pro);
if (isnonzero((const u_char *)THA(ap), HRD_LEN(ap)))
ND_PRINT((ndo, " (%s)",
linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap))));
- ND_PRINT((ndo, " tell %s", ipaddr_string(ndo, SPA(ap))));
+ ND_PRINT((ndo, " tell "));
+ spaddr_print_ip(ndo, ap, pro);
break;
case ARPOP_REPLY:
- ND_PRINT((ndo, "%s is-at %s",
- ipaddr_string(ndo, SPA(ap)),
+ spaddr_print_ip(ndo, ap, pro);
+ ND_PRINT((ndo, " is-at %s",
linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap))));
break;
@@ -387,9 +442,9 @@ arp_print(netdissect_options *ndo,
break;
case ARPOP_REVREPLY:
- ND_PRINT((ndo, "%s at %s",
- linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)),
- ipaddr_string(ndo, TPA(ap))));
+ ND_PRINT((ndo, "%s at ",
+ linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap))));
+ tpaddr_print_ip(ndo, ap, pro);
break;
case ARPOP_INVREQUEST:
@@ -399,9 +454,9 @@ arp_print(netdissect_options *ndo,
break;
case ARPOP_INVREPLY:
- ND_PRINT((ndo,"%s at %s",
- linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)),
- ipaddr_string(ndo, SPA(ap))));
+ ND_PRINT((ndo,"%s at ",
+ linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap))));
+ spaddr_print_ip(ndo, ap, pro);
break;
default:
diff --git a/contrib/tcpdump/print-atm.c b/contrib/tcpdump/print-atm.c
index 596e406..bfaa9ea4 100644
--- a/contrib/tcpdump/print-atm.c
+++ b/contrib/tcpdump/print-atm.c
@@ -262,7 +262,7 @@ atm_if_print(netdissect_options *ndo,
if (*p == LLC_UI) {
if (ndo->ndo_eflag)
ND_PRINT((ndo, "CNLPID "));
- isoclns_print(ndo, p + 1, length - 1, caplen - 1);
+ isoclns_print(ndo, p + 1, length - 1);
return hdrlen;
}
diff --git a/contrib/tcpdump/print-beep.c b/contrib/tcpdump/print-beep.c
index ed502b9..64a162d 100644
--- a/contrib/tcpdump/print-beep.c
+++ b/contrib/tcpdump/print-beep.c
@@ -28,9 +28,17 @@
*/
static int
-l_strnstart(const char *tstr1, u_int tl1, const char *str2, u_int l2)
+l_strnstart(netdissect_options *ndo, const char *tstr1, u_int tl1,
+ const char *str2, u_int l2)
{
-
+ if (!ND_TTEST2(*str2, tl1)) {
+ /*
+ * We don't have tl1 bytes worth of captured data
+ * for the string, so we can't check for this
+ * string.
+ */
+ return 0;
+ }
if (tl1 > l2)
return 0;
@@ -41,19 +49,19 @@ void
beep_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
- if (l_strnstart("MSG", 4, (const char *)bp, length)) /* A REQuest */
+ if (l_strnstart(ndo, "MSG", 4, (const char *)bp, length)) /* A REQuest */
ND_PRINT((ndo, " BEEP MSG"));
- else if (l_strnstart("RPY ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "RPY ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP RPY"));
- else if (l_strnstart("ERR ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "ERR ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP ERR"));
- else if (l_strnstart("ANS ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "ANS ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP ANS"));
- else if (l_strnstart("NUL ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "NUL ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP NUL"));
- else if (l_strnstart("SEQ ", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "SEQ ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP SEQ"));
- else if (l_strnstart("END", 4, (const char *)bp, length))
+ else if (l_strnstart(ndo, "END", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP END"));
else
ND_PRINT((ndo, " BEEP (payload or undecoded)"));
diff --git a/contrib/tcpdump/print-bfd.c b/contrib/tcpdump/print-bfd.c
index ad0a406..10b8f35 100644
--- a/contrib/tcpdump/print-bfd.c
+++ b/contrib/tcpdump/print-bfd.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Bidirectional Forwarding Detection (BFD) printer */
diff --git a/contrib/tcpdump/print-bgp.c b/contrib/tcpdump/print-bgp.c
index 79afeab..c82f1cc 100644
--- a/contrib/tcpdump/print-bgp.c
+++ b/contrib/tcpdump/print-bgp.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
+ * Extensively modified by Hannes Gredler (hannes@gredler.at) for more
* complete BGP support.
*/
@@ -756,11 +756,18 @@ decode_rt_routing_info(netdissect_options *ndo,
{
uint8_t route_target[8];
u_int plen;
+ char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */
+ /* NLRI "prefix length" from RFC 2858 Section 4. */
ND_TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
+ /* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits.
+ * RFC 4684 Section 4 defines the layout of "origin AS" and "route
+ * target" fields inside the "prefix" depending on its length.
+ */
if (0 == plen) {
+ /* Without "origin AS", without "route target". */
snprintf(buf, buflen, "default route target");
return 1;
}
@@ -768,20 +775,29 @@ decode_rt_routing_info(netdissect_options *ndo,
if (32 > plen)
return -1;
+ /* With at least "origin AS", possibly with "route target". */
+ ND_TCHECK_32BITS(pptr + 1);
+ as_printf(ndo, asbuf, sizeof(asbuf), EXTRACT_32BITS(pptr + 1));
+
plen-=32; /* adjust prefix length */
if (64 < plen)
return -1;
+ /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 }
+ * and gives the number of octets in the variable-length "route
+ * target" field inside this NLRI "prefix". Look for it.
+ */
memset(&route_target, 0, sizeof(route_target));
- ND_TCHECK2(pptr[1], (plen + 7) / 8);
- memcpy(&route_target, &pptr[1], (plen + 7) / 8);
+ ND_TCHECK2(pptr[5], (plen + 7) / 8);
+ memcpy(&route_target, &pptr[5], (plen + 7) / 8);
+ /* Which specification says to do this? */
if (plen % 8) {
((u_char *)&route_target)[(plen + 7) / 8 - 1] &=
((0xff00 >> (plen % 8)) & 0xff);
}
snprintf(buf, buflen, "origin AS: %s, route target %s",
- as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)),
+ asbuf,
bgp_vpn_rd_print(ndo, (u_char *)&route_target));
return 5 + (plen + 7) / 8;
@@ -895,6 +911,7 @@ static const struct tok bgp_multicast_vpn_route_type_values[] = {
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"},
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"},
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"},
+ { 0, NULL}
};
static int
@@ -959,13 +976,13 @@ decode_multicast_vpn(netdissect_options *ndo,
case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */
case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
- ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
+ ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
offset = strlen(buf);
snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
bgp_vpn_rd_print(ndo, pptr),
as_printf(ndo, astostr, sizeof(astostr),
EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
- pptr += BGP_VPN_RD_LEN;
+ pptr += BGP_VPN_RD_LEN + 4;
bgp_vpn_sg_print(ndo, pptr, buf, buflen);
break;
@@ -1400,6 +1417,7 @@ bgp_attr_print(netdissect_options *ndo,
ND_TCHECK(tptr[0]);
ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_open_values,
"?", tptr[0])));
+ ND_TCHECK(tptr[1]);
for (i = 0; i < tptr[1] * as_size; i += as_size) {
ND_TCHECK2(tptr[2 + i], as_size);
ND_PRINT((ndo, "%s ",
@@ -1719,7 +1737,7 @@ bgp_attr_print(netdissect_options *ndo,
ND_PRINT((ndo, ", no SNPA"));
}
- while (len - (tptr - pptr) > 0) {
+ while (tptr < pptr + len) {
switch (af<<8 | safi) {
case (AFNUM_INET<<8 | SAFNUM_UNICAST):
case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
@@ -1887,7 +1905,7 @@ bgp_attr_print(netdissect_options *ndo,
tptr += 3;
- while (len - (tptr - pptr) > 0) {
+ while (tptr < pptr + len) {
switch (af<<8 | safi) {
case (AFNUM_INET<<8 | SAFNUM_UNICAST):
case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
@@ -2116,11 +2134,11 @@ bgp_attr_print(netdissect_options *ndo,
{
uint8_t tunnel_type, flags;
+ ND_TCHECK2(tptr[0], 5);
tunnel_type = *(tptr+1);
flags = *tptr;
tlen = len;
- ND_TCHECK2(tptr[0], 5);
ND_PRINT((ndo, "\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u",
tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type),
tunnel_type,
@@ -2175,35 +2193,42 @@ bgp_attr_print(netdissect_options *ndo,
uint8_t type;
uint16_t length;
- ND_TCHECK2(tptr[0], 3);
-
tlen = len;
while (tlen >= 3) {
+ ND_TCHECK2(tptr[0], 3);
+
type = *tptr;
length = EXTRACT_16BITS(tptr+1);
+ tptr += 3;
+ tlen -= 3;
ND_PRINT((ndo, "\n\t %s TLV (%u), length %u",
tok2str(bgp_aigp_values, "Unknown", type),
type, length));
+ if (length < 3)
+ goto trunc;
+ length -= 3;
+
/*
* Check if we can read the TLV data.
*/
- ND_TCHECK2(tptr[3], length - 3);
+ ND_TCHECK2(tptr[3], length);
switch (type) {
case BGP_AIGP_TLV:
- ND_TCHECK2(tptr[3], 8);
+ if (length < 8)
+ goto trunc;
ND_PRINT((ndo, ", metric %" PRIu64,
- EXTRACT_64BITS(tptr+3)));
+ EXTRACT_64BITS(tptr)));
break;
default:
if (ndo->ndo_vflag <= 1) {
- print_unknown_data(ndo, tptr+3,"\n\t ", length-3);
+ print_unknown_data(ndo, tptr,"\n\t ", length);
}
}
diff --git a/contrib/tcpdump/print-bootp.c b/contrib/tcpdump/print-bootp.c
index fe798a0..d87911f 100644
--- a/contrib/tcpdump/print-bootp.c
+++ b/contrib/tcpdump/print-bootp.c
@@ -322,6 +322,7 @@ bootp_print(netdissect_options *ndo,
if (EXTRACT_16BITS(&bp->bp_secs))
ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs)));
+ ND_TCHECK(bp->bp_flags);
ND_PRINT((ndo, ", Flags [%s]",
bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))));
if (ndo->ndo_vflag > 1)
diff --git a/contrib/tcpdump/print-cfm.c b/contrib/tcpdump/print-cfm.c
index 43ad438..bad4add 100644
--- a/contrib/tcpdump/print-cfm.c
+++ b/contrib/tcpdump/print-cfm.c
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE 802.1ag Connectivity Fault Management (CFM) protocols printer */
@@ -217,7 +217,7 @@ static const struct tok cfm_tlv_senderid_chassisid_values[] = {
static int
cfm_network_addr_print(netdissect_options *ndo,
- register const u_char *tptr)
+ register const u_char *tptr, const u_int length)
{
u_int network_addr_type;
u_int hexdump = FALSE;
@@ -227,6 +227,11 @@ cfm_network_addr_print(netdissect_options *ndo,
* 802.1ab specifies that this field width
* is only once octet
*/
+ if (length < 1) {
+ ND_PRINT((ndo, "\n\t Network Address Type (invalid, no data"));
+ return hexdump;
+ }
+ /* The calling function must make any due ND_TCHECK calls. */
network_addr_type = *tptr;
ND_PRINT((ndo, "\n\t Network Address Type %s (%u)",
tok2str(af_values, "Unknown", network_addr_type),
@@ -237,10 +242,20 @@ cfm_network_addr_print(netdissect_options *ndo,
*/
switch(network_addr_type) {
case AFNUM_INET:
+ if (length != 1 + 4) {
+ ND_PRINT((ndo, "(invalid IPv4 address length %u)", length - 1));
+ hexdump = TRUE;
+ break;
+ }
ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr + 1)));
break;
case AFNUM_INET6:
+ if (length != 1 + 16) {
+ ND_PRINT((ndo, "(invalid IPv6 address length %u)", length - 1));
+ hexdump = TRUE;
+ break;
+ }
ND_PRINT((ndo, ", %s", ip6addr_string(ndo, tptr + 1)));
break;
@@ -368,8 +383,11 @@ cfm_print(netdissect_options *ndo,
md_nameformat,
md_namelength));
- /* -2 for the MA short name format and length */
- if (md_namelength > names_data_remaining - 2) {
+ /*
+ * -3 for the MA short name format and length and one byte
+ * of MA short name.
+ */
+ if (md_namelength > names_data_remaining - 3) {
ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining - 2));
return;
}
@@ -581,11 +599,12 @@ cfm_print(netdissect_options *ndo,
if (cfm_tlv_len < 1) {
ND_PRINT((ndo, " (too short, must be >= 1)"));
- return;
+ goto next_tlv;
}
/*
* Get the Chassis ID length and check it.
+ * IEEE 802.1Q-2014 Section 21.5.3.1
*/
chassis_id_length = *tptr;
tptr++;
@@ -593,9 +612,14 @@ cfm_print(netdissect_options *ndo,
cfm_tlv_len--;
if (chassis_id_length) {
+ /*
+ * IEEE 802.1Q-2014 Section 21.5.3.2: Chassis ID Subtype, references
+ * IEEE 802.1AB-2005 Section 9.5.2.2, subsequently
+ * IEEE 802.1AB-2016 Section 8.5.2.2: chassis ID subtype
+ */
if (cfm_tlv_len < 1) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
- return;
+ goto next_tlv;
}
chassis_id_type = *tptr;
cfm_tlv_len--;
@@ -608,16 +632,22 @@ cfm_print(netdissect_options *ndo,
if (cfm_tlv_len < chassis_id_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
- return;
+ goto next_tlv;
}
+ /* IEEE 802.1Q-2014 Section 21.5.3.3: Chassis ID */
switch (chassis_id_type) {
case CFM_CHASSIS_ID_MAC_ADDRESS:
+ if (chassis_id_length != ETHER_ADDR_LEN) {
+ ND_PRINT((ndo, " (invalid MAC address length)"));
+ hexdump = TRUE;
+ break;
+ }
ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, tptr + 1)));
break;
case CFM_CHASSIS_ID_NETWORK_ADDRESS:
- hexdump |= cfm_network_addr_print(ndo, tptr);
+ hexdump |= cfm_network_addr_print(ndo, tptr + 1, chassis_id_length);
break;
case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */
@@ -640,38 +670,53 @@ cfm_print(netdissect_options *ndo,
/*
* Check if there is a Management Address.
+ * IEEE 802.1Q-2014 Section 21.5.3.4: Management Address Domain Length
+ * This and all subsequent fields are not present if the TLV length
+ * allows only the above fields.
*/
if (cfm_tlv_len == 0) {
/* No, there isn't; we're done. */
- return;
+ break;
}
+ /* Here mgmt_addr_length stands for the management domain length. */
mgmt_addr_length = *tptr;
tptr++;
tlen--;
cfm_tlv_len--;
+ ND_PRINT((ndo, "\n\t Management Address Domain Length %u", mgmt_addr_length));
if (mgmt_addr_length) {
+ /* IEEE 802.1Q-2014 Section 21.5.3.5: Management Address Domain */
if (cfm_tlv_len < mgmt_addr_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
- return;
+ goto next_tlv;
}
cfm_tlv_len -= mgmt_addr_length;
/*
* XXX - this is an OID; print it as such.
*/
+ hex_print(ndo, "\n\t Management Address Domain: ", tptr, mgmt_addr_length);
tptr += mgmt_addr_length;
tlen -= mgmt_addr_length;
+ /*
+ * IEEE 802.1Q-2014 Section 21.5.3.6: Management Address Length
+ * This field is present if Management Address Domain Length is not 0.
+ */
if (cfm_tlv_len < 1) {
- ND_PRINT((ndo, "\n\t (TLV too short)"));
- return;
+ ND_PRINT((ndo, " (Management Address Length is missing)"));
+ hexdump = TRUE;
+ break;
}
-
+
+ /* Here mgmt_addr_length stands for the management address length. */
mgmt_addr_length = *tptr;
tptr++;
tlen--;
cfm_tlv_len--;
+ ND_PRINT((ndo, "\n\t Management Address Length %u", mgmt_addr_length));
if (mgmt_addr_length) {
+ /* IEEE 802.1Q-2014 Section 21.5.3.7: Management Address */
if (cfm_tlv_len < mgmt_addr_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
return;
@@ -680,6 +725,7 @@ cfm_print(netdissect_options *ndo,
/*
* XXX - this is a TransportDomain; print it as such.
*/
+ hex_print(ndo, "\n\t Management Address: ", tptr, mgmt_addr_length);
tptr += mgmt_addr_length;
tlen -= mgmt_addr_length;
}
@@ -703,6 +749,7 @@ cfm_print(netdissect_options *ndo,
if (hexdump || ndo->ndo_vflag > 1)
print_unknown_data(ndo, tlv_ptr, "\n\t ", cfm_tlv_len);
+next_tlv:
tptr+=cfm_tlv_len;
tlen-=cfm_tlv_len;
}
diff --git a/contrib/tcpdump/print-chdlc.c b/contrib/tcpdump/print-chdlc.c
index 450d286..24acfbd 100644
--- a/contrib/tcpdump/print-chdlc.c
+++ b/contrib/tcpdump/print-chdlc.c
@@ -46,21 +46,18 @@ static const struct tok chdlc_cast_values[] = {
u_int
chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
{
- register u_int length = h->len;
- register u_int caplen = h->caplen;
-
- if (caplen < CHDLC_HDRLEN) {
- ND_PRINT((ndo, "[|chdlc]"));
- return (caplen);
- }
- return (chdlc_print(ndo, p,length));
+ return chdlc_print(ndo, p, h->len);
}
u_int
chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
{
u_int proto;
+ const u_char *bp = p;
+ if (length < CHDLC_HDRLEN)
+ goto trunc;
+ ND_TCHECK2(*p, CHDLC_HDRLEN);
proto = EXTRACT_16BITS(&p[2]);
if (ndo->ndo_eflag) {
ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ",
@@ -94,12 +91,15 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
break;
case ETHERTYPE_ISO:
/* is the fudge byte set ? lets verify by spotting ISO headers */
+ if (length < 2)
+ goto trunc;
+ ND_TCHECK_16BITS(p);
if (*(p+1) == 0x81 ||
*(p+1) == 0x82 ||
*(p+1) == 0x83)
- isoclns_print(ndo, p + 1, length - 1, ndo->ndo_snapend - p - 1);
+ isoclns_print(ndo, p + 1, length - 1);
else
- isoclns_print(ndo, p, length, ndo->ndo_snapend - p);
+ isoclns_print(ndo, p, length);
break;
default:
if (!ndo->ndo_eflag)
@@ -108,6 +108,10 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
}
return (CHDLC_HDRLEN);
+
+trunc:
+ ND_PRINT((ndo, "[|chdlc]"));
+ return ndo->ndo_snapend - bp;
}
/*
diff --git a/contrib/tcpdump/print-cnfp.c b/contrib/tcpdump/print-cnfp.c
index e3e9b6d..7e7d835 100644
--- a/contrib/tcpdump/print-cnfp.c
+++ b/contrib/tcpdump/print-cnfp.c
@@ -159,7 +159,7 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v1 *nh;
register const struct nfrec_v1 *nr;
- struct protoent *pent;
+ const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@@ -211,14 +211,13 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
- pent = getprotobynumber(nr->proto);
- if (!pent || ndo->ndo_nflag)
- ND_PRINT((ndo, "%u ", nr->proto));
+ if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
+ ND_PRINT((ndo, "%s ", p_name));
else
- ND_PRINT((ndo, "%s ", pent->p_name));
+ ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
- if (pent && pent->p_proto == IPPROTO_TCP) {
+ if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",
@@ -249,7 +248,7 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v5 *nh;
register const struct nfrec_v5 *nr;
- struct protoent *pent;
+ const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@@ -308,14 +307,13 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
- pent = getprotobynumber(nr->proto);
- if (!pent || ndo->ndo_nflag)
- ND_PRINT((ndo, "%u ", nr->proto));
+ if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
+ ND_PRINT((ndo, "%s ", p_name));
else
- ND_PRINT((ndo, "%s ", pent->p_name));
+ ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
- if (pent && pent->p_proto == IPPROTO_TCP) {
+ if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",
@@ -346,7 +344,7 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v6 *nh;
register const struct nfrec_v6 *nr;
- struct protoent *pent;
+ const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@@ -405,14 +403,13 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
- pent = getprotobynumber(nr->proto);
- if (!pent || ndo->ndo_nflag)
- ND_PRINT((ndo, "%u ", nr->proto));
+ if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
+ ND_PRINT((ndo, "%s ", p_name));
else
- ND_PRINT((ndo, "%s ", pent->p_name));
+ ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
- if (pent && pent->p_proto == IPPROTO_TCP) {
+ if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",
diff --git a/contrib/tcpdump/print-decnet.c b/contrib/tcpdump/print-decnet.c
index 88aa9e3..de7de27 100644
--- a/contrib/tcpdump/print-decnet.c
+++ b/contrib/tcpdump/print-decnet.c
@@ -542,6 +542,7 @@ decnet_print(netdissect_options *ndo,
length -= padlen;
caplen -= padlen;
rhp = (const union routehdr *)&(ap[sizeof(short)]);
+ ND_TCHECK(rhp->rh_short.sh_flags);
mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
}
@@ -613,6 +614,7 @@ print_decnet_ctlmsg(netdissect_options *ndo,
register const union routehdr *rhp, u_int length,
u_int caplen)
{
+ /* Our caller has already checked for mflags */
int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
register const union controlmsg *cmp = (const union controlmsg *)rhp;
int src, dst, info, blksize, eco, ueco, hello, other, vers;
diff --git a/contrib/tcpdump/print-dhcp6.c b/contrib/tcpdump/print-dhcp6.c
index 762d918..cbb6d84 100644
--- a/contrib/tcpdump/print-dhcp6.c
+++ b/contrib/tcpdump/print-dhcp6.c
@@ -518,6 +518,10 @@ dhcp6opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "...)"));
break;
case DH6OPT_RECONF_MSG:
+ if (optlen != 1) {
+ ND_PRINT((ndo, " ?)"));
+ break;
+ }
tp = (const u_char *)(dh6o + 1);
switch (*tp) {
case DH6_RENEW:
diff --git a/contrib/tcpdump/print-domain.c b/contrib/tcpdump/print-domain.c
index d0b6996..9a2b9e8 100644
--- a/contrib/tcpdump/print-domain.c
+++ b/contrib/tcpdump/print-domain.c
@@ -151,15 +151,14 @@ ns_nprint(netdissect_options *ndo,
register u_int i, l;
register const u_char *rp = NULL;
register int compress = 0;
- int chars_processed;
int elt;
- int data_size = ndo->ndo_snapend - bp;
+ u_int offset, max_offset;
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
- chars_processed = 1;
+ max_offset = (u_int)(cp - bp);
if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) {
compress = 0;
rp = cp + l;
@@ -174,24 +173,28 @@ ns_nprint(netdissect_options *ndo,
}
if (!ND_TTEST2(*cp, 1))
return(NULL);
- cp = bp + (((i << 8) | *cp) & 0x3fff);
+ offset = (((i << 8) | *cp) & 0x3fff);
+ /*
+ * This must move backwards in the packet.
+ * No RFC explicitly says that, but BIND's
+ * name decompression code requires it,
+ * as a way of preventing infinite loops
+ * and other bad behavior, and it's probably
+ * what was intended (compress by pointing
+ * to domain name suffixes already seen in
+ * the packet).
+ */
+ if (offset >= max_offset) {
+ ND_PRINT((ndo, "<BAD PTR>"));
+ return(NULL);
+ }
+ max_offset = offset;
+ cp = bp + offset;
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
i = *cp++;
- chars_processed++;
-
- /*
- * If we've looked at every character in
- * the message, this pointer will make
- * us look at some character again,
- * which means we're looping.
- */
- if (chars_processed >= data_size) {
- ND_PRINT((ndo, "<LOOP>"));
- return (NULL);
- }
continue;
}
if ((i & INDIR_MASK) == EDNS0_MASK) {
@@ -212,14 +215,12 @@ ns_nprint(netdissect_options *ndo,
}
cp += l;
- chars_processed += l;
ND_PRINT((ndo, "."));
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
i = *cp++;
- chars_processed++;
if (!compress)
rp += l + 1;
}
diff --git a/contrib/tcpdump/print-eap.c b/contrib/tcpdump/print-eap.c
index 125e1ee..d76aea3 100644
--- a/contrib/tcpdump/print-eap.c
+++ b/contrib/tcpdump/print-eap.c
@@ -182,7 +182,9 @@ eap_print(netdissect_options *ndo,
switch (eap->type) {
case EAP_FRAME_TYPE_PACKET:
+ ND_TCHECK_8BITS(tptr);
type = *(tptr);
+ ND_TCHECK_16BITS(tptr+2);
len = EXTRACT_16BITS(tptr+2);
ND_PRINT((ndo, ", %s (%u), id %u, len %u",
tok2str(eap_code_values, "unknown", type),
@@ -193,10 +195,11 @@ eap_print(netdissect_options *ndo,
ND_TCHECK2(*tptr, len);
if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */
+ ND_TCHECK_8BITS(tptr+4);
subtype = *(tptr+4);
ND_PRINT((ndo, "\n\t\t Type %s (%u)",
- tok2str(eap_type_values, "unknown", *(tptr+4)),
- *(tptr + 4)));
+ tok2str(eap_type_values, "unknown", subtype),
+ subtype));
switch (subtype) {
case EAP_TYPE_IDENTITY:
@@ -222,6 +225,7 @@ eap_print(netdissect_options *ndo,
* type one octet per type
*/
while (count < len) {
+ ND_TCHECK_8BITS(tptr+count);
ND_PRINT((ndo, " %s (%u),",
tok2str(eap_type_values, "unknown", *(tptr+count)),
*(tptr + count)));
@@ -230,19 +234,23 @@ eap_print(netdissect_options *ndo,
break;
case EAP_TYPE_TTLS:
- ND_PRINT((ndo, " TTLSv%u",
- EAP_TTLS_VERSION(*(tptr + 5)))); /* fall through */
case EAP_TYPE_TLS:
+ ND_TCHECK_8BITS(tptr + 5);
+ if (subtype == EAP_TYPE_TTLS)
+ ND_PRINT((ndo, " TTLSv%u",
+ EAP_TTLS_VERSION(*(tptr + 5))));
ND_PRINT((ndo, " flags [%s] 0x%02x,",
bittok2str(eap_tls_flags_values, "none", *(tptr+5)),
*(tptr + 5)));
if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
+ ND_TCHECK_32BITS(tptr + 6);
ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6)));
}
break;
case EAP_TYPE_FAST:
+ ND_TCHECK_8BITS(tptr + 5);
ND_PRINT((ndo, " FASTv%u",
EAP_TTLS_VERSION(*(tptr + 5))));
ND_PRINT((ndo, " flags [%s] 0x%02x,",
@@ -250,6 +258,7 @@ eap_print(netdissect_options *ndo,
*(tptr + 5)));
if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
+ ND_TCHECK_32BITS(tptr + 6);
ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6)));
}
@@ -258,6 +267,7 @@ eap_print(netdissect_options *ndo,
case EAP_TYPE_AKA:
case EAP_TYPE_SIM:
+ ND_TCHECK_8BITS(tptr + 5);
ND_PRINT((ndo, " subtype [%s] 0x%02x,",
tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)),
*(tptr + 5)));
diff --git a/contrib/tcpdump/print-eigrp.c b/contrib/tcpdump/print-eigrp.c
index 7e1ffb7..aa11341 100644
--- a/contrib/tcpdump/print-eigrp.c
+++ b/contrib/tcpdump/print-eigrp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
+ * Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at>
* The TCPDUMP project
*
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
/*
* packet format documented at
* http://www.rhyshaden.com/eigrp.htm
+ * RFC 7868
*/
struct eigrp_common_header {
@@ -246,6 +247,12 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
/* ok they seem to want to know everything - lets fully decode it */
+ if (len < sizeof(struct eigrp_common_header)) {
+ ND_PRINT((ndo, "EIGRP %s, length: %u (too short, < %u)",
+ tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
+ len, (u_int) sizeof(struct eigrp_common_header)));
+ return;
+ }
tlen=len-sizeof(struct eigrp_common_header);
/* FIXME print other header info */
@@ -286,6 +293,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
eigrp_tlv_type,
eigrp_tlv_len));
+ if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) sizeof(struct eigrp_tlv_header)));
+ break;
+ }
tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
@@ -296,6 +308,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_GENERAL_PARM:
tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_general_parm)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm))));
+ break;
+ }
ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
@@ -308,6 +325,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_SW_VERSION:
tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_sw_version)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version))));
+ break;
+ }
ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u",
tlv_ptr.eigrp_tlv_sw_version->ios_major,
@@ -318,6 +340,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_IP_INT:
tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_int)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int))));
+ break;
+ }
bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
if (bit_length > 32) {
@@ -347,6 +374,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_IP_EXT:
tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_ext)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext))));
+ break;
+ }
bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
if (bit_length > 32) {
@@ -384,6 +416,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_CABLE_SETUP:
tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup))));
+ break;
+ }
ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
@@ -393,6 +430,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_INT:
tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_int)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int))));
+ break;
+ }
ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
@@ -416,6 +458,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_EXT:
tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;
+ if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_ext)) {
+ ND_PRINT((ndo, " (too short, < %u)",
+ (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext))));
+ break;
+ }
ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),
diff --git a/contrib/tcpdump/print-esp.c b/contrib/tcpdump/print-esp.c
index 1115f36..fb5b129 100644
--- a/contrib/tcpdump/print-esp.c
+++ b/contrib/tcpdump/print-esp.c
@@ -145,6 +145,39 @@ EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
}
#endif
+#ifdef HAVE_EVP_CIPHERINIT_EX
+/*
+ * Initialize the cipher by calling EVP_CipherInit_ex(), because
+ * calling EVP_CipherInit() will reset the cipher context, clearing
+ * the cipher, so calling it twice, with the second call having a
+ * null cipher, will clear the already-set cipher. EVP_CipherInit_ex(),
+ * however, won't reset the cipher context, so you can use it to specify
+ * the IV oin a second call after a first call to EVP_CipherInit_ex()
+ * to set the cipher and the key.
+ *
+ * XXX - is there some reason why we need to make two calls?
+ */
+static int
+set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
+}
+#else
+/*
+ * Initialize the cipher by calling EVP_CipherInit(), because we don't
+ * have EVP_CipherInit_ex(); we rely on it not trashing the context.
+ */
+static int
+set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ return EVP_CipherInit(ctx, cipher, key, iv, enc);
+}
+#endif
+
/*
* this will adjust ndo_packetp and ndo_snapend to new buffer!
*/
@@ -156,8 +189,10 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
{
struct sa_list *sa;
const u_char *iv;
- int len;
+ unsigned int len;
EVP_CIPHER_CTX *ctx;
+ unsigned int block_size, output_buffer_size;
+ u_char *output_buffer;
/* initiator arg is any non-zero value */
if(initiator) initiator=1;
@@ -188,17 +223,36 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
return 0;
- if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0)
+ if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
- EVP_CipherInit(ctx, NULL, NULL, iv, 0);
- EVP_Cipher(ctx, __DECONST(u_char *, buf), buf, len);
+ set_cipher_parameters(ctx, NULL, NULL, iv, 0);
+ /*
+ * Allocate a buffer for the decrypted data.
+ * The output buffer must be separate from the input buffer, and
+ * its size must be a multiple of the cipher block size.
+ */
+ block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
+ output_buffer_size = len + (block_size - len % block_size);
+ output_buffer = (u_char *)malloc(output_buffer_size);
+ if (output_buffer == NULL) {
+ (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ EVP_CIPHER_CTX_free(ctx);
+ return 0;
+ }
+ EVP_Cipher(ctx, output_buffer, buf, len);
EVP_CIPHER_CTX_free(ctx);
+ /*
+ * XXX - of course this is wrong, because buf is a const buffer,
+ * but changing this would require a more complicated fix.
+ */
+ memcpy(__DECONST(u_char *, buf), output_buffer, len);
+ free(output_buffer);
+
ndo->ndo_packetp = buf;
ndo->ndo_snapend = end;
return 1;
-
}
USES_APPLE_RST
@@ -606,6 +660,8 @@ esp_print(netdissect_options *ndo,
const u_char *ivoff;
const u_char *p;
EVP_CIPHER_CTX *ctx;
+ unsigned int block_size, output_buffer_size;
+ u_char *output_buffer;
#endif
esp = (const struct newesp *)bp;
@@ -703,7 +759,9 @@ esp_print(netdissect_options *ndo,
ep = bp2 + len;
}
+ /* pointer to the IV, if there is one */
ivoff = (const u_char *)(esp + 1) + 0;
+ /* length of the IV, if there is one; 0, if there isn't */
ivlen = sa->ivlen;
secret = sa->secret;
ep = ep - sa->authlen;
@@ -711,14 +769,37 @@ esp_print(netdissect_options *ndo,
if (sa->evp) {
ctx = EVP_CIPHER_CTX_new();
if (ctx != NULL) {
- if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0)
+ if (set_cipher_parameters(ctx, sa->evp, secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
p = ivoff;
- EVP_CipherInit(ctx, NULL, NULL, p, 0);
- EVP_Cipher(ctx, __DECONST(u_char *, p + ivlen),
- p + ivlen, ep - (p + ivlen));
+ set_cipher_parameters(ctx, NULL, NULL, p, 0);
+ len = ep - (p + ivlen);
+
+ /*
+ * Allocate a buffer for the decrypted data.
+ * The output buffer must be separate from the
+ * input buffer, and its size must be a multiple
+ * of the cipher block size.
+ */
+ block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
+ output_buffer_size = len + (block_size - len % block_size);
+ output_buffer = (u_char *)malloc(output_buffer_size);
+ if (output_buffer == NULL) {
+ (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ EVP_CIPHER_CTX_free(ctx);
+ return -1;
+ }
+
+ EVP_Cipher(ctx, output_buffer, p + ivlen, len);
EVP_CIPHER_CTX_free(ctx);
+ /*
+ * XXX - of course this is wrong, because buf is a
+ * const buffer, but changing this would require a
+ * more complicated fix.
+ */
+ memcpy(__DECONST(u_char *, p + ivlen), output_buffer, len);
+ free(output_buffer);
advance = ivoff - (const u_char *)esp + ivlen;
} else
advance = sizeof(struct newesp);
diff --git a/contrib/tcpdump/print-ether.c b/contrib/tcpdump/print-ether.c
index bbfd7e9..01dd113 100644
--- a/contrib/tcpdump/print-ether.c
+++ b/contrib/tcpdump/print-ether.c
@@ -366,7 +366,7 @@ ethertype_print(netdissect_options *ndo,
ND_PRINT((ndo, " [|osi]"));
return (1);
}
- isoclns_print(ndo, p + 1, length - 1, caplen - 1);
+ isoclns_print(ndo, p + 1, length - 1);
return(1);
case ETHERTYPE_PPPOED:
diff --git a/contrib/tcpdump/print-fr.c b/contrib/tcpdump/print-fr.c
index da7ee25..7181eb4 100644
--- a/contrib/tcpdump/print-fr.c
+++ b/contrib/tcpdump/print-fr.c
@@ -329,7 +329,7 @@ fr_print(netdissect_options *ndo,
case NLPID_CLNP:
case NLPID_ESIS:
case NLPID_ISIS:
- isoclns_print(ndo, p - 1, length + 1, ndo->ndo_snapend - p + 1); /* OSI printers need the NLPID field */
+ isoclns_print(ndo, p - 1, length + 1); /* OSI printers need the NLPID field */
break;
case NLPID_SNAP:
diff --git a/contrib/tcpdump/print-frag6.c b/contrib/tcpdump/print-frag6.c
index db4a98e..fbcabc5 100644
--- a/contrib/tcpdump/print-frag6.c
+++ b/contrib/tcpdump/print-frag6.c
@@ -27,10 +27,11 @@
#include <netdissect-stdinc.h>
-#include "ip6.h"
#include "netdissect.h"
#include "extract.h"
+#include "ip6.h"
+
int
frag6_print(netdissect_options *ndo, register const u_char *bp, register const u_char *bp2)
{
@@ -40,7 +41,7 @@ frag6_print(netdissect_options *ndo, register const u_char *bp, register const u
dp = (const struct ip6_frag *)bp;
ip6 = (const struct ip6_hdr *)bp2;
- ND_TCHECK(dp->ip6f_offlg);
+ ND_TCHECK(*dp);
if (ndo->ndo_vflag) {
ND_PRINT((ndo, "frag (0x%08x:%d|%ld)",
diff --git a/contrib/tcpdump/print-gre.c b/contrib/tcpdump/print-gre.c
index 505752a..0c13d2a 100644
--- a/contrib/tcpdump/print-gre.c
+++ b/contrib/tcpdump/print-gre.c
@@ -226,7 +226,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length)
atalk_print(ndo, bp, len);
break;
case ETHERTYPE_GRE_ISO:
- isoclns_print(ndo, bp, len, ndo->ndo_snapend - bp);
+ isoclns_print(ndo, bp, len);
break;
case ETHERTYPE_TEB:
ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL);
diff --git a/contrib/tcpdump/print-hncp.c b/contrib/tcpdump/print-hncp.c
index 87ee8bb..11a6a93 100644
--- a/contrib/tcpdump/print-hncp.c
+++ b/contrib/tcpdump/print-hncp.c
@@ -270,6 +270,8 @@ dhcpv4_print(netdissect_options *ndo,
i = 0;
while (i < length) {
+ if (i + 2 > length)
+ return -1;
tlv = cp + i;
type = (uint8_t)tlv[0];
optlen = (uint8_t)tlv[1];
@@ -281,6 +283,8 @@ dhcpv4_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s", tok2str(dh4opt_str, "Unknown", type)));
ND_PRINT((ndo," (%u)", optlen + 2 ));
+ if (i + 2 + optlen > length)
+ return -1;
switch (type) {
case DH4OPT_DNS_SERVERS:
@@ -318,6 +322,8 @@ dhcpv6_print(netdissect_options *ndo,
i = 0;
while (i < length) {
+ if (i + 4 > length)
+ return -1;
tlv = cp + i;
type = EXTRACT_16BITS(tlv);
optlen = EXTRACT_16BITS(tlv + 2);
@@ -329,6 +335,8 @@ dhcpv6_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s", tok2str(dh6opt_str, "Unknown", type)));
ND_PRINT((ndo," (%u)", optlen + 4 ));
+ if (i + 4 + optlen > length)
+ return -1;
switch (type) {
case DH6OPT_DNS_SERVERS:
diff --git a/contrib/tcpdump/print-icmp.c b/contrib/tcpdump/print-icmp.c
index 17e7a75..c33f83a 100644
--- a/contrib/tcpdump/print-icmp.c
+++ b/contrib/tcpdump/print-icmp.c
@@ -582,6 +582,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
ip = (const struct ip *)bp;
ndo->ndo_snaplen = ndo->ndo_snapend - bp;
snapend_save = ndo->ndo_snapend;
+ ND_TCHECK_16BITS(&ip->ip_len);
ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len));
ndo->ndo_snapend = snapend_save;
}
@@ -599,7 +600,8 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
* to check if an extension header is present. This is expedient,
* however not all implementations set the length field proper.
*/
- if (!ext_dp->icmp_length) {
+ if (!ext_dp->icmp_length &&
+ ND_TTEST2(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) {
vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
vec[0].len = plen - ICMP_EXTD_MINLEN;
if (in_cksum(vec, 1)) {
@@ -620,12 +622,14 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
}
hlen = plen - ICMP_EXTD_MINLEN;
- vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
- vec[0].len = hlen;
- ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
- EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
- in_cksum(vec, 1) ? "in" : "",
- hlen));
+ if (ND_TTEST2(ext_dp->icmp_ext_version_res, hlen)) {
+ vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
+ vec[0].len = hlen;
+ ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
+ EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
+ in_cksum(vec, 1) ? "in" : "",
+ hlen));
+ }
hlen -= 4; /* subtract common header size */
obj_tptr = (const uint8_t *)ext_dp->icmp_ext_data;
diff --git a/contrib/tcpdump/print-icmp6.c b/contrib/tcpdump/print-icmp6.c
index 7fe639d..42fe19f 100644
--- a/contrib/tcpdump/print-icmp6.c
+++ b/contrib/tcpdump/print-icmp6.c
@@ -1131,6 +1131,7 @@ icmp6_print(netdissect_options *ndo,
if (ndo->ndo_vflag) {
ND_TCHECK(dp->icmp6_data16[0]);
ND_PRINT((ndo,", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])));
+ ND_TCHECK(dp->icmp6_data16[1]);
if (dp->icmp6_data16[1] & 0xc0)
ND_PRINT((ndo," "));
if (dp->icmp6_data16[1] & 0x80)
@@ -1698,6 +1699,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp,
needcomma = 0;
+ ND_TCHECK2(*dp, sizeof(*ni6));
ni6 = (const struct icmp6_nodeinfo *)dp;
ND_PRINT((ndo," node information reply"));
ND_PRINT((ndo," (")); /*)*/
@@ -1752,6 +1754,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp,
ND_PRINT((ndo,", "));
ND_PRINT((ndo,"DNS name"));
cp = (const u_char *)(ni6 + 1) + 4;
+ ND_TCHECK(cp[0]);
if (cp[0] == ep - cp - 1) {
/* icmp-name-lookup-03, pascal string */
if (ndo->ndo_vflag)
diff --git a/contrib/tcpdump/print-ip.c b/contrib/tcpdump/print-ip.c
index 6071bb2..7978743 100644
--- a/contrib/tcpdump/print-ip.c
+++ b/contrib/tcpdump/print-ip.c
@@ -54,7 +54,7 @@ static const struct tok ip_option_values[] = {
/*
* print the recorded route in an IP RR, LSRR or SSRR option.
*/
-static void
+static int
ip_printroute(netdissect_options *ndo,
register const u_char *cp, u_int length)
{
@@ -63,19 +63,25 @@ ip_printroute(netdissect_options *ndo,
if (length < 3) {
ND_PRINT((ndo, " [bad length %u]", length));
- return;
+ return (0);
}
if ((length + 1) & 3)
ND_PRINT((ndo, " [bad length %u]", length));
+ ND_TCHECK(cp[2]);
ptr = cp[2] - 1;
if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
ND_PRINT((ndo, " [bad ptr %u]", cp[2]));
for (len = 3; len < length; len += 4) {
+ ND_TCHECK2(cp[len], 4);
ND_PRINT((ndo, " %s", ipaddr_string(ndo, &cp[len])));
if (ptr > len)
ND_PRINT((ndo, ","));
}
+ return (0);
+
+trunc:
+ return (-1);
}
/*
@@ -162,7 +168,7 @@ nextproto4_cksum(netdissect_options *ndo,
return (in_cksum(vec, 2));
}
-static void
+static int
ip_printts(netdissect_options *ndo,
register const u_char *cp, u_int length)
{
@@ -173,16 +179,18 @@ ip_printts(netdissect_options *ndo,
if (length < 4) {
ND_PRINT((ndo, "[bad length %u]", length));
- return;
+ return (0);
}
ND_PRINT((ndo, " TS{"));
hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
if ((length - 4) & (hoplen-1))
ND_PRINT((ndo, "[bad length %u]", length));
+ ND_TCHECK(cp[2]);
ptr = cp[2] - 1;
len = 0;
if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
ND_PRINT((ndo, "[bad ptr %u]", cp[2]));
+ ND_TCHECK(cp[3]);
switch (cp[3]&0xF) {
case IPOPT_TS_TSONLY:
ND_PRINT((ndo, "TSONLY"));
@@ -211,6 +219,7 @@ ip_printts(netdissect_options *ndo,
for (len = 4; len < length; len += hoplen) {
if (ptr == len)
type = " ^ ";
+ ND_TCHECK2(cp[len], hoplen);
ND_PRINT((ndo, "%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
hoplen!=8 ? "" : ipaddr_string(ndo, &cp[len])));
type = " ";
@@ -223,6 +232,10 @@ done:
ND_PRINT((ndo, " [%d hops not recorded]} ", cp[3]>>4));
else
ND_PRINT((ndo, "}"));
+ return (0);
+
+trunc:
+ return (-1);
}
/*
@@ -272,13 +285,15 @@ ip_optprint(netdissect_options *ndo,
return;
case IPOPT_TS:
- ip_printts(ndo, cp, option_len);
+ if (ip_printts(ndo, cp, option_len) == -1)
+ goto trunc;
break;
case IPOPT_RR: /* fall through */
case IPOPT_SSRR:
case IPOPT_LSRR:
- ip_printroute(ndo, cp, option_len);
+ if (ip_printroute(ndo, cp, option_len) == -1)
+ goto trunc;
break;
case IPOPT_RA:
@@ -324,7 +339,7 @@ static void
ip_print_demux(netdissect_options *ndo,
struct ip_print_demux_state *ipds)
{
- struct protoent *proto;
+ const char *p_name;
again:
switch (ipds->nh) {
@@ -490,8 +505,8 @@ again:
#endif
default:
- if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
- ND_PRINT((ndo, " %s", proto->p_name));
+ if (ndo->ndo_nflag==0 && (p_name = netdb_protoname(ipds->nh)) != NULL)
+ ND_PRINT((ndo, " %s", p_name));
else
ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
ND_PRINT((ndo, " %d", ipds->len));
@@ -532,7 +547,7 @@ ip_print(netdissect_options *ndo,
u_int hlen;
struct cksum_vec vec[1];
uint16_t sum, ip_sum;
- struct protoent *proto;
+ const char *p_name;
ipds->ip = (const struct ip *)bp;
ND_TCHECK(ipds->ip->ip_vhl);
@@ -677,8 +692,8 @@ ip_print(netdissect_options *ndo,
*/
ND_PRINT((ndo, "%s > %s:", ipaddr_string(ndo, &ipds->ip->ip_src),
ipaddr_string(ndo, &ipds->ip->ip_dst)));
- if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
- ND_PRINT((ndo, " %s", proto->p_name));
+ if (!ndo->ndo_nflag && (p_name = netdb_protoname(ipds->ip->ip_p)) != NULL)
+ ND_PRINT((ndo, " %s", p_name));
else
ND_PRINT((ndo, " ip-proto-%d", ipds->ip->ip_p));
}
diff --git a/contrib/tcpdump/print-ip6.c b/contrib/tcpdump/print-ip6.c
index 9f590f2..a634d7b 100644
--- a/contrib/tcpdump/print-ip6.c
+++ b/contrib/tcpdump/print-ip6.c
@@ -280,6 +280,8 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
advance = sizeof(struct ip6_hdr);
nh = ip6->ip6_nxt;
while (cp < ndo->ndo_snapend && advance > 0) {
+ if (len < (u_int)advance)
+ goto trunc;
cp += advance;
len -= advance;
@@ -322,10 +324,15 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
* mobility header.
*/
advance = mobility_print(ndo, cp, (const u_char *)ip6);
+ if (advance < 0)
+ return;
nh = *cp;
return;
case IPPROTO_ROUTING:
+ ND_TCHECK(*cp);
advance = rt6_print(ndo, cp, (const u_char *)ip6);
+ if (advance < 0)
+ return;
nh = *cp;
break;
case IPPROTO_SCTP:
@@ -345,12 +352,16 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
return;
case IPPROTO_AH:
advance = ah_print(ndo, cp);
+ if (advance < 0)
+ return;
nh = *cp;
break;
case IPPROTO_ESP:
{
int enh, padlen;
advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen);
+ if (advance < 0)
+ return;
nh = enh & 0xff;
len -= padlen;
break;
diff --git a/contrib/tcpdump/print-ip6opts.c b/contrib/tcpdump/print-ip6opts.c
index 4c16d80..14768de 100644
--- a/contrib/tcpdump/print-ip6opts.c
+++ b/contrib/tcpdump/print-ip6opts.c
@@ -35,12 +35,12 @@
#include <netdissect-stdinc.h>
-#include "ip6.h"
-
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
+#include "ip6.h"
+
static void
ip6_sopt_print(netdissect_options *ndo, const u_char *bp, int len)
{
diff --git a/contrib/tcpdump/print-isakmp.c b/contrib/tcpdump/print-isakmp.c
index 3dfa171..04374b0b 100644
--- a/contrib/tcpdump/print-isakmp.c
+++ b/contrib/tcpdump/print-isakmp.c
@@ -51,6 +51,7 @@
#include "ip.h"
#include "ip6.h"
+#include "ipproto.h"
/* refer to RFC 2408 */
@@ -427,7 +428,7 @@ struct notify_messages {
char *msg;
};
-/* 3.8 Notification Payload */
+/* 3.8 Authentication Payload */
struct ikev2_auth {
struct isakmp_gen h;
uint8_t auth_method; /* Protocol-ID */
@@ -911,21 +912,25 @@ struct attrmap {
static const u_char *
ikev1_attrmap_print(netdissect_options *ndo,
- const u_char *p, const u_char *ep,
+ const u_char *p, const u_char *ep2,
const struct attrmap *map, size_t nmap)
{
int totlen;
uint32_t t, v;
+ ND_TCHECK(p[0]);
if (p[0] & 0x80)
totlen = 4;
- else
+ else {
+ ND_TCHECK_16BITS(&p[2]);
totlen = 4 + EXTRACT_16BITS(&p[2]);
- if (ep < p + totlen) {
+ }
+ if (ep2 < p + totlen) {
ND_PRINT((ndo,"[|attr]"));
- return ep + 1;
+ return ep2 + 1;
}
+ ND_TCHECK_16BITS(&p[0]);
ND_PRINT((ndo,"("));
t = EXTRACT_16BITS(&p[0]) & 0x7fff;
if (map && t < nmap && map[t].type)
@@ -934,47 +939,71 @@ ikev1_attrmap_print(netdissect_options *ndo,
ND_PRINT((ndo,"type=#%d ", t));
if (p[0] & 0x80) {
ND_PRINT((ndo,"value="));
+ ND_TCHECK_16BITS(&p[2]);
v = EXTRACT_16BITS(&p[2]);
if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
ND_PRINT((ndo,"%s", map[t].value[v]));
- else
- rawprint(ndo, (const uint8_t *)&p[2], 2);
+ else {
+ if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
+ }
} else {
- ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
- rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
+ ND_PRINT((ndo,"len=%d value=", totlen - 4));
+ if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
}
ND_PRINT((ndo,")"));
return p + totlen;
+
+trunc:
+ return NULL;
}
static const u_char *
-ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
+ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep2)
{
int totlen;
uint32_t t;
+ ND_TCHECK(p[0]);
if (p[0] & 0x80)
totlen = 4;
- else
+ else {
+ ND_TCHECK_16BITS(&p[2]);
totlen = 4 + EXTRACT_16BITS(&p[2]);
- if (ep < p + totlen) {
+ }
+ if (ep2 < p + totlen) {
ND_PRINT((ndo,"[|attr]"));
- return ep + 1;
+ return ep2 + 1;
}
+ ND_TCHECK_16BITS(&p[0]);
ND_PRINT((ndo,"("));
t = EXTRACT_16BITS(&p[0]) & 0x7fff;
ND_PRINT((ndo,"type=#%d ", t));
if (p[0] & 0x80) {
ND_PRINT((ndo,"value="));
t = p[2];
- rawprint(ndo, (const uint8_t *)&p[2], 2);
+ if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
} else {
- ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
- rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
+ ND_PRINT((ndo,"len=%d value=", totlen - 4));
+ if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
}
ND_PRINT((ndo,")"));
return p + totlen;
+
+trunc:
+ return NULL;
}
static const u_char *
@@ -1255,11 +1284,12 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
cp = (const u_char *)(p + 1);
ep2 = (const u_char *)p + item_len;
while (cp < ep && cp < ep2) {
- if (map && nmap) {
- cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
- map, nmap);
- } else
- cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
+ if (map && nmap)
+ cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
+ else
+ cp = ikev1_attr_print(ndo, cp, ep2);
+ if (cp == NULL)
+ goto trunc;
}
if (ep < ep2)
ND_PRINT((ndo,"..."));
@@ -1283,6 +1313,7 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1346,16 +1377,15 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
{
const struct ipsecdoi_id *doi_p;
struct ipsecdoi_id doi_id;
- struct protoent *pe;
+ const char *p_name;
doi_p = (const struct ipsecdoi_id *)ext;
ND_TCHECK(*doi_p);
UNALIGNED_MEMCPY(&doi_id, ext, sizeof(doi_id));
ND_PRINT((ndo," idtype=%s", STR_OR_ID(doi_id.type, ipsecidtypestr)));
/* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */
- pe = doi_id.proto_id ? getprotobynumber(doi_id.proto_id) : NULL;
- if (pe)
- ND_PRINT((ndo," protoid=%s", pe->p_name));
+ if (!ndo->ndo_nflag && doi_id.proto_id && (p_name = netdb_protoname(doi_id.proto_id)) != NULL)
+ ND_PRINT((ndo," protoid=%s", p_name));
else
ND_PRINT((ndo," protoid=%u", doi_id.proto_id));
ND_PRINT((ndo," port=%d", ntohs(doi_id.port)));
@@ -1406,8 +1436,8 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
case IPSECDOI_ID_IPV6_ADDR_SUBNET:
{
const u_char *mask;
- if (len < 20)
- ND_PRINT((ndo," len=%d [bad: < 20]", len));
+ if (len < 32)
+ ND_PRINT((ndo," len=%d [bad: < 32]", len));
else {
mask = (const u_char *)(data + sizeof(struct in6_addr));
/*XXX*/
@@ -1486,6 +1516,7 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
ND_PRINT((ndo," len=%d", item_len - 4));
ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
if (2 < ndo->ndo_vflag && 4 < item_len) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
goto trunc;
@@ -1518,6 +1549,7 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
ND_PRINT((ndo," len=%d", item_len - 4));
ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
if (2 < ndo->ndo_vflag && 4 < item_len) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
goto trunc;
@@ -1542,6 +1574,7 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1566,6 +1599,7 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1590,15 +1624,20 @@ ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
ND_TCHECK(*ext);
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
- ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
- if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
- ND_PRINT((ndo," "));
- if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
- goto trunc;
- } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
- ND_PRINT((ndo," "));
- if (!ike_show_somedata(ndo, (const u_char *)(const uint8_t *)(ext + 1), ep))
- goto trunc;
+ /*
+ * Our caller has ensured that the length is >= 4.
+ */
+ ND_PRINT((ndo," n len=%u", ntohs(e.len) - 4));
+ if (ntohs(e.len) > 4) {
+ if (ndo->ndo_vflag > 2) {
+ ND_PRINT((ndo, " "));
+ if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ } else if (ndo->ndo_vflag > 1) {
+ ND_PRINT((ndo, " "));
+ if (!ike_show_somedata(ndo, (const u_char *)(ext + 1), ep))
+ goto trunc;
+ }
}
return (const u_char *)ext + ntohs(e.len);
trunc:
@@ -1609,8 +1648,8 @@ trunc:
static const u_char *
ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
const struct isakmp_gen *ext, u_int item_len,
- const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
- uint32_t proto0 _U_, int depth)
+ const u_char *ep, uint32_t phase _U_, uint32_t doi0 _U_,
+ uint32_t proto0 _U_, int depth _U_)
{
const struct ikev1_pl_n *p;
struct ikev1_pl_n n;
@@ -1712,35 +1751,44 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
ep2 = (const u_char *)p + item_len;
if (cp < ep) {
- ND_PRINT((ndo," orig=("));
switch (ntohs(n.type)) {
case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
{
const struct attrmap *map = oakley_t_map;
size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
+ ND_PRINT((ndo," attrs=("));
while (cp < ep && cp < ep2) {
- cp = ikev1_attrmap_print(ndo, cp,
- (ep < ep2) ? ep : ep2, map, nmap);
+ cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
+ if (cp == NULL) {
+ ND_PRINT((ndo,")"));
+ goto trunc;
+ }
}
+ ND_PRINT((ndo,")"));
break;
}
case IPSECDOI_NTYPE_REPLAY_STATUS:
+ ND_PRINT((ndo," status=("));
ND_PRINT((ndo,"replay detection %sabled",
EXTRACT_32BITS(cp) ? "en" : "dis"));
- break;
- case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
- if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
- (const struct isakmp_gen *)cp, ep, phase, doi, proto,
- depth) == NULL)
- return NULL;
+ ND_PRINT((ndo,")"));
break;
default:
- /* NULL is dummy */
- isakmp_print(ndo, cp,
- item_len - sizeof(*p) - n.spi_size,
- NULL);
+ /*
+ * XXX - fill in more types here; see, for example,
+ * draft-ietf-ipsec-notifymsg-04.
+ */
+ if (ndo->ndo_vflag > 3) {
+ ND_PRINT((ndo," data=("));
+ if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
+ goto trunc;
+ ND_PRINT((ndo,")"));
+ } else {
+ if (!ike_show_somedata(ndo, cp, ep))
+ goto trunc;
+ }
+ break;
}
- ND_PRINT((ndo,")"));
}
return (const u_char *)ext + item_len;
trunc:
@@ -1807,6 +1855,7 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1841,6 +1890,7 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay,
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -1915,10 +1965,11 @@ ikev2_t_print(netdissect_options *ndo, int tcount,
ep2 = (const u_char *)p + item_len;
while (cp < ep && cp < ep2) {
if (map && nmap) {
- cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
- map, nmap);
+ cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
} else
- cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
+ cp = ikev1_attr_print(ndo, cp, ep2);
+ if (cp == NULL)
+ goto trunc;
}
if (ep < ep2)
ND_PRINT((ndo,"..."));
@@ -1978,7 +2029,6 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
if (prop_length < sizeof(*ext))
goto toolong;
ND_TCHECK(*ext);
-
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
/*
@@ -2065,7 +2115,6 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay,
if (sa_length < sizeof(*ext))
goto toolong;
ND_TCHECK(*ext);
-
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
/*
@@ -2126,7 +2175,7 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay,
const struct ikev2_ke *k;
k = (const struct ikev2_ke *)ext;
- ND_TCHECK(*ext);
+ ND_TCHECK(*k);
UNALIGNED_MEMCPY(&ke, ext, sizeof(ke));
ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
@@ -2151,12 +2200,14 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
uint32_t phase _U_, uint32_t doi _U_,
uint32_t proto _U_, int depth _U_)
{
+ const struct ikev2_id *idp;
struct ikev2_id id;
int id_len, idtype_len, i;
unsigned int dumpascii, dumphex;
const unsigned char *typedata;
- ND_TCHECK(*ext);
+ idp = (const struct ikev2_id *)ext;
+ ND_TCHECK(*idp);
UNALIGNED_MEMCPY(&id, ext, sizeof(id));
ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
@@ -2164,6 +2215,7 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
ND_PRINT((ndo," len=%d", id_len - 4));
if (2 < ndo->ndo_vflag && 4 < id_len) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4))
goto trunc;
@@ -2259,21 +2311,26 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay,
const u_char *authdata = (const u_char*)ext + sizeof(a);
unsigned int len;
- ND_TCHECK(*ext);
+ ND_TCHECK2(*ext, sizeof(a));
UNALIGNED_MEMCPY(&a, ext, sizeof(a));
ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
len = ntohs(a.h.len);
- ND_PRINT((ndo," len=%d method=%s", len-4,
+ /*
+ * Our caller has ensured that the length is >= 4.
+ */
+ ND_PRINT((ndo," len=%u method=%s", len-4,
STR_OR_ID(a.auth_method, v2_auth)));
-
- if (1 < ndo->ndo_vflag && 4 < len) {
- ND_PRINT((ndo," authdata=("));
- if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
- goto trunc;
- ND_PRINT((ndo,") "));
- } else if(ndo->ndo_vflag && 4 < len) {
- if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
+ if (len > 4) {
+ if (ndo->ndo_vflag > 1) {
+ ND_PRINT((ndo, " authdata=("));
+ if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
+ goto trunc;
+ ND_PRINT((ndo, ") "));
+ } else if (ndo->ndo_vflag) {
+ if (!ike_show_somedata(ndo, authdata, ep))
+ goto trunc;
+ }
}
return (const u_char *)ext + len;
@@ -2322,7 +2379,7 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
const struct ikev2_n *p;
struct ikev2_n n;
const u_char *cp;
- u_char showspi, showdata, showsomedata;
+ u_char showspi, showsomedata;
const char *notify_name;
uint32_t type;
@@ -2332,7 +2389,6 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
showspi = 1;
- showdata = 0;
showsomedata=0;
notify_name=NULL;
@@ -2446,7 +2502,6 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
notify_name = "cookie";
showspi = 1;
showsomedata= 1;
- showdata= 0;
break;
case IV2_NOTIFY_USE_TRANSPORT_MODE:
@@ -2499,19 +2554,17 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
cp = (const u_char *)(p + 1) + n.spi_size;
- if(3 < ndo->ndo_vflag) {
- showdata = 1;
- }
-
- if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
- ND_PRINT((ndo," data=("));
- if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
- goto trunc;
-
- ND_PRINT((ndo,")"));
+ if (cp < ep) {
+ if (ndo->ndo_vflag > 3 || (showsomedata && ep-cp < 30)) {
+ ND_PRINT((ndo," data=("));
+ if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
+ goto trunc;
- } else if(showsomedata && cp < ep) {
- if(!ike_show_somedata(ndo, cp, ep)) goto trunc;
+ ND_PRINT((ndo,")"));
+ } else if (showsomedata) {
+ if (!ike_show_somedata(ndo, cp, ep))
+ goto trunc;
+ }
}
return (const u_char *)ext + item_len;
@@ -2554,6 +2607,7 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay,
else ND_PRINT((ndo, "."));
}
if (2 < ndo->ndo_vflag && 4 < len) {
+ /* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@@ -2719,7 +2773,6 @@ ikev1_sub_print(netdissect_options *ndo,
while (np) {
ND_TCHECK(*ext);
-
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_TCHECK2(*ext, ntohs(e.len));
@@ -2887,7 +2940,6 @@ ikev2_sub_print(netdissect_options *ndo,
cp = (const u_char *)ext;
while (np) {
ND_TCHECK(*ext);
-
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_TCHECK2(*ext, ntohs(e.len));
@@ -3041,7 +3093,7 @@ isakmp_rfc3948_print(netdissect_options *ndo,
const u_char *bp, u_int length,
const u_char *bp2)
{
-
+ ND_TCHECK(bp[0]);
if(length == 1 && bp[0]==0xff) {
ND_PRINT((ndo, "isakmp-nat-keep-alive"));
return;
@@ -3050,6 +3102,7 @@ isakmp_rfc3948_print(netdissect_options *ndo,
if(length < 4) {
goto trunc;
}
+ ND_TCHECK(bp[3]);
/*
* see if this is an IKE packet
@@ -3090,7 +3143,3 @@ trunc:
* c-basic-offset: 8
* End:
*/
-
-
-
-
diff --git a/contrib/tcpdump/print-isoclns.c b/contrib/tcpdump/print-isoclns.c
index d08085f..5e08c3c 100644
--- a/contrib/tcpdump/print-isoclns.c
+++ b/contrib/tcpdump/print-isoclns.c
@@ -20,7 +20,7 @@
*
* Original code by Matt Thomas, Digital Equipment Corporation
*
- * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
+ * Extensively modified by Hannes Gredler (hannes@gredler.at) for more
* complete IS-IS & CLNP support.
*/
@@ -564,8 +564,8 @@ struct isis_tlv_ptp_adj {
uint8_t neighbor_extd_local_circuit_id[4];
};
-static int osi_print_cksum(netdissect_options *, const uint8_t *pptr,
- uint16_t checksum, int checksum_offset, int length);
+static void osi_print_cksum(netdissect_options *, const uint8_t *pptr,
+ uint16_t checksum, int checksum_offset, u_int length);
static int clnp_print(netdissect_options *, const uint8_t *, u_int);
static void esis_print(netdissect_options *, const uint8_t *, u_int);
static int isis_print(netdissect_options *, const uint8_t *, u_int);
@@ -670,10 +670,9 @@ struct isis_tlv_lsp {
#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
void
-isoclns_print(netdissect_options *ndo,
- const uint8_t *p, u_int length, u_int caplen)
+isoclns_print(netdissect_options *ndo, const uint8_t *p, u_int length)
{
- if (caplen <= 1) { /* enough bytes on the wire ? */
+ if (!ND_TTEST(*p)) { /* enough bytes on the wire ? */
ND_PRINT((ndo, "|OSI"));
return;
}
@@ -685,7 +684,7 @@ isoclns_print(netdissect_options *ndo,
case NLPID_CLNP:
if (!clnp_print(ndo, p, length))
- print_unknown_data(ndo, p, "\n\t", caplen);
+ print_unknown_data(ndo, p, "\n\t", length);
break;
case NLPID_ESIS:
@@ -694,7 +693,7 @@ isoclns_print(netdissect_options *ndo,
case NLPID_ISIS:
if (!isis_print(ndo, p, length))
- print_unknown_data(ndo, p, "\n\t", caplen);
+ print_unknown_data(ndo, p, "\n\t", length);
break;
case NLPID_NULLNS:
@@ -721,8 +720,8 @@ isoclns_print(netdissect_options *ndo,
if (!ndo->ndo_eflag)
ND_PRINT((ndo, "OSI NLPID 0x%02x unknown", *p));
ND_PRINT((ndo, "%slength: %u", ndo->ndo_eflag ? "" : ", ", length));
- if (caplen > 1)
- print_unknown_data(ndo, p, "\n\t", caplen);
+ if (length > 1)
+ print_unknown_data(ndo, p, "\n\t", length);
break;
}
}
@@ -865,9 +864,8 @@ clnp_print(netdissect_options *ndo,
EXTRACT_16BITS(clnp_header->segment_length),
EXTRACT_16BITS(clnp_header->cksum)));
- if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
- clnp_header->length_indicator) == 0)
- goto trunc;
+ osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
+ clnp_header->length_indicator);
ND_PRINT((ndo, "\n\tFlags [%s]",
bittok2str(clnp_flag_values, "none", clnp_flags)));
@@ -1153,8 +1151,7 @@ esis_print(netdissect_options *ndo,
ND_PRINT((ndo, ", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" ));
ND_PRINT((ndo, ", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum)));
- if (osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li) == 0)
- goto trunc;
+ osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li);
ND_PRINT((ndo, ", holding time: %us, length indicator: %u",
EXTRACT_16BITS(esis_header->holdtime), li));
@@ -1220,10 +1217,18 @@ esis_print(netdissect_options *ndo,
pptr += netal;
li -= netal;
- if (netal == 0)
- ND_PRINT((ndo, "\n\t %s", etheraddr_string(ndo, snpa)));
+ if (snpal == 6)
+ ND_PRINT((ndo, "\n\t SNPA (length: %u): %s",
+ snpal,
+ etheraddr_string(ndo, snpa)));
else
- ND_PRINT((ndo, "\n\t %s", isonsap_string(ndo, neta, netal)));
+ ND_PRINT((ndo, "\n\t SNPA (length: %u): %s",
+ snpal,
+ linkaddr_string(ndo, snpa, LINKADDR_OTHER, snpal)));
+ if (netal != 0)
+ ND_PRINT((ndo, "\n\t NET (length: %u) %s",
+ netal,
+ isonsap_string(ndo, neta, netal)));
break;
}
@@ -1329,7 +1334,7 @@ esis_print(netdissect_options *ndo,
case ESIS_OPTION_PROTOCOLS:
while (opli>0) {
- ND_TCHECK(*pptr);
+ ND_TCHECK(*tptr);
ND_PRINT((ndo, "%s (0x%02x)",
tok2str(nlpid_values,
"unknown",
@@ -1362,7 +1367,7 @@ esis_print(netdissect_options *ndo,
pptr += opli;
}
trunc:
- return;
+ ND_PRINT((ndo, "[|esis]"));
}
static void
@@ -1398,6 +1403,7 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
while (len > 2)
{
+ ND_TCHECK2(*tptr, 2);
stlv_type = *(tptr++);
stlv_len = *(tptr++);
@@ -1410,11 +1416,18 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
/*len -= TLV_TYPE_LEN_OFFSET;*/
len = len -2;
+ /* Make sure the subTLV fits within the space left */
+ if (len < stlv_len)
+ goto trunc;
+ /* Make sure the entire subTLV is in the captured data */
+ ND_TCHECK2(*(tptr), stlv_len);
+
switch (stlv_type)
{
case ISIS_SUBTLV_SPB_MCID:
{
- ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN);
+ if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN)
+ goto trunc;
subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr;
@@ -1429,15 +1442,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
/*tptr += SPB_MCID_MIN_LEN;
len -= SPB_MCID_MIN_LEN; */
- tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
- len = len - sizeof(struct isis_subtlv_spb_mcid);
+ tptr = tptr + ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+ len = len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
break;
}
case ISIS_SUBTLV_SPB_DIGEST:
{
- ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN);
+ if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)
+ goto trunc;
ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d",
(*(tptr) >> 5), (((*tptr)>> 4) & 0x01),
@@ -1456,18 +1471,15 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
}
len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
break;
}
case ISIS_SUBTLV_SPB_BVID:
{
- ND_TCHECK2(*(tptr), stlv_len);
-
- while (len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
+ while (stlv_len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
{
- ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN);
-
ND_PRINT((ndo, "\n\t ECT: %08x",
EXTRACT_32BITS(tptr)));
@@ -1480,14 +1492,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
tptr = tptr + 2;
len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
}
break;
}
default:
- break;
+ break;
}
+ tptr += stlv_len;
+ len -= stlv_len;
}
return 0;
@@ -1506,6 +1521,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
while (len > 2)
{
+ ND_TCHECK2(*tptr, 2);
stlv_type = *(tptr++);
stlv_len = *(tptr++);
@@ -1517,11 +1533,17 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
len = len - 2;
+ /* Make sure the subTLV fits within the space left */
+ if (len < stlv_len)
+ goto trunc;
+ /* Make sure the entire subTLV is in the captured data */
+ ND_TCHECK2(*(tptr), stlv_len);
+
switch (stlv_type)
{
case ISIS_SUBTLV_SPB_INSTANCE:
-
- ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN);
+ if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)
+ goto trunc;
ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr)));
tptr = tptr+4;
@@ -1543,10 +1565,12 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
tmp = *(tptr++);
len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
while (tmp)
{
- ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN);
+ if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)
+ goto trunc;
ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d",
*(tptr) >> 7, (*(tptr) >> 6) & 0x01,
@@ -1564,14 +1588,15 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
tptr = tptr + 3;
len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
+ stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
tmp--;
}
break;
case ISIS_SUBTLV_SPBM_SI:
-
- ND_TCHECK2(*tptr, 8);
+ if (stlv_len < 8)
+ goto trunc;
ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_32BITS(tptr)));
tptr = tptr+4;
@@ -1603,6 +1628,8 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
default:
break;
}
+ tptr += stlv_len;
+ len -= stlv_len;
}
return 0;
@@ -1619,8 +1646,12 @@ isis_print_id(const uint8_t *cp, int id_len)
int i;
static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")];
char *pos = id;
+ int sysid_len;
- for (i = 1; i <= SYSTEM_ID_LEN; i++) {
+ sysid_len = SYSTEM_ID_LEN;
+ if (sysid_len > id_len)
+ sysid_len = id_len;
+ for (i = 1; i <= sysid_len; i++) {
snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++);
pos += strlen(pos);
if (i == 2 || i == 4)
@@ -1830,6 +1861,8 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
break;
case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */
case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD:
+ if (subl == 0)
+ break;
ND_PRINT((ndo, "%sBandwidth Constraints Model ID: %s (%u)",
ident,
tok2str(diffserv_te_bc_values, "unknown", *tptr),
@@ -1837,7 +1870,6 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
tptr++;
/* decode BCs until the subTLV ends */
for (te_class = 0; te_class < (subl-1)/4; te_class++) {
- ND_TCHECK2(*tptr, 4);
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Bandwidth constraint CT%u: %.3f Mbps",
ident,
@@ -1899,13 +1931,15 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
case GMPLS_PSC2:
case GMPLS_PSC3:
case GMPLS_PSC4:
- ND_TCHECK2(*tptr, 6);
+ if (subl < 6)
+ break;
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000));
ND_PRINT((ndo, "%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr + 4)));
break;
case GMPLS_TSC:
- ND_TCHECK2(*tptr, 8);
+ if (subl < 8)
+ break;
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000));
ND_PRINT((ndo, "%s Indication %s", ident,
@@ -2041,7 +2075,7 @@ isis_print_extd_ip_reach(netdissect_options *ndo,
}
processed++;
} else if (afi == AF_INET6) {
- if (!ND_TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */
+ if (!ND_TTEST2(*tptr, 2)) /* fetch status & prefix_len byte */
return (0);
status_byte=*(tptr++);
bit_length=*(tptr++);
@@ -2164,6 +2198,8 @@ isis_print(netdissect_options *ndo,
TLV verification */
isis_header = (const struct isis_common_header *)p;
ND_TCHECK(*isis_header);
+ if (length < ISIS_COMMON_HEADER_SIZE)
+ goto trunc;
pptr = p+(ISIS_COMMON_HEADER_SIZE);
header_iih_lan = (const struct isis_iih_lan_header *)pptr;
header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
@@ -2194,6 +2230,16 @@ isis_print(netdissect_options *ndo,
return (0);
}
+ if (length < isis_header->fixed_len) {
+ ND_PRINT((ndo, "fixed header length %u > packet length %u", isis_header->fixed_len, length));
+ return (0);
+ }
+
+ if (isis_header->fixed_len < ISIS_COMMON_HEADER_SIZE) {
+ ND_PRINT((ndo, "fixed header length %u < minimum header size %u", isis_header->fixed_len, (u_int)ISIS_COMMON_HEADER_SIZE));
+ return (0);
+ }
+
max_area = isis_header->max_area;
switch(max_area) {
case 0:
@@ -2236,254 +2282,255 @@ isis_print(netdissect_options *ndo,
pdu_type=isis_header->pdu_type;
/* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/
- if (ndo->ndo_vflag < 1) {
+ if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, "%s%s",
ndo->ndo_eflag ? "" : ", ",
tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type)));
+ } else {
+ /* ok they seem to want to know everything - lets fully decode it */
+ ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
- switch (pdu_type) {
-
- case ISIS_PDU_L1_LAN_IIH:
- case ISIS_PDU_L2_LAN_IIH:
- ND_TCHECK(*header_iih_lan);
- ND_PRINT((ndo, ", src-id %s",
- isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
- ND_PRINT((ndo, ", lan-id %s, prio %u",
- isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
- header_iih_lan->priority));
- break;
- case ISIS_PDU_PTP_IIH:
- ND_TCHECK(*header_iih_ptp);
- ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
- break;
- case ISIS_PDU_L1_LSP:
- case ISIS_PDU_L2_LSP:
- ND_TCHECK(*header_lsp);
- ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
- isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
- EXTRACT_32BITS(header_lsp->sequence_number),
- EXTRACT_16BITS(header_lsp->remaining_lifetime)));
- break;
- case ISIS_PDU_L1_CSNP:
- case ISIS_PDU_L2_CSNP:
- ND_TCHECK(*header_csnp);
- ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
- break;
- case ISIS_PDU_L1_PSNP:
- case ISIS_PDU_L2_PSNP:
- ND_TCHECK(*header_psnp);
- ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
- break;
-
- }
- ND_PRINT((ndo, ", length %u", length));
-
- return(1);
- }
-
- /* ok they seem to want to know everything - lets fully decode it */
- ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
-
- ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
- tok2str(isis_pdu_values,
- "unknown, type %u",
- pdu_type),
- isis_header->fixed_len,
- isis_header->version,
- isis_header->pdu_version,
- id_length,
- isis_header->id_length,
- max_area,
- isis_header->max_area));
-
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
- return(0); /* for optionally debugging the common header */
+ ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
+ tok2str(isis_pdu_values,
+ "unknown, type %u",
+ pdu_type),
+ isis_header->fixed_len,
+ isis_header->version,
+ isis_header->pdu_version,
+ id_length,
+ isis_header->id_length,
+ max_area,
+ isis_header->max_area));
+
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
+ return (0); /* for optionally debugging the common header */
+ }
}
switch (pdu_type) {
case ISIS_PDU_L1_LAN_IIH:
case ISIS_PDU_L2_LAN_IIH:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
- ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_iih_lan);
- pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
- if (packet_len>pdu_len) {
- packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
- length=pdu_len;
- }
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
+ ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)));
+ return (0);
+ }
+ ND_TCHECK(*header_iih_lan);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", src-id %s",
+ isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
+ ND_PRINT((ndo, ", lan-id %s, prio %u",
+ isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
+ header_iih_lan->priority));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
+ if (packet_len>pdu_len) {
+ packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
+ length=pdu_len;
+ }
- ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
- isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
- EXTRACT_16BITS(header_iih_lan->holding_time),
- tok2str(isis_iih_circuit_type_values,
- "unknown circuit type 0x%02x",
- header_iih_lan->circuit_type)));
+ ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
+ isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
+ EXTRACT_16BITS(header_iih_lan->holding_time),
+ tok2str(isis_iih_circuit_type_values,
+ "unknown circuit type 0x%02x",
+ header_iih_lan->circuit_type)));
- ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u",
- isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
- (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
- pdu_len));
+ ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u",
+ isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
+ (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
+ pdu_len));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
- break;
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
+ break;
case ISIS_PDU_PTP_IIH:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
- ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_iih_ptp);
- pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
- if (packet_len>pdu_len) {
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
+ ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)));
+ return (0);
+ }
+ ND_TCHECK(*header_iih_ptp);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
+ if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
- }
+ }
- ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
- isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
- EXTRACT_16BITS(header_iih_ptp->holding_time),
- tok2str(isis_iih_circuit_type_values,
- "unknown circuit type 0x%02x",
- header_iih_ptp->circuit_type)));
+ ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
+ isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
+ EXTRACT_16BITS(header_iih_ptp->holding_time),
+ tok2str(isis_iih_circuit_type_values,
+ "unknown circuit type 0x%02x",
+ header_iih_ptp->circuit_type)));
- ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u",
- header_iih_ptp->circuit_id,
- pdu_len));
+ ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u",
+ header_iih_ptp->circuit_id,
+ pdu_len));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
- break;
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
+ break;
case ISIS_PDU_L1_LSP:
case ISIS_PDU_L2_LSP:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
- ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_lsp);
- pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
- if (packet_len>pdu_len) {
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
+ ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
+ return (0);
+ }
+ ND_TCHECK(*header_lsp);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
+ isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
+ EXTRACT_32BITS(header_lsp->sequence_number),
+ EXTRACT_16BITS(header_lsp->remaining_lifetime)));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
+ if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
- }
+ }
- ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
+ ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
EXTRACT_32BITS(header_lsp->sequence_number),
EXTRACT_16BITS(header_lsp->remaining_lifetime),
EXTRACT_16BITS(header_lsp->checksum)));
- if (osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
- EXTRACT_16BITS(header_lsp->checksum),
- 12, length-12) == 0)
- goto trunc;
+ osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
+ EXTRACT_16BITS(header_lsp->checksum),
+ 12, length-12);
- ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
+ ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
pdu_len,
ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""));
- if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
- ND_PRINT((ndo, "ATT bit set, "));
- }
- ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
- ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
- ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
+ if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
+ ND_PRINT((ndo, "ATT bit set, "));
+ }
+ ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
+ ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
+ ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
- break;
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
+ break;
case ISIS_PDU_L1_CSNP:
case ISIS_PDU_L2_CSNP:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
- ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_csnp);
- pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
- if (packet_len>pdu_len) {
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
+ ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)));
+ return (0);
+ }
+ ND_TCHECK(*header_csnp);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
+ if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
- }
+ }
- ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
+ ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
isis_print_id(header_csnp->source_id, NODE_ID_LEN),
pdu_len));
- ND_PRINT((ndo, "\n\t start lsp-id: %s",
+ ND_PRINT((ndo, "\n\t start lsp-id: %s",
isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)));
- ND_PRINT((ndo, "\n\t end lsp-id: %s",
+ ND_PRINT((ndo, "\n\t end lsp-id: %s",
isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
break;
case ISIS_PDU_L1_PSNP:
case ISIS_PDU_L2_PSNP:
- if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
- ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
- isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE));
- return (0);
- }
-
- ND_TCHECK(*header_psnp);
- pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
- if (packet_len>pdu_len) {
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
+ ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)));
+ return (0);
+ }
+ ND_TCHECK(*header_psnp);
+ if (length < ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)
+ goto trunc;
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
+ pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
+ if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
- }
+ }
- ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
+ ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
isis_print_id(header_psnp->source_id, NODE_ID_LEN),
pdu_len));
- if (ndo->ndo_vflag > 1) {
- if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE))
- return(0);
- }
+ if (ndo->ndo_vflag > 1) {
+ if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE))
+ return (0);
+ }
- packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
- pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
- break;
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
+ break;
default:
+ if (ndo->ndo_vflag == 0) {
+ ND_PRINT((ndo, ", length %u", length));
+ return (1);
+ }
(void)print_unknown_data(ndo, pptr, "\n\t ", length);
return (0);
}
@@ -2492,20 +2539,15 @@ isis_print(netdissect_options *ndo,
* Now print the TLV's.
*/
- while (packet_len >= 2) {
- if (pptr == ndo->ndo_snapend) {
- return (1);
- }
-
+ while (packet_len > 0) {
ND_TCHECK2(*pptr, 2);
+ if (packet_len < 2)
+ goto trunc;
tlv_type = *pptr++;
tlv_len = *pptr++;
tmp =tlv_len; /* copy temporary len & pointer to packet data */
tptr = pptr;
packet_len -= 2;
- if (tlv_len > packet_len) {
- break;
- }
/* first lets see if we know the TLVs name*/
ND_PRINT((ndo, "\n\t %s TLV #%u, length: %u",
@@ -2518,12 +2560,16 @@ isis_print(netdissect_options *ndo,
if (tlv_len == 0) /* something is invalid */
continue;
+ if (packet_len < tlv_len)
+ goto trunc;
+
/* now check if we have a decoder otherwise do a hexdump at the end*/
switch (tlv_type) {
case ISIS_TLV_AREA_ADDR:
ND_TCHECK2(*tptr, 1);
alen = *tptr++;
while (tmp && alen < tmp) {
+ ND_TCHECK2(*tptr, alen);
ND_PRINT((ndo, "\n\t Area address (length: %u): %s",
alen,
isonsap_string(ndo, tptr, alen)));
@@ -2906,9 +2952,8 @@ isis_print(netdissect_options *ndo,
* to avoid conflicts the checksum TLV is zeroed.
* see rfc3358 for details
*/
- if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr,
- length) == 0)
- goto trunc;
+ osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr,
+ length);
break;
case ISIS_TLV_POI:
@@ -3102,40 +3147,33 @@ isis_print(netdissect_options *ndo,
return(1);
}
-static int
+static void
osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr,
- uint16_t checksum, int checksum_offset, int length)
+ uint16_t checksum, int checksum_offset, u_int length)
{
uint16_t calculated_checksum;
/* do not attempt to verify the checksum if it is zero,
- * if the total length is nonsense,
* if the offset is nonsense,
* or the base pointer is not sane
*/
if (!checksum
- || length < 0
|| checksum_offset < 0
- || length > ndo->ndo_snaplen
- || checksum_offset > ndo->ndo_snaplen
- || checksum_offset > length) {
+ || !ND_TTEST2(*(pptr + checksum_offset), 2)
+ || (u_int)checksum_offset > length
+ || !ND_TTEST2(*pptr, length)) {
ND_PRINT((ndo, " (unverified)"));
- return 1;
} else {
#if 0
- printf("\nosi_print_cksum: %p %u %u %u\n", pptr, checksum_offset, length, ndo->ndo_snaplen);
+ printf("\nosi_print_cksum: %p %u %u\n", pptr, checksum_offset, length);
#endif
- ND_TCHECK2(*pptr, length);
calculated_checksum = create_osi_cksum(pptr, checksum_offset, length);
if (checksum == calculated_checksum) {
ND_PRINT((ndo, " (correct)"));
} else {
ND_PRINT((ndo, " (incorrect should be 0x%04x)", calculated_checksum));
}
- return 1;
}
-trunc:
- return 0;
}
/*
diff --git a/contrib/tcpdump/print-juniper.c b/contrib/tcpdump/print-juniper.c
index 83ac372..ff1de9c 100644
--- a/contrib/tcpdump/print-juniper.c
+++ b/contrib/tcpdump/print-juniper.c
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: DLT_JUNIPER_* printers */
@@ -472,6 +472,7 @@ juniper_ggsn_print(netdissect_options *ndo,
p+=l2info.header_len;
gh = (struct juniper_ggsn_header *)&l2info.cookie;
+ ND_TCHECK(*gh);
if (ndo->ndo_eflag) {
ND_PRINT((ndo, "proto %s (%u), vlan %u: ",
tok2str(juniper_protocol_values,"Unknown",gh->proto),
@@ -492,6 +493,10 @@ juniper_ggsn_print(netdissect_options *ndo,
}
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_services]"));
+ return l2info.header_len;
}
#endif
@@ -519,6 +524,7 @@ juniper_es_print(netdissect_options *ndo,
p+=l2info.header_len;
ih = (const struct juniper_ipsec_header *)p;
+ ND_TCHECK(*ih);
switch (ih->type) {
case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
@@ -564,6 +570,10 @@ juniper_es_print(netdissect_options *ndo,
ip_print(ndo, p, l2info.length);
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_services]"));
+ return l2info.header_len;
}
#endif
@@ -588,6 +598,7 @@ juniper_monitor_print(netdissect_options *ndo,
p+=l2info.header_len;
mh = (const struct juniper_monitor_header *)p;
+ ND_TCHECK(*mh);
if (ndo->ndo_eflag)
ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ",
EXTRACT_32BITS(&mh->service_id),
@@ -598,6 +609,10 @@ juniper_monitor_print(netdissect_options *ndo,
ip_heuristic_guess (ndo, p, l2info.length);
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_services]"));
+ return l2info.header_len;
}
#endif
@@ -622,6 +637,7 @@ juniper_services_print(netdissect_options *ndo,
p+=l2info.header_len;
sh = (const struct juniper_services_header *)p;
+ ND_TCHECK(*sh);
if (ndo->ndo_eflag)
ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
sh->svc_id,
@@ -633,6 +649,10 @@ juniper_services_print(netdissect_options *ndo,
ip_heuristic_guess (ndo, p, l2info.length);
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_services]"));
+ return l2info.header_len;
}
#endif
@@ -740,6 +760,7 @@ juniper_pppoe_atm_print(netdissect_options *ndo,
p+=l2info.header_len;
+ ND_TCHECK2(p[0], 2);
extracted_ethertype = EXTRACT_16BITS(p);
/* this DLT contains nothing but raw PPPoE frames,
* prepended with a type field*/
@@ -752,6 +773,10 @@ juniper_pppoe_atm_print(netdissect_options *ndo,
ND_PRINT((ndo, "unknown ethertype 0x%04x", extracted_ethertype));
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_pppoe_atm]"));
+ return l2info.header_len;
}
#endif
@@ -793,7 +818,7 @@ juniper_mlppp_print(netdissect_options *ndo,
mpls_print(ndo, p, l2info.length);
return l2info.header_len;
case JUNIPER_LSQ_L3_PROTO_ISO:
- isoclns_print(ndo, p, l2info.length, l2info.caplen);
+ isoclns_print(ndo, p, l2info.length);
return l2info.header_len;
default:
break;
@@ -848,7 +873,7 @@ juniper_mfr_print(netdissect_options *ndo,
mpls_print(ndo, p, l2info.length);
return l2info.header_len;
case JUNIPER_LSQ_L3_PROTO_ISO:
- isoclns_print(ndo, p, l2info.length, l2info.caplen);
+ isoclns_print(ndo, p, l2info.length);
return l2info.header_len;
default:
break;
@@ -861,13 +886,13 @@ juniper_mfr_print(netdissect_options *ndo,
ND_PRINT((ndo, "Bundle-ID %u, ", l2info.bundle));
switch (l2info.proto) {
case (LLCSAP_ISONS<<8 | LLCSAP_ISONS):
- isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
+ isoclns_print(ndo, p + 1, l2info.length - 1);
break;
case (LLC_UI<<8 | NLPID_Q933):
case (LLC_UI<<8 | NLPID_IP):
case (LLC_UI<<8 | NLPID_IP6):
/* pass IP{4,6} to the OSI layer for proper link-layer printing */
- isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1);
+ isoclns_print(ndo, p - 1, l2info.length + 1);
break;
default:
ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length));
@@ -896,13 +921,13 @@ juniper_mlfr_print(netdissect_options *ndo,
switch (l2info.proto) {
case (LLC_UI):
case (LLC_UI<<8):
- isoclns_print(ndo, p, l2info.length, l2info.caplen);
+ isoclns_print(ndo, p, l2info.length);
break;
case (LLC_UI<<8 | NLPID_Q933):
case (LLC_UI<<8 | NLPID_IP):
case (LLC_UI<<8 | NLPID_IP6):
/* pass IP{4,6} to the OSI layer for proper link-layer printing */
- isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1);
+ isoclns_print(ndo, p - 1, l2info.length + 1);
break;
default:
ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length));
@@ -940,6 +965,7 @@ juniper_atm1_print(netdissect_options *ndo,
return l2info.header_len;
}
+ ND_TCHECK2(p[0], 3);
if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
@@ -949,7 +975,7 @@ juniper_atm1_print(netdissect_options *ndo,
}
if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
- isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
+ isoclns_print(ndo, p + 1, l2info.length - 1);
/* FIXME check if frame was recognized */
return l2info.header_len;
}
@@ -958,6 +984,10 @@ juniper_atm1_print(netdissect_options *ndo,
return l2info.header_len;
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_atm1]"));
+ return l2info.header_len;
}
#endif
@@ -989,6 +1019,7 @@ juniper_atm2_print(netdissect_options *ndo,
return l2info.header_len;
}
+ ND_TCHECK2(p[0], 3);
if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
@@ -1004,7 +1035,7 @@ juniper_atm2_print(netdissect_options *ndo,
}
if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
- isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
+ isoclns_print(ndo, p + 1, l2info.length - 1);
/* FIXME check if frame was recognized */
return l2info.header_len;
}
@@ -1016,6 +1047,10 @@ juniper_atm2_print(netdissect_options *ndo,
return l2info.header_len;
return l2info.header_len;
+
+trunc:
+ ND_PRINT((ndo, "[|juniper_atm2]"));
+ return l2info.header_len;
}
#endif
@@ -1280,6 +1315,7 @@ juniper_parse_header(netdissect_options *ndo,
l2info->caplen -= l2info->header_len;
/* search through the cookie table and copy values matching for our PIC type */
+ ND_TCHECK(p[0]);
while (lp->s != NULL) {
if (lp->pictype == l2info->pictype) {
@@ -1331,6 +1367,7 @@ juniper_parse_header(netdissect_options *ndo,
if (ndo->ndo_eflag) ND_PRINT((ndo, ": ")); /* print demarc b/w L2/L3*/
+ ND_TCHECK_16BITS(p+l2info->cookie_len);
l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len);
break;
}
@@ -1360,6 +1397,7 @@ juniper_parse_header(netdissect_options *ndo,
case DLT_JUNIPER_MLFR:
switch (l2info->cookie_type) {
case LS_COOKIE_ID:
+ ND_TCHECK2(p[0], 2);
l2info->bundle = l2info->cookie[1];
l2info->proto = EXTRACT_16BITS(p);
l2info->header_len += 2;
@@ -1383,6 +1421,7 @@ juniper_parse_header(netdissect_options *ndo,
case DLT_JUNIPER_MFR:
switch (l2info->cookie_type) {
case LS_COOKIE_ID:
+ ND_TCHECK2(p[0], 2);
l2info->bundle = l2info->cookie[1];
l2info->proto = EXTRACT_16BITS(p);
l2info->header_len += 2;
diff --git a/contrib/tcpdump/print-l2tp.c b/contrib/tcpdump/print-l2tp.c
index 42ae391..d70d434 100644
--- a/contrib/tcpdump/print-l2tp.c
+++ b/contrib/tcpdump/print-l2tp.c
@@ -297,10 +297,14 @@ print_32bits_val(netdissect_options *ndo, const uint32_t *dat)
/* AVP-specific print out routines */
/***********************************/
static void
-l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat)
+l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
EXTRACT_16BITS(ptr))));
}
@@ -310,28 +314,53 @@ l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
- ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr))); ptr++; /* Result Code */
- if (length > 2) { /* Error Code (opt) */
- ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr))); ptr++;
+ /* Result Code */
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
}
- if (length > 4) { /* Error Message (opt) */
- ND_PRINT((ndo, " "));
- print_string(ndo, (const u_char *)ptr, length - 4);
+ ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr)));
+ ptr++;
+ length -= 2;
+
+ /* Error Code (opt) */
+ if (length == 0)
+ return;
+ if (length < 2) {
+ ND_PRINT((ndo, " AVP too short"));
+ return;
}
+ ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr)));
+ ptr++;
+ length -= 2;
+
+ /* Error Message (opt) */
+ if (length == 0)
+ return;
+ ND_PRINT((ndo, " "));
+ print_string(ndo, (const u_char *)ptr, length);
}
static void
-l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat)
+l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length)
{
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ND_PRINT((ndo, "%u.%u", (EXTRACT_16BITS(dat) >> 8),
(EXTRACT_16BITS(dat) & 0xff)));
}
static void
-l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat)
+l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) {
ND_PRINT((ndo, "A"));
}
@@ -341,10 +370,14 @@ l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat)
}
static void
-l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat)
+l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) {
ND_PRINT((ndo, "A"));
}
@@ -356,19 +389,29 @@ l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat)
static void
l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
+ if (length < 3) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
print_16bits_val(ndo, (const uint16_t *)dat);
ND_PRINT((ndo, ", %02x", dat[2]));
- if (length > 3) {
+ dat += 3;
+ length -= 3;
+ if (length != 0) {
ND_PRINT((ndo, " "));
- print_string(ndo, dat+3, length-3);
+ print_string(ndo, dat, length);
}
}
static void
-l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat)
+l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) {
ND_PRINT((ndo, "A"));
}
@@ -378,10 +421,14 @@ l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat)
}
static void
-l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat)
+l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
ND_PRINT((ndo, "A"));
}
@@ -397,67 +444,117 @@ l2tp_packet_proc_delay_print(netdissect_options *ndo)
}
static void
-l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat)
+l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str,
"AuthType-#%u", EXTRACT_16BITS(ptr))));
}
static void
-l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat)
+l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK));
}
static void
-l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat)
+l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
uint16_t val_h, val_l;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ptr++; /* skip "Reserved" */
+ length -= 2;
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l));
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l));
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l));
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l));
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l));
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l));
}
static void
-l2tp_accm_print(netdissect_options *ndo, const u_char *dat)
+l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
uint16_t val_h, val_l;
+ if (length < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
ptr++; /* skip "Reserved" */
+ length -= 2;
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
+ val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "send=%08x ", (val_h<<16) + val_l));
+ if (length < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
ND_PRINT((ndo, "recv=%08x ", (val_h<<16) + val_l));
@@ -468,14 +565,27 @@ l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int lengt
{
const uint16_t *ptr = (const uint16_t *)dat;
- ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(ptr))); ptr++; /* Disconnect Code */
- ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(ptr))); ptr++; /* Control Protocol Number */
+ if (length < 5) {
+ ND_PRINT((ndo, "AVP too short"));
+ return;
+ }
+ /* Disconnect Code */
+ ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(dat)));
+ dat += 2;
+ length -= 2;
+ /* Control Protocol Number */
+ ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(dat)));
+ dat += 2;
+ length -= 2;
+ /* Direction */
ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str,
- "Direction-#%u", *((const u_char *)ptr++))));
+ "Direction-#%u", EXTRACT_8BITS(ptr))));
+ ptr++;
+ length--;
- if (length > 5) {
+ if (length != 0) {
ND_PRINT((ndo, " "));
- print_string(ndo, (const u_char *)ptr, length-5);
+ print_string(ndo, (const u_char *)ptr, length);
}
}
@@ -508,7 +618,12 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
/* If it goes past the end of the remaining length of the captured
data, we'll give up. */
ND_TCHECK2(*ptr, len);
- /* After this point, no need to worry about truncation */
+
+ /*
+ * After this point, we don't need to check whether we go past
+ * the length of the captured data; however, we *do* need to
+ * check whether we go past the end of the AVP.
+ */
if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
ND_PRINT((ndo, "*"));
@@ -537,27 +652,35 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
} else {
switch (attr_type) {
case L2TP_AVP_MSGTYPE:
- l2tp_msgtype_print(ndo, (const u_char *)ptr);
+ l2tp_msgtype_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_RESULT_CODE:
l2tp_result_code_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PROTO_VER:
- l2tp_proto_ver_print(ndo, ptr);
+ l2tp_proto_ver_print(ndo, ptr, len-6);
break;
case L2TP_AVP_FRAMING_CAP:
- l2tp_framing_cap_print(ndo, (const u_char *)ptr);
+ l2tp_framing_cap_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_BEARER_CAP:
- l2tp_bearer_cap_print(ndo, (const u_char *)ptr);
+ l2tp_bearer_cap_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_TIE_BREAKER:
+ if (len-6 < 8) {
+ ND_PRINT((ndo, "AVP too short"));
+ break;
+ }
print_octets(ndo, (const u_char *)ptr, 8);
break;
case L2TP_AVP_FIRM_VER:
case L2TP_AVP_ASSND_TUN_ID:
case L2TP_AVP_RECV_WIN_SIZE:
case L2TP_AVP_ASSND_SESS_ID:
+ if (len-6 < 2) {
+ ND_PRINT((ndo, "AVP too short"));
+ break;
+ }
print_16bits_val(ndo, ptr);
break;
case L2TP_AVP_HOST_NAME:
@@ -582,6 +705,10 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
l2tp_q931_cc_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_CHALLENGE_RESP:
+ if (len-6 < 16) {
+ ND_PRINT((ndo, "AVP too short"));
+ break;
+ }
print_octets(ndo, (const u_char *)ptr, 16);
break;
case L2TP_AVP_CALL_SER_NUM:
@@ -590,28 +717,32 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
case L2TP_AVP_TX_CONN_SPEED:
case L2TP_AVP_PHY_CHANNEL_ID:
case L2TP_AVP_RX_CONN_SPEED:
+ if (len-6 < 4) {
+ ND_PRINT((ndo, "AVP too short"));
+ break;
+ }
print_32bits_val(ndo, (const uint32_t *)ptr);
break;
case L2TP_AVP_BEARER_TYPE:
- l2tp_bearer_type_print(ndo, (const u_char *)ptr);
+ l2tp_bearer_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_FRAMING_TYPE:
- l2tp_framing_type_print(ndo, (const u_char *)ptr);
+ l2tp_framing_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PACKET_PROC_DELAY:
l2tp_packet_proc_delay_print(ndo);
break;
case L2TP_AVP_PROXY_AUTH_TYPE:
- l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr);
+ l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PROXY_AUTH_ID:
- l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr);
+ l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_CALL_ERRORS:
- l2tp_call_errors_print(ndo, (const u_char *)ptr);
+ l2tp_call_errors_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_ACCM:
- l2tp_accm_print(ndo, (const u_char *)ptr);
+ l2tp_accm_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_SEQ_REQUIRED:
break; /* No Attribute Value */
diff --git a/contrib/tcpdump/print-ldp.c b/contrib/tcpdump/print-ldp.c
index 40c9d8c..2a3d1f9 100644
--- a/contrib/tcpdump/print-ldp.c
+++ b/contrib/tcpdump/print-ldp.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
* and Steinar Haug (sthaug@nethelp.no)
*/
diff --git a/contrib/tcpdump/print-llc.c b/contrib/tcpdump/print-llc.c
index 6bdf599..be8886a 100644
--- a/contrib/tcpdump/print-llc.c
+++ b/contrib/tcpdump/print-llc.c
@@ -324,7 +324,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
#endif
if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
&& control == LLC_UI) {
- isoclns_print(ndo, p, length, caplen);
+ isoclns_print(ndo, p, length);
return (hdrlen);
}
diff --git a/contrib/tcpdump/print-lldp.c b/contrib/tcpdump/print-lldp.c
index 730b36f..e87b16b 100644
--- a/contrib/tcpdump/print-lldp.c
+++ b/contrib/tcpdump/print-lldp.c
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
* IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com>
* DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net>
*/
@@ -590,6 +590,7 @@ static const struct tok lldp_evb_mode_values[]={
{ LLDP_EVB_MODE_EVB_BRIDGE, "EVB Bridge"},
{ LLDP_EVB_MODE_EVB_STATION, "EVB Staion"},
{ LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"},
+ { 0, NULL},
};
#define NO_OF_BITS 8
@@ -650,7 +651,7 @@ lldp_private_8021_print(netdissect_options *ndo,
int subtype, hexdump = FALSE;
u_int sublen;
u_int tval;
- uint8_t i;
+ u_int i;
if (tlv_len < 4) {
return hexdump;
@@ -786,9 +787,9 @@ lldp_private_8021_print(netdissect_options *ndo,
ND_PRINT((ndo, "\n\t Application Priority Table"));
while(i<sublen) {
tval=*(tptr+i+5);
- ND_PRINT((ndo, "\n\t Priority: %d, RES: %d, Sel: %d",
- tval >> 5, (tval >> 3) & 0x03, (tval & 0x07)));
- ND_PRINT((ndo, "Protocol ID: %d", EXTRACT_16BITS(tptr + i + 5)));
+ ND_PRINT((ndo, "\n\t Priority: %u, RES: %u, Sel: %u, Protocol ID: %u",
+ tval >> 5, (tval >> 3) & 0x03, (tval & 0x07),
+ EXTRACT_16BITS(tptr + i + 5)));
i=i+3;
}
break;
@@ -897,6 +898,9 @@ lldp_private_8023_print(netdissect_options *ndo,
break;
case LLDP_PRIVATE_8023_SUBTYPE_MTU:
+ if (tlv_len < 6) {
+ return hexdump;
+ }
ND_PRINT((ndo, "\n\t MTU size %u", EXTRACT_16BITS(tptr + 4)));
break;
@@ -926,7 +930,7 @@ lldp_extract_latlon(const u_char *tptr)
* (right now there is only one)
*/
-
+
static int
lldp_private_iana_print(netdissect_options *ndo,
const u_char *tptr, u_int tlv_len)
@@ -950,12 +954,12 @@ lldp_private_iana_print(netdissect_options *ndo,
default:
hexdump=TRUE;
}
-
+
return hexdump;
}
-
+
/*
* Print private TIA extensions.
*/
@@ -1400,7 +1404,7 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo,
if (tlen) {
oid_len = *tptr;
- if (tlen < oid_len) {
+ if (tlen < 1U + oid_len) {
return 0;
}
if (oid_len) {
diff --git a/contrib/tcpdump/print-lmp.c b/contrib/tcpdump/print-lmp.c
index 1c7710c..916a1d6 100644
--- a/contrib/tcpdump/print-lmp.c
+++ b/contrib/tcpdump/print-lmp.c
@@ -10,14 +10,15 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
- * Support for LMP service discovery extensions (defined by UNI 1.0) added
- * by Manu Pathak (mapathak@cisco.com), May 2005
+ * Original code by Hannes Gredler (hannes@gredler.at)
+ * Support for LMP service discovery extensions (defined by OIF UNI 1.0)
+ * added by Manu Pathak (mapathak@cisco.com), May 2005
*/
/* \summary: Link Management Protocol (LMP) printer */
/* specification: RFC 4204 */
+/* OIF UNI 1.0: http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -353,6 +354,73 @@ static const struct tok lmp_ctype_values[] = {
{ 0, NULL}
};
+static int
+lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
+ int total_subobj_len, int offset)
+{
+ int hexdump = FALSE;
+ int subobj_type, subobj_len;
+
+ union { /* int to float conversion buffer */
+ float f;
+ uint32_t i;
+ } bw;
+
+ while (total_subobj_len > 0 && hexdump == FALSE ) {
+ subobj_type = EXTRACT_8BITS(obj_tptr+offset);
+ subobj_len = EXTRACT_8BITS(obj_tptr+offset+1);
+ ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u",
+ tok2str(lmp_data_link_subobj,
+ "Unknown",
+ subobj_type),
+ subobj_type,
+ subobj_len));
+ if (subobj_len < 4) {
+ ND_PRINT((ndo, " (too short)"));
+ break;
+ }
+ if ((subobj_len % 4) != 0) {
+ ND_PRINT((ndo, " (not a multiple of 4)"));
+ break;
+ }
+ if (total_subobj_len < subobj_len) {
+ ND_PRINT((ndo, " (goes past the end of the object)"));
+ break;
+ }
+ switch(subobj_type) {
+ case INT_SWITCHING_TYPE_SUBOBJ:
+ ND_PRINT((ndo, "\n\t Switching Type: %s (%u)",
+ tok2str(gmpls_switch_cap_values,
+ "Unknown",
+ EXTRACT_8BITS(obj_tptr+offset+2)),
+ EXTRACT_8BITS(obj_tptr+offset+2)));
+ ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)",
+ tok2str(gmpls_encoding_values,
+ "Unknown",
+ EXTRACT_8BITS(obj_tptr+offset+3)),
+ EXTRACT_8BITS(obj_tptr+offset+3)));
+ bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
+ ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps",
+ bw.f*8/1000000));
+ bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
+ ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps",
+ bw.f*8/1000000));
+ break;
+ case WAVELENGTH_SUBOBJ:
+ ND_PRINT((ndo, "\n\t Wavelength: %u",
+ EXTRACT_32BITS(obj_tptr+offset+4)));
+ break;
+ default:
+ /* Any Unknown Subobject ==> Exit loop */
+ hexdump=TRUE;
+ break;
+ }
+ total_subobj_len-=subobj_len;
+ offset+=subobj_len;
+ }
+ return (hexdump);
+}
+
void
lmp_print(netdissect_options *ndo,
register const u_char *pptr, register u_int len)
@@ -360,10 +428,10 @@ lmp_print(netdissect_options *ndo,
const struct lmp_common_header *lmp_com_header;
const struct lmp_object_header *lmp_obj_header;
const u_char *tptr,*obj_tptr;
- int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
+ u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
int hexdump;
- int offset,subobj_type,subobj_len,total_subobj_len;
- int link_type;
+ u_int offset;
+ u_int link_type;
union { /* int to float conversion buffer */
float f;
@@ -401,6 +469,14 @@ lmp_print(netdissect_options *ndo,
tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type),
bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags),
tlen));
+ if (tlen < sizeof(const struct lmp_common_header)) {
+ ND_PRINT((ndo, " (too short)"));
+ return;
+ }
+ if (tlen > len) {
+ ND_PRINT((ndo, " (too long)"));
+ tlen = len;
+ }
tptr+=sizeof(const struct lmp_common_header);
tlen-=sizeof(const struct lmp_common_header);
@@ -413,9 +489,6 @@ lmp_print(netdissect_options *ndo,
lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length);
lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f;
- if(lmp_obj_len % 4 || lmp_obj_len < 4)
- return;
-
ND_PRINT((ndo, "\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
tok2str(lmp_obj_values,
"Unknown",
@@ -428,6 +501,15 @@ lmp_print(netdissect_options *ndo,
(lmp_obj_header->ctype)&0x80 ? "" : "non-",
lmp_obj_len));
+ if (lmp_obj_len < 4) {
+ ND_PRINT((ndo, " (too short)"));
+ return;
+ }
+ if ((lmp_obj_len % 4) != 0) {
+ ND_PRINT((ndo, " (not a multiple of 4)"));
+ return;
+ }
+
obj_tptr=tptr+sizeof(struct lmp_object_header);
obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);
@@ -441,6 +523,10 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_LOC:
case LMP_CTYPE_RMT:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Control Channel ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@@ -456,18 +542,30 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4_LOC:
case LMP_CTYPE_IPV4_RMT:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t IPv4 Link ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_IPV6_LOC:
case LMP_CTYPE_IPV6_RMT:
+ if (obj_tlen != 16) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t IPv6 Link ID: %s (0x%08x)",
ip6addr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_UNMD_LOC:
case LMP_CTYPE_UNMD_RMT:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Link ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@@ -480,11 +578,19 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_MESSAGE_ID:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Message ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_2:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Message ID Ack: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@@ -498,6 +604,10 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_LOC:
case LMP_CTYPE_RMT:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Node ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@@ -511,6 +621,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CONFIG:
switch(lmp_obj_ctype) {
case LMP_CTYPE_HELLO_CONFIG:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Hello Interval: %u\n\t Hello Dead Interval: %u",
EXTRACT_16BITS(obj_tptr),
EXTRACT_16BITS(obj_tptr+2)));
@@ -524,6 +638,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_HELLO:
switch(lmp_obj_ctype) {
case LMP_CTYPE_HELLO:
+ if (obj_tlen != 8) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Tx Seq: %u, Rx Seq: %u",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr+4)));
@@ -535,13 +653,17 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_OBJ_TE_LINK:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_IPV4:
+ if (obj_tlen != 12) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Flags: [%s]",
- bittok2str(lmp_obj_te_link_flag_values,
+ bittok2str(lmp_obj_te_link_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr)>>8)));
+ EXTRACT_8BITS(obj_tptr))));
- switch(lmp_obj_ctype) {
- case LMP_CTYPE_IPV4:
ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)"
"\n\t Remote Link-ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+4),
@@ -551,21 +673,57 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_IPV6:
+ if (obj_tlen != 36) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_te_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
+
+ ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)"
+ "\n\t Remote Link-ID: %s (0x%08x)",
+ ip6addr_string(ndo, obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ ip6addr_string(ndo, obj_tptr+20),
+ EXTRACT_32BITS(obj_tptr+20)));
+ break;
+
case LMP_CTYPE_UNMD:
+ if (obj_tlen != 12) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_te_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
+
+ ND_PRINT((ndo, "\n\t Local Link-ID: %u (0x%08x)"
+ "\n\t Remote Link-ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+8),
+ EXTRACT_32BITS(obj_tptr+8)));
+ break;
+
default:
hexdump=TRUE;
}
break;
case LMP_OBJ_DATA_LINK:
- ND_PRINT((ndo, "\n\t Flags: [%s]",
- bittok2str(lmp_obj_data_link_flag_values,
- "none",
- EXTRACT_16BITS(obj_tptr)>>8)));
-
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
- case LMP_CTYPE_UNMD:
+ if (obj_tlen < 12) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_data_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)"
"\n\t Remote Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+4),
@@ -573,51 +731,50 @@ lmp_print(netdissect_options *ndo,
ipaddr_string(ndo, obj_tptr+8),
EXTRACT_32BITS(obj_tptr+8)));
- total_subobj_len = lmp_obj_len - 16;
- offset = 12;
- while (total_subobj_len > 0 && hexdump == FALSE ) {
- subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8;
- subobj_len = EXTRACT_16BITS(obj_tptr+offset)&0x00FF;
- ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u",
- tok2str(lmp_data_link_subobj,
- "Unknown",
- subobj_type),
- subobj_type,
- subobj_len));
- switch(subobj_type) {
- case INT_SWITCHING_TYPE_SUBOBJ:
- ND_PRINT((ndo, "\n\t Switching Type: %s (%u)",
- tok2str(gmpls_switch_cap_values,
- "Unknown",
- EXTRACT_16BITS(obj_tptr+offset+2)>>8),
- EXTRACT_16BITS(obj_tptr+offset+2)>>8));
- ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)",
- tok2str(gmpls_encoding_values,
- "Unknown",
- EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF),
- EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF));
- bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
- ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps",
- bw.f*8/1000000));
- bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
- ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps",
- bw.f*8/1000000));
- break;
- case WAVELENGTH_SUBOBJ:
- ND_PRINT((ndo, "\n\t Wavelength: %u",
- EXTRACT_32BITS(obj_tptr+offset+4)));
- break;
- default:
- /* Any Unknown Subobject ==> Exit loop */
- hexdump=TRUE;
- break;
- }
- total_subobj_len-=subobj_len;
- offset+=subobj_len;
- }
-
+ if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
+ hexdump=TRUE;
break;
+
case LMP_CTYPE_IPV6:
+ if (obj_tlen < 36) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_data_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
+ ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)"
+ "\n\t Remote Interface ID: %s (0x%08x)",
+ ip6addr_string(ndo, obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ ip6addr_string(ndo, obj_tptr+20),
+ EXTRACT_32BITS(obj_tptr+20)));
+
+ if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36))
+ hexdump=TRUE;
+ break;
+
+ case LMP_CTYPE_UNMD:
+ if (obj_tlen < 12) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
+ ND_PRINT((ndo, "\n\t Flags: [%s]",
+ bittok2str(lmp_obj_data_link_flag_values,
+ "none",
+ EXTRACT_8BITS(obj_tptr))));
+ ND_PRINT((ndo, "\n\t Local Interface ID: %u (0x%08x)"
+ "\n\t Remote Interface ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+8),
+ EXTRACT_32BITS(obj_tptr+8)));
+
+ if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
+ hexdump=TRUE;
+ break;
+
default:
hexdump=TRUE;
}
@@ -626,6 +783,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_BEGIN:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
+ if (obj_tlen != 20) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Flags: %s",
bittok2str(lmp_obj_begin_verify_flag_values,
"none",
@@ -654,6 +815,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_BEGIN_ACK:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Verify Dead Interval: %u"
"\n\t Verify Transport Response: %u",
EXTRACT_16BITS(obj_tptr),
@@ -668,6 +833,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_ID:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Verify ID: %u",
EXTRACT_32BITS(obj_tptr)));
break;
@@ -680,19 +849,20 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CHANNEL_STATUS:
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
- case LMP_CTYPE_UNMD:
offset = 0;
/* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
- while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
+ while (offset+8 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
- ND_PRINT((ndo, "\n\t\t Active: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
+ ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
"Allocated" : "Non-allocated",
(EXTRACT_32BITS(obj_tptr+offset+4)>>31)));
- ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
+ ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
"Transmit" : "Receive",
(EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1));
@@ -704,7 +874,61 @@ lmp_print(netdissect_options *ndo,
offset+=8;
}
break;
+
case LMP_CTYPE_IPV6:
+ offset = 0;
+ /* Decode pairs: <Interface_ID (16 bytes), Channel_status (4 bytes)> */
+ while (offset+20 <= obj_tlen) {
+ ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
+ ip6addr_string(ndo, obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset)));
+
+ ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+16)>>31) ?
+ "Allocated" : "Non-allocated",
+ (EXTRACT_32BITS(obj_tptr+offset+16)>>31)));
+
+ ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1 ?
+ "Transmit" : "Receive",
+ (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1));
+
+ ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)",
+ tok2str(lmp_obj_channel_status_values,
+ "Unknown",
+ EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF),
+ EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF));
+ offset+=20;
+ }
+ break;
+
+ case LMP_CTYPE_UNMD:
+ offset = 0;
+ /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
+ while (offset+8 <= obj_tlen) {
+ ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset)));
+
+ ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
+ "Allocated" : "Non-allocated",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>31)));
+
+ ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
+ "Transmit" : "Receive",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1));
+
+ ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)",
+ tok2str(lmp_obj_channel_status_values,
+ "Unknown",
+ EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF),
+ EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF));
+ offset+=8;
+ }
+ break;
+
default:
hexdump=TRUE;
}
@@ -713,16 +937,35 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CHANNEL_STATUS_REQ:
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
- case LMP_CTYPE_UNMD:
offset = 0;
- while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
+ while (offset+4 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
offset+=4;
}
break;
+
case LMP_CTYPE_IPV6:
+ offset = 0;
+ while (offset+16 <= obj_tlen) {
+ ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
+ ip6addr_string(ndo, obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset)));
+ offset+=16;
+ }
+ break;
+
+ case LMP_CTYPE_UNMD:
+ offset = 0;
+ while (offset+4 <= obj_tlen) {
+ ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset)));
+ offset+=4;
+ }
+ break;
+
default:
hexdump=TRUE;
}
@@ -731,6 +974,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_ERROR_CODE:
switch(lmp_obj_ctype) {
case LMP_CTYPE_BEGIN_VERIFY_ERROR:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Error Code: %s",
bittok2str(lmp_obj_begin_verify_error_values,
"none",
@@ -738,6 +985,10 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_LINK_SUMMARY_ERROR:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Error Code: %s",
bittok2str(lmp_obj_link_summary_error_values,
"none",
@@ -751,51 +1002,60 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_SERVICE_CONFIG:
switch (lmp_obj_ctype) {
case LMP_CTYPE_SERVICE_CONFIG_SP:
-
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Flags: %s",
bittok2str(lmp_obj_service_config_sp_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr)>>8)));
+ EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t UNI Version: %u",
- EXTRACT_16BITS(obj_tptr) & 0x00FF));
+ EXTRACT_8BITS(obj_tptr+1)));
break;
case LMP_CTYPE_SERVICE_CONFIG_CPSA:
+ if (obj_tlen != 16) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
- link_type = EXTRACT_16BITS(obj_tptr)>>8;
+ link_type = EXTRACT_8BITS(obj_tptr);
ND_PRINT((ndo, "\n\t Link Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_link_type_values,
"Unknown", link_type),
link_type));
- if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) {
+ switch (link_type) {
+ case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH:
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
"Unknown",
- EXTRACT_16BITS(obj_tptr) & 0x00FF),
- EXTRACT_16BITS(obj_tptr) & 0x00FF));
- }
+ EXTRACT_8BITS(obj_tptr+1)),
+ EXTRACT_8BITS(obj_tptr+1)));
+ break;
- if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) {
+ case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET:
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
"Unknown",
- EXTRACT_16BITS(obj_tptr) & 0x00FF),
- EXTRACT_16BITS(obj_tptr) & 0x00FF));
+ EXTRACT_8BITS(obj_tptr+1)),
+ EXTRACT_8BITS(obj_tptr+1)));
+ break;
}
ND_PRINT((ndo, "\n\t Transparency: %s",
bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr+2)>>8)));
+ EXTRACT_8BITS(obj_tptr+2))));
ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s",
bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF)));
+ EXTRACT_8BITS(obj_tptr+3))));
ND_PRINT((ndo, "\n\t Minimum NCC: %u",
EXTRACT_16BITS(obj_tptr+4)));
@@ -816,6 +1076,10 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM:
+ if (obj_tlen != 8) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Transparency Flags: %s",
bittok2str(
@@ -827,17 +1091,21 @@ lmp_print(netdissect_options *ndo,
bittok2str(
lmp_obj_service_config_nsa_tcm_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr+6) & 0x00FF)));
+ EXTRACT_8BITS(obj_tptr+7))));
break;
case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY:
+ if (obj_tlen != 4) {
+ ND_PRINT((ndo, " (not correct for object)"));
+ break;
+ }
ND_PRINT((ndo, "\n\t Diversity: Flags: %s",
bittok2str(
lmp_obj_service_config_nsa_network_diversity_flag_values,
"none",
- EXTRACT_16BITS(obj_tptr+2) & 0x00FF)));
+ EXTRACT_8BITS(obj_tptr+3))));
break;
default:
diff --git a/contrib/tcpdump/print-lspping.c b/contrib/tcpdump/print-lspping.c
index 4d260db..274cc68 100644
--- a/contrib/tcpdump/print-lspping.c
+++ b/contrib/tcpdump/print-lspping.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: MPLS LSP PING printer */
@@ -104,6 +104,7 @@ static const struct tok lspping_return_code_values[] = {
{ 11, "No label entry at stack-depth"},
{ 12, "Protocol not associated with interface at FEC stack depth"},
{ 13, "Premature termination of ping due to label stack shrinking to a single label"},
+ { 0, NULL},
};
diff --git a/contrib/tcpdump/print-m3ua.c b/contrib/tcpdump/print-m3ua.c
index 1f974b2..71a585f 100644
--- a/contrib/tcpdump/print-m3ua.c
+++ b/contrib/tcpdump/print-m3ua.c
@@ -67,7 +67,7 @@ static const struct tok MessageClasses[] = {
{ M3UA_MSGC_SSNM, "SS7" },
{ M3UA_MSGC_ASPSM, "ASP" },
{ M3UA_MSGC_ASPTM, "ASP" },
- { M3UA_MSGC_RKM, "Routing Key Managment" },
+ { M3UA_MSGC_RKM, "Routing Key Management"},
{ 0, NULL }
};
diff --git a/contrib/tcpdump/print-mobility.c b/contrib/tcpdump/print-mobility.c
index 71cc85b..feb4c98 100644
--- a/contrib/tcpdump/print-mobility.c
+++ b/contrib/tcpdump/print-mobility.c
@@ -28,6 +28,7 @@
*/
/* \summary: IPv6 mobility printer */
+/* RFC 3775 */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -35,11 +36,12 @@
#include <netdissect-stdinc.h>
-#include "ip6.h"
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
+#include "ip6.h"
+
static const char tstr[] = "[|MOBILITY]";
/* Mobility header */
@@ -148,6 +150,7 @@ mobility_opt_print(netdissect_options *ndo,
goto trunc;
}
/* units of 4 secs */
+ ND_TCHECK_16BITS(&bp[i+2]);
ND_PRINT((ndo, "(refresh: %u)",
EXTRACT_16BITS(&bp[i+2]) << 2));
break;
@@ -156,6 +159,7 @@ mobility_opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "(altcoa: trunc)"));
goto trunc;
}
+ ND_TCHECK_128BITS(&bp[i+2]);
ND_PRINT((ndo, "(alt-CoA: %s)", ip6addr_string(ndo, &bp[i+2])));
break;
case IP6MOPT_NONCEID:
@@ -163,6 +167,8 @@ mobility_opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "(ni: trunc)"));
goto trunc;
}
+ ND_TCHECK_16BITS(&bp[i+2]);
+ ND_TCHECK_16BITS(&bp[i+4]);
ND_PRINT((ndo, "(ni: ho=0x%04x co=0x%04x)",
EXTRACT_16BITS(&bp[i+2]),
EXTRACT_16BITS(&bp[i+4])));
@@ -241,7 +247,7 @@ mobility_print(netdissect_options *ndo,
case IP6M_CAREOF_TEST_INIT:
hlen = IP6M_MINLEN;
if (ndo->ndo_vflag) {
- ND_TCHECK2(*mh, hlen + 8);
+ ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Init Cookie=%08x:%08x",
type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@@ -255,7 +261,7 @@ mobility_print(netdissect_options *ndo,
ND_PRINT((ndo, " nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0])));
hlen = IP6M_MINLEN;
if (ndo->ndo_vflag) {
- ND_TCHECK2(*mh, hlen + 8);
+ ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Init Cookie=%08x:%08x",
type == IP6M_HOME_TEST ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@@ -263,7 +269,7 @@ mobility_print(netdissect_options *ndo,
}
hlen += 8;
if (ndo->ndo_vflag) {
- ND_TCHECK2(*mh, hlen + 8);
+ ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Keygen Token=%08x:%08x",
type == IP6M_HOME_TEST ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@@ -275,22 +281,23 @@ mobility_print(netdissect_options *ndo,
ND_TCHECK(mh->ip6m_data16[0]);
ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&mh->ip6m_data16[0])));
hlen = IP6M_MINLEN;
- ND_TCHECK2(*mh, hlen + 1);
- if (bp[hlen] & 0xf0)
+ ND_TCHECK_16BITS(&bp[hlen]);
+ if (bp[hlen] & 0xf0) {
ND_PRINT((ndo, " "));
- if (bp[hlen] & 0x80)
- ND_PRINT((ndo, "A"));
- if (bp[hlen] & 0x40)
- ND_PRINT((ndo, "H"));
- if (bp[hlen] & 0x20)
- ND_PRINT((ndo, "L"));
- if (bp[hlen] & 0x10)
- ND_PRINT((ndo, "K"));
+ if (bp[hlen] & 0x80)
+ ND_PRINT((ndo, "A"));
+ if (bp[hlen] & 0x40)
+ ND_PRINT((ndo, "H"));
+ if (bp[hlen] & 0x20)
+ ND_PRINT((ndo, "L"));
+ if (bp[hlen] & 0x10)
+ ND_PRINT((ndo, "K"));
+ }
/* Reserved (4bits) */
hlen += 1;
/* Reserved (8bits) */
hlen += 1;
- ND_TCHECK2(*mh, hlen + 2);
+ ND_TCHECK_16BITS(&bp[hlen]);
/* units of 4 secs */
ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2));
hlen += 2;
@@ -298,14 +305,15 @@ mobility_print(netdissect_options *ndo,
case IP6M_BINDING_ACK:
ND_TCHECK(mh->ip6m_data8[0]);
ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0]));
+ ND_TCHECK(mh->ip6m_data8[1]);
if (mh->ip6m_data8[1] & 0x80)
ND_PRINT((ndo, " K"));
/* Reserved (7bits) */
hlen = IP6M_MINLEN;
- ND_TCHECK2(*mh, hlen + 2);
+ ND_TCHECK_16BITS(&bp[hlen]);
ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&bp[hlen])));
hlen += 2;
- ND_TCHECK2(*mh, hlen + 2);
+ ND_TCHECK_16BITS(&bp[hlen]);
/* units of 4 secs */
ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2));
hlen += 2;
@@ -315,7 +323,7 @@ mobility_print(netdissect_options *ndo,
ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0]));
/* Reserved */
hlen = IP6M_MINLEN;
- ND_TCHECK2(*mh, hlen + 16);
+ ND_TCHECK2(bp[hlen], 16);
ND_PRINT((ndo, " homeaddr %s", ip6addr_string(ndo, &bp[hlen])));
hlen += 16;
break;
@@ -332,5 +340,5 @@ mobility_print(netdissect_options *ndo,
trunc:
ND_PRINT((ndo, "%s", tstr));
- return(mhlen);
+ return(-1);
}
diff --git a/contrib/tcpdump/print-mpcp.c b/contrib/tcpdump/print-mpcp.c
index 1b9a5d7..3e022ad 100644
--- a/contrib/tcpdump/print-mpcp.c
+++ b/contrib/tcpdump/print-mpcp.c
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE 802.3ah Multi-Point Control Protocol (MPCP) printer */
diff --git a/contrib/tcpdump/print-mpls.c b/contrib/tcpdump/print-mpls.c
index ba42233..5c26e4f 100644
--- a/contrib/tcpdump/print-mpls.c
+++ b/contrib/tcpdump/print-mpls.c
@@ -201,7 +201,7 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length)
break;
case PT_OSI:
- isoclns_print(ndo, p, length, length);
+ isoclns_print(ndo, p, length);
break;
default:
diff --git a/contrib/tcpdump/print-mptcp.c b/contrib/tcpdump/print-mptcp.c
index e757ea4..392791e 100644
--- a/contrib/tcpdump/print-mptcp.c
+++ b/contrib/tcpdump/print-mptcp.c
@@ -178,7 +178,7 @@ mp_capable_print(netdissect_options *ndo,
{
const struct mp_capable *mpc = (const struct mp_capable *) opt;
- if (!(opt_len == 12 && flags & TH_SYN) &&
+ if (!(opt_len == 12 && (flags & TH_SYN)) &&
!(opt_len == 20 && (flags & (TH_SYN | TH_ACK)) == TH_ACK))
return 0;
@@ -202,9 +202,9 @@ mp_join_print(netdissect_options *ndo,
{
const struct mp_join *mpj = (const struct mp_join *) opt;
- if (!(opt_len == 12 && flags & TH_SYN) &&
+ if (!(opt_len == 12 && (flags & TH_SYN)) &&
!(opt_len == 16 && (flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) &&
- !(opt_len == 24 && flags & TH_ACK))
+ !(opt_len == 24 && (flags & TH_ACK)))
return 0;
if (opt_len != 24) {
@@ -236,76 +236,92 @@ mp_join_print(netdissect_options *ndo,
return 1;
}
-static u_int mp_dss_len(const struct mp_dss *m, int csum)
-{
- u_int len;
-
- len = 4;
- if (m->flags & MP_DSS_A) {
- /* Ack present - 4 or 8 octets */
- len += (m->flags & MP_DSS_a) ? 8 : 4;
- }
- if (m->flags & MP_DSS_M) {
- /*
- * Data Sequence Number (DSN), Subflow Sequence Number (SSN),
- * Data-Level Length present, and Checksum possibly present.
- * All but the Checksum are 10 bytes if the m flag is
- * clear (4-byte DSN) and 14 bytes if the m flag is set
- * (8-byte DSN).
- */
- len += (m->flags & MP_DSS_m) ? 14 : 10;
-
- /*
- * The Checksum is present only if negotiated.
- */
- if (csum)
- len += 2;
- }
- return len;
-}
-
static int
mp_dss_print(netdissect_options *ndo,
const u_char *opt, u_int opt_len, u_char flags)
{
const struct mp_dss *mdss = (const struct mp_dss *) opt;
- if ((opt_len != mp_dss_len(mdss, 1) &&
- opt_len != mp_dss_len(mdss, 0)) || flags & TH_SYN)
+ /* We need the flags, at a minimum. */
+ if (opt_len < 4)
+ return 0;
+
+ if (flags & TH_SYN)
return 0;
if (mdss->flags & MP_DSS_F)
ND_PRINT((ndo, " fin"));
opt += 4;
+ opt_len -= 4;
if (mdss->flags & MP_DSS_A) {
+ /* Ack present */
ND_PRINT((ndo, " ack "));
+ /*
+ * If the a flag is set, we have an 8-byte ack; if it's
+ * clear, we have a 4-byte ack.
+ */
if (mdss->flags & MP_DSS_a) {
+ if (opt_len < 8)
+ return 0;
ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt)));
opt += 8;
+ opt_len -= 8;
} else {
+ if (opt_len < 4)
+ return 0;
ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt)));
opt += 4;
+ opt_len -= 4;
}
}
if (mdss->flags & MP_DSS_M) {
+ /*
+ * Data Sequence Number (DSN), Subflow Sequence Number (SSN),
+ * Data-Level Length present, and Checksum possibly present.
+ */
ND_PRINT((ndo, " seq "));
+ /*
+ * If the m flag is set, we have an 8-byte NDS; if it's clear,
+ * we have a 4-byte DSN.
+ */
if (mdss->flags & MP_DSS_m) {
+ if (opt_len < 8)
+ return 0;
ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt)));
opt += 8;
+ opt_len -= 8;
} else {
+ if (opt_len < 4)
+ return 0;
ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt)));
opt += 4;
+ opt_len -= 4;
}
+ if (opt_len < 4)
+ return 0;
ND_PRINT((ndo, " subseq %u", EXTRACT_32BITS(opt)));
opt += 4;
+ opt_len -= 4;
+ if (opt_len < 2)
+ return 0;
ND_PRINT((ndo, " len %u", EXTRACT_16BITS(opt)));
opt += 2;
+ opt_len -= 2;
- if (opt_len == mp_dss_len(mdss, 1))
+ /*
+ * The Checksum is present only if negotiated.
+ * If there are at least 2 bytes left, process the next 2
+ * bytes as the Checksum.
+ */
+ if (opt_len >= 2) {
ND_PRINT((ndo, " csum 0x%x", EXTRACT_16BITS(opt)));
+ opt_len -= 2;
+ }
}
+ if (opt_len != 0)
+ return 0;
return 1;
}
diff --git a/contrib/tcpdump/print-nfs.c b/contrib/tcpdump/print-nfs.c
index a71e068..e752a59 100644
--- a/contrib/tcpdump/print-nfs.c
+++ b/contrib/tcpdump/print-nfs.c
@@ -628,17 +628,15 @@ nfsreq_print_noaddr(netdissect_options *ndo,
if ((dp = parsereq(ndo, rp, length)) != NULL &&
(dp = parsefh(ndo, dp, v3)) != NULL) {
if (v3) {
- ND_TCHECK(dp[2]);
+ ND_TCHECK(dp[4]);
ND_PRINT((ndo, " %u (%u) bytes @ %" PRIu64,
EXTRACT_32BITS(&dp[4]),
EXTRACT_32BITS(&dp[2]),
EXTRACT_64BITS(&dp[0])));
if (ndo->ndo_vflag) {
- dp += 3;
- ND_TCHECK(dp[0]);
ND_PRINT((ndo, " <%s>",
tok2str(nfsv3_writemodes,
- NULL, EXTRACT_32BITS(dp))));
+ NULL, EXTRACT_32BITS(&dp[3]))));
}
} else {
ND_TCHECK(dp[3]);
@@ -809,11 +807,15 @@ nfs_printfh(netdissect_options *ndo,
if (sfsname) {
/* file system ID is ASCII, not numeric, for this server OS */
- static char temp[NFSX_V3FHMAX+1];
+ char temp[NFSX_V3FHMAX+1];
+ u_int stringlen;
/* Make sure string is null-terminated */
- strncpy(temp, sfsname, NFSX_V3FHMAX);
- temp[sizeof(temp) - 1] = '\0';
+ stringlen = len;
+ if (stringlen > NFSX_V3FHMAX)
+ stringlen = NFSX_V3FHMAX;
+ strncpy(temp, sfsname, stringlen);
+ temp[stringlen] = '\0';
/* Remove trailing spaces */
spacep = strchr(temp, ' ');
if (spacep)
@@ -868,7 +870,7 @@ xid_map_enter(netdissect_options *ndo,
const struct ip6_hdr *ip6 = NULL;
struct xid_map_entry *xmep;
- if (!ND_TTEST(rp->rm_call.cb_vers))
+ if (!ND_TTEST(rp->rm_call.cb_proc))
return (0);
switch (IP_V((const struct ip *)bp)) {
case 4:
@@ -1002,11 +1004,11 @@ parserep(netdissect_options *ndo,
* skip past the ar_verf credentials.
*/
dp += (len + (2*sizeof(uint32_t) + 3)) / sizeof(uint32_t);
- ND_TCHECK2(dp[0], 0);
/*
* now we can check the ar_stat field
*/
+ ND_TCHECK(dp[0]);
astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp);
if (astat != SUNRPC_SUCCESS) {
ND_PRINT((ndo, " %s", tok2str(sunrpc_str, "ar_stat %d", astat)));
@@ -1243,6 +1245,7 @@ static const uint32_t *
parse_wcc_attr(netdissect_options *ndo,
const uint32_t *dp)
{
+ /* Our caller has already checked this */
ND_PRINT((ndo, " sz %" PRIu64, EXTRACT_64BITS(&dp[0])));
ND_PRINT((ndo, " mtime %u.%06u ctime %u.%06u",
EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]),
@@ -1511,8 +1514,10 @@ interp_reply(netdissect_options *ndo,
ND_PRINT((ndo, " attr:"));
if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)))
break;
- if (!er)
+ if (!er) {
+ ND_TCHECK(dp[0]);
ND_PRINT((ndo, " c %04x", EXTRACT_32BITS(&dp[0])));
+ }
return;
case NFSPROC_READLINK:
diff --git a/contrib/tcpdump/print-null.c b/contrib/tcpdump/print-null.c
index 14df5fd..59b691c 100644
--- a/contrib/tcpdump/print-null.c
+++ b/contrib/tcpdump/print-null.c
@@ -117,7 +117,7 @@ null_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
break;
case BSD_AFNUM_ISO:
- isoclns_print(ndo, p, length, caplen);
+ isoclns_print(ndo, p, length);
break;
case BSD_AFNUM_APPLETALK:
diff --git a/contrib/tcpdump/print-olsr.c b/contrib/tcpdump/print-olsr.c
index e095ef7..e67988d 100644
--- a/contrib/tcpdump/print-olsr.c
+++ b/contrib/tcpdump/print-olsr.c
@@ -13,7 +13,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler <hannes@juniper.net>
+ * Original code by Hannes Gredler <hannes@gredler.at>
* IPv6 additions by Florian Forster <octo at verplant.org>
*/
@@ -359,10 +359,9 @@ olsr_print(netdissect_options *ndo,
} msgptr;
int msg_len_valid = 0;
- ND_TCHECK2(*tptr, sizeof(struct olsr_msg4));
-
if (is_ipv6)
{
+ ND_TCHECK2(*tptr, sizeof(struct olsr_msg6));
msgptr.v6 = (const struct olsr_msg6 *) tptr;
msg_type = msgptr.v6->msg_type;
msg_len = EXTRACT_16BITS(msgptr.v6->msg_len);
@@ -393,6 +392,7 @@ olsr_print(netdissect_options *ndo,
}
else /* (!is_ipv6) */
{
+ ND_TCHECK2(*tptr, sizeof(struct olsr_msg4));
msgptr.v4 = (const struct olsr_msg4 *) tptr;
msg_type = msgptr.v4->msg_type;
msg_len = EXTRACT_16BITS(msgptr.v4->msg_len);
@@ -616,22 +616,25 @@ olsr_print(netdissect_options *ndo,
case OLSR_NAMESERVICE_MSG:
{
- u_int name_entries = EXTRACT_16BITS(msg_data+2);
- u_int addr_size = 4;
- int name_entries_valid = 0;
+ u_int name_entries;
+ u_int addr_size;
+ int name_entries_valid;
u_int i;
+ if (msg_tlen < 4)
+ goto trunc;
+ ND_TCHECK2(*msg_data, 4);
+
+ name_entries = EXTRACT_16BITS(msg_data+2);
+ addr_size = 4;
if (is_ipv6)
addr_size = 16;
+ name_entries_valid = 0;
if ((name_entries > 0)
&& ((name_entries * (4 + addr_size)) <= msg_tlen))
name_entries_valid = 1;
- if (msg_tlen < 4)
- goto trunc;
- ND_TCHECK2(*msg_data, 4);
-
ND_PRINT((ndo, "\n\t Version %u, Entries %u%s",
EXTRACT_16BITS(msg_data),
name_entries, (name_entries_valid == 0) ? " (invalid)" : ""));
diff --git a/contrib/tcpdump/print-ospf6.c b/contrib/tcpdump/print-ospf6.c
index e8a9dc6..a5ac305 100644
--- a/contrib/tcpdump/print-ospf6.c
+++ b/contrib/tcpdump/print-ospf6.c
@@ -648,6 +648,7 @@ ospf6_print_lsa(netdissect_options *ndo,
if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix))
return (1);
lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix);
+ ND_TCHECK(llsap->llsa_nprefix);
prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix);
ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:",
llsap->llsa_priority,
@@ -735,6 +736,7 @@ ospf6_decode_v3(netdissect_options *ndo,
case OSPF_TYPE_HELLO: {
register const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
+ ND_TCHECK_32BITS(&hellop->hello_options);
ND_PRINT((ndo, "\n\tOptions [%s]",
bittok2str(ospf6_option_values, "none",
EXTRACT_32BITS(&hellop->hello_options))));
@@ -933,10 +935,12 @@ ospf6_decode_v3_trailer(netdissect_options *ndo,
if (op->ospf6_type == OSPF_TYPE_HELLO) {
const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
+ ND_TCHECK(hellop->hello_options);
if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L)
lls_hello = 1;
} else if (op->ospf6_type == OSPF_TYPE_DD) {
const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN);
+ ND_TCHECK(ddp->db_options);
if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L)
lls_dd = 1;
}
diff --git a/contrib/tcpdump/print-pgm.c b/contrib/tcpdump/print-pgm.c
index 6d5c01c..8340f2c 100644
--- a/contrib/tcpdump/print-pgm.c
+++ b/contrib/tcpdump/print-pgm.c
@@ -169,13 +169,12 @@ pgm_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s > %s: [|pgm]",
ip6addr_string(ndo, &ip6->ip6_src),
ip6addr_string(ndo, &ip6->ip6_dst)));
- return;
} else {
ND_PRINT((ndo, "%s > %s: [|pgm]",
ipaddr_string(ndo, &ip->ip_src),
ipaddr_string(ndo, &ip->ip_dst)));
- return;
}
+ return;
}
sport = EXTRACT_16BITS(&pgm->pgm_sport);
@@ -362,6 +361,7 @@ pgm_print(netdissect_options *ndo,
* and stopping if we don't have enough.
*/
bp += (2 * sizeof(uint16_t));
+ ND_TCHECK_16BITS(bp);
switch (EXTRACT_16BITS(bp)) {
case AFNUM_INET:
ND_TCHECK2(*bp, sizeof(struct in_addr));
@@ -457,6 +457,10 @@ pgm_print(netdissect_options *ndo,
ND_PRINT((ndo, "[Total option length leaves no room for final option]"));
return;
}
+ if (!ND_TTEST2(*bp, 2)) {
+ ND_PRINT((ndo, " [|OPT]"));
+ return;
+ }
opt_type = *bp++;
opt_len = *bp++;
if (opt_len < PGM_MIN_OPT_LEN) {
@@ -475,112 +479,130 @@ pgm_print(netdissect_options *ndo,
switch (opt_type & PGM_OPT_MASK) {
case PGM_OPT_LENGTH:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len));
+#define PGM_OPT_LENGTH_LEN (2+2)
+ if (opt_len != PGM_OPT_LENGTH_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != %u]",
+ opt_len, PGM_OPT_LENGTH_LEN));
return;
}
ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp)));
- bp += sizeof(uint16_t);
- opts_len -= 4;
+ bp += 2;
+ opts_len -= PGM_OPT_LENGTH_LEN;
break;
case PGM_OPT_FRAGMENT:
- if (opt_len != 16) {
- ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != 16]", opt_len));
+#define PGM_OPT_FRAGMENT_LEN (2+2+4+4+4)
+ if (opt_len != PGM_OPT_FRAGMENT_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != %u]",
+ opt_len, PGM_OPT_FRAGMENT_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
len = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len));
- opts_len -= 16;
+ opts_len -= PGM_OPT_FRAGMENT_LEN;
break;
case PGM_OPT_NAK_LIST:
bp += 2;
- opt_len -= sizeof(uint32_t); /* option header */
+ opt_len -= 4; /* option header */
ND_PRINT((ndo, " NAK LIST"));
while (opt_len) {
- if (opt_len < sizeof(uint32_t)) {
+ if (opt_len < 4) {
ND_PRINT((ndo, "[Option length not a multiple of 4]"));
return;
}
- ND_TCHECK2(*bp, sizeof(uint32_t));
+ ND_TCHECK2(*bp, 4);
ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp)));
- bp += sizeof(uint32_t);
- opt_len -= sizeof(uint32_t);
- opts_len -= sizeof(uint32_t);
+ bp += 4;
+ opt_len -= 4;
+ opts_len -= 4;
}
break;
case PGM_OPT_JOIN:
- if (opt_len != 8) {
- ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != 8]", opt_len));
+#define PGM_OPT_JOIN_LEN (2+2+4)
+ if (opt_len != PGM_OPT_JOIN_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != %u]",
+ opt_len, PGM_OPT_JOIN_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " JOIN %u", seq));
- opts_len -= 8;
+ opts_len -= PGM_OPT_JOIN_LEN;
break;
case PGM_OPT_NAK_BO_IVL:
- if (opt_len != 12) {
- ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len));
+#define PGM_OPT_NAK_BO_IVL_LEN (2+2+4+4)
+ if (opt_len != PGM_OPT_NAK_BO_IVL_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != %u]",
+ opt_len, PGM_OPT_NAK_BO_IVL_LEN));
return;
}
bp += 2;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq));
- opts_len -= 12;
+ opts_len -= PGM_OPT_NAK_BO_IVL_LEN;
break;
case PGM_OPT_NAK_BO_RNG:
- if (opt_len != 12) {
- ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len));
+#define PGM_OPT_NAK_BO_RNG_LEN (2+2+4+4)
+ if (opt_len != PGM_OPT_NAK_BO_RNG_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != %u]",
+ opt_len, PGM_OPT_NAK_BO_RNG_LEN));
return;
}
bp += 2;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq));
- opts_len -= 12;
+ opts_len -= PGM_OPT_NAK_BO_RNG_LEN;
break;
case PGM_OPT_REDIRECT:
+#define PGM_OPT_REDIRECT_FIXED_LEN (2+2+2+2)
+ if (opt_len < PGM_OPT_REDIRECT_FIXED_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u < %u]",
+ opt_len, PGM_OPT_REDIRECT_FIXED_LEN));
+ return;
+ }
bp += 2;
nla_afnum = EXTRACT_16BITS(bp);
- bp += (2 * sizeof(uint16_t));
+ bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
- if (opt_len != 4 + sizeof(struct in_addr)) {
- ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len));
+ if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]",
+ opt_len, PGM_OPT_REDIRECT_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
- opts_len -= 4 + sizeof(struct in_addr);
+ opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
- if (opt_len != 4 + sizeof(struct in6_addr)) {
- ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len));
+ if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]",
+ PGM_OPT_REDIRECT_FIXED_LEN, opt_len));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
- opts_len -= 4 + sizeof(struct in6_addr);
+ opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;
@@ -591,49 +613,57 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_PARITY_PRM:
- if (opt_len != 8) {
- ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len));
+#define PGM_OPT_PARITY_PRM_LEN (2+2+4)
+ if (opt_len != PGM_OPT_PARITY_PRM_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != %u]",
+ opt_len, PGM_OPT_PARITY_PRM_LEN));
return;
}
bp += 2;
len = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " PARITY MAXTGS %u", len));
- opts_len -= 8;
+ opts_len -= PGM_OPT_PARITY_PRM_LEN;
break;
case PGM_OPT_PARITY_GRP:
- if (opt_len != 8) {
- ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len));
+#define PGM_OPT_PARITY_GRP_LEN (2+2+4)
+ if (opt_len != PGM_OPT_PARITY_GRP_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != %u]",
+ opt_len, PGM_OPT_PARITY_GRP_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " PARITY GROUP %u", seq));
- opts_len -= 8;
+ opts_len -= PGM_OPT_PARITY_GRP_LEN;
break;
case PGM_OPT_CURR_TGSIZE:
- if (opt_len != 8) {
- ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len));
+#define PGM_OPT_CURR_TGSIZE_LEN (2+2+4)
+ if (opt_len != PGM_OPT_CURR_TGSIZE_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != %u]",
+ opt_len, PGM_OPT_CURR_TGSIZE_LEN));
return;
}
bp += 2;
len = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
ND_PRINT((ndo, " PARITY ATGS %u", len));
- opts_len -= 8;
+ opts_len -= PGM_OPT_CURR_TGSIZE_LEN;
break;
case PGM_OPT_NBR_UNREACH:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len));
+#define PGM_OPT_NBR_UNREACH_LEN (2+2)
+ if (opt_len != PGM_OPT_NBR_UNREACH_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != %u]",
+ opt_len, PGM_OPT_NBR_UNREACH_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " NBR_UNREACH"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_NBR_UNREACH_LEN;
break;
case PGM_OPT_PATH_NLA:
@@ -643,33 +673,39 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_SYN:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != 4]", opt_len));
+#define PGM_OPT_SYN_LEN (2+2)
+ if (opt_len != PGM_OPT_SYN_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != %u]",
+ opt_len, PGM_OPT_SYN_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " SYN"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_SYN_LEN;
break;
case PGM_OPT_FIN:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != 4]", opt_len));
+#define PGM_OPT_FIN_LEN (2+2)
+ if (opt_len != PGM_OPT_FIN_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != %u]",
+ opt_len, PGM_OPT_FIN_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " FIN"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_FIN_LEN;
break;
case PGM_OPT_RST:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_RST option, length %u != 4]", opt_len));
+#define PGM_OPT_RST_LEN (2+2)
+ if (opt_len != PGM_OPT_RST_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_RST option, length %u != %u]",
+ opt_len, PGM_OPT_RST_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " RST"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_RST_LEN;
break;
case PGM_OPT_CR:
@@ -679,41 +715,51 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_CRQST:
- if (opt_len != 4) {
- ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != 4]", opt_len));
+#define PGM_OPT_CRQST_LEN (2+2)
+ if (opt_len != PGM_OPT_CRQST_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != %u]",
+ opt_len, PGM_OPT_CRQST_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " CRQST"));
- opts_len -= 4;
+ opts_len -= PGM_OPT_CRQST_LEN;
break;
case PGM_OPT_PGMCC_DATA:
+#define PGM_OPT_PGMCC_DATA_FIXED_LEN (2+2+4+2+2)
+ if (opt_len < PGM_OPT_PGMCC_DATA_FIXED_LEN) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u < %u]",
+ opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
+ return;
+ }
bp += 2;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
nla_afnum = EXTRACT_16BITS(bp);
- bp += (2 * sizeof(uint16_t));
+ bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
- if (opt_len != 12 + sizeof(struct in_addr)) {
- ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
+ if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]",
+ opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
- opts_len -= 12 + sizeof(struct in_addr);
+ opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
- if (opt_len != 12 + sizeof(struct in6_addr)) {
- ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
+ if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]",
+ opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
- opts_len -= 12 + sizeof(struct in6_addr);
+ opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;
@@ -724,31 +770,39 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_PGMCC_FEEDBACK:
+#define PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN (2+2+4+2+2)
+ if (opt_len < PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN) {
+ ND_PRINT((ndo, "[Bad PGM_OPT_PGMCC_FEEDBACK option, length %u < %u]",
+ opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
+ return;
+ }
bp += 2;
offset = EXTRACT_32BITS(bp);
- bp += sizeof(uint32_t);
+ bp += 4;
nla_afnum = EXTRACT_16BITS(bp);
- bp += (2 * sizeof(uint16_t));
+ bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
- if (opt_len != 12 + sizeof(struct in_addr)) {
- ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
+ if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]",
+ opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
- opts_len -= 12 + sizeof(struct in_addr);
+ opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
- if (opt_len != 12 + sizeof(struct in6_addr)) {
- ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
+ if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr)) {
+ ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]",
+ opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
- opts_len -= 12 + sizeof(struct in6_addr);
+ opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;
diff --git a/contrib/tcpdump/print-pim.c b/contrib/tcpdump/print-pim.c
index 2552595..9c8ca54 100644
--- a/contrib/tcpdump/print-pim.c
+++ b/contrib/tcpdump/print-pim.c
@@ -169,20 +169,28 @@ pimv1_join_prune_print(netdissect_options *ndo,
return;
}
+ if (len < sizeof(struct in_addr))
+ goto trunc;
ND_TCHECK2(bp[0], sizeof(struct in_addr));
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n"));
ND_PRINT((ndo, " Upstream Nbr: %s", ipaddr_string(ndo, bp)));
- ND_TCHECK2(bp[6], 2);
+ bp += 4;
+ len -= 4;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(bp[2], 2);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n"));
ND_PRINT((ndo, " Hold time: "));
- unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[6]));
+ unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2]));
if (ndo->ndo_vflag < 2)
return;
- bp += 8;
- len -= 8;
+ bp += 4;
+ len -= 4;
+ if (len < 4)
+ goto trunc;
ND_TCHECK2(bp[0], 4);
ngroups = bp[3];
bp += 4;
@@ -192,17 +200,27 @@ pimv1_join_prune_print(netdissect_options *ndo,
* XXX - does the address have length "addrlen" and the
* mask length "maddrlen"?
*/
+ if (len < 4)
+ goto trunc;
ND_TCHECK2(bp[0], sizeof(struct in_addr));
ND_PRINT((ndo, "\n\tGroup: %s", ipaddr_string(ndo, bp)));
- ND_TCHECK2(bp[4], sizeof(struct in_addr));
- if (EXTRACT_32BITS(&bp[4]) != 0xffffffff)
- ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[4])));
- ND_TCHECK2(bp[8], 4);
- njoin = EXTRACT_16BITS(&bp[8]);
- nprune = EXTRACT_16BITS(&bp[10]);
+ bp += 4;
+ len -= 4;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(bp[0], sizeof(struct in_addr));
+ if (EXTRACT_32BITS(&bp[0]) != 0xffffffff)
+ ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[0])));
+ bp += 4;
+ len -= 4;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(bp[0], 4);
+ njoin = EXTRACT_16BITS(&bp[0]);
+ nprune = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, " joined: %d pruned: %d", njoin, nprune));
- bp += 12;
- len -= 12;
+ bp += 4;
+ len -= 4;
for (njp = 0; njp < (njoin + nprune); njp++) {
const char *type;
@@ -210,12 +228,15 @@ pimv1_join_prune_print(netdissect_options *ndo,
type = "Join ";
else
type = "Prune";
+ if (len < 6)
+ goto trunc;
ND_TCHECK2(bp[0], 6);
ND_PRINT((ndo, "\n\t%s %s%s%s%s/%d", type,
(bp[0] & 0x01) ? "Sparse " : "Dense ",
(bp[1] & 0x80) ? "WC " : "",
(bp[1] & 0x40) ? "RP " : "SPT ",
- ipaddr_string(ndo, &bp[2]), bp[1] & 0x3f));
+ ipaddr_string(ndo, &bp[2]),
+ bp[1] & 0x3f));
bp += 6;
len -= 6;
}
@@ -230,13 +251,8 @@ void
pimv1_print(netdissect_options *ndo,
register const u_char *bp, register u_int len)
{
- register const u_char *ep;
register u_char type;
- ep = (const u_char *)ndo->ndo_snapend;
- if (bp >= ep)
- return;
-
ND_TCHECK(bp[1]);
type = bp[1];
@@ -302,10 +318,14 @@ pimv1_print(netdissect_options *ndo,
case PIMV1_TYPE_JOIN_PRUNE:
case PIMV1_TYPE_GRAFT:
case PIMV1_TYPE_GRAFT_ACK:
- if (ndo->ndo_vflag)
+ if (ndo->ndo_vflag) {
+ if (len < 8)
+ goto trunc;
pimv1_join_prune_print(ndo, &bp[8], len - 8);
+ }
break;
}
+ ND_TCHECK(bp[4]);
if ((bp[4] >> 4) != 1)
ND_PRINT((ndo, " [v%d]", bp[4] >> 4));
return;
@@ -329,6 +349,8 @@ cisco_autorp_print(netdissect_options *ndo,
int numrps;
int hold;
+ if (len < 8)
+ goto trunc;
ND_TCHECK(bp[0]);
ND_PRINT((ndo, " auto-rp "));
type = bp[0];
@@ -376,10 +398,16 @@ cisco_autorp_print(netdissect_options *ndo,
int nentries;
char s;
+ if (len < 4)
+ goto trunc;
ND_TCHECK2(bp[0], 4);
ND_PRINT((ndo, " RP %s", ipaddr_string(ndo, bp)));
- ND_TCHECK(bp[4]);
- switch (bp[4] & 0x3) {
+ bp += 4;
+ len -= 4;
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
+ switch (bp[0] & 0x3) {
case 0: ND_PRINT((ndo, " PIMv?"));
break;
case 1: ND_PRINT((ndo, " PIMv1"));
@@ -389,13 +417,20 @@ cisco_autorp_print(netdissect_options *ndo,
case 3: ND_PRINT((ndo, " PIMv1+2"));
break;
}
- if (bp[4] & 0xfc)
- ND_PRINT((ndo, " [rsvd=0x%02x]", bp[4] & 0xfc));
- ND_TCHECK(bp[5]);
- nentries = bp[5];
- bp += 6; len -= 6;
+ if (bp[0] & 0xfc)
+ ND_PRINT((ndo, " [rsvd=0x%02x]", bp[0] & 0xfc));
+ bp += 1;
+ len -= 1;
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
+ nentries = bp[0];
+ bp += 1;
+ len -= 1;
s = ' ';
for (; nentries; nentries--) {
+ if (len < 6)
+ goto trunc;
ND_TCHECK2(bp[0], 6);
ND_PRINT((ndo, "%c%s%s/%d", s, bp[0] & 1 ? "!" : "",
ipaddr_string(ndo, &bp[2]), bp[1]));
@@ -420,16 +455,13 @@ void
pim_print(netdissect_options *ndo,
register const u_char *bp, register u_int len, const u_char *bp2)
{
- register const u_char *ep;
register const struct pim *pim = (const struct pim *)bp;
- ep = (const u_char *)ndo->ndo_snapend;
- if (bp >= ep)
- return;
#ifdef notyet /* currently we see only version and type */
ND_TCHECK(pim->pim_rsv);
#endif
+ ND_TCHECK(pim->pim_typever);
switch (PIM_VER(pim->pim_typever)) {
case 2:
if (!ndo->ndo_vflag) {
@@ -453,6 +485,10 @@ pim_print(netdissect_options *ndo,
break;
}
return;
+
+trunc:
+ ND_PRINT((ndo, "[|pim]"));
+ return;
}
/*
@@ -495,8 +531,6 @@ pim_print(netdissect_options *ndo,
*
*/
-static int pimv2_addr_len;
-
enum pimv2_addrtype {
pimv2_unicast, pimv2_group, pimv2_source
};
@@ -523,23 +557,24 @@ enum pimv2_addrtype {
*/
static int
pimv2_addr_print(netdissect_options *ndo,
- const u_char *bp, enum pimv2_addrtype at, int silent)
+ const u_char *bp, u_int len, enum pimv2_addrtype at,
+ u_int addr_len, int silent)
{
int af;
- int len, hdrlen;
-
- ND_TCHECK(bp[0]);
+ int hdrlen;
- if (pimv2_addr_len == 0) {
+ if (addr_len == 0) {
+ if (len < 2)
+ goto trunc;
ND_TCHECK(bp[1]);
switch (bp[0]) {
case 1:
af = AF_INET;
- len = sizeof(struct in_addr);
+ addr_len = (u_int)sizeof(struct in_addr);
break;
case 2:
af = AF_INET6;
- len = sizeof(struct in6_addr);
+ addr_len = (u_int)sizeof(struct in6_addr);
break;
default:
return -1;
@@ -548,7 +583,7 @@ pimv2_addr_print(netdissect_options *ndo,
return -1;
hdrlen = 2;
} else {
- switch (pimv2_addr_len) {
+ switch (addr_len) {
case sizeof(struct in_addr):
af = AF_INET;
break;
@@ -559,14 +594,16 @@ pimv2_addr_print(netdissect_options *ndo,
return -1;
break;
}
- len = pimv2_addr_len;
hdrlen = 0;
}
bp += hdrlen;
+ len -= hdrlen;
switch (at) {
case pimv2_unicast:
- ND_TCHECK2(bp[0], len);
+ if (len < addr_len)
+ goto trunc;
+ ND_TCHECK2(bp[0], addr_len);
if (af == AF_INET) {
if (!silent)
ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp)));
@@ -575,10 +612,12 @@ pimv2_addr_print(netdissect_options *ndo,
if (!silent)
ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp)));
}
- return hdrlen + len;
+ return hdrlen + addr_len;
case pimv2_group:
case pimv2_source:
- ND_TCHECK2(bp[0], len + 2);
+ if (len < addr_len + 2)
+ goto trunc;
+ ND_TCHECK2(bp[0], addr_len + 2);
if (af == AF_INET) {
if (!silent) {
ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp + 2)));
@@ -607,7 +646,7 @@ pimv2_addr_print(netdissect_options *ndo,
ND_PRINT((ndo, ")"));
}
}
- return hdrlen + 2 + len;
+ return hdrlen + 2 + addr_len;
default:
return -1;
}
@@ -655,21 +694,21 @@ static void
pimv2_print(netdissect_options *ndo,
register const u_char *bp, register u_int len, const u_char *bp2)
{
- register const u_char *ep;
register const struct pim *pim = (const struct pim *)bp;
int advance;
enum checksum_status cksum_status;
+ int pimv2_addr_len;
- ep = (const u_char *)ndo->ndo_snapend;
- if (bp >= ep)
- return;
- if (ep > bp + len)
- ep = bp + len;
+ if (len < 2)
+ goto trunc;
ND_TCHECK(pim->pim_rsv);
pimv2_addr_len = pim->pim_rsv;
if (pimv2_addr_len != 0)
ND_PRINT((ndo, ", RFC2117-encoding"));
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK(pim->pim_cksum);
ND_PRINT((ndo, ", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum)));
if (EXTRACT_16BITS(&pim->pim_cksum) == 0) {
ND_PRINT((ndo, "(unverified)"));
@@ -710,26 +749,36 @@ pimv2_print(netdissect_options *ndo,
break;
}
}
+ bp += 4;
+ len -= 4;
switch (PIM_TYPE(pim->pim_typever)) {
case PIMV2_TYPE_HELLO:
{
uint16_t otype, olen;
- bp += 4;
- while (bp < ep) {
+ while (len > 0) {
+ if (len < 4)
+ goto trunc;
ND_TCHECK2(bp[0], 4);
otype = EXTRACT_16BITS(&bp[0]);
olen = EXTRACT_16BITS(&bp[2]);
- ND_TCHECK2(bp[0], 4 + olen);
ND_PRINT((ndo, "\n\t %s Option (%u), length %u, Value: ",
tok2str(pimv2_hello_option_values, "Unknown", otype),
otype,
olen));
bp += 4;
+ len -= 4;
+ if (len < olen)
+ goto trunc;
+ ND_TCHECK2(bp[0], olen);
switch (otype) {
case PIMV2_HELLO_OPTION_HOLDTIME:
- unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
+ if (olen != 2) {
+ ND_PRINT((ndo, "ERROR: Option Length != 2 Bytes (%u)", olen));
+ } else {
+ unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
+ }
break;
case PIMV2_HELLO_OPTION_LANPRUNEDELAY:
@@ -763,17 +812,25 @@ pimv2_print(netdissect_options *ndo,
break;
case PIMV2_HELLO_OPTION_GENID:
- ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp)));
+ if (olen != 4) {
+ ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen));
+ } else {
+ ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp)));
+ }
break;
case PIMV2_HELLO_OPTION_REFRESH_CAP:
- ND_PRINT((ndo, "v%d", *bp));
- if (*(bp+1) != 0) {
- ND_PRINT((ndo, ", interval "));
- unsigned_relts_print(ndo, *(bp+1));
- }
- if (EXTRACT_16BITS(bp+2) != 0) {
- ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2)));
+ if (olen != 4) {
+ ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen));
+ } else {
+ ND_PRINT((ndo, "v%d", *bp));
+ if (*(bp+1) != 0) {
+ ND_PRINT((ndo, ", interval "));
+ unsigned_relts_print(ndo, *(bp+1));
+ }
+ if (EXTRACT_16BITS(bp+2) != 0) {
+ ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2)));
+ }
}
break;
@@ -784,14 +841,14 @@ pimv2_print(netdissect_options *ndo,
case PIMV2_HELLO_OPTION_ADDRESS_LIST:
if (ndo->ndo_vflag > 1) {
const u_char *ptr = bp;
+ u_int plen = len;
while (ptr < (bp+olen)) {
ND_PRINT((ndo, "\n\t "));
- advance = pimv2_addr_print(ndo, ptr, pimv2_unicast, 0);
- if (advance < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ advance = pimv2_addr_print(ndo, ptr, plen, pimv2_unicast, pimv2_addr_len, 0);
+ if (advance < 0)
+ goto trunc;
ptr += advance;
+ plen -= advance;
}
}
break;
@@ -804,6 +861,7 @@ pimv2_print(netdissect_options *ndo,
if (ndo->ndo_vflag> 1)
print_unknown_data(ndo, bp, "\n\t ", olen);
bp += olen;
+ len -= olen;
}
break;
}
@@ -812,18 +870,24 @@ pimv2_print(netdissect_options *ndo,
{
const struct ip *ip;
- ND_TCHECK2(*(bp + 4), PIMV2_REGISTER_FLAG_LEN);
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(*bp, PIMV2_REGISTER_FLAG_LEN);
ND_PRINT((ndo, ", Flags [ %s ]\n\t",
tok2str(pimv2_register_flag_values,
"none",
- EXTRACT_32BITS(bp+4))));
+ EXTRACT_32BITS(bp))));
- bp += 8; len -= 8;
+ bp += 4; len -= 4;
/* encapsulated multicast packet */
+ if (len == 0)
+ goto trunc;
ip = (const struct ip *)bp;
+ ND_TCHECK(ip->ip_vhl);
switch (IP_V(ip)) {
case 0: /* Null header */
+ ND_TCHECK(ip->ip_dst);
ND_PRINT((ndo, "IP-Null-header %s > %s",
ipaddr_string(ndo, &ip->ip_src),
ipaddr_string(ndo, &ip->ip_dst)));
@@ -845,22 +909,13 @@ pimv2_print(netdissect_options *ndo,
}
case PIMV2_TYPE_REGISTER_STOP:
- bp += 4; len -= 4;
- if (bp >= ep)
- break;
ND_PRINT((ndo, " group="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
- if (bp >= ep)
- break;
ND_PRINT((ndo, " source="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
break;
@@ -911,19 +966,15 @@ pimv2_print(netdissect_options *ndo,
uint16_t nprune;
int i, j;
- bp += 4; len -= 4;
if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/
- if (bp >= ep)
- break;
ND_PRINT((ndo, ", upstream-neighbor: "));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
}
- if (bp + 4 > ep)
- break;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(*bp, 4);
ngroup = bp[1];
holdtime = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, "\n\t %u group(s)", ngroup));
@@ -936,139 +987,125 @@ pimv2_print(netdissect_options *ndo,
}
bp += 4; len -= 4;
for (i = 0; i < ngroup; i++) {
- if (bp >= ep)
- goto jp_done;
ND_PRINT((ndo, "\n\t group #%u: ", i+1));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
- ND_PRINT((ndo, "...)"));
- goto jp_done;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
- if (bp + 4 > ep) {
- ND_PRINT((ndo, "...)"));
- goto jp_done;
- }
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK2(*bp, 4);
njoin = EXTRACT_16BITS(&bp[0]);
nprune = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, ", joined sources: %u, pruned sources: %u", njoin, nprune));
bp += 4; len -= 4;
for (j = 0; j < njoin; j++) {
ND_PRINT((ndo, "\n\t joined source #%u: ", j+1));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) {
- ND_PRINT((ndo, "...)"));
- goto jp_done;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
}
for (j = 0; j < nprune; j++) {
ND_PRINT((ndo, "\n\t pruned source #%u: ", j+1));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) {
- ND_PRINT((ndo, "...)"));
- goto jp_done;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
}
}
- jp_done:
break;
}
case PIMV2_TYPE_BOOTSTRAP:
{
int i, j, frpcnt;
- bp += 4;
/* Fragment Tag, Hash Mask len, and BSR-priority */
- if (bp + sizeof(uint16_t) >= ep) break;
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " tag=%x", EXTRACT_16BITS(bp)));
- bp += sizeof(uint16_t);
- if (bp >= ep) break;
+ bp += 2;
+ len -= 2;
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
ND_PRINT((ndo, " hashmlen=%d", bp[0]));
- if (bp + 1 >= ep) break;
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK(bp[2]);
ND_PRINT((ndo, " BSRprio=%d", bp[1]));
bp += 2;
+ len -= 2;
/* Encoded-Unicast-BSR-Address */
- if (bp >= ep) break;
ND_PRINT((ndo, " BSR="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
- for (i = 0; bp < ep; i++) {
+ for (i = 0; len > 0; i++) {
/* Encoded-Group Address */
ND_PRINT((ndo, " (group%d: ", i));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0))
- < 0) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
/* RP-Count, Frag RP-Cnt, and rsvd */
- if (bp >= ep) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
ND_PRINT((ndo, " RPcnt=%d", bp[0]));
- if (bp + 1 >= ep) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK(bp[1]);
ND_PRINT((ndo, " FRPcnt=%d", frpcnt = bp[1]));
+ if (len < 4)
+ goto trunc;
bp += 4;
+ len -= 4;
- for (j = 0; j < frpcnt && bp < ep; j++) {
+ for (j = 0; j < frpcnt && len > 0; j++) {
/* each RP info */
ND_PRINT((ndo, " RP%d=", j));
- if ((advance = pimv2_addr_print(ndo, bp,
+ if ((advance = pimv2_addr_print(ndo, bp, len,
pimv2_unicast,
- 0)) < 0) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ pimv2_addr_len,
+ 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
- if (bp + 1 >= ep) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, ",holdtime="));
unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
- if (bp + 2 >= ep) {
- ND_PRINT((ndo, "...)"));
- goto bs_done;
- }
+ if (len < 3)
+ goto trunc;
+ ND_TCHECK(bp[2]);
ND_PRINT((ndo, ",prio=%d", bp[2]));
+ if (len < 4)
+ goto trunc;
bp += 4;
+ len -= 4;
}
ND_PRINT((ndo, ")"));
}
- bs_done:
break;
}
case PIMV2_TYPE_ASSERT:
- bp += 4; len -= 4;
- if (bp >= ep)
- break;
ND_PRINT((ndo, " group="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
- if (bp >= ep)
- break;
ND_PRINT((ndo, " src="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance; len -= advance;
- if (bp + 8 > ep)
- break;
+ if (len < 8)
+ goto trunc;
+ ND_TCHECK2(*bp, 8);
if (bp[0] & 0x80)
ND_PRINT((ndo, " RPT"));
ND_PRINT((ndo, " pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff));
@@ -1078,61 +1115,62 @@ pimv2_print(netdissect_options *ndo,
case PIMV2_TYPE_CANDIDATE_RP:
{
int i, pfxcnt;
- bp += 4;
/* Prefix-Cnt, Priority, and Holdtime */
- if (bp >= ep) break;
+ if (len < 1)
+ goto trunc;
+ ND_TCHECK(bp[0]);
ND_PRINT((ndo, " prefix-cnt=%d", bp[0]));
pfxcnt = bp[0];
- if (bp + 1 >= ep) break;
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK(bp[1]);
ND_PRINT((ndo, " prio=%d", bp[1]));
- if (bp + 3 >= ep) break;
+ if (len < 4)
+ goto trunc;
+ ND_TCHECK_16BITS(&bp[2]);
ND_PRINT((ndo, " holdtime="));
unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2]));
bp += 4;
+ len -= 4;
/* Encoded-Unicast-RP-Address */
- if (bp >= ep) break;
ND_PRINT((ndo, " RP="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
/* Encoded-Group Addresses */
- for (i = 0; i < pfxcnt && bp < ep; i++) {
+ for (i = 0; i < pfxcnt && len > 0; i++) {
ND_PRINT((ndo, " Group%d=", i));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0))
- < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
}
break;
}
case PIMV2_TYPE_PRUNE_REFRESH:
ND_PRINT((ndo, " src="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
ND_PRINT((ndo, " grp="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
+ len -= advance;
ND_PRINT((ndo, " forwarder="));
- if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
- ND_PRINT((ndo, "..."));
- break;
- }
+ if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
+ goto trunc;
bp += advance;
- ND_TCHECK2(bp[0], 2);
+ len -= advance;
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " TUNR "));
unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
break;
diff --git a/contrib/tcpdump/print-pktap.c b/contrib/tcpdump/print-pktap.c
index 7144f3c..4a295fd 100644
--- a/contrib/tcpdump/print-pktap.c
+++ b/contrib/tcpdump/print-pktap.c
@@ -104,6 +104,7 @@ pktap_if_print(netdissect_options *ndo,
u_int length = h->len;
if_printer printer;
const pktap_header_t *hdr;
+ struct pcap_pkthdr nhdr;
if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) {
ND_PRINT((ndo, "[|pktap]"));
@@ -144,7 +145,10 @@ pktap_if_print(netdissect_options *ndo,
case PKT_REC_PACKET:
if ((printer = lookup_printer(dlt)) != NULL) {
- hdrlen += printer(ndo, h, p);
+ nhdr = *h;
+ nhdr.caplen = caplen;
+ nhdr.len = length;
+ hdrlen += printer(ndo, &nhdr, p);
} else {
if (!ndo->ndo_eflag)
pktap_header_print(ndo, (const u_char *)hdr,
diff --git a/contrib/tcpdump/print-ppp.c b/contrib/tcpdump/print-ppp.c
index ee8239c..8917617 100644
--- a/contrib/tcpdump/print-ppp.c
+++ b/contrib/tcpdump/print-ppp.c
@@ -611,7 +611,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 6)"));
return len;
}
- ND_TCHECK2(*(p + 2), 3);
+ ND_TCHECK_24BITS(p + 2);
ND_PRINT((ndo, ": Vendor: %s (%u)",
tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)),
EXTRACT_24BITS(p + 2)));
@@ -630,7 +630,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return len;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_ACCM:
@@ -638,7 +638,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return len;
}
- ND_TCHECK2(*(p + 2), 4);
+ ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
break;
case LCPOPT_AP:
@@ -646,7 +646,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2))));
switch (EXTRACT_16BITS(p+2)) {
@@ -668,7 +668,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p+2);
if (EXTRACT_16BITS(p+2) == PPP_LQM)
ND_PRINT((ndo, ": LQR"));
else
@@ -679,7 +679,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 4);
+ ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
break;
case LCPOPT_PFC:
@@ -691,7 +691,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_CBACK:
@@ -710,7 +710,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_MLED:
@@ -811,6 +811,15 @@ handle_mlppp(netdissect_options *ndo,
if (!ndo->ndo_eflag)
ND_PRINT((ndo, "MLPPP, "));
+ if (length < 2) {
+ ND_PRINT((ndo, "[|mlppp]"));
+ return;
+ }
+ if (!ND_TTEST_16BITS(p)) {
+ ND_PRINT((ndo, "[|mlppp]"));
+ return;
+ }
+
ND_PRINT((ndo, "seq 0x%03x, Flags [%s], length %u",
(EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */
bittok2str(ppp_ml_flag_values, "none", *p & 0xc0),
@@ -1055,7 +1064,7 @@ print_ipcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return 0;
}
- ND_TCHECK2(*(p + 2), 2);
+ ND_TCHECK_16BITS(p+2);
compproto = EXTRACT_16BITS(p+2);
ND_PRINT((ndo, ": %s (0x%02x):",
@@ -1241,7 +1250,7 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 3)"));
return len;
}
- ND_TCHECK2(*(p + 2), 1);
+ ND_TCHECK(p[2]);
ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u",
p[2] >> 5, p[2] & 0x1f));
break;
@@ -1250,7 +1259,7 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
- ND_TCHECK2(*(p + 2), 1);
+ ND_TCHECK(p[3]);
ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u",
(p[2] & 0xc0) >> 6,
(p[2] & 0x20) ? "Enabled" : "Disabled",
@@ -1261,10 +1270,10 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
- ND_TCHECK2(*(p + 2), 1);
+ ND_TCHECK(p[3]);
ND_PRINT((ndo, ": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u",
(p[2] & 0xf0) >> 4,
- ((p[2] & 0x0f) == 8) ? "zlib" : "unkown",
+ ((p[2] & 0x0f) == 8) ? "zlib" : "unknown",
p[2] & 0x0f, (p[3] & 0xfc) >> 2, p[3] & 0x03));
break;
@@ -1336,7 +1345,7 @@ print_bacp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return len;
}
- ND_TCHECK2(*(p + 2), 4);
+ ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)));
break;
default:
@@ -1484,7 +1493,7 @@ handle_ppp(netdissect_options *ndo,
ipx_print(ndo, p, length);
break;
case PPP_OSI:
- isoclns_print(ndo, p, length, length);
+ isoclns_print(ndo, p, length);
break;
case PPP_MPLS_UCAST:
case PPP_MPLS_MCAST:
diff --git a/contrib/tcpdump/print-radius.c b/contrib/tcpdump/print-radius.c
index eb48de5..682cad6 100644
--- a/contrib/tcpdump/print-radius.c
+++ b/contrib/tcpdump/print-radius.c
@@ -496,10 +496,7 @@ print_attr_string(netdissect_options *ndo,
{
case TUNNEL_PASS:
if (length < 3)
- {
- ND_PRINT((ndo, "%s", tstr));
- return;
- }
+ goto trunc;
if (*data && (*data <=0x1F) )
ND_PRINT((ndo, "Tag[%u] ", *data));
else
@@ -519,10 +516,7 @@ print_attr_string(netdissect_options *ndo,
if (*data <= 0x1F)
{
if (length < 1)
- {
- ND_PRINT((ndo, "%s", tstr));
- return;
- }
+ goto trunc;
if (*data)
ND_PRINT((ndo, "Tag[%u] ", *data));
else
@@ -532,6 +526,8 @@ print_attr_string(netdissect_options *ndo,
}
break;
case EGRESS_VLAN_NAME:
+ if (length < 1)
+ goto trunc;
ND_PRINT((ndo, "%s (0x%02x) ",
tok2str(rfc4675_tagged,"Unknown tag",*data),
*data));
@@ -540,7 +536,7 @@ print_attr_string(netdissect_options *ndo,
break;
}
- for (i=0; *data && i < length ; i++, data++)
+ for (i=0; i < length && *data; i++, data++)
ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data));
return;
diff --git a/contrib/tcpdump/print-resp.c b/contrib/tcpdump/print-resp.c
index 9d71e21..cc72124 100644
--- a/contrib/tcpdump/print-resp.c
+++ b/contrib/tcpdump/print-resp.c
@@ -481,8 +481,10 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
ND_TCHECK(*bp);
c = *bp;
if (!(c >= '0' && c <= '9')) {
- if (!saw_digit)
+ if (!saw_digit) {
+ bp++;
goto invalid;
+ }
break;
}
c -= '0';
@@ -491,7 +493,7 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
too_large = 1;
} else {
result *= 10;
- if (result == INT_MAX && c > (INT_MAX % 10)) {
+ if (result == ((INT_MAX / 10) * 10) && c > (INT_MAX % 10)) {
/* This will overflow an int when we add c */
too_large = 1;
} else
@@ -501,24 +503,24 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
len--;
saw_digit = 1;
}
- if (!saw_digit)
- goto invalid;
/*
- * OK, the next thing should be \r\n.
+ * OK, we found a non-digit character. It should be a \r, followed
+ * by a \n.
*/
- if (len == 0)
- goto trunc;
- ND_TCHECK(*bp);
- if (*bp != '\r')
+ if (*bp != '\r') {
+ bp++;
goto invalid;
+ }
bp++;
len--;
if (len == 0)
goto trunc;
ND_TCHECK(*bp);
- if (*bp != '\n')
+ if (*bp != '\n') {
+ bp++;
goto invalid;
+ }
bp++;
len--;
*endp = bp;
@@ -531,8 +533,10 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
return (too_large ? -3 : result);
trunc:
+ *endp = bp;
return (-2);
invalid:
+ *endp = bp;
return (-5);
}
diff --git a/contrib/tcpdump/print-ripng.c b/contrib/tcpdump/print-ripng.c
index 25e9bbc..7113239 100644
--- a/contrib/tcpdump/print-ripng.c
+++ b/contrib/tcpdump/print-ripng.c
@@ -110,65 +110,74 @@ ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
{
register const struct rip6 *rp = (const struct rip6 *)dat;
register const struct netinfo6 *ni;
- register u_int amt;
- register u_int i;
- int j;
- int trunc;
-
- if (ndo->ndo_snapend < dat)
- return;
- amt = ndo->ndo_snapend - dat;
- i = min(length, amt);
- if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
- return;
- i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
+ unsigned int length_left;
+ u_int j;
+ ND_TCHECK(rp->rip6_cmd);
switch (rp->rip6_cmd) {
case RIP6_REQUEST:
- j = length / sizeof(*ni);
- if (j == 1
- && rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
- && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
- ND_PRINT((ndo, " ripng-req dump"));
- break;
+ length_left = length;
+ if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
+ goto trunc;
+ length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
+ j = length_left / sizeof(*ni);
+ if (j == 1) {
+ ND_TCHECK(rp->rip6_nets);
+ if (rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
+ && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
+ ND_PRINT((ndo, " ripng-req dump"));
+ break;
+ }
}
- if (j * sizeof(*ni) != length - 4)
- ND_PRINT((ndo, " ripng-req %d[%u]:", j, length));
+ if (j * sizeof(*ni) != length_left)
+ ND_PRINT((ndo, " ripng-req %u[%u]:", j, length));
else
- ND_PRINT((ndo, " ripng-req %d:", j));
- trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
- for (ni = rp->rip6_nets; i >= sizeof(*ni);
- i -= sizeof(*ni), ++ni) {
+ ND_PRINT((ndo, " ripng-req %u:", j));
+ for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
+ length_left -= sizeof(*ni), ++ni) {
+ ND_TCHECK(*ni);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n\t"));
else
ND_PRINT((ndo, " "));
rip6_entry_print(ndo, ni, 0);
}
+ if (length_left != 0)
+ goto trunc;
break;
case RIP6_RESPONSE:
- j = length / sizeof(*ni);
- if (j * sizeof(*ni) != length - 4)
+ length_left = length;
+ if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
+ goto trunc;
+ length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
+ j = length_left / sizeof(*ni);
+ if (j * sizeof(*ni) != length_left)
ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length));
else
ND_PRINT((ndo, " ripng-resp %d:", j));
- trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
- for (ni = rp->rip6_nets; i >= sizeof(*ni);
- i -= sizeof(*ni), ++ni) {
+ for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
+ length_left -= sizeof(*ni), ++ni) {
+ ND_TCHECK(*ni);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n\t"));
else
ND_PRINT((ndo, " "));
rip6_entry_print(ndo, ni, ni->rip6_metric);
}
- if (trunc)
- ND_PRINT((ndo, "[|ripng]"));
+ if (length_left != 0)
+ goto trunc;
break;
default:
ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length));
break;
}
+ ND_TCHECK(rp->rip6_vers);
if (rp->rip6_vers != RIP6_VERSION)
ND_PRINT((ndo, " [vers %d]", rp->rip6_vers));
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|ripng]"));
+ return;
}
diff --git a/contrib/tcpdump/print-rpki-rtr.c b/contrib/tcpdump/print-rpki-rtr.c
index 77e29c7..8e4c73f 100644
--- a/contrib/tcpdump/print-rpki-rtr.c
+++ b/contrib/tcpdump/print-rpki-rtr.c
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Resource Public Key Infrastructure (RPKI) to Router Protocol printer */
@@ -82,6 +82,9 @@ typedef struct rpki_rtr_pdu_ipv6_prefix_ {
typedef struct rpki_rtr_pdu_error_report_ {
rpki_rtr_pdu pdu_header;
u_char encapsulated_pdu_length[4]; /* Encapsulated PDU length */
+ /* Copy of Erroneous PDU (variable, optional) */
+ /* Length of Error Text (4 octets in network byte order) */
+ /* Arbitrary Text of Error Diagnostic Message (variable, optional) */
} rpki_rtr_pdu_error_report;
/*
@@ -171,17 +174,38 @@ indent_string (u_int indent)
/*
* Print a single PDU.
*/
-static int
-rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
+static u_int
+rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len,
+ const u_char recurse, const u_int indent)
{
const rpki_rtr_pdu *pdu_header;
u_int pdu_type, pdu_len, hexdump;
const u_char *msg;
+ /* Protocol Version */
+ ND_TCHECK_8BITS(tptr);
+ if (*tptr != 0) {
+ /* Skip the rest of the input buffer because even if this is
+ * a well-formed PDU of a future RPKI-Router protocol version
+ * followed by a well-formed PDU of RPKI-Router protocol
+ * version 0, there is no way to know exactly how to skip the
+ * current PDU.
+ */
+ ND_PRINT((ndo, "%sRPKI-RTRv%u (unknown)", indent_string(8), *tptr));
+ return len;
+ }
+ if (len < sizeof(rpki_rtr_pdu)) {
+ ND_PRINT((ndo, "(%u bytes is too few to decode)", len));
+ goto invalid;
+ }
+ ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu));
pdu_header = (const rpki_rtr_pdu *)tptr;
pdu_type = pdu_header->pdu_type;
pdu_len = EXTRACT_32BITS(pdu_header->length);
- ND_TCHECK2(*tptr, pdu_len);
+ /* Do not check bounds with pdu_len yet, do it in the case blocks
+ * below to make it possible to decode at least the beginning of
+ * a truncated Error Report PDU or a truncated encapsulated PDU.
+ */
hexdump = FALSE;
ND_PRINT((ndo, "%sRPKI-RTRv%u, %s PDU (%u), length: %u",
@@ -189,6 +213,8 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
pdu_header->version,
tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type),
pdu_type, pdu_len));
+ if (pdu_len < sizeof(rpki_rtr_pdu) || pdu_len > len)
+ goto invalid;
switch (pdu_type) {
@@ -198,6 +224,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
case RPKI_RTR_SERIAL_NOTIFY_PDU:
case RPKI_RTR_SERIAL_QUERY_PDU:
case RPKI_RTR_END_OF_DATA_PDU:
+ if (pdu_len != sizeof(rpki_rtr_pdu) + 4)
+ goto invalid;
+ ND_TCHECK2(*tptr, pdu_len);
msg = (const u_char *)(pdu_header + 1);
ND_PRINT((ndo, "%sSession ID: 0x%04x, Serial: %u",
indent_string(indent+2),
@@ -210,6 +239,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
*/
case RPKI_RTR_RESET_QUERY_PDU:
case RPKI_RTR_CACHE_RESET_PDU:
+ if (pdu_len != sizeof(rpki_rtr_pdu))
+ goto invalid;
+ /* no additional boundary to check */
/*
* Zero payload PDUs.
@@ -217,6 +249,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
break;
case RPKI_RTR_CACHE_RESPONSE_PDU:
+ if (pdu_len != sizeof(rpki_rtr_pdu))
+ goto invalid;
+ /* no additional boundary to check */
ND_PRINT((ndo, "%sSession ID: 0x%04x",
indent_string(indent+2),
EXTRACT_16BITS(pdu_header->u.session_id)));
@@ -226,6 +261,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
{
const rpki_rtr_pdu_ipv4_prefix *pdu;
+ if (pdu_len != sizeof(rpki_rtr_pdu) + 12)
+ goto invalid;
+ ND_TCHECK2(*tptr, pdu_len);
pdu = (const rpki_rtr_pdu_ipv4_prefix *)tptr;
ND_PRINT((ndo, "%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
indent_string(indent+2),
@@ -239,6 +277,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
{
const rpki_rtr_pdu_ipv6_prefix *pdu;
+ if (pdu_len != sizeof(rpki_rtr_pdu) + 24)
+ goto invalid;
+ ND_TCHECK2(*tptr, pdu_len);
pdu = (const rpki_rtr_pdu_ipv6_prefix *)tptr;
ND_PRINT((ndo, "%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
indent_string(indent+2),
@@ -253,10 +294,17 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
const rpki_rtr_pdu_error_report *pdu;
u_int encapsulated_pdu_length, text_length, tlen, error_code;
+ tlen = sizeof(rpki_rtr_pdu);
+ /* Do not test for the "Length of Error Text" data element yet. */
+ if (pdu_len < tlen + 4)
+ goto invalid;
+ ND_TCHECK2(*tptr, tlen + 4);
+ /* Safe up to and including the "Length of Encapsulated PDU"
+ * data element, more data elements may be present.
+ */
pdu = (const rpki_rtr_pdu_error_report *)tptr;
encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length);
- ND_TCHECK2(*tptr, encapsulated_pdu_length);
- tlen = pdu_len;
+ tlen += 4;
error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code);
ND_PRINT((ndo, "%sError code: %s (%u), Encapsulated PDU length: %u",
@@ -264,41 +312,58 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
tok2str(rpki_rtr_error_codes, "Unknown", error_code),
error_code, encapsulated_pdu_length));
- tptr += sizeof(*pdu);
- tlen -= sizeof(*pdu);
-
- /*
- * Recurse if there is an encapsulated PDU.
- */
- if (encapsulated_pdu_length &&
- (encapsulated_pdu_length <= tlen)) {
- ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
- if (rpki_rtr_pdu_print(ndo, tptr, indent+2))
- goto trunc;
+ if (encapsulated_pdu_length) {
+ /* Section 5.10 of RFC 6810 says:
+ * "An Error Report PDU MUST NOT be sent for an Error Report PDU."
+ *
+ * However, as far as the protocol encoding goes Error Report PDUs can
+ * happen to be nested in each other, however many times, in which case
+ * the decoder should still print such semantically incorrect PDUs.
+ *
+ * That said, "the Erroneous PDU field MAY be truncated" (ibid), thus
+ * to keep things simple this implementation decodes only the two
+ * outermost layers of PDUs and makes bounds checks in the outer and
+ * the inner PDU independently.
+ */
+ if (pdu_len < tlen + encapsulated_pdu_length)
+ goto invalid;
+ if (! recurse) {
+ ND_TCHECK2(*tptr, tlen + encapsulated_pdu_length);
+ }
+ else {
+ ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
+ rpki_rtr_pdu_print(ndo, tptr + tlen,
+ encapsulated_pdu_length, 0, indent + 2);
+ }
+ tlen += encapsulated_pdu_length;
}
- tptr += encapsulated_pdu_length;
- tlen -= encapsulated_pdu_length;
+ if (pdu_len < tlen + 4)
+ goto invalid;
+ ND_TCHECK2(*tptr, tlen + 4);
+ /* Safe up to and including the "Length of Error Text" data element,
+ * one more data element may be present.
+ */
/*
* Extract, trail-zero and print the Error message.
*/
- text_length = 0;
- if (tlen > 4) {
- text_length = EXTRACT_32BITS(tptr);
- tptr += 4;
- tlen -= 4;
- }
- ND_TCHECK2(*tptr, text_length);
- if (text_length && (text_length <= tlen )) {
+ text_length = EXTRACT_32BITS(tptr + tlen);
+ tlen += 4;
+
+ if (text_length) {
+ if (pdu_len < tlen + text_length)
+ goto invalid;
+ /* fn_printn() makes the bounds check */
ND_PRINT((ndo, "%sError text: ", indent_string(indent+2)));
- if (fn_printn(ndo, tptr, text_length, ndo->ndo_snapend))
+ if (fn_printn(ndo, tptr + tlen, text_length, ndo->ndo_snapend))
goto trunc;
}
}
break;
default:
+ ND_TCHECK2(*tptr, pdu_len);
/*
* Unknown data, please hexdump.
@@ -310,57 +375,29 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
print_unknown_data(ndo,tptr,"\n\t ", pdu_len);
}
- return 0;
+ return pdu_len;
+invalid:
+ ND_PRINT((ndo, "%s", istr));
+ ND_TCHECK2(*tptr, len);
+ return len;
trunc:
- return 1;
+ ND_PRINT((ndo, "\n\t%s", tstr));
+ return len;
}
void
rpki_rtr_print(netdissect_options *ndo, register const u_char *pptr, register u_int len)
{
- u_int tlen, pdu_type, pdu_len;
- const u_char *tptr;
- const rpki_rtr_pdu *pdu_header;
-
- tptr = pptr;
- tlen = len;
-
if (!ndo->ndo_vflag) {
ND_PRINT((ndo, ", RPKI-RTR"));
return;
}
-
- while (tlen >= sizeof(rpki_rtr_pdu)) {
-
- ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu));
-
- pdu_header = (const rpki_rtr_pdu *)tptr;
- pdu_type = pdu_header->pdu_type;
- pdu_len = EXTRACT_32BITS(pdu_header->length);
- ND_TCHECK2(*tptr, pdu_len);
-
- /* infinite loop check */
- if (!pdu_type || !pdu_len) {
- break;
- }
-
- if (tlen < pdu_len) {
- goto trunc;
- }
-
- /*
- * Print the PDU.
- */
- if (rpki_rtr_pdu_print(ndo, tptr, 8))
- goto trunc;
-
- tlen -= pdu_len;
- tptr += pdu_len;
+ while (len) {
+ u_int pdu_len = rpki_rtr_pdu_print(ndo, pptr, len, 1, 8);
+ len -= pdu_len;
+ pptr += pdu_len;
}
- return;
-trunc:
- ND_PRINT((ndo, "\n\t%s", tstr));
}
/*
diff --git a/contrib/tcpdump/print-rsvp.c b/contrib/tcpdump/print-rsvp.c
index be3dfa3..93b4b65 100644
--- a/contrib/tcpdump/print-rsvp.c
+++ b/contrib/tcpdump/print-rsvp.c
@@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Resource ReSerVation Protocol (RSVP) printer */
@@ -1205,6 +1205,17 @@ rsvp_obj_print(netdissect_options *ndo,
/* read variable length subobjects */
total_subobj_len = obj_tlen;
while(total_subobj_len > 0) {
+ /* If RFC 3476 Section 3.1 defined that a sub-object of the
+ * GENERALIZED_UNI RSVP object must have the Length field as
+ * a multiple of 4, instead of the check below it would be
+ * better to test total_subobj_len only once before the loop.
+ * So long as it does not define it and this while loop does
+ * not implement such a requirement, let's accept that within
+ * each iteration subobj_len may happen to be a multiple of 1
+ * and test it and total_subobj_len respectively.
+ */
+ if (total_subobj_len < 4)
+ goto invalid;
subobj_len = EXTRACT_16BITS(obj_tptr);
subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8;
af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF;
@@ -1216,7 +1227,13 @@ rsvp_obj_print(netdissect_options *ndo,
tok2str(af_values, "Unknown", af), af,
subobj_len));
- if(subobj_len == 0)
+ /* In addition to what is explained above, the same spec does not
+ * explicitly say that the same Length field includes the 4-octet
+ * sub-object header, but as long as this while loop implements it
+ * as it does include, let's keep the check below consistent with
+ * the rest of the code.
+ */
+ if(subobj_len < 4 || subobj_len > total_subobj_len)
goto invalid;
switch(subobj_type) {
@@ -1472,12 +1489,12 @@ rsvp_obj_print(netdissect_options *ndo,
case RSVP_OBJ_FASTREROUTE:
/* the differences between c-type 1 and 7 are minor */
obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
- bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
switch(rsvp_obj_ctype) {
case RSVP_CTYPE_1: /* new style */
if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
return-1;
+ bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
ident,
(int)obj_ptr.rsvp_obj_frr->setup_prio,
@@ -1496,6 +1513,7 @@ rsvp_obj_print(netdissect_options *ndo,
case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
if (obj_tlen < 16)
return-1;
+ bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
ident,
(int)obj_ptr.rsvp_obj_frr->setup_prio,
diff --git a/contrib/tcpdump/print-rt6.c b/contrib/tcpdump/print-rt6.c
index 35dbed9..78a6a57 100644
--- a/contrib/tcpdump/print-rt6.c
+++ b/contrib/tcpdump/print-rt6.c
@@ -29,12 +29,12 @@
#include <string.h>
-#include "ip6.h"
-
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
+#include "ip6.h"
+
int
rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 _U_)
{
@@ -45,13 +45,13 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2
register const struct in6_addr *addr;
dp = (const struct ip6_rthdr *)bp;
- len = dp->ip6r_len;
/* 'ep' points to the end of available data. */
ep = ndo->ndo_snapend;
ND_TCHECK(dp->ip6r_segleft);
+ len = dp->ip6r_len;
ND_PRINT((ndo, "srcrt (len=%d", dp->ip6r_len)); /*)*/
ND_PRINT((ndo, ", type=%d", dp->ip6r_type));
ND_PRINT((ndo, ", segleft=%d", dp->ip6r_segleft));
@@ -62,7 +62,7 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2
dp0 = (const struct ip6_rthdr0 *)dp;
ND_TCHECK(dp0->ip6r0_reserved);
- if (dp0->ip6r0_reserved || ndo->ndo_vflag) {
+ if (EXTRACT_32BITS(dp0->ip6r0_reserved) || ndo->ndo_vflag) {
ND_PRINT((ndo, ", rsv=0x%0x",
EXTRACT_32BITS(&dp0->ip6r0_reserved)));
}
diff --git a/contrib/tcpdump/print-rx.c b/contrib/tcpdump/print-rx.c
index ea3a5e6..77c51ec 100644
--- a/contrib/tcpdump/print-rx.c
+++ b/contrib/tcpdump/print-rx.c
@@ -75,12 +75,12 @@
#define PRSFS_ADMINISTER 64 /* Change ACL's */
struct rx_header {
- uint32_t epoch;
- uint32_t cid;
- uint32_t callNumber;
- uint32_t seq;
- uint32_t serial;
- uint8_t type;
+ nd_uint32_t epoch;
+ nd_uint32_t cid;
+ nd_uint32_t callNumber;
+ nd_uint32_t seq;
+ nd_uint32_t serial;
+ nd_uint8_t type;
#define RX_PACKET_TYPE_DATA 1
#define RX_PACKET_TYPE_ACK 2
#define RX_PACKET_TYPE_BUSY 3
@@ -91,7 +91,7 @@ struct rx_header {
#define RX_PACKET_TYPE_DEBUG 8
#define RX_PACKET_TYPE_PARAMS 9
#define RX_PACKET_TYPE_VERSION 13
- uint8_t flags;
+ nd_uint8_t flags;
#define RX_CLIENT_INITIATED 1
#define RX_REQUEST_ACK 2
#define RX_LAST_PACKET 4
@@ -99,10 +99,10 @@ struct rx_header {
#define RX_FREE_PACKET 16
#define RX_SLOW_START_OK 32
#define RX_JUMBO_PACKET 32
- uint8_t userStatus;
- uint8_t securityIndex;
- uint16_t spare; /* How clever: even though the AFS */
- uint16_t serviceId; /* header files indicate that the */
+ nd_uint8_t userStatus;
+ nd_uint8_t securityIndex;
+ nd_uint16_t spare; /* How clever: even though the AFS */
+ nd_uint16_t serviceId; /* header files indicate that the */
}; /* serviceId is first, it's really */
/* encoded _after_ the spare field */
/* I wasted a day figuring that out! */
@@ -690,11 +690,11 @@ rx_cache_insert(netdissect_options *ndo,
if (++rx_cache_next >= RX_CACHE_SIZE)
rx_cache_next = 0;
- rxent->callnum = rxh->callNumber;
+ rxent->callnum = EXTRACT_32BITS(&rxh->callNumber);
UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t));
UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t));
rxent->dport = dport;
- rxent->serviceId = rxh->serviceId;
+ rxent->serviceId = EXTRACT_32BITS(&rxh->serviceId);
rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
}
@@ -722,10 +722,10 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,
i = rx_cache_hint;
do {
rxent = &rx_cache[i];
- if (rxent->callnum == rxh->callNumber &&
+ if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) &&
rxent->client.s_addr == clip &&
rxent->server.s_addr == sip &&
- rxent->serviceId == rxh->serviceId &&
+ rxent->serviceId == EXTRACT_32BITS(&rxh->serviceId) &&
rxent->dport == sport) {
/* We got a match! */
@@ -1262,6 +1262,7 @@ cb_print(netdissect_options *ndo,
if (j == 0)
ND_PRINT((ndo, " <none!>"));
+ ND_TCHECK_32BITS(bp);
j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
@@ -2533,6 +2534,10 @@ ubik_print(netdissect_options *ndo,
* gleaned from ubik/ubik_int.xg
*/
+ /* Every function that calls this function first makes a bounds check
+ * for (sizeof(rx_header) + 4) bytes, so long as it remains this way
+ * the line below will not over-read.
+ */
ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
ND_PRINT((ndo, " ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)));
@@ -2577,6 +2582,7 @@ ubik_print(netdissect_options *ndo,
INTOUT();
ND_PRINT((ndo, " length"));
INTOUT();
+ ND_TCHECK_32BITS(bp);
temp = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
tok2str(ubik_lock_types, "type %d", temp);
diff --git a/contrib/tcpdump/print-sip.c b/contrib/tcpdump/print-sip.c
index 8e308ed..a617d23 100644
--- a/contrib/tcpdump/print-sip.c
+++ b/contrib/tcpdump/print-sip.c
@@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
* Turned into common "text protocol" code, which this uses, by
* Guy Harris.
*/
diff --git a/contrib/tcpdump/print-sl.c b/contrib/tcpdump/print-sl.c
index 3fd7e89..a02077b 100644
--- a/contrib/tcpdump/print-sl.c
+++ b/contrib/tcpdump/print-sl.c
@@ -131,8 +131,21 @@ sliplink_print(netdissect_options *ndo,
u_int hlen;
dir = p[SLX_DIR];
- ND_PRINT((ndo, dir == SLIPDIR_IN ? "I " : "O "));
+ switch (dir) {
+ case SLIPDIR_IN:
+ ND_PRINT((ndo, "I "));
+ break;
+
+ case SLIPDIR_OUT:
+ ND_PRINT((ndo, "O "));
+ break;
+
+ default:
+ ND_PRINT((ndo, "Invalid direction %d ", dir));
+ dir = -1;
+ break;
+ }
if (ndo->ndo_nflag) {
/* XXX just dump the header */
register int i;
@@ -155,13 +168,21 @@ sliplink_print(netdissect_options *ndo,
* has restored the IP header copy to IPPROTO_TCP.
*/
lastconn = ((const struct ip *)&p[SLX_CHDR])->ip_p;
+ ND_PRINT((ndo, "utcp %d: ", lastconn));
+ if (dir == -1) {
+ /* Direction is bogus, don't use it */
+ return;
+ }
hlen = IP_HL(ip);
hlen += TH_OFF((const struct tcphdr *)&((const int *)ip)[hlen]);
lastlen[dir][lastconn] = length - (hlen << 2);
- ND_PRINT((ndo, "utcp %d: ", lastconn));
break;
default:
+ if (dir == -1) {
+ /* Direction is bogus, don't use it */
+ return;
+ }
if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
compressed_sl_print(ndo, &p[SLX_CHDR], ip,
length, dir);
diff --git a/contrib/tcpdump/print-slow.c b/contrib/tcpdump/print-slow.c
index 92d4a7b..d148479 100644
--- a/contrib/tcpdump/print-slow.c
+++ b/contrib/tcpdump/print-slow.c
@@ -15,7 +15,7 @@
* support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad
* OAM as per 802.3ah
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE "slow protocols" (802.3ad/802.3ah) printer */
diff --git a/contrib/tcpdump/print-stp.c b/contrib/tcpdump/print-stp.c
index 2f5c917..ee0627c 100644
--- a/contrib/tcpdump/print-stp.c
+++ b/contrib/tcpdump/print-stp.c
@@ -256,6 +256,7 @@ stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu,
return 1;
}
+ ND_TCHECK(stp_bpdu->flags);
ND_PRINT((ndo, "\n\tport-role %s, ",
tok2str(rstp_obj_port_role_values, "Unknown",
RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags))));
@@ -475,6 +476,7 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length)
if (stp_bpdu->protocol_version == STP_PROTO_SPB)
{
/* Validate v4 length */
+ ND_TCHECK_16BITS(p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
spb_len += 2;
if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) ||
diff --git a/contrib/tcpdump/print-syslog.c b/contrib/tcpdump/print-syslog.c
index ff86676..1756aa6 100644
--- a/contrib/tcpdump/print-syslog.c
+++ b/contrib/tcpdump/print-syslog.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
+ * Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at>
* The TCPDUMP project
*
* Redistribution and use in source and binary forms, with or without
diff --git a/contrib/tcpdump/print-telnet.c b/contrib/tcpdump/print-telnet.c
index a664034..10fad9f 100644
--- a/contrib/tcpdump/print-telnet.c
+++ b/contrib/tcpdump/print-telnet.c
@@ -442,6 +442,7 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print)
break;
p++;
}
+ ND_TCHECK(*p);
if (*p != IAC)
goto pktend;
diff --git a/contrib/tcpdump/print-tftp.c b/contrib/tcpdump/print-tftp.c
index 69bc601..6600c9c 100644
--- a/contrib/tcpdump/print-tftp.c
+++ b/contrib/tcpdump/print-tftp.c
@@ -46,21 +46,6 @@
#define TFTP_ERROR 05 /* error code */
#define OACK 06 /* option acknowledgement */
-struct tftphdr {
- unsigned short th_opcode; /* packet type */
- union {
- unsigned short tu_block; /* block # */
- unsigned short tu_code; /* error code */
- char tu_stuff[1]; /* request packet stuff */
- } th_u;
- char th_data[1]; /* data or error string */
-};
-
-#define th_block th_u.tu_block
-#define th_code th_u.tu_code
-#define th_stuff th_u.tu_stuff
-#define th_msg th_data
-
/*
* Error codes.
*/
@@ -106,80 +91,75 @@ void
tftp_print(netdissect_options *ndo,
register const u_char *bp, u_int length)
{
- register const struct tftphdr *tp;
register const char *cp;
- register const u_char *p;
register int opcode;
u_int ui;
- tp = (const struct tftphdr *)bp;
-
/* Print length */
ND_PRINT((ndo, " %d", length));
/* Print tftp request type */
if (length < 2)
goto trunc;
- ND_TCHECK(tp->th_opcode);
- opcode = EXTRACT_16BITS(&tp->th_opcode);
+ ND_TCHECK_16BITS(bp);
+ opcode = EXTRACT_16BITS(bp);
cp = tok2str(op2str, "tftp-#%d", opcode);
- length -= 2;
ND_PRINT((ndo, " %s", cp));
/* Bail if bogus opcode */
if (*cp == 't')
return;
+ bp += 2;
+ length -= 2;
switch (opcode) {
case RRQ:
case WRQ:
- p = (const u_char *)tp->th_stuff;
if (length == 0)
goto trunc;
ND_PRINT((ndo, " "));
/* Print filename */
ND_PRINT((ndo, "\""));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
ND_PRINT((ndo, "\""));
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
/* Print the mode - RRQ and WRQ only */
if (length == 0)
goto trunc; /* no mode */
ND_PRINT((ndo, " "));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
/* Print options, if any */
while (length != 0) {
- ND_TCHECK(*p);
- if (*p != '\0')
+ ND_TCHECK(*bp);
+ if (*bp != '\0')
ND_PRINT((ndo, " "));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
}
break;
case OACK:
- p = (const u_char *)tp->th_stuff;
/* Print options */
while (length != 0) {
- ND_TCHECK(*p);
- if (*p != '\0')
+ ND_TCHECK(*bp);
+ if (*bp != '\0')
ND_PRINT((ndo, " "));
- ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
- p += ui;
+ bp += ui;
length -= ui;
}
break;
@@ -188,23 +168,24 @@ tftp_print(netdissect_options *ndo,
case DATA:
if (length < 2)
goto trunc; /* no block number */
- ND_TCHECK(tp->th_block);
- ND_PRINT((ndo, " block %d", EXTRACT_16BITS(&tp->th_block)));
+ ND_TCHECK_16BITS(bp);
+ ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp)));
break;
case TFTP_ERROR:
/* Print error code string */
if (length < 2)
goto trunc; /* no error code */
- ND_TCHECK(tp->th_code);
+ ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"",
- EXTRACT_16BITS(&tp->th_code))));
+ EXTRACT_16BITS(bp))));
+ bp += 2;
length -= 2;
/* Print error message string */
if (length == 0)
goto trunc; /* no error message */
ND_PRINT((ndo, " \""));
- ui = fn_printztn(ndo, (const u_char *)tp->th_data, length, ndo->ndo_snapend);
+ ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
ND_PRINT((ndo, "\""));
if (ui == 0)
goto trunc;
diff --git a/contrib/tcpdump/print-vqp.c b/contrib/tcpdump/print-vqp.c
index 44a2193..90cf8dd 100644
--- a/contrib/tcpdump/print-vqp.c
+++ b/contrib/tcpdump/print-vqp.c
@@ -26,6 +26,7 @@
#include "netdissect.h"
#include "extract.h"
#include "addrtoname.h"
+#include "ether.h"
#define VQP_VERSION 1
#define VQP_EXTRACT_VERSION(x) ((x)&0xFF)
@@ -105,13 +106,15 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
const u_char *tptr;
uint16_t vqp_obj_len;
uint32_t vqp_obj_type;
- int tlen;
+ u_int tlen;
uint8_t nitems;
tptr=pptr;
tlen = len;
vqp_common_header = (const struct vqp_common_header_t *)pptr;
ND_TCHECK(*vqp_common_header);
+ if (sizeof(struct vqp_common_header_t) > tlen)
+ goto trunc;
/*
* Sanity checking of the header.
@@ -151,6 +154,9 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
while (nitems > 0 && tlen > 0) {
vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr;
+ ND_TCHECK(*vqp_obj_tlv);
+ if (sizeof(struct vqp_obj_tlv_t) > tlen)
+ goto trunc;
vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type);
vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length);
tptr+=sizeof(struct vqp_obj_tlv_t);
@@ -167,9 +173,13 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
/* did we capture enough for fully decoding the object ? */
ND_TCHECK2(*tptr, vqp_obj_len);
+ if (vqp_obj_len > tlen)
+ goto trunc;
switch(vqp_obj_type) {
case VQP_OBJ_IP_ADDRESS:
+ if (vqp_obj_len != 4)
+ goto trunc;
ND_PRINT((ndo, "%s (0x%08x)", ipaddr_string(ndo, tptr), EXTRACT_32BITS(tptr)));
break;
/* those objects have similar semantics - fall through */
@@ -182,6 +192,8 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
/* those objects have similar semantics - fall through */
case VQP_OBJ_MAC_ADDRESS:
case VQP_OBJ_MAC_NULL:
+ if (vqp_obj_len != ETHER_ADDR_LEN)
+ goto trunc;
ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr)));
break;
default:
diff --git a/contrib/tcpdump/print-vtp.c b/contrib/tcpdump/print-vtp.c
index 285beb9..d153cc1 100644
--- a/contrib/tcpdump/print-vtp.c
+++ b/contrib/tcpdump/print-vtp.c
@@ -13,9 +13,8 @@
* FOR A PARTICULAR PURPOSE.
*
* Reference documentation:
- * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml
- * http://www.cisco.com/warp/public/473/21.html
- * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ * http://www.cisco.com/c/en/us/support/docs/lan-switching/vtp/10558-21.html
+ * http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
*
* Original code ode by Carles Kishimoto <carles.kishimoto@gmail.com>
*/
@@ -36,7 +35,7 @@
#define VTP_DOMAIN_NAME_LEN 32
#define VTP_MD5_DIGEST_LEN 16
#define VTP_UPDATE_TIMESTAMP_LEN 12
-#define VTP_VLAN_INFO_OFFSET 12
+#define VTP_VLAN_INFO_FIXED_PART_LEN 12 /* length of VLAN info before VLAN name */
#define VTP_SUMMARY_ADV 0x01
#define VTP_SUBSET_ADV 0x02
@@ -223,6 +222,7 @@ vtp_print (netdissect_options *ndo,
*
*/
+ ND_TCHECK_32BITS(tptr);
ND_PRINT((ndo, ", Config Rev %x", EXTRACT_32BITS(tptr)));
/*
@@ -243,6 +243,7 @@ vtp_print (netdissect_options *ndo,
tptr += 4;
while (tptr < (pptr+length)) {
+ ND_TCHECK_8BITS(tptr);
len = *tptr;
if (len == 0)
break;
@@ -250,6 +251,8 @@ vtp_print (netdissect_options *ndo,
ND_TCHECK2(*tptr, len);
vtp_vlan = (const struct vtp_vlan_*)tptr;
+ if (len < VTP_VLAN_INFO_FIXED_PART_LEN)
+ goto trunc;
ND_TCHECK(*vtp_vlan);
ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ",
tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status),
@@ -257,22 +260,33 @@ vtp_print (netdissect_options *ndo,
EXTRACT_16BITS(&vtp_vlan->vlanid),
EXTRACT_16BITS(&vtp_vlan->mtu),
EXTRACT_32BITS(&vtp_vlan->index)));
- fn_printzp(ndo, tptr + VTP_VLAN_INFO_OFFSET, vtp_vlan->name_len, NULL);
-
- /*
- * Vlan names are aligned to 32-bit boundaries.
- */
- len -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
- tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
+ len -= VTP_VLAN_INFO_FIXED_PART_LEN;
+ tptr += VTP_VLAN_INFO_FIXED_PART_LEN;
+ if (len < 4*((vtp_vlan->name_len + 3)/4))
+ goto trunc;
+ ND_TCHECK2(*tptr, vtp_vlan->name_len);
+ fn_printzp(ndo, tptr, vtp_vlan->name_len, NULL);
+
+ /*
+ * Vlan names are aligned to 32-bit boundaries.
+ */
+ len -= 4*((vtp_vlan->name_len + 3)/4);
+ tptr += 4*((vtp_vlan->name_len + 3)/4);
/* TLV information follows */
while (len > 0) {
/*
- * Cisco specs says 2 bytes for type + 2 bytes for length, take only 1
- * See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ * Cisco specs say 2 bytes for type + 2 bytes for length;
+ * see http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ * However, actual packets on the wire appear to use 1
+ * byte for the type and 1 byte for the length, so that's
+ * what we do.
*/
+ if (len < 2)
+ goto trunc;
+ ND_TCHECK2(*tptr, 2);
type = *tptr;
tlv_len = *(tptr+1);
@@ -280,59 +294,65 @@ vtp_print (netdissect_options *ndo,
tok2str(vtp_vlan_tlv_values, "Unknown", type),
type));
- /*
- * infinite loop check
- */
- if (type == 0 || tlv_len == 0) {
+ if (len < tlv_len * 2 + 2) {
+ ND_PRINT((ndo, " (TLV goes past the end of the packet)"));
return;
}
-
ND_TCHECK2(*tptr, tlv_len * 2 +2);
- tlv_value = EXTRACT_16BITS(tptr+2);
-
- switch (type) {
- case VTP_VLAN_STE_HOP_COUNT:
- ND_PRINT((ndo, ", %u", tlv_value));
- break;
-
- case VTP_VLAN_PRUNING:
- ND_PRINT((ndo, ", %s (%u)",
- tlv_value == 1 ? "Enabled" : "Disabled",
- tlv_value));
- break;
-
- case VTP_VLAN_STP_TYPE:
- ND_PRINT((ndo, ", %s (%u)",
- tok2str(vtp_stp_type_values, "Unknown", tlv_value),
- tlv_value));
- break;
-
- case VTP_VLAN_BRIDGE_TYPE:
- ND_PRINT((ndo, ", %s (%u)",
- tlv_value == 1 ? "SRB" : "SRT",
- tlv_value));
- break;
-
- case VTP_VLAN_BACKUP_CRF_MODE:
- ND_PRINT((ndo, ", %s (%u)",
- tlv_value == 1 ? "Backup" : "Not backup",
- tlv_value));
- break;
-
- /*
- * FIXME those are the defined TLVs that lack a decoder
- * you are welcome to contribute code ;-)
- */
-
- case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
- case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
- case VTP_VLAN_PARENT_VLAN:
- case VTP_VLAN_TRANS_BRIDGED_VLAN:
- case VTP_VLAN_ARP_HOP_COUNT:
- default:
- print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2);
- break;
+ /*
+ * We assume the value is a 2-byte integer; the length is
+ * in units of 16-bit words.
+ */
+ if (tlv_len != 1) {
+ ND_PRINT((ndo, " (invalid TLV length %u != 1)", tlv_len));
+ return;
+ } else {
+ tlv_value = EXTRACT_16BITS(tptr+2);
+
+ switch (type) {
+ case VTP_VLAN_STE_HOP_COUNT:
+ ND_PRINT((ndo, ", %u", tlv_value));
+ break;
+
+ case VTP_VLAN_PRUNING:
+ ND_PRINT((ndo, ", %s (%u)",
+ tlv_value == 1 ? "Enabled" : "Disabled",
+ tlv_value));
+ break;
+
+ case VTP_VLAN_STP_TYPE:
+ ND_PRINT((ndo, ", %s (%u)",
+ tok2str(vtp_stp_type_values, "Unknown", tlv_value),
+ tlv_value));
+ break;
+
+ case VTP_VLAN_BRIDGE_TYPE:
+ ND_PRINT((ndo, ", %s (%u)",
+ tlv_value == 1 ? "SRB" : "SRT",
+ tlv_value));
+ break;
+
+ case VTP_VLAN_BACKUP_CRF_MODE:
+ ND_PRINT((ndo, ", %s (%u)",
+ tlv_value == 1 ? "Backup" : "Not backup",
+ tlv_value));
+ break;
+
+ /*
+ * FIXME those are the defined TLVs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
+ case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
+ case VTP_VLAN_PARENT_VLAN:
+ case VTP_VLAN_TRANS_BRIDGED_VLAN:
+ case VTP_VLAN_ARP_HOP_COUNT:
+ default:
+ print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2);
+ break;
+ }
}
len -= 2 + tlv_len*2;
tptr += 2 + tlv_len*2;
diff --git a/contrib/tcpdump/print-wb.c b/contrib/tcpdump/print-wb.c
index 88857d9..c0df48d 100644
--- a/contrib/tcpdump/print-wb.c
+++ b/contrib/tcpdump/print-wb.c
@@ -263,9 +263,8 @@ wb_prep(netdissect_options *ndo,
const u_char *ep = ndo->ndo_snapend;
ND_PRINT((ndo, " wb-prep:"));
- if (len < sizeof(*prep)) {
+ if (len < sizeof(*prep) || !ND_TTEST(*prep))
return (-1);
- }
n = EXTRACT_32BITS(&prep->pp_n);
ps = (const struct pgstate *)(prep + 1);
while (--n >= 0 && ND_TTEST(*ps)) {
@@ -419,31 +418,37 @@ wb_print(netdissect_options *ndo,
case PT_ID:
if (wb_id(ndo, (const struct pkt_id *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_RREQ:
if (wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_RREP:
if (wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_DRAWOP:
if (wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_PREQ:
if (wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
case PT_PREP:
if (wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len) >= 0)
return;
+ ND_PRINT((ndo, "%s", tstr));
break;
default:
diff --git a/contrib/tcpdump/print-zephyr.c b/contrib/tcpdump/print-zephyr.c
index 38b0cd0..735e273 100644
--- a/contrib/tcpdump/print-zephyr.c
+++ b/contrib/tcpdump/print-zephyr.c
@@ -76,30 +76,41 @@ static const struct tok z_types[] = {
{ Z_PACKET_SERVACK, "serv-ack" },
{ Z_PACKET_SERVNAK, "serv-nak" },
{ Z_PACKET_CLIENTACK, "client-ack" },
- { Z_PACKET_STAT, "stat" }
+ { Z_PACKET_STAT, "stat" },
+ { 0, NULL }
};
static char z_buf[256];
static const char *
-parse_field(netdissect_options *ndo, const char **pptr, int *len)
+parse_field(netdissect_options *ndo, const char **pptr, int *len, int *truncated)
{
const char *s;
- if (*len <= 0 || !pptr || !*pptr)
- return NULL;
- if (*pptr > (const char *) ndo->ndo_snapend)
- return NULL;
-
+ /* Start of string */
s = *pptr;
- while (*pptr <= (const char *) ndo->ndo_snapend && *len >= 0 && **pptr) {
+ /* Scan for the NUL terminator */
+ for (;;) {
+ if (*len == 0) {
+ /* Ran out of packet data without finding it */
+ return NULL;
+ }
+ if (!ND_TTEST(**pptr)) {
+ /* Ran out of captured data without finding it */
+ *truncated = 1;
+ return NULL;
+ }
+ if (**pptr == '\0') {
+ /* Found it */
+ break;
+ }
+ /* Keep scanning */
(*pptr)++;
(*len)--;
}
+ /* Skip the NUL terminator */
(*pptr)++;
(*len)--;
- if (*len < 0 || *pptr > (const char *) ndo->ndo_snapend)
- return NULL;
return s;
}
@@ -138,6 +149,7 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
int parselen = length;
const char *s;
int lose = 0;
+ int truncated = 0;
/* squelch compiler warnings */
@@ -148,8 +160,9 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
z.sender = 0;
z.recipient = 0;
-#define PARSE_STRING \
- s = parse_field(ndo, &parse, &parselen); \
+#define PARSE_STRING \
+ s = parse_field(ndo, &parse, &parselen, &truncated); \
+ if (truncated) goto trunc; \
if (!s) lose = 1;
#define PARSE_FIELD_INT(field) \
@@ -182,10 +195,8 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
PARSE_FIELD_INT(z.multi);
PARSE_FIELD_STR(z.multi_uid);
- if (lose) {
- ND_PRINT((ndo, " [|zephyr] (%d)", length));
- return;
- }
+ if (lose)
+ goto trunc;
ND_PRINT((ndo, " zephyr"));
if (strncmp(z.version+4, "0.2", 3)) {
@@ -317,4 +328,9 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
ND_PRINT((ndo, " to %s", z_triple(z.class, z.inst, z.recipient)));
if (*z.opcode)
ND_PRINT((ndo, " op %s", z.opcode));
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|zephyr] (%d)", length));
+ return;
}
diff --git a/contrib/tcpdump/print.c b/contrib/tcpdump/print.c
index 0e8a509..16a5369 100644
--- a/contrib/tcpdump/print.c
+++ b/contrib/tcpdump/print.c
@@ -229,23 +229,16 @@ static const struct printer printers[] = {
static void ndo_default_print(netdissect_options *ndo, const u_char *bp,
u_int length);
-static void ndo_error(netdissect_options *ndo, const char *fmt, ...)
- __attribute__((noreturn))
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 2, 3)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
-static void ndo_warning(netdissect_options *ndo, const char *fmt, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 2, 3)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
-
-static int ndo_printf(netdissect_options *ndo, const char *fmt, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute ((format (printf, 2, 3)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+static void ndo_error(netdissect_options *ndo,
+ FORMAT_STRING(const char *fmt), ...)
+ NORETURN PRINTFLIKE(2, 3);
+static void ndo_warning(netdissect_options *ndo,
+ FORMAT_STRING(const char *fmt), ...)
+ PRINTFLIKE(2, 3);
+
+static int ndo_printf(netdissect_options *ndo,
+ FORMAT_STRING(const char *fmt), ...)
+ PRINTFLIKE(2, 3);
void
init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask,
diff --git a/contrib/tcpdump/signature.c b/contrib/tcpdump/signature.c
index 1af798a..2091afb 100644
--- a/contrib/tcpdump/signature.c
+++ b/contrib/tcpdump/signature.c
@@ -12,7 +12,7 @@
*
* Functions for signature and digest verification.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
diff --git a/contrib/tcpdump/signature.h b/contrib/tcpdump/signature.h
index 239ee3e..bbb63ed 100644
--- a/contrib/tcpdump/signature.h
+++ b/contrib/tcpdump/signature.h
@@ -12,7 +12,7 @@
*
* Functions for signature and digest verification.
*
- * Original code by Hannes Gredler (hannes@juniper.net)
+ * Original code by Hannes Gredler (hannes@gredler.at)
*/
/* for netdissect_options */
diff --git a/contrib/tcpdump/smbutil.c b/contrib/tcpdump/smbutil.c
index b38d73a..fc9b3cc 100644
--- a/contrib/tcpdump/smbutil.c
+++ b/contrib/tcpdump/smbutil.c
@@ -237,6 +237,7 @@ name_len(netdissect_options *ndo,
return(-1); /* name goes past the end of the buffer */
ND_TCHECK2(*s, 1);
s += (*s) + 1;
+ ND_TCHECK2(*s, 1);
}
return(PTR_DIFF(s, s0) + 1);
diff --git a/contrib/tcpdump/tcpdump.1.in b/contrib/tcpdump/tcpdump.1.in
index f04a579..081e5d1 100644
--- a/contrib/tcpdump/tcpdump.1.in
+++ b/contrib/tcpdump/tcpdump.1.in
@@ -20,7 +20,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH TCPDUMP 1 "17 September 2015"
+.TH TCPDUMP 1 "2 February 2017"
.SH NAME
tcpdump \- dump traffic on a network
.SH SYNOPSIS
@@ -985,6 +985,27 @@ gives a brief description and examples of most of the formats.
.B
..
.HD
+Timestamps
+.LP
+By default, all output lines are preceded by a timestamp.
+The timestamp
+is the current clock time in the form
+.RS
+.nf
+\fIhh:mm:ss.frac\fP
+.fi
+.RE
+and is as accurate as the kernel's clock.
+The timestamp reflects the time the kernel applied a time stamp to the packet.
+No attempt is made to account for the time lag between when the network
+interface finished receiving the packet from the network and when the
+kernel applied a time stamp to the packet; that time lag could include a
+delay between the time when the network interface finished receiving a
+packet from the network and the time when an interrupt was delivered to
+the kernel to get it to read the packet and a delay between the time
+when the kernel serviced the `new packet' interrupt and the time when it
+applied a time stamp to the packet.
+.HD
Link Level Headers
.LP
If the '-e' option is given, the link level header is printed out.
@@ -1094,39 +1115,84 @@ For the first packet this says the Ethernet source address is RTSG, the
destination is the Ethernet broadcast address, the type field
contained hex 0806 (type ETHER_ARP) and the total length was 64 bytes.
.HD
+IPv4 Packets
+.LP
+If the link-layer header is not being printed, for IPv4 packets,
+\fBIP\fP is printed after the time stamp.
+.LP
+If the
+.B \-v
+flag is specified, information from the IPv4 header is shown in
+parentheses after the \fBIP\fP or the link-layer header.
+The general format of this information is:
+.RS
+.nf
+.sp .5
+tos \fItos\fP, ttl \fIttl\fP, id \fIid\fP, offset \fIoffset\fP, flags [\fIflags\fP], proto \fIproto\fP, length \fIlength\fP, options (\fIoptions\fP)
+.sp .5
+.fi
+.RE
+\fItos\fP is the type of service field; if the ECN bits are non-zero,
+those are reported as \fBECT(1)\fP, \fBECT(0)\fP, or \fBCE\fP.
+\fIttl\fP is the time-to-live; it is not reported if it is zero.
+\fIid\fP is the IP identification field.
+\fIoffset\fP is the fragment offset field; it is printed whether this is
+part of a fragmented datagram or not.
+\fIflags\fP are the MF and DF flags; \fB+\fP is reported if MF is set,
+and \fBDF\P is reported if F is set. If neither are set, \fB.\fP is
+reported.
+\fIproto\fP is the protocol ID field.
+\fIlength\fP is the total length field.
+\fIoptions\fP are the IP options, if any.
+.LP
+Next, for TCP and UDP packets, the source and destination IP addresses
+and TCP or UDP ports, with a dot between each IP address and its
+corresponding port, will be printed, with a > separating the source and
+destination. For other protocols, the addresses will be printed, with
+a > separating the source and destination. Higher level protocol
+information, if any, will be printed after that.
+.LP
+For fragmented IP datagrams, the first fragment contains the higher
+level protocol header; fragments after the first contain no higher level
+protocol header. Fragmentation information will be printed only with
+the
+.B \-v
+flag, in the IP header information, as described above.
+.HD
TCP Packets
.LP
\fI(N.B.:The following description assumes familiarity with
the TCP protocol described in RFC-793.
If you are not familiar
-with the protocol, neither this description nor \fItcpdump\fP will
+with the protocol, this description will not
be of much use to you.)\fP
.LP
-The general format of a tcp protocol line is:
+The general format of a TCP protocol line is:
.RS
.nf
.sp .5
-\fIsrc > dst: flags data-seqno ack window urgent options\fP
+\fIsrc\fP > \fIdst\fP: Flags [\fItcpflags\fP], seq \fIdata-seqno\fP, ack \fIackno\fP, win \fIwindow\fP, urg \fIurgent\fP, options [\fIopts\fP], length \fIlen\fP
.sp .5
.fi
.RE
\fISrc\fP and \fIdst\fP are the source and destination IP
addresses and ports.
-\fIFlags\fP are some combination of S (SYN),
+\fITcpflags\fP are some combination of S (SYN),
F (FIN), P (PUSH), R (RST), U (URG), W (ECN CWR), E (ECN-Echo) or
`.' (ACK), or `none' if no flags are set.
\fIData-seqno\fP describes the portion of sequence space covered
by the data in this packet (see example below).
-\fIAck\fP is sequence number of the next data expected the other
+\fIAckno\fP is sequence number of the next data expected the other
direction on this connection.
\fIWindow\fP is the number of bytes of receive buffer space available
the other direction on this connection.
\fIUrg\fP indicates there is `urgent' data in the packet.
-\fIOptions\fP are tcp options enclosed in angle brackets (e.g., <mss 1024>).
+\fIOpts\fP are TCP options (e.g., mss 1024).
+\fILen\fP is the length of payload data.
.LP
-\fISrc, dst\fP and \fIflags\fP are always present.
+\fIIptype\fR, \fISrc\fP, \fIdst\fP, and \fIflags\fP are always present.
The other fields
-depend on the contents of the packet's tcp protocol header and
+depend on the contents of the packet's TCP protocol header and
are output only if appropriate.
.LP
Here is the opening portion of an rlogin from host \fIrtsg\fP to
@@ -1134,26 +1200,26 @@ host \fIcsam\fP.
.RS
.nf
.sp .5
-\s-2\f(CWrtsg.1023 > csam.login: S 768512:768512(0) win 4096 <mss 1024>
-csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 <mss 1024>
-rtsg.1023 > csam.login: . ack 1 win 4096
-rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096
-csam.login > rtsg.1023: . ack 2 win 4096
-rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096
-csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077
-csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1
-csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1\fR\s+2
+\s-2\f(CWIP rtsg.1023 > csam.login: Flags [S], seq 768512:768512, win 4096, opts [mss 1024]
+IP csam.login > rtsg.1023: Flags [S.], seq, 947648:947648, ack 768513, win 4096, opts [mss 1024]
+IP rtsg.1023 > csam.login: Flags [.], ack 1, win 4096
+IP rtsg.1023 > csam.login: Flags [P.], seq 1:2, ack 1, win 4096, length 1
+IP csam.login > rtsg.1023: Flags [.], ack 2, win 4096
+IP rtsg.1023 > csam.login: Flags [P.], seq 2:21, ack 1, win 4096, length 19
+IP csam.login > rtsg.1023: Flags [P.], seq 1:2, ack 21, win 4077, length 1
+IP csam.login > rtsg.1023: Flags [P.], seq 2:3, ack 21, win 4077, urg 1, length 1
+IP csam.login > rtsg.1023: Flags [P.], seq 3:4, ack 21, win 4077, urg 1, length 1\fR\s+2
.sp .5
.fi
.RE
-The first line says that tcp port 1023 on rtsg sent a packet
+The first line says that TCP port 1023 on rtsg sent a packet
to port \fIlogin\fP
on csam.
The \fBS\fP indicates that the \fISYN\fP flag was set.
The packet sequence number was 768512 and it contained no data.
-(The notation is `first:last(nbytes)' which means `sequence
+(The notation is `first:last' which means `sequence
numbers \fIfirst\fP
-up to but not including \fIlast\fP which is \fInbytes\fP bytes of user data'.)
+up to but not including \fIlast\fP.)
There was no piggy-backed ack, the available receive window was 4096
bytes and there was a max-segment-size option requesting an mss of
1024 bytes.
@@ -1162,11 +1228,11 @@ Csam replies with a similar packet except it includes a piggy-backed
ack for rtsg's SYN.
Rtsg then acks csam's SYN.
The `.' means the ACK flag was set.
-The packet contained no data so there is no data sequence number.
+The packet contained no data so there is no data sequence number or length.
Note that the ack sequence
number is a small integer (1).
The first time \fItcpdump\fP sees a
-tcp `conversation', it prints the sequence number from the packet.
+TCP `conversation', it prints the sequence number from the packet.
On subsequent packets of the conversation, the difference between
the current packet's sequence number and this initial sequence number
is printed.
@@ -1811,81 +1877,6 @@ jssmag.209 initiates the next request.
The `*' on the request
indicates that XO (`exactly once') was \fInot\fP set.
-.HD
-IP Fragmentation
-.LP
-Fragmented Internet datagrams are printed as
-.RS
-.nf
-.sp .5
-\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB+)\fR
-\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB)\fR
-.sp .5
-.fi
-.RE
-(The first form indicates there are more fragments.
-The second
-indicates this is the last fragment.)
-.LP
-\fIId\fP is the fragment id.
-\fISize\fP is the fragment
-size (in bytes) excluding the IP header.
-\fIOffset\fP is this
-fragment's offset (in bytes) in the original datagram.
-.LP
-The fragment information is output for each fragment.
-The first
-fragment contains the higher level protocol header and the frag
-info is printed after the protocol info.
-Fragments
-after the first contain no higher level protocol header and the
-frag info is printed after the source and destination addresses.
-For example, here is part of an ftp from arizona.edu to lbl-rtsg.arpa
-over a CSNET connection that doesn't appear to handle 576 byte datagrams:
-.RS
-.nf
-.sp .5
-\s-2\f(CWarizona.ftp-data > rtsg.1170: . 1024:1332(308) ack 1 win 4096 (frag 595a:328@0+)
-arizona > rtsg: (frag 595a:204@328)
-rtsg.1170 > arizona.ftp-data: . ack 1536 win 2560\fP\s+2
-.sp .5
-.fi
-.RE
-There are a couple of things to note here: First, addresses in the
-2nd line don't include port numbers.
-This is because the TCP
-protocol information is all in the first fragment and we have no idea
-what the port or sequence numbers are when we print the later fragments.
-Second, the tcp sequence information in the first line is printed as if there
-were 308 bytes of user data when, in fact, there are 512 bytes (308 in
-the first frag and 204 in the second).
-If you are looking for holes
-in the sequence space or trying to match up acks
-with packets, this can fool you.
-.LP
-A packet with the IP \fIdon't fragment\fP flag is marked with a
-trailing \fB(DF)\fP.
-.HD
-Timestamps
-.LP
-By default, all output lines are preceded by a timestamp.
-The timestamp
-is the current clock time in the form
-.RS
-.nf
-\fIhh:mm:ss.frac\fP
-.fi
-.RE
-and is as accurate as the kernel's clock.
-The timestamp reflects the time the kernel applied a time stamp to the packet.
-No attempt is made to account for the time lag between when the network
-interface finished receiving the packet from the network and when the
-kernel applied a time stamp to the packet; that time lag could include a
-delay between the time when the network interface finished receiving a
-packet from the network and the time when an interrupt was delivered to
-the kernel to get it to read the packet and a delay between the time
-when the kernel serviced the `new packet' interrupt and the time when it
-applied a time stamp to the packet.
.SH "SEE ALSO"
stty(1), pcap(3PCAP), bpf(4), nit(4P), pcap-savefile(@MAN_FILE_FORMATS@),
pcap-filter(@MAN_MISC_INFO@), pcap-tstamp(@MAN_MISC_INFO@)
@@ -1919,12 +1910,12 @@ The original distribution is available via anonymous ftp:
IPv6/IPsec support is added by WIDE/KAME project.
This program uses Eric Young's SSLeay library, under specific configurations.
.SH BUGS
-Please send problems, bugs, questions, desirable enhancements, patches
-etc. to:
+To report a security issue please send an e-mail to \%security@tcpdump.org.
.LP
-.RS
-tcpdump-workers@lists.tcpdump.org
-.RE
+To report bugs and other problems, contribute patches, request a
+feature, provide generic feedback etc please see the file
+.I CONTRIBUTING
+in the tcpdump source tree root.
.LP
NIT doesn't let you watch your own outbound traffic, BPF will.
We recommend that you use the latter.
diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c
index 202dce2..b3e60da 100644
--- a/contrib/tcpdump/tcpdump.c
+++ b/contrib/tcpdump/tcpdump.c
@@ -136,7 +136,7 @@ The Regents of the University of California. All rights reserved.\n";
#endif
static int Bflag; /* buffer size */
-static int Cflag; /* rotate dump files after this many bytes */
+static long Cflag; /* rotate dump files after this many bytes */
static int Cflag_count; /* Keep track of which file number we're writing */
static int Dflag; /* list available devices and exit */
/*
@@ -181,26 +181,17 @@ cap_channel_t *capdns;
#endif
/* Forwards */
-static void error(const char *, ...)
- __attribute__((noreturn))
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 1, 2)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
-static void warning(const char *, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 1, 2)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
-static void exit_tcpdump(int) __attribute__((noreturn));
+static void error(FORMAT_STRING(const char *), ...) NORETURN PRINTFLIKE(1, 2);
+static void warning(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2);
+static void exit_tcpdump(int) NORETURN;
static RETSIGTYPE cleanup(int);
static RETSIGTYPE child_cleanup(int);
static void print_version(void);
static void print_usage(void);
-static void show_tstamp_types_and_exit(pcap_t *, const char *device) __attribute__((noreturn));
-static void show_dlts_and_exit(pcap_t *, const char *device) __attribute__((noreturn));
+static void show_tstamp_types_and_exit(pcap_t *, const char *device) NORETURN;
+static void show_dlts_and_exit(pcap_t *, const char *device) NORETURN;
#ifdef HAVE_PCAP_FINDALLDEVS
-static void show_devices_and_exit (void) __attribute__((noreturn));
+static void show_devices_and_exit (void) NORETURN;
#endif
static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
@@ -1085,9 +1076,9 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf)
/*
* Return an error for our caller to handle.
*/
- pcap_close(pc);
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)",
device, pcap_statustostr(status), cp);
+ pcap_close(pc);
return (NULL);
} else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0')
error("%s: %s\n(%s)", device,
@@ -1922,10 +1913,10 @@ main(int argc, char **argv)
/*
* The various libpcap devices use a combination of
- * read (bpf), ioctl (bpf, netmap), poll (netmap).
- * Grant the relevant access rights, sorted by name.
+ * read (bpf), ioctl (bpf, netmap), poll (netmap)
+ * so we add the relevant access rights.
*/
- cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ);
+ cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_EVENT);
if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
errno != ENOSYS) {
error("unable to limit pcap descriptor");
@@ -2674,6 +2665,14 @@ print_version(void)
smi_version_string = nd_smi_version_string();
if (smi_version_string != NULL)
(void)fprintf (stderr, "SMI-library: %s\n", smi_version_string);
+
+#if defined(__SANITIZE_ADDRESS__)
+ (void)fprintf (stderr, "Compiled with AddressSanitizer/GCC.\n");
+#elif defined(__has_feature)
+# if __has_feature(address_sanitizer)
+ (void)fprintf (stderr, "Compiled with AddressSanitizer/CLang.\n");
+# endif
+#endif /* __SANITIZE_ADDRESS__ or __has_feature */
}
USES_APPLE_RST
diff --git a/contrib/tcpdump/util-print.c b/contrib/tcpdump/util-print.c
index 5db042a..90e11b9 100644
--- a/contrib/tcpdump/util-print.c
+++ b/contrib/tcpdump/util-print.c
@@ -21,7 +21,7 @@
/*
* txtproto_print() derived from original code by Hannes Gredler
- * (hannes@juniper.net):
+ * (hannes@gredler.at):
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code
@@ -521,8 +521,9 @@ static char *
bittok2str_internal(register const struct tok *lp, register const char *fmt,
register u_int v, const char *sep)
{
- static char buf[256]; /* our stringbuffer */
- int buflen=0;
+ static char buf[1024+1]; /* our string buffer */
+ char *bufp = buf;
+ size_t space_left = sizeof(buf), string_size;
register u_int rotbit; /* this is the bit we rotate through all bitpositions */
register u_int tokval;
const char * sepstr = "";
@@ -537,8 +538,20 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt,
*/
if (tokval == (v&rotbit)) {
/* ok we have found something */
- buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s",
- sepstr, lp->s);
+ if (space_left <= 1)
+ return (buf); /* only enough room left for NUL, if that */
+ string_size = strlcpy(bufp, sepstr, space_left);
+ if (string_size >= space_left)
+ return (buf); /* we ran out of room */
+ bufp += string_size;
+ space_left -= string_size;
+ if (space_left <= 1)
+ return (buf); /* only enough room left for NUL, if that */
+ string_size = strlcpy(bufp, lp->s, space_left);
+ if (string_size >= space_left)
+ return (buf); /* we ran out of room */
+ bufp += string_size;
+ space_left -= string_size;
sepstr = sep;
break;
}
@@ -547,7 +560,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt,
lp++;
}
- if (buflen == 0)
+ if (bufp == buf)
/* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
(void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v);
return (buf);
@@ -902,7 +915,7 @@ safeputs(netdissect_options *ndo,
{
u_int idx = 0;
- while (*s && idx < maxlen) {
+ while (idx < maxlen && *s) {
safeputchar(ndo, *s);
idx++;
s++;
diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index 516da89..3569289 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -51,6 +51,7 @@ tmpmfs_flags="-S" # Extra mdmfs options for the mfs /tmp
varmfs="AUTO" # Set to YES to always create an mfs /var, NO to never
varsize="32m" # Size of mfs /var if created
varmfs_flags="-S" # Extra mount options for the mfs /var
+mfs_type="auto" # "md", "tmpfs", "auto" to prefer tmpfs with md as fallback
populate_var="AUTO" # Set to YES to always (re)populate /var, NO to never
cleanvar_enable="YES" # Clean the /var directory
local_startup="/usr/local/etc/rc.d" # startup script dirs.
diff --git a/etc/mtree/BSD.debug.dist b/etc/mtree/BSD.debug.dist
index 6219da0..47ec36f 100644
--- a/etc/mtree/BSD.debug.dist
+++ b/etc/mtree/BSD.debug.dist
@@ -29,7 +29,7 @@
..
lib
clang
- 5.0.0
+ 5.0.1
lib
freebsd
..
diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index 5ec19c2..51b8c0d 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -65,6 +65,8 @@
sbin
..
usr.bin
+ ctfconvert
+ ..
..
usr.sbin
dtrace
@@ -640,6 +642,8 @@
..
file2c
..
+ fold
+ ..
getconf
..
grep
@@ -672,6 +676,8 @@
..
procstat
..
+ rs
+ ..
sdiff
..
sed
diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
index af0a10a..f8d30b6 100644
--- a/etc/mtree/BSD.usr.dist
+++ b/etc/mtree/BSD.usr.dist
@@ -19,7 +19,7 @@
aout
..
clang
- 5.0.0
+ 5.0.1
include
sanitizer
..
diff --git a/etc/rc.initdiskless b/etc/rc.initdiskless
index ae91f28..3e9c2c7 100644
--- a/etc/rc.initdiskless
+++ b/etc/rc.initdiskless
@@ -195,10 +195,11 @@ handle_remount() { # $1 = mount point
to_umount="$b ${to_umount}"
}
-# Create a generic memory disk
-#
+# Create a generic memory disk.
+# The 'auto' parameter will attempt to use tmpfs(5), falls back to md(4).
+# $1 is size in 512-byte sectors, $2 is the mount point.
mount_md() {
- /sbin/mdmfs -S -i 4096 -s $1 -M md $2
+ /sbin/mdmfs -s $1 auto $2
}
# Create the memory filesystem if it has not already been created
diff --git a/etc/rc.subr b/etc/rc.subr
index 7d88efc..bfa43e2 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -1834,7 +1834,7 @@ mount_md()
if [ -n "$3" ]; then
flags="$3"
fi
- /sbin/mdmfs $flags -s $1 md $2
+ /sbin/mdmfs $flags -s $1 ${mfs_type} $2
}
# Code common to scripts that need to load a kernel module
diff --git a/lib/Makefile b/lib/Makefile
index 3a48482..42ed476 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -49,7 +49,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
libdwarf \
libedit \
${_libefivar} \
- ${_libelftc} \
+ libelftc \
libevent \
libexecinfo \
libexpat \
@@ -188,7 +188,6 @@ _cuse= libcuse
.endif
.if ${MK_TOOLCHAIN} != "no"
-_libelftc= libelftc
_libpe= libpe
.endif
diff --git a/lib/clang/headers/Makefile b/lib/clang/headers/Makefile
index 710e9f4..3e401ef 100644
--- a/lib/clang/headers/Makefile
+++ b/lib/clang/headers/Makefile
@@ -4,7 +4,7 @@
.PATH: ${CLANG_SRCS}/lib/Headers
-INCSDIR= ${LIBDIR}/clang/5.0.0/include
+INCSDIR= ${LIBDIR}/clang/5.0.1/include
GENINCS+= arm_neon.h
diff --git a/lib/clang/include/clang/Basic/Version.inc b/lib/clang/include/clang/Basic/Version.inc
index 51e63ee..67ace7f 100644
--- a/lib/clang/include/clang/Basic/Version.inc
+++ b/lib/clang/include/clang/Basic/Version.inc
@@ -1,11 +1,11 @@
/* $FreeBSD$ */
-#define CLANG_VERSION 5.0.0
-#define CLANG_VERSION_STRING "5.0.0"
+#define CLANG_VERSION 5.0.1
+#define CLANG_VERSION_STRING "5.0.1"
#define CLANG_VERSION_MAJOR 5
#define CLANG_VERSION_MINOR 0
-#define CLANG_VERSION_PATCHLEVEL 0
+#define CLANG_VERSION_PATCHLEVEL 1
#define CLANG_VENDOR "FreeBSD "
-#define SVN_REVISION "312559"
+#define SVN_REVISION "320880"
diff --git a/lib/clang/include/clang/Config/config.h b/lib/clang/include/clang/Config/config.h
index b8bc8c4..5f59345 100644
--- a/lib/clang/include/clang/Config/config.h
+++ b/lib/clang/include/clang/Config/config.h
@@ -46,7 +46,7 @@
#define CLANG_HAVE_RLIMITS 1
/* The LLVM product name and version */
-#define BACKEND_PACKAGE_STRING "LLVM 5.0.0svn"
+#define BACKEND_PACKAGE_STRING "LLVM 5.0.1"
/* Linker version detected at compile time. */
/* #undef HOST_LINK_VERSION */
diff --git a/lib/clang/include/lld/Config/Version.inc b/lib/clang/include/lld/Config/Version.inc
index 4dad500..6f72748 100644
--- a/lib/clang/include/lld/Config/Version.inc
+++ b/lib/clang/include/lld/Config/Version.inc
@@ -1,8 +1,8 @@
// $FreeBSD$
-#define LLD_VERSION 5.0.0
-#define LLD_VERSION_STRING "5.0.0"
+#define LLD_VERSION 5.0.1
+#define LLD_VERSION_STRING "5.0.1"
#define LLD_VERSION_MAJOR 5
#define LLD_VERSION_MINOR 0
-#define LLD_REVISION_STRING "312559"
+#define LLD_REVISION_STRING "320880"
#define LLD_REPOSITORY_STRING "FreeBSD"
diff --git a/lib/clang/include/llvm/Config/config.h b/lib/clang/include/llvm/Config/config.h
index 1a0d316..6f3fb10 100644
--- a/lib/clang/include/llvm/Config/config.h
+++ b/lib/clang/include/llvm/Config/config.h
@@ -386,10 +386,10 @@
#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
-#define LLVM_VERSION_PATCH 0
+#define LLVM_VERSION_PATCH 1
/* LLVM version string */
-#define LLVM_VERSION_STRING "5.0.0svn"
+#define LLVM_VERSION_STRING "5.0.1"
/* Define to the extension used for shared libraries, say, ".so". */
#define LTDL_SHLIB_EXT ".so"
@@ -401,13 +401,13 @@
#define PACKAGE_NAME "LLVM"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "LLVM 5.0.0svn"
+#define PACKAGE_STRING "LLVM 5.0.1"
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
-#define PACKAGE_VERSION "5.0.0svn"
+#define PACKAGE_VERSION "5.0.1"
/* Define to the vendor of this package. */
/* #undef PACKAGE_VENDOR */
diff --git a/lib/clang/include/llvm/Config/llvm-config.h b/lib/clang/include/llvm/Config/llvm-config.h
index f922655..d288d8a 100644
--- a/lib/clang/include/llvm/Config/llvm-config.h
+++ b/lib/clang/include/llvm/Config/llvm-config.h
@@ -70,9 +70,9 @@
#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
-#define LLVM_VERSION_PATCH 0
+#define LLVM_VERSION_PATCH 1
/* LLVM version string */
-#define LLVM_VERSION_STRING "5.0.0svn"
+#define LLVM_VERSION_STRING "5.0.1"
#endif
diff --git a/lib/clang/include/llvm/Support/VCSRevision.h b/lib/clang/include/llvm/Support/VCSRevision.h
index a1682db..053a7d4 100644
--- a/lib/clang/include/llvm/Support/VCSRevision.h
+++ b/lib/clang/include/llvm/Support/VCSRevision.h
@@ -1,2 +1,2 @@
/* $FreeBSD$ */
-#define LLVM_REVISION "svn-r312559"
+#define LLVM_REVISION "svn-r320880"
diff --git a/lib/libc/gen/isgreater.3 b/lib/libc/gen/isgreater.3
index 9a6d85c..27e958f 100644
--- a/lib/libc/gen/isgreater.3
+++ b/lib/libc/gen/isgreater.3
@@ -75,9 +75,9 @@ macro takes arguments
.Fa x
and
.Fa y
-and returns non-zero if and only if neither
+and returns non-zero if and only if any of
.Fa x
-nor
+or
.Fa y
are NaNs.
For any pair of floating-point values, one
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
index d705028..ba61eb8 100644
--- a/lib/libc/net/getaddrinfo.c
+++ b/lib/libc/net/getaddrinfo.c
@@ -1275,7 +1275,8 @@ explore_numeric(const struct addrinfo *pai, const char *hostname,
* does not accept. So we need to separate the case for
* AF_INET.
*/
- if (inet_aton(hostname, (struct in_addr *)pton) != 1)
+ if (inet_aton(hostname, (struct in_addr *)pton) != 1 ||
+ hostname[strspn(hostname, "0123456789.xabcdefXABCDEF")] != '\0')
return 0;
p = pton;
break;
diff --git a/lib/libclang_rt/Makefile.inc b/lib/libclang_rt/Makefile.inc
index f7687ef..9d915dd 100644
--- a/lib/libclang_rt/Makefile.inc
+++ b/lib/libclang_rt/Makefile.inc
@@ -7,7 +7,7 @@ CRTSRC= ${SRCTOP}/contrib/compiler-rt
.PATH: ${CRTSRC}/lib
-CLANGDIR= /usr/lib/clang/5.0.0
+CLANGDIR= /usr/lib/clang/5.0.1
LIBDIR= ${CLANGDIR}/lib/freebsd
NO_PIC=
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index 1e9c794..badabac 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -1075,7 +1075,7 @@ user(char *name)
}
}
if (logging)
- strncpy(curname, name, sizeof(curname)-1);
+ strlcpy(curname, name, sizeof(curname));
pwok = 0;
#ifdef USE_PAM
diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf
index 5637325..984fbac 100644
--- a/release/tools/ec2.conf
+++ b/release/tools/ec2.conf
@@ -9,7 +9,7 @@
export VM_EXTRA_PACKAGES="ec2-scripts firstboot-freebsd-update firstboot-pkgs dual-dhclient"
# Set to a list of third-party software to enable in rc.conf(5).
-export VM_RC_LIST="ec2_configinit ec2_fetchkey ec2_ephemeralswap ec2_loghostkey firstboot_freebsd_update firstboot_pkgs"
+export VM_RC_LIST="ec2_configinit ec2_fetchkey ec2_ephemeralswap ec2_loghostkey firstboot_freebsd_update firstboot_pkgs ntpd"
# Build with a 2 GB UFS partition; the growfs rc.d script will expand
# the partition to fill the root disk after the EC2 instance is launched.
@@ -81,6 +81,11 @@ vm_extra_pre_umount() {
# Load the kernel module for the Amazon "Elastic Network Adapter"
echo 'if_ena_load="YES"' >> ${DESTDIR}/boot/loader.conf
+ # Use the NTP service provided by Amazon
+ sed -i '' -e 's/^pool/#pool/' \
+ -e 's/^#server.*/server 169.254.169.123 iburst/' \
+ ${DESTDIR}/etc/ntp.conf
+
# The first time the AMI boots, the installed "first boot" scripts
# should be allowed to run:
# * ec2_configinit (download and process EC2 user-data)
diff --git a/sbin/geom/class/mirror/gmirror.8 b/sbin/geom/class/mirror/gmirror.8
index d8400f1..128138b 100644
--- a/sbin/geom/class/mirror/gmirror.8
+++ b/sbin/geom/class/mirror/gmirror.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 27, 2016
+.Dd November 30, 2017
.Dt GMIRROR 8
.Os
.Sh NAME
@@ -179,7 +179,7 @@ Defaults to 4096 bytes.
Clear metadata on the given providers.
.It Cm create
Similar to
-.Cm label,
+.Cm label ,
but creates mirror without storing on-disk metadata in last sector.
This special "manual" operation mode assumes some external control to manage
mirror detection after reboot, device hot-plug and other external events.
@@ -337,6 +337,45 @@ gmirror deactivate data da1
dd if=/dev/da1 of=/backup/data.img bs=1m
gmirror activate data da1
.Ed
+.Sh SYSCTL VARIABLES
+The following
+.Xr sysctl 8
+variables can be used to configure behavior for all mirrors.
+.Bl -tag -width indent
+.It Va kern.geom.mirror.debug
+Control the verbosity of kernel logging related to mirrors.
+A value larger than 0 will enable debug logging.
+.It Va kern.geom.mirror.timeout
+The amount of time, in seconds, to wait for all copies of a mirror to
+appear before starting the mirror.
+Disks that appear after the mirror has been started are not automatically
+added to the mirror.
+.It Va kern.geom.mirror.idletime
+The amount of time, in seconds, which must elapse after the last write to
+a mirror before that mirror is marked clean.
+Clean mirrors do not need to be synchronized after a power failure or
+system crash.
+A small value may result in frequent overwrites of the disks' metadata
+sectors, and thus may reduce the longevity of the disks.
+.It Va kern.geom.mirror.disconnect_on_failure
+Determine whether a disk is automatically removed from its mirror when an
+I/O request to that disk fails.
+.It Va kern.geom.mirror.sync_requests
+The number of parallel I/O requests used while synchronizing a mirror.
+This parameter may only be configured as a
+.Xr loader.conf 5
+tunable.
+.It Va kern.geom.mirror.sync_update_period
+The period, in seconds, at which a synchronizing mirror's metadata is
+updated.
+Periodic updates are used to record a synchronization's progress so that
+an interrupted synchronization may be resumed starting at the recorded
+offset, rather than at the beginning.
+A smaller value results in more accurate progress tracking, but also
+increases the number of non-sequential writes to the disk being synchronized.
+If the sysctl value is 0, no updates are performed until the synchronization
+is complete.
+.El
.Sh NOTES
Doing kernel dumps to
.Nm
@@ -382,6 +421,7 @@ there.
.Xr mount 8 ,
.Xr newfs 8 ,
.Xr savecore 8 ,
+.Xr sysctl 8 ,
.Xr umount 8
.Sh HISTORY
The
@@ -394,7 +434,3 @@ utility appeared in
There should be a way to change a component's priority inside a running mirror.
.Pp
There should be a section with an implementation description.
-.Pp
-Documentation for sysctls
-.Va kern.geom.mirror.*
-is missing.
diff --git a/sbin/ifconfig/ifvxlan.c b/sbin/ifconfig/ifvxlan.c
index 91c2538..ba4f7fa 100644
--- a/sbin/ifconfig/ifvxlan.c
+++ b/sbin/ifconfig/ifvxlan.c
@@ -594,6 +594,7 @@ setvxlan_flush(const char *val, int d, int s, const struct afswtch *afp)
static struct cmd vxlan_cmds[] = {
+ DEF_CLONE_CMD_ARG("vni", setvxlan_vni),
DEF_CLONE_CMD_ARG("vxlanid", setvxlan_vni),
DEF_CLONE_CMD_ARG("vxlanlocal", setvxlan_local),
DEF_CLONE_CMD_ARG("vxlanremote", setvxlan_remote),
@@ -608,7 +609,8 @@ static struct cmd vxlan_cmds[] = {
DEF_CLONE_CMD("vxlanlearn", 1, setvxlan_learn),
DEF_CLONE_CMD("-vxlanlearn", 0, setvxlan_learn),
- DEF_CMD_ARG("vxlanvni", setvxlan_vni),
+ DEF_CMD_ARG("vni", setvxlan_vni),
+ DEF_CMD_ARG("vxlanid", setvxlan_vni),
DEF_CMD_ARG("vxlanlocal", setvxlan_local),
DEF_CMD_ARG("vxlanremote", setvxlan_remote),
DEF_CMD_ARG("vxlangroup", setvxlan_group),
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index bb870fb..97ee75d 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -2262,12 +2262,13 @@ do_range_cmd(int cmd, ipfw_range_tlv *rt)
void
ipfw_sets_handler(char *av[])
{
- uint32_t masks[2];
- int i;
- uint8_t cmd, rulenum;
ipfw_range_tlv rt;
char *msg;
size_t size;
+ uint32_t masks[2];
+ int i;
+ uint16_t rulenum;
+ uint8_t cmd;
av++;
memset(&rt, 0, sizeof(rt));
diff --git a/sbin/mdmfs/mdmfs.8 b/sbin/mdmfs/mdmfs.8
index a91cab2..46ed654 100644
--- a/sbin/mdmfs/mdmfs.8
+++ b/sbin/mdmfs/mdmfs.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 9, 2016
+.Dd September 9, 2017
.Dt MDMFS 8
.Os
.Sh NAME
@@ -33,7 +33,9 @@
.Nm mount_mfs
.Nd configure and mount an in-memory file system using the
.Xr md 4
-driver
+driver or the
+.Xr tmpfs 5
+filesystem
.Sh SYNOPSIS
.Nm
.Op Fl DLlMNnPStTUX
@@ -63,9 +65,13 @@ utility is designed to be a work-alike and look-alike of the deprecated
.Xr mount_mfs 8 .
The end result is essentially the same,
but is accomplished in a completely different way.
-The
+Based on
+.Ar md-device ,
+the
.Nm
-utility configures an
+utility either creates a
+.Xr tmpfs 5
+filesystem, or it configures an
.Xr md 4
disk using
.Xr mdconfig 8 ,
@@ -81,6 +87,44 @@ compressed disk images, as long as the kernel supports this GEOM class.
All the command line options are passed to the appropriate program
at the appropriate stage in order to achieve the desired effect.
.Pp
+When
+.Ar md-device
+is `auto',
+.Nm
+uses
+.Xr tmpfs 5
+if it is present in the kernel or can be loaded as a module,
+otherwise it falls back to using
+.Xr md 4
+auto-unit as if `md' had been specified.
+.Pp
+When
+.Ar md-device
+is `tmpfs',
+.Nm
+mounts a
+.Xr tmpfs 5
+filesystem, translating the
+.Fl s
+size option, if present, into a `-o size=' mount option.
+Any
+.Fl o
+options on the command line are passed through to the
+.Xr tmpfs 5
+mount.
+Options specific to
+.Xr mdconfig 8
+or
+.Xr newfs 8
+are ignored.
+.Pp
+When
+.Ar md-device
+does not result in
+.Xr tmpfs 5
+being used, then an
+.Xr md 4
+device is configured instead.
By default,
.Nm
creates a swap-based
@@ -218,14 +262,10 @@ is
.Em not
specified.
That is,
-this will work for the default swap-backed
-.Pq Dv MD_SWAP
-disks,
-and the optional
-.Pq Fl M
-.Xr malloc 9
-backed disks
-.Pq Dv MD_MALLOC .
+this will work when the backing storage is some form of
+memory, as opposed to a fixed-size file.
+The size may include the usual SI suffixes (k, m, g, t, p).
+A number without a suffix is interpreted as a count of 512-byte sectors.
.It Fl t
Turn on the TRIM enable flag for
.Xr newfs 8 .
@@ -391,6 +431,7 @@ was given on the command line.
.Sh SEE ALSO
.Xr md 4 ,
.Xr fstab 5 ,
+.Xr tmpfs 5 ,
.Xr mdconfig 8 ,
.Xr mount 8 ,
.Xr newfs 8
diff --git a/sbin/mdmfs/mdmfs.c b/sbin/mdmfs/mdmfs.c
index 4b3a012..d2089f2 100644
--- a/sbin/mdmfs/mdmfs.c
+++ b/sbin/mdmfs/mdmfs.c
@@ -34,15 +34,19 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/linker.h>
#include <sys/mdioctl.h>
+#include <sys/module.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <assert.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <grp.h>
+#include <inttypes.h>
#include <paths.h>
#include <pwd.h>
#include <stdarg.h>
@@ -78,7 +82,8 @@ static void debugprintf(const char *, ...) __printflike(1, 2);
static void do_mdconfig_attach(const char *, const enum md_types);
static void do_mdconfig_attach_au(const char *, const enum md_types);
static void do_mdconfig_detach(void);
-static void do_mount(const char *, const char *);
+static void do_mount_md(const char *, const char *);
+static void do_mount_tmpfs(const char *, const char *);
static void do_mtptsetup(const char *, struct mtpt_info *);
static void do_newfs(const char *);
static void extract_ugid(const char *, struct mtpt_info *);
@@ -89,14 +94,15 @@ int
main(int argc, char **argv)
{
struct mtpt_info mi; /* Mountpoint info. */
+ intmax_t mdsize;
char *mdconfig_arg, *newfs_arg, /* Args to helper programs. */
*mount_arg;
enum md_types mdtype; /* The type of our memory disk. */
- bool have_mdtype;
+ bool have_mdtype, mlmac;
bool detach, softdep, autounit, newfs;
- char *mtpoint, *unitstr;
+ const char *mtpoint, *size_arg, *unitstr;
char *p;
- int ch;
+ int ch, idx;
void *set;
unsigned long ul;
@@ -105,6 +111,7 @@ main(int argc, char **argv)
detach = true;
softdep = true;
autounit = false;
+ mlmac = false;
newfs = true;
have_mdtype = false;
mdtype = MD_SWAP;
@@ -119,6 +126,7 @@ main(int argc, char **argv)
mdconfig_arg = strdup("");
newfs_arg = strdup("");
mount_arg = strdup("");
+ size_arg = NULL;
/* If we were started as mount_mfs or mfs, imply -C. */
if (strcmp(getprogname(), "mount_mfs") == 0 ||
@@ -175,6 +183,7 @@ main(int argc, char **argv)
loudsubs = true;
break;
case 'l':
+ mlmac = true;
argappend(&newfs_arg, "-l");
break;
case 'M':
@@ -213,7 +222,7 @@ main(int argc, char **argv)
softdep = false;
break;
case 's':
- argappend(&mdconfig_arg, "-s %s", optarg);
+ size_arg = optarg;
break;
case 't':
argappend(&newfs_arg, "-t");
@@ -242,42 +251,107 @@ main(int argc, char **argv)
if (argc < 2)
usage();
- /* Derive 'unit' (global). */
+ /*
+ * Historically our size arg was passed directly to mdconfig, which
+ * treats a number without a suffix as a count of 512-byte sectors;
+ * tmpfs would treat it as a count of bytes. To get predictable
+ * behavior for 'auto' we document that the size always uses mdconfig
+ * rules. To make that work, decode the size here so it can be passed
+ * to either tmpfs or mdconfig as a count of bytes.
+ */
+ if (size_arg != NULL) {
+ mdsize = (intmax_t)strtoumax(size_arg, &p, 0);
+ if (p == size_arg || (p[0] != 0 && p[1] != 0) || mdsize < 0)
+ errx(1, "invalid size '%s'", size_arg);
+ switch (*p) {
+ case 'p':
+ case 'P':
+ mdsize *= 1024;
+ case 't':
+ case 'T':
+ mdsize *= 1024;
+ case 'g':
+ case 'G':
+ mdsize *= 1024;
+ case 'm':
+ case 'M':
+ mdsize *= 1024;
+ case 'k':
+ case 'K':
+ mdsize *= 1024;
+ case 'b':
+ case 'B':
+ break;
+ case '\0':
+ mdsize *= 512;
+ break;
+ default:
+ errx(1, "invalid size suffix on '%s'", size_arg);
+ }
+ }
+
+ /*
+ * Based on the command line 'md-device' either mount a tmpfs filesystem
+ * or configure the md device then format and mount a filesystem on it.
+ * If the device is 'auto' use tmpfs if it is available and there is no
+ * request for multilabel MAC (which tmpfs does not support).
+ */
unitstr = argv[0];
- if (strncmp(unitstr, "/dev/", 5) == 0)
- unitstr += 5;
- if (strncmp(unitstr, mdname, mdnamelen) == 0)
- unitstr += mdnamelen;
- if (!isdigit(*unitstr)) {
- autounit = true;
- unit = -1;
- mdsuffix = unitstr;
+ mtpoint = argv[1];
+
+ if (strcmp(unitstr, "auto") == 0) {
+ if (mlmac)
+ idx = -1; /* Must use md for mlmac. */
+ else if ((idx = modfind("tmpfs")) == -1)
+ idx = kldload("tmpfs");
+ if (idx == -1)
+ unitstr = "md";
+ else
+ unitstr = "tmpfs";
+ }
+
+ if (strcmp(unitstr, "tmpfs") == 0) {
+ if (size_arg != NULL && mdsize != 0)
+ argappend(&mount_arg, "-o size=%jd", mdsize);
+ do_mount_tmpfs(mount_arg, mtpoint);
} else {
- ul = strtoul(unitstr, &p, 10);
- if (ul == ULONG_MAX)
- errx(1, "bad device unit: %s", unitstr);
- unit = ul;
- mdsuffix = p; /* can be empty */
+ if (size_arg != NULL)
+ argappend(&mdconfig_arg, "-s %jdB", mdsize);
+ if (strncmp(unitstr, "/dev/", 5) == 0)
+ unitstr += 5;
+ if (strncmp(unitstr, mdname, mdnamelen) == 0)
+ unitstr += mdnamelen;
+ if (!isdigit(*unitstr)) {
+ autounit = true;
+ unit = -1;
+ mdsuffix = unitstr;
+ } else {
+ ul = strtoul(unitstr, &p, 10);
+ if (ul == ULONG_MAX)
+ errx(1, "bad device unit: %s", unitstr);
+ unit = ul;
+ mdsuffix = p; /* can be empty */
+ }
+
+ if (!have_mdtype)
+ mdtype = MD_SWAP;
+ if (softdep)
+ argappend(&newfs_arg, "-U");
+ if (mdtype != MD_VNODE && !newfs)
+ errx(1, "-P requires a vnode-backed disk");
+
+ /* Do the work. */
+ if (detach && !autounit)
+ do_mdconfig_detach();
+ if (autounit)
+ do_mdconfig_attach_au(mdconfig_arg, mdtype);
+ else
+ do_mdconfig_attach(mdconfig_arg, mdtype);
+ if (newfs)
+ do_newfs(newfs_arg);
+ do_mount_md(mount_arg, mtpoint);
}
- mtpoint = argv[1];
- if (!have_mdtype)
- mdtype = MD_SWAP;
- if (softdep)
- argappend(&newfs_arg, "-U");
- if (mdtype != MD_VNODE && !newfs)
- errx(1, "-P requires a vnode-backed disk");
-
- /* Do the work. */
- if (detach && !autounit)
- do_mdconfig_detach();
- if (autounit)
- do_mdconfig_attach_au(mdconfig_arg, mdtype);
- else
- do_mdconfig_attach(mdconfig_arg, mdtype);
- if (newfs)
- do_newfs(newfs_arg);
- do_mount(mount_arg, mtpoint);
do_mtptsetup(mtpoint, &mi);
return (0);
@@ -434,7 +508,7 @@ do_mdconfig_detach(void)
* Mount the configured memory disk.
*/
static void
-do_mount(const char *args, const char *mtpoint)
+do_mount_md(const char *args, const char *mtpoint)
{
int rv;
@@ -445,6 +519,19 @@ do_mount(const char *args, const char *mtpoint)
}
/*
+ * Mount the configured tmpfs.
+ */
+static void
+do_mount_tmpfs(const char *args, const char *mtpoint)
+{
+ int rv;
+
+ rv = run(NULL, "%s -t tmpfs %s tmp %s", _PATH_MOUNT, args, mtpoint);
+ if (rv)
+ errx(1, "tmpfs mount exited with error code %d", rv);
+}
+
+/*
* Various configuration of the mountpoint. Mostly, enact 'mip'.
*/
static void
diff --git a/share/man/man4/lm75.4 b/share/man/man4/lm75.4
index d137eb0..75f6907 100644
--- a/share/man/man4/lm75.4
+++ b/share/man/man4/lm75.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 11, 2014
+.Dd December 26, 2017
.Dt LM75 4
.Os
.Sh NAME
@@ -122,7 +122,7 @@ clones may not work reliably.
.Pp
On a
.Xr device.hints 5
-based system, like
+based system, such as
.Li MIPS ,
these values are configurable for
.Nm :
@@ -140,31 +140,28 @@ i2c address on the
.Pp
On a
.Xr FDT 4
-based system, like
+based system, such as
.Li ARM ,
the DTS part for a
.Nm
device usually looks like:
.Bd -literal
i2c {
-
+ /* Properties describing the controller appear here. */
...
-
- lm750 {
+ lm750@49 {
compatible = "national,lm75";
- i2c-address = <0x49>;
+ reg = <0x49>;
};
};
.Ed
.Pp
Where:
-.Bl -tag -width ".Va i2c-address"
+.Bl -tag -width ".Va compatible"
.It Va compatible
Should always be set to "national,lm75".
-.It Va i2c-address
-The
-.Va i2c-address
-property indicates which i2c address the
+.It Va reg
+Indicates which 7-bit i2c address the
.Nm
is wired at.
.Nm
diff --git a/share/man/man4/md.4 b/share/man/man4/md.4
index f13aa4d..133c085 100644
--- a/share/man/man4/md.4
+++ b/share/man/man4/md.4
@@ -7,7 +7,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 5, 2017
+.Dd December 26, 2017
.Dt MD 4
.Os
.Sh NAME
@@ -79,7 +79,8 @@ To create a kernel with a ramdisk or MD file system, your kernel config
needs the following options:
.Bd -literal -offset indent
options MD_ROOT # MD is a potential root device
-options MD_ROOT_SIZE=8192 # 8MB ram disk
+options MD_ROOT_READONLY # disallow mounting root writeable
+options MD_ROOT_SIZE=8192 # 8MB ram disk
makeoptions MFS_IMAGE=/h/foo/ARM-MD
options ROOTDEVNAME=\\"ufs:md0\\"
.Ed
@@ -92,6 +93,47 @@ disk found in the
.Xr mdconfig 8
man page.
Other tools will also create these images, such as NanoBSD.
+.Sh ARM KERNEL OPTIONS
+On armv6 and armv7 architectures, an MD_ROOT image larger than
+approximately 55 MiB may require building a custom kernel using
+several tuning options related to kernel memory usage.
+.Bl -tag -width indent
+.It Cd options LOCORE_MAP_MB=<num>
+This configures how much memory is mapped for the kernel during
+the early initialization stages.
+The value must be at least as large as the kernel plus all preloaded
+modules, including the root image.
+There is no downside to setting this value too large, as long
+as it does not exceed the amount of physical memory.
+The default is 64 MiB.
+.It Cd options NKPT2PG=<num>
+This configures the number of kernel L2 page table pages to
+preallocate during kernel initialization.
+Each L2 page can map 4 MiB of kernel space.
+The value must be large enough to map the kernel plus all preloaded
+modules, including the root image.
+The default value is 32, which is sufficient to map 128 MiB.
+.It Cd options VM_KMEM_SIZE_SCALE=<num>
+This configures the amount of kernel virtual address (KVA) space to
+dedicate to the kmem_arena map.
+The scale value is the ratio of physical to virtual pages.
+The default value of 3 allocates a page of KVA for each 3 pages
+of physical ram in the system.
+
+The kernel and modules, including the root image, also consume KVA.
+The combination of a large root image and the default scaling
+may preallocate so much KVA that there is not enough
+remaining address space to allocate kernel stacks, IO buffers,
+and other resources that are not part of kmem_arena.
+Overallocating kmem_arena space is likely to manifest as failure to
+launch userland processes with "cannot allocate kernel stack" messages.
+
+Setting the scale value too high may result in kernel failure to allocate
+memory because kmem_arena is too small, and the failure may require
+significant runtime to manifest.
+Empirically, a value of 5 works well for a 200 MiB root image on
+a system with 2 GiB of physical ram.
+.El
.Sh SEE ALSO
.Xr gpart 8 ,
.Xr loader 8 ,
diff --git a/share/man/man4/smp.4 b/share/man/man4/smp.4
index a1b8c09..b2c73c2 100644
--- a/share/man/man4/smp.4
+++ b/share/man/man4/smp.4
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 7, 2008
+.Dd January 6, 2017
.Dt SMP 4
.Os
.Sh NAME
@@ -57,6 +57,11 @@ The
.Xr mptable 1
command may be used to view the status of multi-processor support.
.Pp
+.Nm
+support can be disabled by setting the loader tunable
+.Va kern.smp.disabled
+to 1.
+.Pp
The number of CPUs detected by the system is available in
the read-only sysctl variable
.Va hw.ncpu .
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index dbd37bd..0ccfea4 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 8, 2016
+.Dd December 17, 2017
.Dt RC.CONF 5
.Os
.Sh NAME
@@ -1778,21 +1778,40 @@ This variable is deprecated in favor of
Set to the list of
.Xr gif 4
tunnel interfaces to configure on this host.
-A
-.Va gifconfig_ Ns Aq Ar interface
-variable is assumed to exist for each value of
-.Ar interface .
+For each
+.Xr gif
+tunnel interface, set a variable named
+.Va ifconfig_ Ns Aq Ar interface
+with the parameters for the
+.Xr ifconfig 8
+command to configure the link level for
+.Ar interface
+with the
+.Cm tunnel
+option.
The value of this variable is used to configure the link layer of the
-tunnel according to the syntax of the
+tunnel using the
.Cm tunnel
option to
-.Xr ifconfig 8 .
+.Xr ifconfig .
+For example, configure two
+.Xr gif
+interfaces with:
+.Bd -literal -offset indent
+gif_interfaces="gif0 gif1"
+ifconfig_gif0="tunnel src_addr0 dst_addr0"
+ifconfig_gif1="tunnel src_addr1 dst_addr1"
+.Ed
+.Pp
Additionally, this option ensures that each listed interface is created
via the
.Cm create
option to
-.Xr ifconfig 8
-before attempting to configure it.
+.Xr ifconfig .
+This example also works with
+.Va cloned_interfaces
+instead of
+.Va gif_interfaces .
.It Va sppp_interfaces
.Pq Vt str
Set to the list of
diff --git a/share/man/man7/build.7 b/share/man/man7/build.7
index 2272947..c8ad66f 100644
--- a/share/man/man7/build.7
+++ b/share/man/man7/build.7
@@ -441,6 +441,15 @@ If set, this variable supplies a list of additional directories relative to
the root of the source tree to build as part of the
.Cm everything
target.
+The directories are built in parallel with each other,
+and with the base system directories.
+Insert a
+.Va .WAIT
+directive at the beginning of the
+.Va LOCAL_DIRS
+list to ensure all base system directories are built first.
+.Va .WAIT
+may also be used as needed elsewhere within the list.
.It Va LOCAL_ITOOLS
If set, this variable supplies a list of additional tools that are used by the
.Cm installworld
@@ -452,6 +461,15 @@ If set, this variable supplies a list of additional directories relative to
the root of the source tree to build as part of the
.Cm libraries
target.
+The directories are built in parallel with each other,
+and with the base system libraries.
+Insert a
+.Va .WAIT
+directive at the beginning of the
+.Va LOCAL_DIRS
+list to ensure all base system libraries are built first.
+.Va .WAIT
+may also be used as needed elsewhere within the list.
.It Va LOCAL_MTREE
If set, this variable supplies a list of additional mtrees relative to the
root of the source tree to use as part of the
diff --git a/share/man/man9/EVENTHANDLER.9 b/share/man/man9/EVENTHANDLER.9
index b6be883..93dcfc0 100644
--- a/share/man/man9/EVENTHANDLER.9
+++ b/share/man/man9/EVENTHANDLER.9
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\" $FreeBSD$
.\"
-.Dd March 27, 2017
+.Dd October 1, 2017
.Dt EVENTHANDLER 9
.Os
.Sh NAME
@@ -37,6 +37,7 @@
.Ft eventhandler_tag
.Fn EVENTHANDLER_REGISTER name func arg priority
.Fn EVENTHANDLER_DEREGISTER name tag
+.Fn EVENTHANDLER_DEREGISTER_NOWAIT name tag
.Ft eventhandler_tag
.Fo eventhandler_register
.Fa "struct eventhandler_list *list"
@@ -50,6 +51,11 @@
.Fa "struct eventhandler_list *list"
.Fa "eventhandler_tag tag"
.Fc
+.Ft void
+.Fo eventhandler_deregister_nowait
+.Fa "struct eventhandler_list *list"
+.Fa "eventhandler_tag tag"
+.Fc
.Ft "struct eventhandler_list *"
.Fn eventhandler_find_list "const char *name"
.Ft void
@@ -121,6 +127,18 @@ This macro removes a previously registered callback associated with tag
.Fa tag
from the event handler named by argument
.Fa name .
+It waits until no threads are running handlers for this event before
+returning, making it safe to unload a module immediately upon return
+from this function.
+.It Fn EVENTHANDLER_DEREGISTER_NOWAIT
+This macro removes a previously registered callback associated with tag
+.Fa tag
+from the event handler named by argument
+.Fa name .
+Upon return, one or more threads could still be running the removed
+function(s), but no new calls will be made.
+To remove a handler function from within that function, use this
+version of deregister, to avoid a deadlock.
.It Fn EVENTHANDLER_INVOKE
This macro is used to invoke all the callbacks associated with event
handler
@@ -182,6 +200,21 @@ function removes the callback associated with tag
.Fa tag
from the event handler list pointed to by
.Fa list .
+If
+.Fa tag
+is
+.Va NULL ,
+all callback functions for the event are removed.
+This function will not return until all threads have exited from the
+removed handler callback function(s).
+This function is not safe to call from inside an event handler callback.
+.It Fn eventhandler_deregister_nowait
+The
+.Fn eventhandler_deregister
+function removes the callback associated with tag
+.Fa tag
+from the event handler list pointed to by
+.Fa list .
This function is safe to call from inside an event handler
callback.
.It Fn eventhandler_find_list
diff --git a/share/man/man9/atomic.9 b/share/man/man9/atomic.9
index c344ab0..e171262 100644
--- a/share/man/man9/atomic.9
+++ b/share/man/man9/atomic.9
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 23, 2017
+.Dd December 22, 2017
.Dt ATOMIC 9
.Os
.Sh NAME
@@ -36,7 +36,8 @@
.Nm atomic_readandclear ,
.Nm atomic_set ,
.Nm atomic_subtract ,
-.Nm atomic_store
+.Nm atomic_store ,
+.Nm atomic_thread_fence
.Nd atomic operations
.Sh SYNOPSIS
.In sys/types.h
@@ -60,7 +61,7 @@
.Ft <type>
.Fn atomic_fetchadd_<type> "volatile <type> *p" "<type> v"
.Ft <type>
-.Fn atomic_load_acq_<type> "volatile <type> *p"
+.Fn atomic_load_[acq_]<type> "volatile <type> *p"
.Ft <type>
.Fn atomic_readandclear_<type> "volatile <type> *p"
.Ft void
@@ -68,19 +69,33 @@
.Ft void
.Fn atomic_subtract_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
.Ft void
-.Fn atomic_store_rel_<type> "volatile <type> *p" "<type> v"
+.Fn atomic_store_[rel_]<type> "volatile <type> *p" "<type> v"
.Ft <type>
.Fn atomic_swap_<type> "volatile <type> *p" "<type> v"
.Ft int
.Fn atomic_testandclear_<type> "volatile <type> *p" "u_int v"
.Ft int
.Fn atomic_testandset_<type> "volatile <type> *p" "u_int v"
+.Ft void
+.Fn atomic_thread_fence_[acq|acq_rel|rel|seq_cst] "void"
.Sh DESCRIPTION
-All of these operations are performed atomically across multiple
-threads and in the presence of interrupts, meaning that they are
-performed in an indivisible manner from the perspective of concurrently
+Atomic operations are commonly used to implement reference counts and as
+building blocks for synchronization primitives, such as mutexes.
+.Pp
+All of these operations are performed
+.Em atomically
+across multiple threads and in the presence of interrupts, meaning that they
+are performed in an indivisible manner from the perspective of concurrently
running threads and interrupt handlers.
.Pp
+On all architectures supported by
+.Fx ,
+ordinary loads and stores of integers in cache-coherent memory are
+inherently atomic if the integer is naturally aligned and its size does not
+exceed the processor's word size.
+However, such loads and stores may be elided from the program by
+the compiler, whereas atomic operations are always performed.
+.Pp
When atomic operations are performed on cache-coherent memory, all
operations on the same location are totally ordered.
.Pp
@@ -93,29 +108,16 @@ interrupt handler will observe a
.Em torn write ,
or partial modification of the location.
.Pp
-On all architectures supported by
-.Fx ,
-ordinary loads and stores of naturally aligned integer types
-are atomic, as executed by the processor.
-.Pp
-Atomic operations can be used to implement reference counts or as
-building blocks for synchronization primitives such as mutexes.
-.Pp
-The semantics of
-.Fx Ns 's
-atomic operations are almost identical to those of the similarly named
-C11 operations.
-The one important difference is that the C11 standard does not
-require ordinary loads and stores to ever be atomic.
-This is is why the
-.Fn atomic_load_explicit memory_order_relaxed
-operation exists in the C11 standard, but is not provided by
-.In machine/atomic.h .
+Except as noted below, the semantics of these operations are almost
+identical to the semantics of similarly named C11 atomic operations.
.Ss Types
-Each atomic operation operates on a specific
+Most atomic operations act upon a specific
.Fa type .
-The type to use is indicated in the function name.
-The available types that can be used are:
+That type is indicated in the function name.
+In contrast to C11 atomic operations,
+.Fx Ns 's
+atomic operations are performed on ordinary integer types.
+The available types are:
.Pp
.Bl -tag -offset indent -width short -compact
.It Li int
@@ -147,8 +149,7 @@ unsigned 8-bit integer
unsigned 16-bit integer
.El
.Pp
-These must not be used in MI code because the instructions to implement them
-efficiently might not be available.
+These types must not be used in machine-independent code.
.Ss Acquire and Release Operations
By default, a thread's accesses to different memory locations might not be
performed in
@@ -167,52 +168,67 @@ Moreover, in some cases, such as the implementation of synchronization between
threads, arbitrary reordering might result in the incorrect execution of the
program.
To constrain the reordering that both the compiler and processor might perform
-on a thread's accesses, the thread should use atomic operations with
+on a thread's accesses, a programmer can use atomic operations with
.Em acquire
and
.Em release
semantics.
.Pp
-Most of the atomic operations on memory have three variants.
-The first variant performs the operation without imposing any ordering
-constraints on memory accesses to other locations.
+Atomic operations on memory have up to three variants.
+The first, or
+.Em relaxed
+variant, performs the operation without imposing any ordering constraints on
+accesses to other memory locations.
+This variant is the default.
The second variant has acquire semantics, and the third variant has release
semantics.
-In effect, operations with acquire and release semantics establish one-way
-barriers to reordering.
.Pp
-When an atomic operation has acquire semantics, the effects of the operation
-must have completed before any subsequent load or store (by program order) is
+When an atomic operation has acquire semantics, the operation must have
+completed before any subsequent load or store (by program order) is
performed.
Conversely, acquire semantics do not require that prior loads or stores have
completed before the atomic operation is performed.
+An atomic operation can only have acquire semantics if it performs a load
+from memory.
To denote acquire semantics, the suffix
.Dq Li _acq
is inserted into the function name immediately prior to the
.Dq Li _ Ns Aq Fa type
suffix.
-For example, to subtract two integers ensuring that subsequent loads and
-stores happen after the subtraction is performed, use
+For example, to subtract two integers ensuring that the subtraction is
+completed before any subsequent loads and stores are performed, use
.Fn atomic_subtract_acq_int .
.Pp
-When an atomic operation has release semantics, the effects of all prior
-loads or stores (by program order) must have completed before the operation
-is performed.
-Conversely, release semantics do not require that the effects of the
-atomic operation must have completed before any subsequent load or store is
-performed.
+When an atomic operation has release semantics, all prior loads or stores
+(by program order) must have completed before the operation is performed.
+Conversely, release semantics do not require that the atomic operation must
+have completed before any subsequent load or store is performed.
+An atomic operation can only have release semantics if it performs a store
+to memory.
To denote release semantics, the suffix
.Dq Li _rel
is inserted into the function name immediately prior to the
.Dq Li _ Ns Aq Fa type
suffix.
For example, to add two long integers ensuring that all prior loads and
-stores happen before the addition, use
+stores are completed before the addition is performed, use
.Fn atomic_add_rel_long .
.Pp
-The one-way barriers provided by acquire and release operations allow the
-implementations of common synchronization primitives to express their
-ordering requirements without also imposing unnecessary ordering.
+When a release operation by one thread
+.Em synchronizes with
+an acquire operation by another thread, usually meaning that the acquire
+operation reads the value written by the release operation, then the effects
+of all prior stores by the releasing thread must become visible to
+subsequent loads by the acquiring thread.
+Moreover, the effects of all stores (by other threads) that were visible to
+the releasing thread must also become visible to the acquiring thread.
+These rules only apply to the synchronizing threads.
+Other threads might observe these stores in a different order.
+.Pp
+In effect, atomic operations with acquire and release semantics establish
+one-way barriers to reordering that enable the implementations of
+synchronization primitives to express their ordering requirements without
+also imposing unnecessary ordering.
For example, for a critical section guarded by a mutex, an acquire operation
when the mutex is locked and a release operation when the mutex is unlocked
will prevent any loads or stores from moving outside of the critical
@@ -220,6 +236,61 @@ section.
However, they will not prevent the compiler or processor from moving loads
or stores into the critical section, which does not violate the semantics of
a mutex.
+.Ss Thread Fence Operations
+Alternatively, a programmer can use atomic thread fence operations to
+constrain the reordering of accesses.
+In contrast to other atomic operations, fences do not, themselves, access
+memory.
+.Pp
+When a fence has acquire semantics, all prior loads (by program order) must
+have completed before any subsequent load or store is performed.
+Thus, an acquire fence is a two-way barrier for load operations.
+To denote acquire semantics, the suffix
+.Dq Li _acq
+is appended to the function name, for example,
+.Fn atomic_thread_fence_acq .
+.Pp
+When a fence has release semantics, all prior loads or stores (by program
+order) must have completed before any subsequent store operation is
+performed.
+Thus, a release fence is a two-way barrier for store operations.
+To denote release semantics, the suffix
+.Dq Li _rel
+is appended to the function name, for example,
+.Fn atomic_thread_fence_rel .
+.Pp
+Although
+.Fn atomic_thread_fence_acq_rel
+implements both acquire and release semantics, it is not a full barrier.
+For example, a store prior to the fence (in program order) may be completed
+after a load subsequent to the fence.
+In contrast,
+.Fn atomic_thread_fence_seq_cst
+implements a full barrier.
+Neither loads nor stores may cross this barrier in either direction.
+.Pp
+In C11, a release fence by one thread synchronizes with an acquire fence by
+another thread when an atomic load that is prior to the acquire fence (by
+program order) reads the value written by an atomic store that is subsequent
+to the release fence.
+In constrast, in FreeBSD, because of the atomicity of ordinary, naturally
+aligned loads and stores, fences can also be synchronized by ordinary loads
+and stores.
+This simplifies the implementation and use of some synchronization
+primitives in
+.Fx .
+.Pp
+Since neither a compiler nor a processor can foresee which (atomic) load
+will read the value written by an (atomic) store, the ordering constraints
+imposed by fences must be more restrictive than acquire loads and release
+stores.
+Essentially, this is why fences are two-way barriers.
+.Pp
+Although fences impose more restrictive ordering than acquire loads and
+release stores, by separating access from ordering, they can sometimes
+facilitate more efficient implementations of synchronization primitives.
+For example, they can be used to avoid executing a memory barrier until a
+memory access shows that some condition is satisfied.
.Ss Multiple Processors
In multiprocessor systems, the atomicity of the atomic operations on memory
depends on support for cache coherence in the underlying architecture.
@@ -326,12 +397,6 @@ and do not have any variants with memory barriers at this time.
.Bd -literal -compact
return (*p);
.Ed
-.El
-.Pp
-The
-.Fn atomic_load
-functions are only provided with acquire memory barriers.
-.Bl -hang
.It Fn atomic_readandclear p
.Bd -literal -compact
tmp = *p;
@@ -363,12 +428,6 @@ and do not have any variants with memory barriers at this time.
.Bd -literal -compact
*p = v;
.Ed
-.El
-.Pp
-The
-.Fn atomic_store
-functions are only provided with release memory barriers.
-.Bl -hang
.It Fn atomic_swap p v
.Bd -literal -compact
tmp = *p;
@@ -490,43 +549,54 @@ The
.Fn atomic_set ,
and
.Fn atomic_subtract
-operations were first introduced in
+operations were introduced in
.Fx 3.0 .
-This first set only supported the types
+Initially, these operations were defined on the types
.Dq Li char ,
.Dq Li short ,
.Dq Li int ,
and
.Dq Li long .
+.Pp
The
.Fn atomic_cmpset ,
-.Fn atomic_load ,
+.Fn atomic_load_acq ,
.Fn atomic_readandclear ,
and
-.Fn atomic_store
+.Fn atomic_store_rel
operations were added in
.Fx 5.0 .
-The types
+Simultaneously, the acquire and release variants were introduced, and
+support was added for operation on the types
.Dq Li 8 ,
.Dq Li 16 ,
.Dq Li 32 ,
.Dq Li 64 ,
and
-.Dq Li ptr
-and all of the acquire and release variants
-were added in
-.Fx 5.0
-as well.
+.Dq Li ptr .
+.Pp
The
.Fn atomic_fetchadd
-operations were added in
+operation was added in
.Fx 6.0 .
+.Pp
The
.Fn atomic_swap
and
.Fn atomic_testandset
operations were added in
.Fx 10.0 .
+.Pp
+The
.Fn atomic_testandclear
-operation was added in
+and
+.Fn atomic_thread_fence
+operations were added in
.Fx 11.0 .
+.Pp
+The relaxed variants of
+.Fn atomic_load
+and
+.Fn atomic_store
+were added in
+.Fx 12.0 .
diff --git a/share/skel/dot.shrc b/share/skel/dot.shrc
index 974db46..e56256e 100644
--- a/share/skel/dot.shrc
+++ b/share/skel/dot.shrc
@@ -21,7 +21,7 @@
# some useful aliases
alias h='fc -l'
alias j=jobs
-alias m=$PAGER
+alias m="$PAGER"
alias ll='ls -laFo'
alias l='ls -l'
alias g='egrep -i'
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index ba81e11..6037b03 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -537,14 +537,12 @@ pmap_delayed_invl_genp(vm_page_t m)
static void
pmap_delayed_invl_wait(vm_page_t m)
{
- struct thread *td;
struct turnstile *ts;
u_long *m_gen;
#ifdef PV_STATS
bool accounted = false;
#endif
- td = curthread;
m_gen = pmap_delayed_invl_genp(m);
while (*m_gen > pmap_invl_gen) {
#ifdef PV_STATS
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
index e7af5d7..99d887d 100644
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -214,7 +214,7 @@ END(fillw)
*/
/*
- * copyout(from_kernel, to_user, len) - MP SAFE
+ * copyout(from_kernel, to_user, len)
* %rdi, %rsi, %rdx
*/
ENTRY(copyout)
@@ -277,7 +277,7 @@ copyout_fault:
END(copyout)
/*
- * copyin(from_user, to_kernel, len) - MP SAFE
+ * copyin(from_user, to_kernel, len)
* %rdi, %rsi, %rdx
*/
ENTRY(copyin)
@@ -494,7 +494,7 @@ fusufault:
/*
* Store a 64-bit word, a 32-bit word, a 16-bit word, or an 8-bit byte to
- * user memory. All these functions are MPSAFE.
+ * user memory.
* addr = %rdi, value = %rsi
*/
ALTENTRY(suword64)
@@ -569,7 +569,7 @@ ENTRY(subyte)
END(subyte)
/*
- * copyinstr(from, to, maxlen, int *lencopied) - MP SAFE
+ * copyinstr(from, to, maxlen, int *lencopied)
* %rdi, %rsi, %rdx, %rcx
*
* copy a string from from to to, stop when a 0 character is reached.
@@ -640,7 +640,7 @@ cpystrflt_x:
END(copyinstr)
/*
- * copystr(from, to, maxlen, int *lencopied) - MP SAFE
+ * copystr(from, to, maxlen, int *lencopied)
* %rdi, %rsi, %rdx, %rcx
*/
ENTRY(copystr)
@@ -680,7 +680,6 @@ END(copystr)
/*
* Handling of special amd64 registers and descriptor tables etc
- * %rdi
*/
/* void lgdt(struct region_descriptor *rdp); */
ENTRY(lgdt)
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index a99cb13..8ae7772 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -162,9 +162,6 @@ SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RWTUN,
void
trap(struct trapframe *frame)
{
-#ifdef KDTRACE_HOOKS
- struct reg regs;
-#endif
ksiginfo_t ksi;
struct thread *td;
struct proc *p;
@@ -276,9 +273,8 @@ trap(struct trapframe *frame)
enable_intr();
#ifdef KDTRACE_HOOKS
if (type == T_BPTFLT) {
- fill_frame_regs(frame, &regs);
if (dtrace_pid_probe_ptr != NULL &&
- dtrace_pid_probe_ptr(&regs) == 0)
+ dtrace_pid_probe_ptr(frame) == 0)
return;
}
#endif
@@ -404,9 +400,8 @@ trap(struct trapframe *frame)
#ifdef KDTRACE_HOOKS
case T_DTRACE_RET:
enable_intr();
- fill_frame_regs(frame, &regs);
if (dtrace_return_probe_ptr != NULL)
- dtrace_return_probe_ptr(&regs);
+ dtrace_return_probe_ptr(frame);
return;
#endif
}
@@ -611,7 +606,6 @@ trap_pfault(struct trapframe *frame, int usermode)
td = curthread;
p = td->td_proc;
eva = frame->tf_addr;
- rv = 0;
if (__predict_false((td->td_pflags & TDP_NOFAULTING) != 0)) {
/*
@@ -663,7 +657,7 @@ trap_pfault(struct trapframe *frame, int usermode)
* Don't allow user-mode faults in kernel address space.
*/
if (usermode)
- goto nogo;
+ return (SIGSEGV);
map = kernel_map;
} else {
@@ -718,7 +712,6 @@ trap_pfault(struct trapframe *frame, int usermode)
#endif
return (0);
}
-nogo:
if (!usermode) {
if (td->td_intr_nesting_level == 0 &&
curpcb->pcb_onfault != NULL) {
@@ -947,6 +940,6 @@ amd64_syscall(struct thread *td, int traced)
* not be safe. Instead, use the full return path which
* catches the problem safely.
*/
- if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS)
+ if (__predict_false(td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS))
set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
}
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index 09a5f9c..481a398 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -55,6 +55,8 @@
#define wmb() __asm __volatile("sfence;" : : : "memory")
#define rmb() __asm __volatile("lfence;" : : : "memory")
+#include <sys/atomic_common.h>
+
/*
* Various simple operations on memory, each of which is atomic in the
* presence of interrupts and multiple processors.
diff --git a/sys/amd64/vmm/io/vhpet.c b/sys/amd64/vmm/io/vhpet.c
index 6d9b0fe..b11095f 100644
--- a/sys/amd64/vmm/io/vhpet.c
+++ b/sys/amd64/vmm/io/vhpet.c
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_VHPET, "vhpet", "bhyve virtual hpet");
-#define HPET_FREQ 10000000 /* 10.0 Mhz */
+#define HPET_FREQ 16777216 /* 16.7 (2^24) Mhz */
#define FS_PER_S 1000000000000000ul
/* Timer N Configuration and Capabilities Register */
diff --git a/sys/arm/allwinner/std.allwinner b/sys/arm/allwinner/std.allwinner
index 5a1bf94..4155530 100644
--- a/sys/arm/allwinner/std.allwinner
+++ b/sys/arm/allwinner/std.allwinner
@@ -5,9 +5,6 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-makeoptions KERNVIRTADDR=0xc0200000
-options KERNVIRTADDR=0xc0200000
-
options IPI_IRQ_START=0
options IPI_IRQ_END=15
diff --git a/sys/arm/allwinner/std.allwinner_up b/sys/arm/allwinner/std.allwinner_up
index 6294cd0..2ed96c6 100644
--- a/sys/arm/allwinner/std.allwinner_up
+++ b/sys/arm/allwinner/std.allwinner_up
@@ -5,9 +5,6 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-makeoptions KERNVIRTADDR=0xc0200000
-options KERNVIRTADDR=0xc0200000
-
files "../allwinner/files.allwinner_up"
files "../allwinner/files.allwinner"
files "../allwinner/a10/files.a10"
diff --git a/sys/arm/altera/socfpga/std.socfpga b/sys/arm/altera/socfpga/std.socfpga
index 687c5a7..dde1fb9 100644
--- a/sys/arm/altera/socfpga/std.socfpga
+++ b/sys/arm/altera/socfpga/std.socfpga
@@ -4,9 +4,6 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-makeoptions KERNVIRTADDR=0xc0f00000
-options KERNVIRTADDR=0xc0f00000
-
options IPI_IRQ_START=0
options IPI_IRQ_END=15
diff --git a/sys/arm/arm/dump_machdep.c b/sys/arm/arm/dump_machdep.c
index 2c11141..a8d0591 100644
--- a/sys/arm/arm/dump_machdep.c
+++ b/sys/arm/arm/dump_machdep.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/armreg.h>
+#include <machine/vmparam.h> /* For KERNVIRTADDR */
int do_minidump = 1;
SYSCTL_INT(_debug, OID_AUTO, minidump, CTLFLAG_RWTUN, &do_minidump, 0,
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c
index 53bf23a..014c053 100644
--- a/sys/arm/arm/elf_trampoline.c
+++ b/sys/arm/arm/elf_trampoline.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/armreg.h>
#include <machine/cpu.h>
+#include <machine/vmparam.h> /* For KERNVIRTADDR */
extern char kernel_start[];
extern char kernel_end[];
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c
index b70d5dd..b5cc952 100644
--- a/sys/arm/arm/genassym.c
+++ b/sys/arm/arm/genassym.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpuinfo.h>
#include <machine/intr.h>
#include <machine/sysarch.h>
+#include <machine/vmparam.h> /* For KERNVIRTADDR */
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -57,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_var.h>
ASSYM(KERNBASE, KERNBASE);
+ASSYM(KERNVIRTADDR, KERNVIRTADDR);
#if __ARM_ARCH >= 6
ASSYM(CPU_ASID_KERNEL,CPU_ASID_KERNEL);
#endif
@@ -159,3 +161,12 @@ ASSYM(DCACHE_LINE_SIZE, offsetof(struct cpuinfo, dcache_line_size));
ASSYM(DCACHE_LINE_MASK, offsetof(struct cpuinfo, dcache_line_mask));
ASSYM(ICACHE_LINE_SIZE, offsetof(struct cpuinfo, icache_line_size));
ASSYM(ICACHE_LINE_MASK, offsetof(struct cpuinfo, icache_line_mask));
+
+/*
+ * Emit the LOCORE_MAP_MB option as a #define only if the option was set.
+ */
+#include "opt_locore.h"
+
+#ifdef LOCORE_MAP_MB
+ASSYM(LOCORE_MAP_MB, LOCORE_MAP_MB);
+#endif
diff --git a/sys/arm/arm/locore-v6.S b/sys/arm/arm/locore-v6.S
index 10aaace..775b867 100644
--- a/sys/arm/arm/locore-v6.S
+++ b/sys/arm/arm/locore-v6.S
@@ -38,6 +38,10 @@
__FBSDID("$FreeBSD$");
+/* We map 64MB of kernel unless overridden in assym.s by the kernel option. */
+#ifndef LOCORE_MAP_MB
+#define LOCORE_MAP_MB 64
+#endif
#if __ARM_ARCH >= 7
#if defined(__ARM_ARCH_7VE__) || defined(__clang__)
@@ -172,12 +176,13 @@ ASENTRY_NP(_start)
bl build_pagetables
/*
- * Next we do 64MiB starting at the physical load address, mapped to
- * the VA the kernel is linked for.
+ * Next we map the kernel starting at the physical load address, mapped
+ * to the VA the kernel is linked for. The default size we map is 64MiB
+ * but it can be overridden with a kernel option.
*/
mov r1, r5
ldr r2, =(KERNVIRTADDR)
- mov r3, #64
+ ldr r3, =(LOCORE_MAP_MB)
bl build_pagetables
/* Create a device mapping for early_printf if specified. */
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 049ac25..bc2e198 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -1116,6 +1116,19 @@ initarm(struct arm_boot_params *abp)
pmap_bootstrap_prepare(lastaddr);
/*
+ * If EARLY_PRINTF support is enabled, we need to re-establish the
+ * mapping after pmap_bootstrap_prepare() switches to new page tables.
+ * Note that we can only do the remapping if the VA is outside the
+ * kernel, now that we have real virtual (not VA=PA) mappings in effect.
+ * Early printf does not work between the time pmap_set_tex() does
+ * cp15_prrr_set() and this code remaps the VA.
+ */
+#if defined(EARLY_PRINTF) && defined(SOCDEV_PA) && defined(SOCDEV_VA) && SOCDEV_VA < KERNBASE
+ pmap_preboot_map_attr(SOCDEV_PA, SOCDEV_VA, 1024 * 1024,
+ VM_PROT_READ | VM_PROT_WRITE, VM_MEMATTR_DEVICE);
+#endif
+
+ /*
* Now that proper page tables are installed, call cpu_setup() to enable
* instruction and data caches and other chip-specific features.
*/
@@ -1178,6 +1191,14 @@ initarm(struct arm_boot_params *abp)
platform_gpio_init();
cninit();
+ /*
+ * If we made a mapping for EARLY_PRINTF after pmap_bootstrap_prepare(),
+ * undo it now that the normal console printf works.
+ */
+#if defined(EARLY_PRINTF) && defined(SOCDEV_PA) && defined(SOCDEV_VA) && SOCDEV_VA < KERNBASE
+ pmap_kremove(SOCDEV_VA);
+#endif
+
debugf("initarm: console initialized\n");
debugf(" arg1 kmdp = 0x%08x\n", (uint32_t)kmdp);
debugf(" boothowto = 0x%08x\n", boothowto);
diff --git a/sys/arm/arm/machdep_boot.c b/sys/arm/arm/machdep_boot.c
index cb2c682..adb15f4 100644
--- a/sys/arm/arm/machdep_boot.c
+++ b/sys/arm/arm/machdep_boot.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <machine/machdep.h>
#include <machine/metadata.h>
#include <machine/physmem.h>
+#include <machine/vmparam.h> /* For KERNVIRTADDR */
#ifdef FDT
#include <contrib/libfdt/libfdt.h>
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index 7248c12..11fb7b5 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -1311,10 +1311,16 @@ pmap_kenter(vm_offset_t va, vm_paddr_t pa)
PMAP_INLINE void
pmap_kremove(vm_offset_t va)
{
+ pt1_entry_t *pte1p;
pt2_entry_t *pte2p;
- pte2p = pt2map_entry(va);
- pte2_clear(pte2p);
+ pte1p = kern_pte1(va);
+ if (pte1_is_section(pte1_load(pte1p))) {
+ pte1_clear(pte1p);
+ } else {
+ pte2p = pt2map_entry(va);
+ pte2_clear(pte2p);
+ }
}
/*
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
index 6a313ef..62c5c12 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
@@ -2,6 +2,7 @@
* Copyright (c) 2001 Tsubai Masanari.
* Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
* Copyright (c) 2013 Luiz Otavio O Souza <loos@freebsd.org>
+ * Copyright (c) 2017 Ian Lepore <ian@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +30,57 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+/*
+ * Driver for bcm2835 i2c-compatible two-wire bus, named 'BSC' on this SoC.
+ *
+ * This controller can only perform complete transfers, it does not provide
+ * low-level control over sending start/repeat-start/stop sequences on the bus.
+ * In addition, bugs in the silicon make it somewhat difficult to perform a
+ * repeat-start, and limit the repeat-start to a read following a write on
+ * the same slave device. (The i2c protocol allows a repeat start to change
+ * direction or not, and change slave address or not at any time.)
+ *
+ * The repeat-start bug and workaround are described in a problem report at
+ * https://github.com/raspberrypi/linux/issues/254 with the crucial part being
+ * in a comment block from a fragment of a GPU i2c driver, containing this:
+ *
+ * -----------------------------------------------------------------------------
+ * - See i2c.v: The I2C peripheral samples the values for rw_bit and xfer_count
+ * - in the IDLE state if start is set.
+ * -
+ * - We want to generate a ReSTART not a STOP at the end of the TX phase. In
+ * - order to do that we must ensure the state machine goes RACK1 -> RACK2 ->
+ * - SRSTRT1 (not RACK1 -> RACK2 -> SSTOP1).
+ * -
+ * - So, in the RACK2 state when (TX) xfer_count==0 we must therefore have
+ * - already set, ready to be sampled:
+ * - READ ; rw_bit <= I2CC bit 0 -- must be "read"
+ * - ST; start <= I2CC bit 7 -- must be "Go" in order to not issue STOP
+ * - DLEN; xfer_count <= I2CDLEN -- must be equal to our read amount
+ * -
+ * - The plan to do this is:
+ * - 1. Start the sub-address write, but don't let it finish
+ * - (keep xfer_count > 0)
+ * - 2. Populate READ, DLEN and ST in preparation for ReSTART read sequence
+ * - 3. Let TX finish (write the rest of the data)
+ * - 4. Read back data as it arrives
+ * -----------------------------------------------------------------------------
+ *
+ * The transfer function below scans the list of messages passed to it, looking
+ * for a read following a write to the same slave. When it finds that, it
+ * starts the write without prefilling the tx fifo, which holds xfer_count>0,
+ * then presets the direction, length, and start command for the following read,
+ * as described above. Then the tx fifo is filled and the rest of the transfer
+ * proceeds as normal, with the controller automatically supplying a
+ * repeat-start on the bus when the write operation finishes.
+ *
+ * XXX I suspect the controller may be able to do a repeat-start on any
+ * write->read or write->write transition, even when the slave addresses differ.
+ * It's unclear whether the slave address can be prestaged along with the
+ * direction and length while the write xfer_count is being held at zero. In
+ * fact, if it can't do this, then it couldn't be used to read EDID data.
+ */
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -58,6 +110,14 @@ static struct ofw_compat_data compat_data[] = {
{NULL, 0}
};
+#define DEVICE_DEBUGF(sc, lvl, fmt, args...) \
+ if ((lvl) <= (sc)->sc_debug) \
+ device_printf((sc)->sc_dev, fmt, ##args)
+
+#define DEBUGF(sc, lvl, fmt, args...) \
+ if ((lvl) <= (sc)->sc_debug) \
+ printf(fmt, ##args)
+
static void bcm_bsc_intr(void *);
static int bcm_bsc_detach(device_t);
@@ -197,6 +257,9 @@ bcm_bsc_sysctl_init(struct bcm_bsc_softc *sc)
SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "rise_edge_delay",
CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
bcm_bsc_rise_proc, "IU", "I2C BUS rising edge delay");
+ SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "debug",
+ CTLFLAG_RWTUN, &sc->sc_debug, 0,
+ "Enable debug; 1=reads/writes, 2=add starts/stops");
}
static void
@@ -322,6 +385,8 @@ bcm_bsc_detach(device_t dev)
bus_generic_detach(dev);
sc = device_get_softc(dev);
+ if (sc->sc_iicbus != NULL)
+ device_delete_child(dev, sc->sc_iicbus);
mtx_destroy(&sc->sc_mtx);
if (sc->sc_intrhand)
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
@@ -334,6 +399,76 @@ bcm_bsc_detach(device_t dev)
}
static void
+bcm_bsc_empty_rx_fifo(struct bcm_bsc_softc *sc)
+{
+ uint32_t status;
+
+ /* Assumes sc_totlen > 0 and BCM_BSC_STATUS_RXD is asserted on entry. */
+ do {
+ if (sc->sc_resid == 0) {
+ sc->sc_data = sc->sc_curmsg->buf;
+ sc->sc_dlen = sc->sc_curmsg->len;
+ sc->sc_resid = sc->sc_dlen;
+ ++sc->sc_curmsg;
+ }
+ do {
+ *sc->sc_data = BCM_BSC_READ(sc, BCM_BSC_DATA);
+ DEBUGF(sc, 1, "0x%02x ", *sc->sc_data);
+ ++sc->sc_data;
+ --sc->sc_resid;
+ --sc->sc_totlen;
+ status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+ } while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_RXD));
+ } while (sc->sc_totlen > 0 && (status & BCM_BSC_STATUS_RXD));
+}
+
+static void
+bcm_bsc_fill_tx_fifo(struct bcm_bsc_softc *sc)
+{
+ uint32_t status;
+
+ /* Assumes sc_totlen > 0 and BCM_BSC_STATUS_TXD is asserted on entry. */
+ do {
+ if (sc->sc_resid == 0) {
+ sc->sc_data = sc->sc_curmsg->buf;
+ sc->sc_dlen = sc->sc_curmsg->len;
+ sc->sc_resid = sc->sc_dlen;
+ ++sc->sc_curmsg;
+ }
+ do {
+ BCM_BSC_WRITE(sc, BCM_BSC_DATA, *sc->sc_data);
+ DEBUGF(sc, 1, "0x%02x ", *sc->sc_data);
+ ++sc->sc_data;
+ --sc->sc_resid;
+ --sc->sc_totlen;
+ status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+ } while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_TXD));
+ /*
+ * If a repeat-start was pending and we just hit the end of a tx
+ * buffer, see if it's also the end of the writes that preceeded
+ * the repeat-start. If so, log the repeat-start and the start
+ * of the following read, and return because we're not writing
+ * anymore (and TXD will be true because there's room to write
+ * in the fifo).
+ */
+ if (sc->sc_replen > 0 && sc->sc_resid == 0) {
+ sc->sc_replen -= sc->sc_dlen;
+ if (sc->sc_replen == 0) {
+ DEBUGF(sc, 1, " err=0\n");
+ DEVICE_DEBUGF(sc, 2, "rstart 0x%02x\n",
+ sc->sc_curmsg->slave | 0x01);
+ DEVICE_DEBUGF(sc, 1,
+ "read 0x%02x len %d: ",
+ sc->sc_curmsg->slave | 0x01,
+ sc->sc_totlen);
+ sc->sc_flags |= BCM_I2C_READ;
+ return;
+ }
+ }
+ } while (sc->sc_totlen > 0 && (status & BCM_BSC_STATUS_TXD));
+}
+
+static void
bcm_bsc_intr(void *arg)
{
struct bcm_bsc_softc *sc;
@@ -350,35 +485,28 @@ bcm_bsc_intr(void *arg)
}
status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+ DEBUGF(sc, 4, " <intrstatus=0x%08x> ", status);
- /* Check for errors. */
- if (status & (BCM_BSC_STATUS_CLKT | BCM_BSC_STATUS_ERR)) {
- /* Disable interrupts. */
- bcm_bsc_reset(sc);
- sc->sc_flags |= BCM_I2C_ERROR;
- wakeup(sc->sc_dev);
- BCM_BSC_UNLOCK(sc);
- return;
- }
-
- if (sc->sc_flags & BCM_I2C_READ) {
- while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_RXD)) {
- *sc->sc_data++ = BCM_BSC_READ(sc, BCM_BSC_DATA);
- sc->sc_resid--;
- status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
- }
- } else {
- while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_TXD)) {
- BCM_BSC_WRITE(sc, BCM_BSC_DATA, *sc->sc_data++);
- sc->sc_resid--;
- status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
- }
- }
+ /* RXD and DONE can assert together, empty fifo before checking done. */
+ if ((sc->sc_flags & BCM_I2C_READ) && (status & BCM_BSC_STATUS_RXD))
+ bcm_bsc_empty_rx_fifo(sc);
- if (status & BCM_BSC_STATUS_DONE) {
+ /* Check for completion. */
+ if (status & (BCM_BSC_STATUS_ERRBITS | BCM_BSC_STATUS_DONE)) {
+ sc->sc_flags |= BCM_I2C_DONE;
+ if (status & BCM_BSC_STATUS_ERRBITS)
+ sc->sc_flags |= BCM_I2C_ERROR;
/* Disable interrupts. */
bcm_bsc_reset(sc);
- wakeup(sc->sc_dev);
+ wakeup(sc);
+ } else if (!(sc->sc_flags & BCM_I2C_READ)) {
+ /*
+ * Don't check for TXD until after determining whether the
+ * transfer is complete; TXD will be asserted along with ERR or
+ * DONE if there is room in the fifo.
+ */
+ if ((status & BCM_BSC_STATUS_TXD) && sc->sc_totlen > 0)
+ bcm_bsc_fill_tx_fifo(sc);
}
BCM_BSC_UNLOCK(sc);
@@ -388,8 +516,11 @@ static int
bcm_bsc_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
{
struct bcm_bsc_softc *sc;
- uint32_t intr, read, status;
- int i, err;
+ struct iic_msg *endmsgs, *nxtmsg;
+ uint32_t readctl, status;
+ int err;
+ uint16_t curlen;
+ uint8_t curisread, curslave, nxtisread, nxtslave;
sc = device_get_softc(dev);
BCM_BSC_LOCK(sc);
@@ -401,54 +532,157 @@ bcm_bsc_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
/* Now we have control over the BSC controller. */
sc->sc_flags = BCM_I2C_BUSY;
+ DEVICE_DEBUGF(sc, 3, "Transfer %d msgs\n", nmsgs);
+
/* Clear the FIFO and the pending interrupts. */
bcm_bsc_reset(sc);
+ /*
+ * Perform all the transfers requested in the array of msgs. Note that
+ * it is bcm_bsc_empty_rx_fifo() and bcm_bsc_fill_tx_fifo() that advance
+ * sc->sc_curmsg through the array of messages, as the data from each
+ * message is fully consumed, but it is this loop that notices when we
+ * have no more messages to process.
+ */
err = 0;
- for (i = 0; i < nmsgs; i++) {
-
- /* Write the slave address. */
- BCM_BSC_WRITE(sc, BCM_BSC_SLAVE, msgs[i].slave >> 1);
+ sc->sc_resid = 0;
+ sc->sc_curmsg = msgs;
+ endmsgs = &msgs[nmsgs];
+ while (sc->sc_curmsg < endmsgs) {
+ readctl = 0;
+ curslave = sc->sc_curmsg->slave >> 1;
+ curisread = sc->sc_curmsg->flags & IIC_M_RD;
+ sc->sc_replen = 0;
+ sc->sc_totlen = sc->sc_curmsg->len;
+ /*
+ * Scan for scatter/gather IO (same slave and direction) or
+ * repeat-start (read following write for the same slave).
+ */
+ for (nxtmsg = sc->sc_curmsg + 1; nxtmsg < endmsgs; ++nxtmsg) {
+ nxtslave = nxtmsg->slave >> 1;
+ if (curslave == nxtslave) {
+ nxtisread = nxtmsg->flags & IIC_M_RD;
+ if (curisread == nxtisread) {
+ /*
+ * Same slave and direction, this
+ * message will be part of the same
+ * transfer as the previous one.
+ */
+ sc->sc_totlen += nxtmsg->len;
+ continue;
+ } else if (curisread == IIC_M_WR) {
+ /*
+ * Read after write to same slave means
+ * repeat-start, remember how many bytes
+ * come before the repeat-start, switch
+ * the direction to IIC_M_RD, and gather
+ * up following reads to the same slave.
+ */
+ curisread = IIC_M_RD;
+ sc->sc_replen = sc->sc_totlen;
+ sc->sc_totlen += nxtmsg->len;
+ continue;
+ }
+ }
+ break;
+ }
- /* Write the data length. */
- BCM_BSC_WRITE(sc, BCM_BSC_DLEN, msgs[i].len);
+ /*
+ * curslave and curisread temporaries from above may refer to
+ * the after-repstart msg, reset them to reflect sc_curmsg.
+ */
+ curisread = (sc->sc_curmsg->flags & IIC_M_RD) ? 1 : 0;
+ curslave = sc->sc_curmsg->slave | curisread;
- sc->sc_data = msgs[i].buf;
- sc->sc_resid = msgs[i].len;
- if ((msgs[i].flags & IIC_M_RD) == 0) {
- /* Fill up the TX FIFO. */
- status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
- while (sc->sc_resid > 0 &&
- (status & BCM_BSC_STATUS_TXD)) {
- BCM_BSC_WRITE(sc, BCM_BSC_DATA, *sc->sc_data);
- sc->sc_data++;
- sc->sc_resid--;
- status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+ /* Write the slave address. */
+ BCM_BSC_WRITE(sc, BCM_BSC_SLAVE, curslave >> 1);
+
+ DEVICE_DEBUGF(sc, 2, "start 0x%02x\n", curslave);
+
+ /*
+ * Either set up read length and direction variables for a
+ * simple transfer or get the hardware started on the first
+ * piece of a transfer that involves a repeat-start and set up
+ * the read length and direction vars for the second piece.
+ */
+ if (sc->sc_replen == 0) {
+ DEVICE_DEBUGF(sc, 1, "%-6s 0x%02x len %d: ",
+ (curisread) ? "read" : "write", curslave,
+ sc->sc_totlen);
+ curlen = sc->sc_totlen;
+ if (curisread) {
+ readctl = BCM_BSC_CTRL_READ;
+ sc->sc_flags |= BCM_I2C_READ;
+ } else {
+ readctl = 0;
+ sc->sc_flags &= ~BCM_I2C_READ;
}
- read = 0;
- intr = BCM_BSC_CTRL_INTT;
- sc->sc_flags &= ~BCM_I2C_READ;
} else {
- sc->sc_flags |= BCM_I2C_READ;
- read = BCM_BSC_CTRL_READ;
- intr = BCM_BSC_CTRL_INTR;
+ DEVICE_DEBUGF(sc, 1, "%-6s 0x%02x len %d: ",
+ (curisread) ? "read" : "write", curslave,
+ sc->sc_replen);
+
+ /*
+ * Start the write transfer with an empty fifo and wait
+ * for the 'transfer active' status bit to light up;
+ * that indicates that the hardware has latched the
+ * direction and length for the write, and we can safely
+ * reload those registers and issue the start for the
+ * following read; interrupts are not enabled here.
+ */
+ BCM_BSC_WRITE(sc, BCM_BSC_DLEN, sc->sc_replen);
+ BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN |
+ BCM_BSC_CTRL_ST);
+ do {
+ status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+ if (status & BCM_BSC_STATUS_ERR) {
+ /* no ACK on slave addr */
+ err = EIO;
+ goto xfer_done;
+ }
+ } while ((status & BCM_BSC_STATUS_TA) == 0);
+ /*
+ * Set curlen and readctl for the repeat-start read that
+ * we need to set up below, but set sc_flags to write,
+ * because that is the operation in progress right now.
+ */
+ curlen = sc->sc_totlen - sc->sc_replen;
+ readctl = BCM_BSC_CTRL_READ;
+ sc->sc_flags &= ~BCM_I2C_READ;
}
- intr |= BCM_BSC_CTRL_INTD;
- /* Start the transfer. */
- BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN |
- BCM_BSC_CTRL_ST | read | intr);
+ /*
+ * Start the transfer with interrupts enabled, then if doing a
+ * write, fill the tx fifo. Not prefilling the fifo until after
+ * this start command is the key workaround for making
+ * repeat-start work, and it's harmless to do it in this order
+ * for a regular write too.
+ */
+ BCM_BSC_WRITE(sc, BCM_BSC_DLEN, curlen);
+ BCM_BSC_WRITE(sc, BCM_BSC_CTRL, readctl | BCM_BSC_CTRL_I2CEN |
+ BCM_BSC_CTRL_ST | BCM_BSC_CTRL_INT_ALL);
+
+ if (!(sc->sc_curmsg->flags & IIC_M_RD)) {
+ bcm_bsc_fill_tx_fifo(sc);
+ }
/* Wait for the transaction to complete. */
- err = mtx_sleep(dev, &sc->sc_mtx, 0, "bsciow", hz);
-
+ while (err == 0 && !(sc->sc_flags & BCM_I2C_DONE)) {
+ err = mtx_sleep(sc, &sc->sc_mtx, 0, "bsciow", hz);
+ }
/* Check for errors. */
if (err == 0 && (sc->sc_flags & BCM_I2C_ERROR))
err = EIO;
+xfer_done:
+ DEBUGF(sc, 1, " err=%d\n", err);
+ DEVICE_DEBUGF(sc, 2, "stop\n");
if (err != 0)
break;
}
+ /* Disable interrupts, clean fifo, etc. */
+ bcm_bsc_reset(sc);
+
/* Clean the controller flags. */
sc->sc_flags = 0;
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h b/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h
index d48ce37..48b31b6 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h
+++ b/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h
@@ -40,6 +40,9 @@
#define BCM_BSC_CTRL_CLEAR1 (1 << 5)
#define BCM_BSC_CTRL_CLEAR0 (1 << 4)
#define BCM_BSC_CTRL_READ (1 << 0)
+#define BCM_BSC_CTRL_INT_ALL \
+ (BCM_BSC_CTRL_INTR | BCM_BSC_CTRL_INTT | BCM_BSC_CTRL_INTD)
+
#define BCM_BSC_STATUS 0x04
#define BCM_BSC_STATUS_CLKT (1 << 9)
#define BCM_BSC_STATUS_ERR (1 << 8)
@@ -51,6 +54,9 @@
#define BCM_BSC_STATUS_TXW (1 << 2)
#define BCM_BSC_STATUS_DONE (1 << 1)
#define BCM_BSC_STATUS_TA (1 << 0)
+#define BCM_BSC_STATUS_ERRBITS \
+ (BCM_BSC_STATUS_CLKT | BCM_BSC_STATUS_ERR)
+
#define BCM_BSC_DLEN 0x08
#define BCM_BSC_SLAVE 0x0c
#define BCM_BSC_DATA 0x10
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h b/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h
index 6b31dc3..7797485 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h
+++ b/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h
@@ -40,23 +40,31 @@ struct {
};
#define BCM_BSC_BASE_MASK 0x00ffffff
+struct iic_msg;
+
struct bcm_bsc_softc {
device_t sc_dev;
device_t sc_iicbus;
struct mtx sc_mtx;
struct resource * sc_mem_res;
struct resource * sc_irq_res;
+ void * sc_intrhand;
+ struct iic_msg * sc_curmsg;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
+ int sc_debug;
+ uint16_t sc_replen;
+ uint16_t sc_totlen;
uint16_t sc_resid;
- uint8_t *sc_data;
+ uint16_t sc_dlen;
+ uint8_t * sc_data;
uint8_t sc_flags;
- void * sc_intrhand;
};
#define BCM_I2C_BUSY 0x01
#define BCM_I2C_READ 0x02
#define BCM_I2C_ERROR 0x04
+#define BCM_I2C_DONE 0x08
#define BCM_BSC_WRITE(_sc, _off, _val) \
bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, _off, _val)
diff --git a/sys/arm/broadcom/bcm2835/std.rpi b/sys/arm/broadcom/bcm2835/std.rpi
index 793eab1..48593c1 100644
--- a/sys/arm/broadcom/bcm2835/std.rpi
+++ b/sys/arm/broadcom/bcm2835/std.rpi
@@ -1,5 +1,3 @@
# $FreeBSD$
-options KERNVIRTADDR=0xc0100000
-makeoptions KERNVIRTADDR=0xc0100000
options LINUX_BOOT_ABI
diff --git a/sys/arm/conf/NOTES b/sys/arm/conf/NOTES
index b785927..a2e31b4 100644
--- a/sys/arm/conf/NOTES
+++ b/sys/arm/conf/NOTES
@@ -24,11 +24,9 @@ files "../xscale/ixp425/files.ixp425"
files "../xscale/pxa/files.pxa"
options PHYSADDR=0x00000000
-options KERNVIRTADDR=0xc0000000
makeoptions LDFLAGS="-zmuldefs"
makeoptions KERNPHYSADDR=0x00000000
-makeoptions KERNVIRTADDR=0xc0000000
options FDT
diff --git a/sys/arm/freescale/imx/imx6_hdmi.c b/sys/arm/freescale/imx/imx6_hdmi.c
index c6e7fe4..f8a0d0c 100644
--- a/sys/arm/freescale/imx/imx6_hdmi.c
+++ b/sys/arm/freescale/imx/imx6_hdmi.c
@@ -63,11 +63,11 @@ struct imx_hdmi_softc {
device_t sc_dev;
struct resource *sc_mem_res;
int sc_mem_rid;
- struct intr_config_hook sc_mode_hook;
struct videomode sc_mode;
uint8_t *sc_edid;
uint8_t sc_edid_len;
phandle_t sc_i2c_xref;
+ eventhandler_tag eh_tag;
};
static struct ofw_compat_data compat_data[] = {
@@ -626,15 +626,51 @@ hdmi_edid_read(struct imx_hdmi_softc *sc, uint8_t **edid, uint32_t *edid_len)
return (result);
}
+/*
+ * Deferred HDMI init. dwc_hdmi_init() does i2c transfers for DDC/EDID. The imx
+ * i2c devices also use a config_intrhook function to finish their init, because
+ * they require interrupts to perform transfers. There is no way to control
+ * whether the i2c or our hdmi intrhook function runs first. If we go first we
+ * have to continue waiting until after the i2c driver is ready to do transfers
+ * and has registered its phandle.
+ *
+ * This function is used as both a config_intrhook function and after that as an
+ * eventhandler callback function (if necessary), to see if our i2c device is
+ * ready yet. When it is, continue with hdmi init. When first called as an
+ * intrhook function the i2c devices might be ready, in which case we never
+ * register as an eventhandler at all. Otherwise we register to see newbus
+ * attach events, and as each device attaches we check to see whether it was the
+ * i2c device we care about. Once we have our i2c device we unregister from
+ * seeing further attach events.
+ */
static void
-imx_hdmi_detect_cable(void *arg)
+imx_hdmi_init(void *dev)
{
struct imx_hdmi_softc *sc;
- sc = arg;
- EVENTHANDLER_INVOKE(hdmi_event, sc->sc_dev, HDMI_EVENT_CONNECTED);
- /* Finished with the interrupt hook */
- config_intrhook_disestablish(&sc->sc_mode_hook);
+ sc = device_get_softc((device_t)dev);
+
+ if (OF_device_from_xref(sc->sc_i2c_xref) != NULL) {
+ if (sc->eh_tag != NULL) {
+ EVENTHANDLER_DEREGISTER_NOWAIT(device_attach,
+ sc->eh_tag);
+ }
+ WR1(sc, HDMI_PHY_POL0, HDMI_PHY_HPD);
+ WR1(sc, HDMI_IH_PHY_STAT0, HDMI_IH_PHY_STAT0_HPD);
+ if ((RD1(sc, HDMI_IH_PHY_STAT0) & HDMI_IH_PHY_STAT0_HPD) != 0) {
+ EVENTHANDLER_INVOKE(hdmi_event, sc->sc_dev,
+ HDMI_EVENT_CONNECTED);
+ }
+ return;
+ }
+
+ if (bootverbose)
+ device_printf((device_t)dev, "Waiting for DDC i2c device\n");
+
+ if (sc->eh_tag == NULL) {
+ sc->eh_tag = EVENTHANDLER_REGISTER(device_attach,
+ imx_hdmi_init, dev, EVENTHANDLER_PRI_ANY);
+ }
}
static int
@@ -673,14 +709,6 @@ imx_hdmi_attach(device_t dev)
goto out;
}
- sc->sc_mode_hook.ich_func = imx_hdmi_detect_cable;
- sc->sc_mode_hook.ich_arg = sc;
-
- if (config_intrhook_establish(&sc->sc_mode_hook) != 0) {
- err = ENOMEM;
- goto out;
- }
-
node = ofw_bus_get_node(dev);
if (OF_getencprop(node, "ddc-i2c-bus", &i2c_xref, sizeof(i2c_xref)) == -1)
sc->sc_i2c_xref = 0;
@@ -702,8 +730,8 @@ imx_hdmi_attach(device_t dev)
gpr3 |= IOMUXC_GPR3_HDMI_IPU1_DI0;
imx_iomux_gpr_set(IOMUXC_GPR3, gpr3);
- WR1(sc, HDMI_PHY_POL0, HDMI_PHY_HPD);
- WR1(sc, HDMI_IH_PHY_STAT0, HDMI_IH_PHY_STAT0_HPD);
+ /* Further HDMI init requires interrupts for i2c transfers. */
+ config_intrhook_oneshot(imx_hdmi_init, dev);
out:
diff --git a/sys/arm/freescale/imx/std.imx51 b/sys/arm/freescale/imx/std.imx51
index 4f9ac14..a6f0329 100644
--- a/sys/arm/freescale/imx/std.imx51
+++ b/sys/arm/freescale/imx/std.imx51
@@ -3,9 +3,6 @@ machine arm armv6
cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
-options KERNVIRTADDR=0xc0100000
-makeoptions KERNVIRTADDR=0xc0100000
-
device fdt_pinctrl
files "../freescale/imx/files.imx5"
diff --git a/sys/arm/freescale/imx/std.imx53 b/sys/arm/freescale/imx/std.imx53
index 4f9ac14..a6f0329 100644
--- a/sys/arm/freescale/imx/std.imx53
+++ b/sys/arm/freescale/imx/std.imx53
@@ -3,9 +3,6 @@ machine arm armv6
cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
-options KERNVIRTADDR=0xc0100000
-makeoptions KERNVIRTADDR=0xc0100000
-
device fdt_pinctrl
files "../freescale/imx/files.imx5"
diff --git a/sys/arm/freescale/imx/std.imx6 b/sys/arm/freescale/imx/std.imx6
index 7d9dc3c..3221c5c 100644
--- a/sys/arm/freescale/imx/std.imx6
+++ b/sys/arm/freescale/imx/std.imx6
@@ -3,9 +3,6 @@ machine arm armv6
cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
-options KERNVIRTADDR = 0xc2000000
-makeoptions KERNVIRTADDR = 0xc2000000
-
options IPI_IRQ_START=0
options IPI_IRQ_END=15
diff --git a/sys/arm/freescale/vybrid/std.vybrid b/sys/arm/freescale/vybrid/std.vybrid
index 6baf948..da3098e 100644
--- a/sys/arm/freescale/vybrid/std.vybrid
+++ b/sys/arm/freescale/vybrid/std.vybrid
@@ -4,7 +4,4 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-makeoptions KERNVIRTADDR=0xc0100000
-options KERNVIRTADDR=0xc0100000
-
files "../freescale/vybrid/files.vybrid"
diff --git a/sys/arm/include/atomic.h b/sys/arm/include/atomic.h
index ed87fb4..94735fc 100644
--- a/sys/arm/include/atomic.h
+++ b/sys/arm/include/atomic.h
@@ -39,6 +39,8 @@
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
+#include <sys/atomic_common.h>
+
#include <machine/armreg.h>
#ifndef _KERNEL
@@ -51,32 +53,6 @@
#include <machine/atomic-v4.h>
#endif /* Arch >= v6 */
-static __inline int
-atomic_load_32(volatile uint32_t *v)
-{
-
- return (*v);
-}
-
-static __inline void
-atomic_store_32(volatile uint32_t *dst, uint32_t src)
-{
- *dst = src;
-}
-
-static __inline int
-atomic_load_long(volatile u_long *v)
-{
-
- return (*v);
-}
-
-static __inline void
-atomic_store_long(volatile u_long *dst, u_long src)
-{
- *dst = src;
-}
-
#define atomic_clear_ptr atomic_clear_32
#define atomic_clear_acq_ptr atomic_clear_acq_32
#define atomic_clear_rel_ptr atomic_clear_rel_32
@@ -90,7 +66,6 @@ atomic_store_long(volatile u_long *dst, u_long src)
#define atomic_cmpset_acq_ptr atomic_cmpset_acq_32
#define atomic_cmpset_rel_ptr atomic_cmpset_rel_32
#define atomic_load_acq_ptr atomic_load_acq_32
-#define atomic_store_ptr atomic_store_32
#define atomic_store_rel_ptr atomic_store_rel_32
#define atomic_swap_ptr atomic_swap_32
#define atomic_readandclear_ptr atomic_readandclear_32
diff --git a/sys/arm/include/vmparam.h b/sys/arm/include/vmparam.h
index 061ccab..9ada97d 100644
--- a/sys/arm/include/vmparam.h
+++ b/sys/arm/include/vmparam.h
@@ -73,6 +73,19 @@
#endif
/*
+ * The virtual address the kernel is linked to run at. For armv4/5 platforms
+ * the low-order 30 bits of this must match the low-order bits of the physical
+ * address the kernel is loaded at, so the value is most often provided as a
+ * kernel config option in the std.platform file. For armv6/7 the kernel can
+ * be loaded at any 2MB boundary, and KERNVIRTADDR can also be set to any 2MB
+ * boundary. It is typically overridden in the std.platform file only when
+ * KERNBASE is also set to a lower address to provide more KVA.
+ */
+#ifndef KERNVIRTADDR
+#define KERNVIRTADDR 0xc0000000
+#endif
+
+/*
* max number of non-contig chunks of physical RAM you can have
*/
diff --git a/sys/arm/mv/armada38x/std.armada38x b/sys/arm/mv/armada38x/std.armada38x
index 732fd90..cbfe91d 100644
--- a/sys/arm/mv/armada38x/std.armada38x
+++ b/sys/arm/mv/armada38x/std.armada38x
@@ -5,8 +5,6 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-makeoptions KERNVIRTADDR=0xc0000000
-options KERNVIRTADDR=0xc0000000
options IPI_IRQ_START=0
options IPI_IRQ_END=15
diff --git a/sys/arm/mv/armadaxp/std.armadaxp b/sys/arm/mv/armadaxp/std.armadaxp
index 84361f5..b720e3d 100644
--- a/sys/arm/mv/armadaxp/std.armadaxp
+++ b/sys/arm/mv/armadaxp/std.armadaxp
@@ -1,4 +1,2 @@
# $FreeBSD$
-makeoptions KERNVIRTADDR=0xc0200000
-options KERNVIRTADDR=0xc0200000
diff --git a/sys/arm/nvidia/tegra124/std.tegra124 b/sys/arm/nvidia/tegra124/std.tegra124
index 35de225..e8201c3 100644
--- a/sys/arm/nvidia/tegra124/std.tegra124
+++ b/sys/arm/nvidia/tegra124/std.tegra124
@@ -3,9 +3,6 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-options KERNVIRTADDR = 0xc0200000
-makeoptions KERNVIRTADDR = 0xc0200000
-
options INTRNG
options IPI_IRQ_START=0
diff --git a/sys/arm/rockchip/std.rk30xx b/sys/arm/rockchip/std.rk30xx
index 431526b..63fcfce 100644
--- a/sys/arm/rockchip/std.rk30xx
+++ b/sys/arm/rockchip/std.rk30xx
@@ -5,9 +5,6 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-makeoptions KERNVIRTADDR=0xc0400000
-options KERNVIRTADDR=0xc0400000
-
options IPI_IRQ_START=0
options IPI_IRQ_END=15
diff --git a/sys/arm/samsung/exynos/std.exynos5250 b/sys/arm/samsung/exynos/std.exynos5250
index 52e4508..ef97dd8 100644
--- a/sys/arm/samsung/exynos/std.exynos5250
+++ b/sys/arm/samsung/exynos/std.exynos5250
@@ -4,9 +4,6 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-makeoptions KERNVIRTADDR=0xc0f00000
-options KERNVIRTADDR=0xc0f00000
-
options IPI_IRQ_START=0
options IPI_IRQ_END=15
diff --git a/sys/arm/samsung/exynos/std.exynos5420 b/sys/arm/samsung/exynos/std.exynos5420
index 52e4508..ef97dd8 100644
--- a/sys/arm/samsung/exynos/std.exynos5420
+++ b/sys/arm/samsung/exynos/std.exynos5420
@@ -4,9 +4,6 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
-makeoptions KERNVIRTADDR=0xc0f00000
-options KERNVIRTADDR=0xc0f00000
-
options IPI_IRQ_START=0
options IPI_IRQ_END=15
diff --git a/sys/arm/ti/am335x/std.am335x b/sys/arm/ti/am335x/std.am335x
index b5565c2..8f4ac21 100644
--- a/sys/arm/ti/am335x/std.am335x
+++ b/sys/arm/ti/am335x/std.am335x
@@ -3,7 +3,4 @@
files "../ti/am335x/files.am335x"
include "../ti/std.ti"
-options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
-makeoptions KERNVIRTADDR=0xc0200000
-
options SOC_TI_AM335X
diff --git a/sys/arm/ti/omap4/std.omap4 b/sys/arm/ti/omap4/std.omap4
index 8d5764b..6bcf40d 100644
--- a/sys/arm/ti/omap4/std.omap4
+++ b/sys/arm/ti/omap4/std.omap4
@@ -3,7 +3,4 @@
files "../ti/omap4/files.omap4"
include "../ti/std.ti"
-options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
-makeoptions KERNVIRTADDR=0xc0200000
-
options SOC_OMAP4
diff --git a/sys/arm/ti/ti_pruss.c b/sys/arm/ti/ti_pruss.c
index cbf8050..e3f84b2 100644
--- a/sys/arm/ti/ti_pruss.c
+++ b/sys/arm/ti/ti_pruss.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2013 Rui Paulo <rpaulo@FreeBSD.org>
+ * Copyright (c) 2017 Manuel Stuehn
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,28 +27,33 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <sys/uio.h>
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/fcntl.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
#include <sys/event.h>
#include <sys/selinfo.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/intr.h>
+#include <machine/atomic.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include <machine/bus.h>
-
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_pruss.h>
@@ -60,27 +66,72 @@ __FBSDID("$FreeBSD$");
#define DPRINTF(fmt, ...)
#endif
+static d_open_t ti_pruss_irq_open;
+static d_read_t ti_pruss_irq_read;
+static d_poll_t ti_pruss_irq_poll;
+
static device_probe_t ti_pruss_probe;
static device_attach_t ti_pruss_attach;
static device_detach_t ti_pruss_detach;
static void ti_pruss_intr(void *);
static d_open_t ti_pruss_open;
static d_mmap_t ti_pruss_mmap;
-static void ti_pruss_kq_read_detach(struct knote *);
-static int ti_pruss_kq_read_event(struct knote *, long);
-static d_kqfilter_t ti_pruss_kqfilter;
+static void ti_pruss_irq_kqread_detach(struct knote *);
+static int ti_pruss_irq_kqevent(struct knote *, long);
+static d_kqfilter_t ti_pruss_irq_kqfilter;
+static void ti_pruss_privdtor(void *data);
+
+#define TI_PRUSS_PRU_IRQS 2
+#define TI_PRUSS_HOST_IRQS 8
+#define TI_PRUSS_IRQS (TI_PRUSS_HOST_IRQS+TI_PRUSS_PRU_IRQS)
+#define TI_PRUSS_EVENTS 64
+#define NOT_SET_STR "NONE"
+#define TI_TS_ARRAY 16
+
+struct ctl
+{
+ size_t cnt;
+ size_t idx;
+};
+
+struct ts_ring_buf
+{
+ struct ctl ctl;
+ uint64_t ts[TI_TS_ARRAY];
+};
+
+struct ti_pruss_irqsc
+{
+ struct mtx sc_mtx;
+ struct cdev *sc_pdev;
+ struct selinfo sc_selinfo;
+ int8_t channel;
+ int8_t last;
+ int8_t event;
+ bool enable;
+ struct ts_ring_buf tstamps;
+};
-#define TI_PRUSS_IRQS 8
+static struct cdevsw ti_pruss_cdevirq = {
+ .d_version = D_VERSION,
+ .d_name = "ti_pruss_irq",
+ .d_open = ti_pruss_irq_open,
+ .d_read = ti_pruss_irq_read,
+ .d_poll = ti_pruss_irq_poll,
+ .d_kqfilter = ti_pruss_irq_kqfilter,
+};
struct ti_pruss_softc {
struct mtx sc_mtx;
struct resource *sc_mem_res;
- struct resource *sc_irq_res[TI_PRUSS_IRQS];
- void *sc_intr[TI_PRUSS_IRQS];
+ struct resource *sc_irq_res[TI_PRUSS_HOST_IRQS];
+ void *sc_intr[TI_PRUSS_HOST_IRQS];
+ struct ti_pruss_irqsc sc_irq_devs[TI_PRUSS_IRQS];
bus_space_tag_t sc_bt;
bus_space_handle_t sc_bh;
struct cdev *sc_pdev;
struct selinfo sc_selinfo;
+ bool sc_glob_irqen;
};
static struct cdevsw ti_pruss_cdevsw = {
@@ -88,7 +139,6 @@ static struct cdevsw ti_pruss_cdevsw = {
.d_name = "ti_pruss",
.d_open = ti_pruss_open,
.d_mmap = ti_pruss_mmap,
- .d_kqfilter = ti_pruss_kqfilter,
};
static device_method_t ti_pruss_methods[] = {
@@ -108,6 +158,7 @@ static driver_t ti_pruss_driver = {
static devclass_t ti_pruss_devclass;
DRIVER_MODULE(ti_pruss, simplebus, ti_pruss_driver, ti_pruss_devclass, 0, 0);
+MODULE_DEPEND(ti_pruss, ti_prcm, 1, 1, 1);
static struct resource_spec ti_pruss_irq_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE },
@@ -120,7 +171,111 @@ static struct resource_spec ti_pruss_irq_spec[] = {
{ SYS_RES_IRQ, 7, RF_ACTIVE },
{ -1, 0, 0 }
};
-CTASSERT(TI_PRUSS_IRQS == nitems(ti_pruss_irq_spec) - 1);
+CTASSERT(TI_PRUSS_HOST_IRQS == nitems(ti_pruss_irq_spec) - 1);
+
+static int
+ti_pruss_irq_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+{
+ struct ctl* irqs;
+ struct ti_pruss_irqsc *sc;
+ sc = dev->si_drv1;
+
+ irqs = malloc(sizeof(struct ctl), M_DEVBUF, M_WAITOK);
+ if (!irqs)
+ return (ENOMEM);
+
+ irqs->cnt = sc->tstamps.ctl.cnt;
+ irqs->idx = sc->tstamps.ctl.idx;
+
+ return devfs_set_cdevpriv(irqs, ti_pruss_privdtor);
+}
+
+static void
+ti_pruss_privdtor(void *data)
+{
+ free(data, M_DEVBUF);
+}
+
+static int
+ti_pruss_irq_poll(struct cdev *dev, int events, struct thread *td)
+{
+ struct ctl* irqs;
+ struct ti_pruss_irqsc *sc;
+ sc = dev->si_drv1;
+
+ devfs_get_cdevpriv((void**)&irqs);
+
+ if (events & (POLLIN | POLLRDNORM)) {
+ if (sc->tstamps.ctl.cnt != irqs->cnt)
+ return events & (POLLIN | POLLRDNORM);
+ else
+ selrecord(td, &sc->sc_selinfo);
+ }
+ return 0;
+}
+
+static int
+ti_pruss_irq_read(struct cdev *cdev, struct uio *uio, int ioflag)
+{
+ const size_t ts_len = sizeof(uint64_t);
+ struct ti_pruss_irqsc* irq;
+ struct ctl* priv;
+ int error = 0;
+ size_t idx;
+ ssize_t level;
+
+ irq = cdev->si_drv1;
+
+ if (uio->uio_resid < ts_len)
+ return (EINVAL);
+
+ error = devfs_get_cdevpriv((void**)&priv);
+ if (error)
+ return (error);
+
+ mtx_lock(&irq->sc_mtx);
+
+ if (irq->tstamps.ctl.cnt - priv->cnt > TI_TS_ARRAY)
+ {
+ priv->cnt = irq->tstamps.ctl.cnt;
+ priv->idx = irq->tstamps.ctl.idx;
+ mtx_unlock(&irq->sc_mtx);
+ return (ENXIO);
+ }
+
+ do {
+ idx = priv->idx;
+ level = irq->tstamps.ctl.idx - idx;
+ if (level < 0)
+ level += TI_TS_ARRAY;
+
+ if (level == 0) {
+ if (ioflag & O_NONBLOCK) {
+ mtx_unlock(&irq->sc_mtx);
+ return (EWOULDBLOCK);
+ }
+
+ error = msleep(irq, &irq->sc_mtx, PCATCH | PDROP,
+ "pruirq", 0);
+ if (error)
+ return error;
+
+ mtx_lock(&irq->sc_mtx);
+ }
+ }while(level == 0);
+
+ mtx_unlock(&irq->sc_mtx);
+
+ error = uiomove(&irq->tstamps.ts[idx], ts_len, uio);
+
+ if (++idx == TI_TS_ARRAY)
+ idx = 0;
+ priv->idx = idx;
+
+ atomic_add_32(&priv->cnt, 1);
+
+ return (error);
+}
static struct ti_pruss_irq_arg {
int irq;
@@ -139,6 +294,204 @@ ti_pruss_reg_write(struct ti_pruss_softc *sc, uint32_t reg, uint32_t val)
bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
}
+static __inline void
+ti_pruss_interrupts_clear(struct ti_pruss_softc *sc)
+{
+ /* disable global interrupt */
+ ti_pruss_reg_write(sc, PRUSS_INTC_GER, 0 );
+
+ /* clear all events */
+ ti_pruss_reg_write(sc, PRUSS_INTC_SECR0, 0xFFFFFFFF);
+ ti_pruss_reg_write(sc, PRUSS_INTC_SECR1, 0xFFFFFFFF);
+
+ /* disable all host interrupts */
+ ti_pruss_reg_write(sc, PRUSS_INTC_HIER, 0);
+}
+
+static __inline int
+ti_pruss_interrupts_enable(struct ti_pruss_softc *sc, int8_t irq, bool enable)
+{
+ if (enable && ((sc->sc_irq_devs[irq].channel == -1) ||
+ (sc->sc_irq_devs[irq].event== -1)))
+ {
+ device_printf( sc->sc_pdev->si_drv1,
+ "Interrupt chain not fully configured, not possible to enable\n" );
+ return (EINVAL);
+ }
+
+ sc->sc_irq_devs[irq].enable = enable;
+
+ if (sc->sc_irq_devs[irq].sc_pdev) {
+ destroy_dev(sc->sc_irq_devs[irq].sc_pdev);
+ sc->sc_irq_devs[irq].sc_pdev = NULL;
+ }
+
+ if (enable) {
+ sc->sc_irq_devs[irq].sc_pdev = make_dev(&ti_pruss_cdevirq, 0, UID_ROOT, GID_WHEEL,
+ 0600, "pruss%d.irq%d", device_get_unit(sc->sc_pdev->si_drv1), irq);
+ sc->sc_irq_devs[irq].sc_pdev->si_drv1 = &sc->sc_irq_devs[irq];
+
+ sc->sc_irq_devs[irq].tstamps.ctl.idx = 0;
+ }
+
+ uint32_t reg = enable ? PRUSS_INTC_HIEISR : PRUSS_INTC_HIDISR;
+ ti_pruss_reg_write(sc, reg, sc->sc_irq_devs[irq].channel);
+
+ reg = enable ? PRUSS_INTC_EISR : PRUSS_INTC_EICR;
+ ti_pruss_reg_write(sc, reg, sc->sc_irq_devs[irq].event );
+
+ return (0);
+}
+
+static __inline void
+ti_pruss_map_write(struct ti_pruss_softc *sc, uint32_t basereg, uint8_t index, uint8_t content)
+{
+ const size_t regadr = basereg + index & ~0x03;
+ const size_t bitpos = (index & 0x03) * 8;
+ uint32_t rmw = ti_pruss_reg_read(sc, regadr);
+ rmw = (rmw & ~( 0xF << bitpos)) | ( (content & 0xF) << bitpos);
+ ti_pruss_reg_write(sc, regadr, rmw);
+}
+
+static int
+ti_pruss_event_map( SYSCTL_HANDLER_ARGS )
+{
+ struct ti_pruss_softc *sc;
+ const int8_t irq = arg2;
+ int err;
+ char event[sizeof(NOT_SET_STR)];
+
+ sc = arg1;
+
+ if(sc->sc_irq_devs[irq].event == -1)
+ bcopy(NOT_SET_STR, event, sizeof(event));
+ else
+ snprintf(event, sizeof(event), "%d", sc->sc_irq_devs[irq].event);
+
+ err = sysctl_handle_string(oidp, event, sizeof(event), req);
+ if(err != 0)
+ return (err);
+
+ if (req->newptr) { // write event
+ if (strcmp(NOT_SET_STR, event) == 0) {
+ ti_pruss_interrupts_enable(sc, irq, false);
+ sc->sc_irq_devs[irq].event = -1;
+ } else {
+ if (sc->sc_irq_devs[irq].channel == -1) {
+ device_printf( sc->sc_pdev->si_drv1,
+ "corresponding channel not configured\n");
+ return (ENXIO);
+ }
+
+ const int8_t channelnr = sc->sc_irq_devs[irq].channel;
+ const int8_t eventnr = strtol( event, NULL, 10 ); // TODO: check if strol is valid
+ if (eventnr > TI_PRUSS_EVENTS || eventnr < 0) {
+ device_printf( sc->sc_pdev->si_drv1,
+ "Event number %d not valid (0 - %d)",
+ channelnr, TI_PRUSS_EVENTS -1);
+ return (EINVAL);
+ }
+
+ sc->sc_irq_devs[irq].channel = channelnr;
+ sc->sc_irq_devs[irq].event = eventnr;
+
+ // event[nr] <= channel
+ ti_pruss_map_write(sc, PRUSS_INTC_CMR_BASE,
+ eventnr, channelnr);
+ }
+ }
+ return (err);
+}
+
+static int
+ti_pruss_channel_map(SYSCTL_HANDLER_ARGS)
+{
+ struct ti_pruss_softc *sc;
+ int err;
+ char channel[sizeof(NOT_SET_STR)];
+ const int8_t irq = arg2;
+
+ sc = arg1;
+
+ if (sc->sc_irq_devs[irq].channel == -1)
+ bcopy(NOT_SET_STR, channel, sizeof(channel));
+ else
+ snprintf(channel, sizeof(channel), "%d", sc->sc_irq_devs[irq].channel);
+
+ err = sysctl_handle_string(oidp, channel, sizeof(channel), req);
+ if (err != 0)
+ return (err);
+
+ if (req->newptr) { // write event
+ if (strcmp(NOT_SET_STR, channel) == 0) {
+ ti_pruss_interrupts_enable(sc, irq, false);
+ ti_pruss_reg_write(sc, PRUSS_INTC_HIDISR,
+ sc->sc_irq_devs[irq].channel);
+ sc->sc_irq_devs[irq].channel = -1;
+ } else {
+ const int8_t channelnr = strtol(channel, NULL, 10); // TODO: check if strol is valid
+ if (channelnr > TI_PRUSS_IRQS || channelnr < 0)
+ {
+ device_printf(sc->sc_pdev->si_drv1,
+ "Channel number %d not valid (0 - %d)",
+ channelnr, TI_PRUSS_IRQS-1);
+ return (EINVAL);
+ }
+
+ sc->sc_irq_devs[irq].channel = channelnr;
+ sc->sc_irq_devs[irq].last = -1;
+
+ // channel[nr] <= irqnr
+ ti_pruss_map_write(sc, PRUSS_INTC_HMR_BASE,
+ irq, channelnr);
+ }
+ }
+
+ return (err);
+}
+
+static int
+ti_pruss_interrupt_enable(SYSCTL_HANDLER_ARGS)
+{
+ struct ti_pruss_softc *sc;
+ int err;
+ bool irqenable;
+ const int8_t irq = arg2;
+
+ sc = arg1;
+ irqenable = sc->sc_irq_devs[arg2].enable;
+
+ err = sysctl_handle_bool(oidp, &irqenable, arg2, req);
+ if (err != 0)
+ return (err);
+
+ if (req->newptr) // write enable
+ return ti_pruss_interrupts_enable(sc, irq, irqenable);
+
+ return (err);
+}
+
+static int
+ti_pruss_global_interrupt_enable(SYSCTL_HANDLER_ARGS)
+{
+ struct ti_pruss_softc *sc;
+ int err;
+ bool glob_irqen;
+
+ sc = arg1;
+ glob_irqen = sc->sc_glob_irqen;
+
+ err = sysctl_handle_bool(oidp, &glob_irqen, arg2, req);
+ if (err != 0)
+ return (err);
+
+ if (req->newptr) {
+ sc->sc_glob_irqen = glob_irqen;
+ ti_pruss_reg_write(sc, PRUSS_INTC_GER, glob_irqen);
+ }
+
+ return (err);
+}
static int
ti_pruss_probe(device_t dev)
{
@@ -168,13 +521,31 @@ ti_pruss_attach(device_t dev)
sc = device_get_softc(dev);
rid = 0;
mtx_init(&sc->sc_mtx, "TI PRUSS", NULL, MTX_DEF);
- knlist_init_mtx(&sc->sc_selinfo.si_note, &sc->sc_mtx);
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->sc_mem_res == NULL) {
device_printf(dev, "could not allocate memory resource\n");
return (ENXIO);
}
+
+ struct sysctl_ctx_list *clist = device_get_sysctl_ctx(dev);
+ if (!clist)
+ return (EINVAL);
+
+ struct sysctl_oid *poid;
+ poid = device_get_sysctl_tree( dev );
+ if (!poid)
+ return (EINVAL);
+
+ sc->sc_glob_irqen = false;
+ struct sysctl_oid *irq_root = SYSCTL_ADD_NODE(clist, SYSCTL_CHILDREN(poid),
+ OID_AUTO, "irq", CTLFLAG_RD, 0,
+ "PRUSS Host Interrupts");
+ SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(poid), OID_AUTO,
+ "global_interrupt_enable", CTLFLAG_RW | CTLTYPE_U8,
+ sc, 0, ti_pruss_global_interrupt_enable,
+ "CU", "Global interrupt enable");
+
sc->sc_bt = rman_get_bustag(sc->sc_mem_res);
sc->sc_bh = rman_get_bushandle(sc->sc_mem_res);
if (bus_alloc_resources(dev, ti_pruss_irq_spec, sc->sc_irq_res) != 0) {
@@ -182,48 +553,91 @@ ti_pruss_attach(device_t dev)
ti_pruss_detach(dev);
return (ENXIO);
}
+
+ ti_pruss_interrupts_clear(sc);
+
for (i = 0; i < TI_PRUSS_IRQS; i++) {
- ti_pruss_irq_args[i].irq = i;
- ti_pruss_irq_args[i].sc = sc;
- if (bus_setup_intr(dev, sc->sc_irq_res[i],
- INTR_MPSAFE | INTR_TYPE_MISC,
- NULL, ti_pruss_intr, &ti_pruss_irq_args[i],
- &sc->sc_intr[i]) != 0) {
- device_printf(dev,
- "unable to setup the interrupt handler\n");
- ti_pruss_detach(dev);
- return (ENXIO);
+ char name[8];
+ snprintf(name, sizeof(name), "%d", i);
+
+ struct sysctl_oid *irq_nodes = SYSCTL_ADD_NODE(clist, SYSCTL_CHILDREN(irq_root),
+ OID_AUTO, name, CTLFLAG_RD, 0,
+ "PRUSS Interrupts");
+ SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(irq_nodes), OID_AUTO,
+ "channel", CTLFLAG_RW | CTLTYPE_STRING, sc, i, ti_pruss_channel_map,
+ "A", "Channel attached to this irq");
+ SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(irq_nodes), OID_AUTO,
+ "event", CTLFLAG_RW | CTLTYPE_STRING, sc, i, ti_pruss_event_map,
+ "A", "Event attached to this irq");
+ SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(irq_nodes), OID_AUTO,
+ "enable", CTLFLAG_RW | CTLTYPE_U8, sc, i, ti_pruss_interrupt_enable,
+ "CU", "Enable/Disable interrupt");
+
+ sc->sc_irq_devs[i].event = -1;
+ sc->sc_irq_devs[i].channel = -1;
+ sc->sc_irq_devs[i].tstamps.ctl.idx = 0;
+
+ if (i < TI_PRUSS_HOST_IRQS) {
+ ti_pruss_irq_args[i].irq = i;
+ ti_pruss_irq_args[i].sc = sc;
+ if (bus_setup_intr(dev, sc->sc_irq_res[i],
+ INTR_MPSAFE | INTR_TYPE_MISC,
+ NULL, ti_pruss_intr, &ti_pruss_irq_args[i],
+ &sc->sc_intr[i]) != 0) {
+ device_printf(dev,
+ "unable to setup the interrupt handler\n");
+ ti_pruss_detach(dev);
+
+ return (ENXIO);
+ }
+ mtx_init(&sc->sc_irq_devs[i].sc_mtx, "TI PRUSS IRQ", NULL, MTX_DEF);
+ knlist_init_mtx(&sc->sc_irq_devs[i].sc_selinfo.si_note, &sc->sc_irq_devs[i].sc_mtx);
}
}
- if (ti_pruss_reg_read(sc, PRUSS_AM18XX_INTC) == PRUSS_AM18XX_REV)
- device_printf(dev, "AM18xx PRU-ICSS\n");
- else if (ti_pruss_reg_read(sc, PRUSS_AM33XX_INTC) == PRUSS_AM33XX_REV)
+
+ if (ti_pruss_reg_read(sc, PRUSS_AM33XX_INTC) == PRUSS_AM33XX_REV)
device_printf(dev, "AM33xx PRU-ICSS\n");
sc->sc_pdev = make_dev(&ti_pruss_cdevsw, 0, UID_ROOT, GID_WHEEL,
0600, "pruss%d", device_get_unit(dev));
sc->sc_pdev->si_drv1 = dev;
+ /* Acc. to datasheet always write 1 to polarity registers */
+ ti_pruss_reg_write(sc, PRUSS_INTC_SIPR0, 0xFFFFFFFF);
+ ti_pruss_reg_write(sc, PRUSS_INTC_SIPR1, 0xFFFFFFFF);
+
+ /* Acc. to datasheet always write 0 to event type registers */
+ ti_pruss_reg_write(sc, PRUSS_INTC_SITR0, 0);
+ ti_pruss_reg_write(sc, PRUSS_INTC_SITR1, 0);
+
return (0);
}
static int
ti_pruss_detach(device_t dev)
{
- struct ti_pruss_softc *sc;
- int i;
+ struct ti_pruss_softc *sc = device_get_softc(dev);
+
+ ti_pruss_interrupts_clear(sc);
+
+ for (int i = 0; i < TI_PRUSS_HOST_IRQS; i++) {
+ ti_pruss_interrupts_enable( sc, i, false );
- sc = device_get_softc(dev);
- for (i = 0; i < TI_PRUSS_IRQS; i++) {
if (sc->sc_intr[i])
bus_teardown_intr(dev, sc->sc_irq_res[i], sc->sc_intr[i]);
if (sc->sc_irq_res[i])
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->sc_irq_res[i]),
sc->sc_irq_res[i]);
+ knlist_clear(&sc->sc_irq_devs[i].sc_selinfo.si_note, 0);
+ mtx_lock(&sc->sc_irq_devs[i].sc_mtx);
+ if (!knlist_empty(&sc->sc_irq_devs[i].sc_selinfo.si_note))
+ printf("IRQ %d KQueue not empty!\n", i );
+ mtx_unlock(&sc->sc_irq_devs[i].sc_mtx);
+ knlist_destroy(&sc->sc_irq_devs[i].sc_selinfo.si_note);
+ mtx_destroy(&sc->sc_irq_devs[i].sc_mtx);
}
- knlist_clear(&sc->sc_selinfo.si_note, 0);
- knlist_destroy(&sc->sc_selinfo.si_note);
+
mtx_destroy(&sc->sc_mtx);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_mem_res),
@@ -241,19 +655,38 @@ ti_pruss_intr(void *arg)
struct ti_pruss_irq_arg *iap = arg;
struct ti_pruss_softc *sc = iap->sc;
/*
- * Interrupts pr1_host_intr[0:7] are mapped to
+ * Interrupts pr1_host_intr[0:7] are mapped to
* Host-2 to Host-9 of PRU-ICSS IRQ-controller.
*/
- const int pru_int = iap->irq + 2;
+ const int pru_int = iap->irq + TI_PRUSS_PRU_IRQS;
const int pru_int_mask = (1 << pru_int);
+ const int pru_channel = sc->sc_irq_devs[pru_int].channel;
+ const int pru_event = sc->sc_irq_devs[pru_channel].event;
- val = ti_pruss_reg_read(sc, PRUSS_AM33XX_INTC + PRUSS_INTC_HIER);
- DPRINTF("interrupt %p, %d", sc, pru_int);
+ val = ti_pruss_reg_read(sc, PRUSS_INTC_HIER);
if (!(val & pru_int_mask))
return;
- ti_pruss_reg_write(sc, PRUSS_AM33XX_INTC + PRUSS_INTC_HIDISR,
- pru_int);
- KNOTE_UNLOCKED(&sc->sc_selinfo.si_note, pru_int);
+
+ ti_pruss_reg_write(sc, PRUSS_INTC_HIDISR, pru_int);
+ ti_pruss_reg_write(sc, PRUSS_INTC_SICR, pru_event);
+ ti_pruss_reg_write(sc, PRUSS_INTC_HIEISR, pru_int);
+
+ struct ti_pruss_irqsc* irq = &sc->sc_irq_devs[pru_channel];
+ size_t wr = irq->tstamps.ctl.idx;
+
+ struct timespec ts;
+ nanouptime(&ts);
+ irq->tstamps.ts[wr] = ts.tv_sec * 1000000000 + ts.tv_nsec;
+
+ if (++wr == TI_TS_ARRAY)
+ wr = 0;
+ atomic_add_32(&irq->tstamps.ctl.cnt, 1);
+
+ irq->tstamps.ctl.idx = wr;
+
+ KNOTE_UNLOCKED(&irq->sc_selinfo.si_note, pru_int);
+ wakeup(irq);
+ selwakeup(&irq->sc_selinfo);
}
static int
@@ -271,7 +704,7 @@ ti_pruss_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
struct ti_pruss_softc *sc = device_get_softc(dev);
if (offset > rman_get_size(sc->sc_mem_res))
- return (-1);
+ return (ENOSPC);
*paddr = rman_get_start(sc->sc_mem_res) + offset;
*memattr = VM_MEMATTR_UNCACHEABLE;
@@ -280,31 +713,43 @@ ti_pruss_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
static struct filterops ti_pruss_kq_read = {
.f_isfd = 1,
- .f_detach = ti_pruss_kq_read_detach,
- .f_event = ti_pruss_kq_read_event,
+ .f_detach = ti_pruss_irq_kqread_detach,
+ .f_event = ti_pruss_irq_kqevent,
};
static void
-ti_pruss_kq_read_detach(struct knote *kn)
+ti_pruss_irq_kqread_detach(struct knote *kn)
{
- struct ti_pruss_softc *sc = kn->kn_hook;
+ struct ti_pruss_irqsc *sc = kn->kn_hook;
knlist_remove(&sc->sc_selinfo.si_note, kn, 0);
}
static int
-ti_pruss_kq_read_event(struct knote *kn, long hint)
+ti_pruss_irq_kqevent(struct knote *kn, long hint)
{
- kn->kn_data = hint;
+ struct ti_pruss_irqsc* irq_sc;
+ int notify;
+
+ irq_sc = kn->kn_hook;
+
+ if (hint > 0)
+ kn->kn_data = hint - 2;
- return (hint);
+ if (hint > 0 || irq_sc->last > 0)
+ notify = 1;
+ else
+ notify = 0;
+
+ irq_sc->last = hint;
+
+ return (notify);
}
static int
-ti_pruss_kqfilter(struct cdev *cdev, struct knote *kn)
+ti_pruss_irq_kqfilter(struct cdev *cdev, struct knote *kn)
{
- device_t dev = cdev->si_drv1;
- struct ti_pruss_softc *sc = device_get_softc(dev);
+ struct ti_pruss_irqsc *sc = cdev->si_drv1;
switch (kn->kn_filter) {
case EVFILT_READ:
diff --git a/sys/arm/ti/ti_pruss.h b/sys/arm/ti/ti_pruss.h
index 4eea12e..44552a5 100644
--- a/sys/arm/ti/ti_pruss.h
+++ b/sys/arm/ti/ti_pruss.h
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2013 Rui Paulo <rpaulo@FreeBSD.org>
+ * Copyright (c) 2017 Manuel Stuehn
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +34,22 @@
#define PRUSS_AM33XX_REV 0x4e82A900
#define PRUSS_AM33XX_INTC 0x20000
-#define PRUSS_INTC_HIER 0x1500
-#define PRUSS_INTC_HIDISR 0x0038
-#define PRUSS_INTC_HIPIR_BASE 0x0900
+#define PRUSS_INTC_GER (PRUSS_AM33XX_INTC + 0x0010)
+#define PRUSS_INTC_SISR (PRUSS_AM33XX_INTC + 0x0020)
+#define PRUSS_INTC_SICR (PRUSS_AM33XX_INTC + 0x0024)
+#define PRUSS_INTC_EISR (PRUSS_AM33XX_INTC + 0x0028)
+#define PRUSS_INTC_EICR (PRUSS_AM33XX_INTC + 0x002C)
+#define PRUSS_INTC_HIEISR (PRUSS_AM33XX_INTC + 0x0034)
+#define PRUSS_INTC_HIDISR (PRUSS_AM33XX_INTC + 0x0038)
+#define PRUSS_INTC_SECR0 (PRUSS_AM33XX_INTC + 0x0280)
+#define PRUSS_INTC_SECR1 (PRUSS_AM33XX_INTC + 0x0284)
+#define PRUSS_INTC_CMR_BASE (PRUSS_AM33XX_INTC + 0x0400)
+#define PRUSS_INTC_HMR_BASE (PRUSS_AM33XX_INTC + 0x0800)
+#define PRUSS_INTC_HIPIR_BASE (PRUSS_AM33XX_INTC + 0x0900)
+#define PRUSS_INTC_SIPR0 (PRUSS_AM33XX_INTC + 0x0D00)
+#define PRUSS_INTC_SIPR1 (PRUSS_AM33XX_INTC + 0x0D04)
+#define PRUSS_INTC_SITR0 (PRUSS_AM33XX_INTC + 0x0D80)
+#define PRUSS_INTC_SITR1 (PRUSS_AM33XX_INTC + 0x0D84)
+#define PRUSS_INTC_HIER (PRUSS_AM33XX_INTC + 0x1500)
#endif /* _TI_PRUSS_H_ */
diff --git a/sys/arm/xilinx/std.zynq7 b/sys/arm/xilinx/std.zynq7
index addf7bc..218db64 100644
--- a/sys/arm/xilinx/std.zynq7
+++ b/sys/arm/xilinx/std.zynq7
@@ -9,8 +9,5 @@ makeoptions CONF_CFLAGS="-march=armv7a"
files "../xilinx/files.zynq7"
-options KERNVIRTADDR=0xc0100000 # Used in ldscript.arm
-makeoptions KERNVIRTADDR=0xc0100000
-
options IPI_IRQ_START=0
options IPI_IRQ_END=15
diff --git a/sys/arm64/include/atomic.h b/sys/arm64/include/atomic.h
index 08bb103..a870f40 100644
--- a/sys/arm64/include/atomic.h
+++ b/sys/arm64/include/atomic.h
@@ -29,6 +29,8 @@
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
+#include <sys/atomic_common.h>
+
#define isb() __asm __volatile("isb" : : : "memory")
/*
diff --git a/sys/boot/arm/uboot/start.S b/sys/boot/arm/uboot/start.S
index 3f7764f..ede6a62 100644
--- a/sys/boot/arm/uboot/start.S
+++ b/sys/boot/arm/uboot/start.S
@@ -46,11 +46,8 @@ _start:
mcr p15, 0, ip, c1, c0, 0
#endif
- /*
- * Save r0 and r1 (argc and argv passed from u-boot), and lr (trashed
- * by the call to self_reloc below) until we're ready to call main().
- */
- push {r0, r1, lr}
+ /* Save the arguments and return register before calling self_reloc */
+ push {r0, r1, r9, lr}
/*
* Do self-relocation when the weak external symbol _DYNAMIC is non-NULL.
@@ -68,22 +65,31 @@ _start:
addne r1, r1, r0 /* r1 = dynamic section physaddr. */
blne _C_LABEL(self_reloc) /* Do reloc if _DYNAMIC is non-NULL. */
+ /* Restore saved arguments */
+ pop {r0, r1, r9, lr}
+
/* Hint where to look for the API signature */
ldr ip, =uboot_address
str sp, [ip]
- /* Save U-Boot's r8 and r9 */
+ /* Save U-Boot's r8 and r9 for syscall trampoline */
ldr ip, =saved_regs
- str r8, [ip, #0]
- str r9, [ip, #4]
+ str r8, [ip, #0] /* old gd pointer (use to hold lr) */
+ str r9, [ip, #4] /* new gd pointer */
/*
- * First restore argc, argv, and the u-boot return address, then
- * Start loader. This is basically a tail-recursion call; if main()
- * returns, it returns to u-boot (which reports the value returned r0).
+ * Start loader. Save return address first (r8 is available from
+ * trampoline save).
*/
- pop {r0, r1, lr}
- b main
+ mov r8, lr
+ bl main
+ mov lr, r8
+
+ /* Restore U-Boot environment */
+ ldr ip, =saved_regs
+ ldr r8, [ip, #0]
+ ldr r9, [ip, #4]
+ mov pc, lr
/*
* Data for self-relocation, in the text segment for pc-rel access.
diff --git a/sys/boot/fdt/dts/arm/bcm2835.dtsi b/sys/boot/fdt/dts/arm/bcm2835.dtsi
index a1c955d..fba4040 100644
--- a/sys/boot/fdt/dts/arm/bcm2835.dtsi
+++ b/sys/boot/fdt/dts/arm/bcm2835.dtsi
@@ -431,7 +431,7 @@
interrupts = <24 25 26 27 28 29 30 31 32 33 34 35 36>;
interrupt-parent = <&intc>;
- broadcom,channels = <0>; /* Set by VideoCore */
+ broadcom,channels = <0x7f35>;
};
vc_mbox: mbox {
diff --git a/sys/boot/fdt/dts/arm/bcm2836.dtsi b/sys/boot/fdt/dts/arm/bcm2836.dtsi
index 5cb80af..87355f1 100644
--- a/sys/boot/fdt/dts/arm/bcm2836.dtsi
+++ b/sys/boot/fdt/dts/arm/bcm2836.dtsi
@@ -424,7 +424,7 @@
interrupts = <24 25 26 27 28 29 30 31 32 33 34 35 36>;
interrupt-parent = <&intc>;
- broadcom,channels = <0>; /* Set by VideoCore */
+ broadcom,channels = <0x7f35>;
};
vc_mbox: mbox {
diff --git a/sys/boot/uboot/lib/libuboot.h b/sys/boot/uboot/lib/libuboot.h
index e4201d8..c6cf93c 100644
--- a/sys/boot/uboot/lib/libuboot.h
+++ b/sys/boot/uboot/lib/libuboot.h
@@ -45,9 +45,16 @@ struct uboot_devdesc
#define d_disk d_kind.disk
/*
- * Default network packet alignment in memory
+ * Default network packet alignment in memory. On arm arches packets must be
+ * aligned to cacheline boundaries.
*/
+#if defined(__aarch64__)
+#define PKTALIGN 128
+#elif defined(__arm__)
+#define PKTALIGN 64
+#else
#define PKTALIGN 32
+#endif
int uboot_getdev(void **vdev, const char *devspec, const char **path);
char *uboot_fmtdev(void *vdev);
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 31ef71e..a87834d 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -1386,7 +1386,7 @@ adasysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct ada_softc *softc;
- char tmpstr[80], tmpstr2[80];
+ char tmpstr[32], tmpstr2[16];
periph = (struct cam_periph *)context;
diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c
index aa37de2..a017d41 100644
--- a/sys/cam/ata/ata_pmp.c
+++ b/sys/cam/ata/ata_pmp.c
@@ -338,7 +338,7 @@ pmpsysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct pmp_softc *softc;
- char tmpstr[80], tmpstr2[80];
+ char tmpstr[32], tmpstr2[16];
periph = (struct cam_periph *)context;
if (cam_periph_acquire(periph) != CAM_REQ_CMP)
diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index 13ecf43..ec3c0c3 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -592,7 +592,7 @@ ndasysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct nda_softc *softc;
- char tmpstr[80], tmpstr2[80];
+ char tmpstr[32], tmpstr2[16];
periph = (struct cam_periph *)context;
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 42dd491..4bd628f 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -469,7 +469,7 @@ cdsysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct cd_softc *softc;
- char tmpstr[80], tmpstr2[80];
+ char tmpstr[32], tmpstr2[16];
periph = (struct cam_periph *)context;
if (cam_periph_acquire(periph) != CAM_REQ_CMP)
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index 58d5d3b..6e09709 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -1919,7 +1919,7 @@ dasysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct da_softc *softc;
- char tmpstr[80], tmpstr2[80];
+ char tmpstr[32], tmpstr2[16];
struct ccb_trans_settings cts;
periph = (struct cam_periph *)context;
diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c
index fd25e4f..5a21999 100644
--- a/sys/cam/scsi/scsi_sa.c
+++ b/sys/cam/scsi/scsi_sa.c
@@ -2294,7 +2294,7 @@ sasysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct sa_softc *softc;
- char tmpstr[80], tmpstr2[80];
+ char tmpstr[32], tmpstr2[16];
periph = (struct cam_periph *)context;
/*
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index 18d1995..21e430c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -13838,6 +13838,7 @@ static int
dtrace_dof_relocate(dof_hdr_t *dof, dof_sec_t *sec, uint64_t ubase)
{
uintptr_t daddr = (uintptr_t)dof;
+ uintptr_t ts_end;
dof_relohdr_t *dofr =
(dof_relohdr_t *)(uintptr_t)(daddr + sec->dofs_offset);
dof_sec_t *ss, *rs, *ts;
@@ -13853,6 +13854,7 @@ dtrace_dof_relocate(dof_hdr_t *dof, dof_sec_t *sec, uint64_t ubase)
ss = dtrace_dof_sect(dof, DOF_SECT_STRTAB, dofr->dofr_strtab);
rs = dtrace_dof_sect(dof, DOF_SECT_RELTAB, dofr->dofr_relsec);
ts = dtrace_dof_sect(dof, DOF_SECT_NONE, dofr->dofr_tgtsec);
+ ts_end = (uintptr_t)ts + sizeof (dof_sec_t);
if (ss == NULL || rs == NULL || ts == NULL)
return (-1); /* dtrace_dof_error() has been called already */
@@ -13879,6 +13881,11 @@ dtrace_dof_relocate(dof_hdr_t *dof, dof_sec_t *sec, uint64_t ubase)
return (-1);
}
+ if (taddr >= (uintptr_t)ts && taddr < ts_end) {
+ dtrace_dof_error(dof, "bad relocation offset");
+ return (-1);
+ }
+
if (!IS_P2ALIGNED(taddr, sizeof (uint64_t))) {
dtrace_dof_error(dof, "misaligned setx relo");
return (-1);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
index a986f0d..063bd8b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
@@ -6619,6 +6619,11 @@ arc_init(void)
void
arc_fini(void)
{
+#ifdef _KERNEL
+ if (arc_event_lowmem != NULL)
+ EVENTHANDLER_DEREGISTER(vm_lowmem, arc_event_lowmem);
+#endif
+
mutex_enter(&arc_reclaim_lock);
arc_reclaim_thread_exit = B_TRUE;
/*
@@ -6664,11 +6669,6 @@ arc_fini(void)
buf_fini();
ASSERT0(arc_loaned_bytes);
-
-#ifdef _KERNEL
- if (arc_event_lowmem != NULL)
- EVENTHANDLER_DEREGISTER(vm_lowmem, arc_event_lowmem);
-#endif
}
/*
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
index 849511d..18ebe29 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -851,35 +851,10 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
if (cp == NULL) {
ZFS_LOG(1, "Vdev %s not found.", vd->vdev_path);
error = ENOENT;
- } else if (cp->provider->sectorsize > VDEV_PAD_SIZE ||
- !ISP2(cp->provider->sectorsize)) {
- ZFS_LOG(1, "Provider %s has unsupported sectorsize.",
- cp->provider->name);
-
- vdev_geom_close_locked(vd);
- error = EINVAL;
- cp = NULL;
- } else if (cp->acw == 0 && (spa_mode(vd->vdev_spa) & FWRITE) != 0) {
- int i;
-
- for (i = 0; i < 5; i++) {
- error = g_access(cp, 0, 1, 0);
- if (error == 0)
- break;
- g_topology_unlock();
- tsleep(vd, 0, "vdev", hz / 2);
- g_topology_lock();
- }
- if (error != 0) {
- printf("ZFS WARNING: Unable to open %s for writing (error=%d).\n",
- cp->provider->name, error);
- vdev_geom_close_locked(vd);
- cp = NULL;
- }
- }
- if (cp != NULL) {
+ } else {
struct consumer_priv_t *priv;
struct consumer_vdev_elem *elem;
+ int spamode;
priv = (struct consumer_priv_t*)&cp->private;
if (cp->private == NULL)
@@ -887,6 +862,34 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
elem = g_malloc(sizeof(*elem), M_WAITOK|M_ZERO);
elem->vd = vd;
SLIST_INSERT_HEAD(priv, elem, elems);
+
+ spamode = spa_mode(vd->vdev_spa);
+ if (cp->provider->sectorsize > VDEV_PAD_SIZE ||
+ !ISP2(cp->provider->sectorsize)) {
+ ZFS_LOG(1, "Provider %s has unsupported sectorsize.",
+ cp->provider->name);
+
+ vdev_geom_close_locked(vd);
+ error = EINVAL;
+ cp = NULL;
+ } else if (cp->acw == 0 && (spamode & FWRITE) != 0) {
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ error = g_access(cp, 0, 1, 0);
+ if (error == 0)
+ break;
+ g_topology_unlock();
+ tsleep(vd, 0, "vdev", hz / 2);
+ g_topology_lock();
+ }
+ if (error != 0) {
+ printf("ZFS WARNING: Unable to open %s for writing (error=%d).\n",
+ cp->provider->name, error);
+ vdev_geom_close_locked(vd);
+ cp = NULL;
+ }
+ }
}
/* Fetch initial physical path information for this device. */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h
index c104e79..d2fbf5f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fasttrap_impl.h
@@ -221,9 +221,9 @@ extern int fasttrap_tracepoint_init(proc_t *, fasttrap_tracepoint_t *,
extern int fasttrap_tracepoint_install(proc_t *, fasttrap_tracepoint_t *);
extern int fasttrap_tracepoint_remove(proc_t *, fasttrap_tracepoint_t *);
-struct reg;
-extern int fasttrap_pid_probe(struct reg *);
-extern int fasttrap_return_probe(struct reg *);
+struct trapframe;
+extern int fasttrap_pid_probe(struct trapframe *);
+extern int fasttrap_return_probe(struct trapframe *);
extern uint64_t fasttrap_pid_getarg(void *, dtrace_id_t, void *, int, int);
extern uint64_t fasttrap_usdt_getarg(void *, dtrace_id_t, void *, int, int);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h b/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h
index aa84f36..ee6e552 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/sysmacros.h
@@ -388,7 +388,7 @@ highbit(ulong_t i)
#if defined(__FreeBSD__) && defined(_KERNEL) && defined(HAVE_INLINE_FLSL)
return (flsl(i));
#else
- register int h = 1;
+ int h = 1;
if (i == 0)
return (0);
diff --git a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
index 0e134fe..10781c5 100644
--- a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
+++ b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
@@ -967,14 +967,12 @@ fasttrap_do_seg(fasttrap_tracepoint_t *tp, struct reg *rp, uintptr_t *addr)
}
int
-fasttrap_pid_probe(struct reg *rp)
+fasttrap_pid_probe(struct trapframe *tf)
{
- proc_t *p = curproc;
-#ifndef illumos
+ struct reg reg, *rp;
+ proc_t *p = curproc, *pp;
struct rm_priotracker tracker;
- proc_t *pp;
-#endif
- uintptr_t pc = rp->r_rip - 1;
+ uintptr_t pc;
uintptr_t new_pc = 0;
fasttrap_bucket_t *bucket;
#ifdef illumos
@@ -985,6 +983,11 @@ fasttrap_pid_probe(struct reg *rp)
dtrace_icookie_t cookie;
uint_t is_enabled = 0;
+ fill_frame_regs(tf, &reg);
+ rp = &reg;
+
+ pc = rp->r_rip - 1;
+
/*
* It's possible that a user (in a veritable orgy of bad planning)
* could redirect this thread's flow of control before it reached the
@@ -1796,12 +1799,16 @@ done:
}
int
-fasttrap_return_probe(struct reg *rp)
+fasttrap_return_probe(struct trapframe *tf)
{
+ struct reg reg, *rp;
proc_t *p = curproc;
uintptr_t pc = curthread->t_dtrace_pc;
uintptr_t npc = curthread->t_dtrace_npc;
+ fill_frame_regs(tf, &reg);
+ rp = &reg;
+
curthread->t_dtrace_pc = 0;
curthread->t_dtrace_npc = 0;
curthread->t_dtrace_scrpc = 0;
@@ -1821,9 +1828,7 @@ fasttrap_return_probe(struct reg *rp)
/*
* We set rp->r_rip to the address of the traced instruction so
* that it appears to dtrace_probe() that we're on the original
- * instruction, and so that the user can't easily detect our
- * complex web of lies. dtrace_return_probe() (our caller)
- * will correctly set %pc after we return.
+ * instruction.
*/
rp->r_rip = pc;
diff --git a/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c b/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c
index b0fc581..69ba0f3 100644
--- a/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c
+++ b/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c
@@ -328,11 +328,12 @@ fasttrap_branch_taken(int bo, int bi, struct reg *regs)
int
-fasttrap_pid_probe(struct reg *rp)
+fasttrap_pid_probe(struct trapframe *frame)
{
+ struct reg reg, *rp;
struct rm_priotracker tracker;
proc_t *p = curproc;
- uintptr_t pc = rp->pc;
+ uintptr_t pc;
uintptr_t new_pc = 0;
fasttrap_bucket_t *bucket;
fasttrap_tracepoint_t *tp, tp_local;
@@ -340,6 +341,10 @@ fasttrap_pid_probe(struct reg *rp)
dtrace_icookie_t cookie;
uint_t is_enabled = 0;
+ fill_regs(curthread, &reg);
+ rp = &reg;
+ pc = rp->pc;
+
/*
* It's possible that a user (in a veritable orgy of bad planning)
* could redirect this thread's flow of control before it reached the
@@ -515,8 +520,9 @@ done:
}
int
-fasttrap_return_probe(struct reg *rp)
+fasttrap_return_probe(struct trapframe *tf)
{
+ struct reg reg, *rp;
proc_t *p = curproc;
uintptr_t pc = curthread->t_dtrace_pc;
uintptr_t npc = curthread->t_dtrace_npc;
@@ -526,12 +532,13 @@ fasttrap_return_probe(struct reg *rp)
curthread->t_dtrace_scrpc = 0;
curthread->t_dtrace_astpc = 0;
+ fill_regs(curthread, &reg);
+ rp = &reg;
+
/*
* We set rp->pc to the address of the traced instruction so
* that it appears to dtrace_probe() that we're on the original
- * instruction, and so that the user can't easily detect our
- * complex web of lies. dtrace_return_probe() (our caller)
- * will correctly set %pc after we return.
+ * instruction.
*/
rp->pc = pc;
@@ -539,4 +546,3 @@ fasttrap_return_probe(struct reg *rp)
return (0);
}
-
diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
index 717f455..fd00cf3 100644
--- a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
@@ -353,11 +353,11 @@ SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init,
* Returns nanoseconds since boot.
*/
uint64_t
-dtrace_gethrtime()
+dtrace_gethrtime(void)
{
uint64_t tsc;
- uint32_t lo;
- uint32_t hi;
+ uint32_t lo, hi;
+ register_t rflags;
/*
* We split TSC value into lower and higher 32-bit halves and separately
@@ -365,7 +365,10 @@ dtrace_gethrtime()
* (see nsec_scale calculations) taking into account 32-bit shift of
* the higher half and finally add.
*/
+ rflags = intr_disable();
tsc = rdtsc() - tsc_skew[curcpu];
+ intr_restore(rflags);
+
lo = tsc;
hi = tsc >> 32;
return (((lo * nsec_scale) >> SCALE_SHIFT) +
diff --git a/sys/cddl/dev/dtrace/i386/dtrace_subr.c b/sys/cddl/dev/dtrace/i386/dtrace_subr.c
index 3801c1b..bc6ee01 100644
--- a/sys/cddl/dev/dtrace/i386/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/i386/dtrace_subr.c
@@ -355,11 +355,11 @@ SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init,
* Returns nanoseconds since boot.
*/
uint64_t
-dtrace_gethrtime()
+dtrace_gethrtime(void)
{
uint64_t tsc;
- uint32_t lo;
- uint32_t hi;
+ uint32_t lo, hi;
+ register_t eflags;
/*
* We split TSC value into lower and higher 32-bit halves and separately
@@ -367,7 +367,10 @@ dtrace_gethrtime()
* (see nsec_scale calculations) taking into account 32-bit shift of
* the higher half and finally add.
*/
+ eflags = intr_disable();
tsc = rdtsc() - tsc_skew[curcpu];
+ intr_restore(eflags);
+
lo = tsc;
hi = tsc >> 32;
return (((lo * nsec_scale) >> SCALE_SHIFT) +
diff --git a/sys/cddl/dev/sdt/sdt.c b/sys/cddl/dev/sdt/sdt.c
index 26a41f0..e9d0118 100644
--- a/sys/cddl/dev/sdt/sdt.c
+++ b/sys/cddl/dev/sdt/sdt.c
@@ -76,6 +76,8 @@ static void sdt_kld_unload_try(void *, struct linker_file *, int *);
static MALLOC_DEFINE(M_SDT, "SDT", "DTrace SDT providers");
+static int sdt_probes_enabled_count;
+
static dtrace_pattr_t sdt_attr = {
{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
@@ -208,6 +210,9 @@ sdt_enable(void *arg __unused, dtrace_id_t id, void *parg)
probe->sdtp_lf->nenabled++;
if (strcmp(probe->prov->name, "lockstat") == 0)
lockstat_enabled++;
+ sdt_probes_enabled_count++;
+ if (sdt_probes_enabled_count == 1)
+ sdt_probes_enabled = true;
}
static void
@@ -217,6 +222,9 @@ sdt_disable(void *arg __unused, dtrace_id_t id, void *parg)
KASSERT(probe->sdtp_lf->nenabled > 0, ("no probes enabled"));
+ sdt_probes_enabled_count--;
+ if (sdt_probes_enabled_count == 0)
+ sdt_probes_enabled = false;
if (strcmp(probe->prov->name, "lockstat") == 0)
lockstat_enabled--;
probe->id = 0;
diff --git a/sys/conf/Makefile.arm b/sys/conf/Makefile.arm
index 39e2910..0fd6898 100644
--- a/sys/conf/Makefile.arm
+++ b/sys/conf/Makefile.arm
@@ -53,6 +53,11 @@ CFLAGS += -mllvm -arm-enable-ehabi
.endif
.endif
+# "makeoptions KERNVIRTADDR=" is now optional, supply the default value.
+.if empty(KERNVIRTADDR)
+KERNVIRTADDR= 0xc0000000
+.endif
+
# hack because genassym.c includes sys/bus.h which includes these.
genassym.o: bus_if.h device_if.h
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index e60eb25..11cfb47 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1102,6 +1102,9 @@ options MD_ROOT_SIZE=10
# images of type mfs_root or md_root.
options MD_ROOT
+# Write-protect the md root device so that it may not be mounted writeable.
+options MD_ROOT_READONLY
+
# Disk quotas are supported when this option is enabled.
options QUOTA #enable disk quotas
diff --git a/sys/conf/dtb.mk b/sys/conf/dtb.mk
index f32b020..81c98ef 100644
--- a/sys/conf/dtb.mk
+++ b/sys/conf/dtb.mk
@@ -76,3 +76,4 @@ _dtbinstall:
.include <bsd.dep.mk>
.include <bsd.obj.mk>
+.include <bsd.links.mk>
diff --git a/sys/conf/files b/sys/conf/files
index d1f0ec7..ed45a69 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -515,6 +515,7 @@ contrib/dev/acpica/components/utilities/utresdecode.c optional acpi acpi_debug
contrib/dev/acpica/components/utilities/utresrc.c optional acpi
contrib/dev/acpica/components/utilities/utstate.c optional acpi
contrib/dev/acpica/components/utilities/utstring.c optional acpi
+contrib/dev/acpica/components/utilities/utstrsuppt.c optional acpi
contrib/dev/acpica/components/utilities/utstrtoul64.c optional acpi
contrib/dev/acpica/components/utilities/utuuid.c optional acpi acpi_debug
contrib/dev/acpica/components/utilities/utxface.c optional acpi
diff --git a/sys/conf/ldscript.amd64 b/sys/conf/ldscript.amd64
index e64a957..838a3c4 100644
--- a/sys/conf/ldscript.amd64
+++ b/sys/conf/ldscript.amd64
@@ -146,6 +146,10 @@ SECTIONS
. = DATA_SEGMENT_RELRO_END (24, .);
.got.plt : { *(.got.plt) }
. = ALIGN(64);
+ .data.read_frequently :
+ {
+ *(.data.read_frequently)
+ }
.data.read_mostly :
{
*(.data.read_mostly)
diff --git a/sys/conf/options b/sys/conf/options
index b0d1b2e..12c7163 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -165,6 +165,7 @@ MAC_STUB opt_dontuse.h
MAC_TEST opt_dontuse.h
MD_ROOT opt_md.h
MD_ROOT_FSTYPE opt_md.h
+MD_ROOT_READONLY opt_md.h
MD_ROOT_SIZE opt_md.h
MFI_DEBUG opt_mfi.h
MFI_DECODE_LOG opt_mfi.h
diff --git a/sys/conf/options.arm b/sys/conf/options.arm
index 4e6aa74..23c1acc 100644
--- a/sys/conf/options.arm
+++ b/sys/conf/options.arm
@@ -35,6 +35,7 @@ KERNVIRTADDR opt_global.h
LINUX_BOOT_ABI opt_global.h
LOADERRAMADDR opt_global.h
MULTIDELAY opt_global.h
+LOCORE_MAP_MB opt_locore.h
PHYSADDR opt_global.h
PLATFORM opt_global.h
PLATFORM_SMP opt_global.h
diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt
index d0fe928..2a72a51 100644
--- a/sys/contrib/dev/acpica/changes.txt
+++ b/sys/contrib/dev/acpica/changes.txt
@@ -1,4 +1,246 @@
----------------------------------------
+14 December 2017. Summary of changes for version 20171214:
+
+
+1) ACPICA kernel-resident subsystem:
+
+Fixed a regression in the external (public) AcpiEvaluateObjectTyped
+interface where the optional "pathname" argument had inadvertently become
+a required argument returning an error if omitted (NULL pointer
+argument).
+
+Fixed two possible memory leaks related to the recently developed "late
+resolution" of reference objects within ASL Package Object definitions.
+
+Added two recently defined _OSI strings: "Windows 2016" and "Windows
+2017". Mario Limonciello.
+
+Implemented and deployed a safer version of the C library function
+strncpy: AcpiUtSafeStrncpy. The intent is to at least prevent the
+creation of unterminated strings as a possible result of a standard
+strncpy.
+
+Cleaned up and restructured the global variable file (acglobal.h). There
+are many changes, but no functional changes.
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL Table Compiler: Fixed a problem with the DBG2 ACPI table where the
+optional OemData field at the end of the table was incorrectly required
+for proper compilation. It is now correctly an optional field.
+
+ASLTS: The entire suite was converted from standard ASL to the ASL+
+language, using the ASL-to-ASL+ converter which is integrated into the
+iASL compiler. A binary compare of all output files has verified the
+correctness of the conversion.
+
+iASL: Fixed the source code build for platforms where "char" is unsigned.
+This affected the iASL lexer only. Jung-uk Kim.
+
+----------------------------------------
+10 November 2017. Summary of changes for version 20171110:
+
+
+1) ACPICA kernel-resident subsystem:
+
+This release implements full support for ACPI 6.2A:
+ NFIT - Added a new subtable, "Platform Capabilities Structure"
+No other changes to ACPICA were required, since ACPI 6.2A is primarily an
+errata release of the specification.
+
+Other ACPI table changes:
+ IORT: Added the SMMUv3 Device ID mapping index. Hanjun Guo
+ PPTT: Added cache attribute flag definitions to actbl1.h. Jeremy
+Linton
+
+Utilities: Modified the string/integer conversion functions to use
+internal 64-bit divide support instead of a native divide. On 32-bit
+platforms, a 64-bit divide typically requires a library function which
+may not be present in the build (kernel or otherwise).
+
+Implemented a targeted error message for timeouts returned from the
+Embedded Controller device driver. This is seen frequently enough to
+special-case an AE_TIME returned from an EC operation region access:
+ "Timeout from EC hardware or EC device driver"
+
+Changed the "ACPI Exception" message prefix to "ACPI Error" so that all
+runtime error messages have the identical prefix.
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+AcpiXtract: Fixed a problem with table header detection within the
+acpidump file. Processing a table could be ended early if a 0x40 (@)
+appears in the original binary table, resulting in the @ symbol appearing
+in the decoded ASCII field at the end of the acpidump text line. The
+symbol caused acpixtract to incorrectly think it had reached the end of
+the current table and the beginning of a new table.
+
+AcpiXtract: Added an option (-f) to ignore some errors during table
+extraction. This initial implementation ignores non-ASCII and non-
+printable characters found in the acpidump text file.
+
+TestSuite(ASLTS)/AcpiExec: Fixed and restored the memory usage statistics
+for ASLTS. This feature is used to track memory allocations from
+different memory caches within the ACPICA code. At the end of an ASLTS
+run, these memory statistics are recorded and stored in a log file.
+
+Debugger (user-space version): Implemented a simple "Background" command.
+Creates a new thread to execute a control method in the background, while
+control returns to the debugger prompt to allow additional commands.
+ Syntax: Background <Namepath> [Arguments]
+
+----------------------------------------
+29 September 2017. Summary of changes for version 20170929:
+
+
+1) ACPICA kernel-resident subsystem:
+
+Redesigned and implemented an improved ASL While() loop timeout
+mechanism. This mechanism is used to prevent infinite loops in the kernel
+AML interpreter caused by either non-responsive hardware or incorrect AML
+code. The new implementation uses AcpiOsGetTimer instead of a simple
+maximum loop count, and is thus more accurate and constant across
+different machines. The default timeout is currently 30 seconds, but this
+may be adjusted later.
+
+Renamed the ACPI_AML_INFINITE_LOOP exception to AE_AML_LOOP_TIMEOUT to
+better reflect the new implementation of the loop timeout mechanism.
+
+Updated the AcpiGetTimerDuration interface to cleanup the 64-bit support
+and to fix an off-by-one error. Jung-uk Kim.
+
+Fixed an EFI build problem by updating the makefiles to for a new file
+that was added, utstrsuppt.c
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+Implemented full support for the PDTT, SDEV, and TPM2 ACPI tables. This
+includes support in the table disassembler, compiler, and template
+generator.
+
+iASL: Added an exception for an illegal type of recursive method
+invocation. If a method creates named objects, the first recursive call
+will fail at runtime. This change adds an error detection at compile time
+to catch the problem up front. Note: Marking such a method as
+"serialized" will not help with this problem, because the same thread can
+acquire the method mutex more than once. Example compiler and runtime
+output:
+
+ Method (MTH1)
+ {
+ Name (INT1, 1)
+ MTH1 ()
+ }
+
+ dsdt.asl 22: MTH1 ()
+ Error 6152 - ^ Illegal recursive call to method
+ that creates named objects (MTH1)
+
+Previous runtime exception:
+ ACPI Error: [INT1] Namespace lookup failure,
+ AE_ALREADY_EXISTS (20170831/dswload2-465)
+
+iASL: Updated support for External() opcodes to improve namespace
+management and error detection. These changes are related to issues seen
+with multiple-segment namespace pathnames within External declarations,
+such as below:
+
+ External(\_SB.PCI0.GFX0, DeviceObj)
+ External(\_SB.PCI0.GFX0.ALSI)
+
+iASL: Implemented support for multi-line error/warning messages. This
+enables more detailed and helpful error messages as below, from the
+initial deployment for the duplicate names error:
+
+ DSDT.iiii 1692: Device(PEG2) {
+ Error 6074 - ^ Name already exists in scope
+(PEG2)
+
+ Original name creation/declaration below:
+ DSDT.iiii 93: External(\_SB.PCI0.PEG2, DeviceObj)
+
+AcpiXtract: Added additional flexibility to support differing input hex
+dump formats. Specifically, hex dumps that contain partial disassembly
+and/or comments within the ACPI table data definition. There exist some
+dump utilities seen in the field that create this type of hex dump (such
+as Simics). For example:
+
+ DSDT @ 0xdfffd0c0 (10999 bytes)
+ Signature DSDT
+ Length 10999
+ Revision 1
+ Checksum 0xf3 (Ok)
+ OEM_ID BXPC
+ OEM_table_id BXDSDT
+ OEM_revision 1
+ Creator_id 1280593481
+ Creator_revision 537399345
+ 0000: 44 53 44 54 f7 2a 00 00 01 f3 42 58 50 43 00 00
+ ...
+ 2af0: 5f 4c 30 46 00 a4 01
+
+Test suite: Miscellaneous changes/fixes:
+ More cleanup and simplification of makefiles
+ Continue compilation of test cases after a compile failure
+ Do not perform binary compare unless both files actually exist
+
+iASL: Performed some code/module restructuring. Moved all memory
+allocation functions to new modules. Two new files, aslallocate.c and
+aslcache.c
+
+----------------------------------------
+31 August 2017. Summary of changes for version 20170831:
+
+
+1) ACPICA kernel-resident subsystem:
+
+Implemented internal support for full 64-bit addresses that appear in all
+Generic Address Structure (GAS) structures. Previously, only the lower 32
+bits were used. Affects the use of GAS structures in the FADT and other
+tables, as well as the GAS structures passed to the AcpiRead and
+AcpiWrite public external interfaces that are used by drivers. Lv Zheng.
+
+Added header support for the PDTT ACPI table (Processor Debug Trigger
+Table). Full support in the iASL Data Table Compiler and disassembler is
+forthcoming.
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL/Disassembler: Fixed a problem with the PPTT ACPI table (Processor
+Properties Topology Table) where a flag bit was specified in the wrong
+bit position ("Line Size Valid", bit 6).
+
+iASL: Implemented support for Octal integer constants as defined by the
+ASL language grammar, per the ACPI specification. Any integer constant
+that starts with a zero is an octal constant. For example,
+ Store (037777, Local0) /* Octal constant */
+ Store (0x3FFF, Local0) /* Hex equivalent */
+ Store (16383, Local0) /* Decimal equivalent */
+
+iASL: Improved overflow detection for 64-bit string conversions during
+compilation of integer constants. "Overflow" in this case means a string
+that represents an integer that is too large to fit into a 64-bit value.
+Any 64-bit constants within a 32-bit DSDT or SSDT are still truncated to
+the low-order 32 bits with a warning, as previously implemented. Several
+new exceptions are defined that indicate a 64-bit overflow, as well as
+the base (radix) that was used during the attempted conversion. Examples:
+ Local0 = 0xAAAABBBBCCCCDDDDEEEEFFFF // AE_HEX_OVERFLOW
+ Local0 = 01111222233334444555566667777 // AE_OCTAL_OVERFLOW
+ Local0 = 11112222333344445555666677778888 // AE_DECIMAL_OVERFLOW
+
+iASL: Added a warning for the case where a ResourceTemplate is declared
+with no ResourceDescriptor entries (coded as "ResourceTemplate(){}"). In
+this case, the resulting template is created with a single END_TAG
+descriptor, which is essentially useless.
+
+iASL: Expanded the -vw option (ignore specific warnings/remarks) to
+include compilation error codes as well.
+
+----------------------------------------
28 July 2017. Summary of changes for version 20170728:
diff --git a/sys/contrib/dev/acpica/common/adfile.c b/sys/contrib/dev/acpica/common/adfile.c
index 115a185..a3abdce 100644
--- a/sys/contrib/dev/acpica/common/adfile.c
+++ b/sys/contrib/dev/acpica/common/adfile.c
@@ -314,7 +314,7 @@ FlGenerateFilename (
* Copy the original filename to a new buffer. Leave room for the worst
* case where we append the suffix, an added dot and the null terminator.
*/
- NewFilename = UtStringCacheCalloc ((ACPI_SIZE)
+ NewFilename = UtLocalCacheCalloc ((ACPI_SIZE)
strlen (InputFilename) + strlen (Suffix) + 2);
strcpy (NewFilename, InputFilename);
@@ -358,7 +358,7 @@ FlStrdup (
char *NewString;
- NewString = UtStringCacheCalloc ((ACPI_SIZE) strlen (String) + 1);
+ NewString = UtLocalCacheCalloc ((ACPI_SIZE) strlen (String) + 1);
strcpy (NewString, String);
return (NewString);
}
diff --git a/sys/contrib/dev/acpica/common/adisasm.c b/sys/contrib/dev/acpica/common/adisasm.c
index 4ee6b99..3ea3d02 100644
--- a/sys/contrib/dev/acpica/common/adisasm.c
+++ b/sys/contrib/dev/acpica/common/adisasm.c
@@ -457,9 +457,9 @@ AdDisassembleOneTable (
* (.xxx) file produced from the converter in case if
* it fails to get deleted.
*/
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
- strncpy (Table->Signature, AcpiGbl_TableSig, 4);
+ strncpy (Table->Signature, AcpiGbl_TableSig, ACPI_NAME_SIZE);
}
#endif
diff --git a/sys/contrib/dev/acpica/common/ahtable.c b/sys/contrib/dev/acpica/common/ahtable.c
index c288edf..247ff29 100644
--- a/sys/contrib/dev/acpica/common/ahtable.c
+++ b/sys/contrib/dev/acpica/common/ahtable.c
@@ -232,6 +232,7 @@ const AH_TABLE Gbl_AcpiSupportedTables[] =
{ACPI_SIG_MTMR, "MID Timer Table"},
{ACPI_SIG_NFIT, "NVDIMM Firmware Interface Table"},
{ACPI_SIG_PCCT, "Platform Communications Channel Table"},
+ {ACPI_SIG_PDTT, "Platform Debug Trigger Table"},
{ACPI_SIG_PMTT, "Platform Memory Topology Table"},
{ACPI_SIG_PPTT, "Processor Properties Topology Table"},
{ACPI_SIG_RASF, "RAS Features Table"},
@@ -240,6 +241,7 @@ const AH_TABLE Gbl_AcpiSupportedTables[] =
{ACPI_SIG_S3PT, "S3 Performance Table"},
{ACPI_SIG_SBST, "Smart Battery Specification Table"},
{ACPI_SIG_SDEI, "Software Delegated Exception Interface Table"},
+ {ACPI_SIG_SDEV, "Secure Devices table"},
{ACPI_SIG_SLIC, "Software Licensing Description Table"},
{ACPI_SIG_SLIT, "System Locality Information Table"},
{ACPI_SIG_SPCR, "Serial Port Console Redirection table"},
diff --git a/sys/contrib/dev/acpica/common/dmswitch.c b/sys/contrib/dev/acpica/common/dmswitch.c
index a0bf68f..0cf913a 100644
--- a/sys/contrib/dev/acpica/common/dmswitch.c
+++ b/sys/contrib/dev/acpica/common/dmswitch.c
@@ -543,6 +543,10 @@ AcpiDmIsSwitchBlock (
* statement, so check for it.
*/
CurrentOp = StoreOp->Common.Next->Common.Next;
+ if (!CurrentOp)
+ {
+ return (FALSE);
+ }
if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
{
CurrentOp = CurrentOp->Common.Next;
diff --git a/sys/contrib/dev/acpica/common/dmtable.c b/sys/contrib/dev/acpica/common/dmtable.c
index 4356d42..cf5d601 100644
--- a/sys/contrib/dev/acpica/common/dmtable.c
+++ b/sys/contrib/dev/acpica/common/dmtable.c
@@ -154,7 +154,6 @@
#include <contrib/dev/acpica/include/acdisasm.h>
#include <contrib/dev/acpica/include/actables.h>
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
/* This module used for application-level code only */
@@ -290,9 +289,9 @@ static const char *AcpiDmHestSubnames[] =
"IA-32 Machine Check Exception",
"IA-32 Corrected Machine Check",
"IA-32 Non-Maskable Interrupt",
- "Unknown SubTable Type", /* 3 - Reserved */
- "Unknown SubTable Type", /* 4 - Reserved */
- "Unknown SubTable Type", /* 5 - Reserved */
+ "Unknown Subtable Type", /* 3 - Reserved */
+ "Unknown Subtable Type", /* 4 - Reserved */
+ "Unknown Subtable Type", /* 5 - Reserved */
"PCI Express Root Port AER",
"PCI Express AER (AER Endpoint)",
"PCI Express/PCI-X Bridge AER",
@@ -357,6 +356,7 @@ static const char *AcpiDmNfitSubnames[] =
"NVDIMM Control Region", /* ACPI_NFIT_TYPE_CONTROL_REGION */
"NVDIMM Block Data Window Region", /* ACPI_NFIT_TYPE_DATA_REGION */
"Flush Hint Address", /* ACPI_NFIT_TYPE_FLUSH_ADDRESS */
+ "Platform Capabilities", /* ACPI_NFIT_TYPE_CAPABILITIES */
"Unknown Subtable Type" /* Reserved */
};
@@ -374,7 +374,7 @@ static const char *AcpiDmPmttSubnames[] =
{
"Socket", /* ACPI_PMTT_TYPE_SOCKET */
"Memory Controller", /* ACPI_PMTT_TYPE_CONTROLLER */
- "Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */
+ "Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */
"Unknown Subtable Type" /* Reserved */
};
@@ -382,7 +382,14 @@ static const char *AcpiDmPpttSubnames[] =
{
"Processor Hierarchy Node", /* ACPI_PPTT_TYPE_PROCESSOR */
"Cache Type", /* ACPI_PPTT_TYPE_CACHE */
- "ID", /* ACPI_PMTT_TYPE_ID */
+ "ID", /* ACPI_PPTT_TYPE_ID */
+ "Unknown Subtable Type" /* Reserved */
+};
+
+static const char *AcpiDmSdevSubnames[] =
+{
+ "Namespace Device", /* ACPI_SDEV_TYPE_NAMESPACE_DEVICE */
+ "PCIe Endpoint Device", /* ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE */
"Unknown Subtable Type" /* Reserved */
};
@@ -396,6 +403,23 @@ static const char *AcpiDmSratSubnames[] =
"Unknown Subtable Type" /* Reserved */
};
+static const char *AcpiDmTpm2Subnames[] =
+{
+ "Illegal Start Method value",
+ "Reserved",
+ "ACPI Start Method",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Memory Mapped I/O",
+ "Command Response Buffer",
+ "Command Response Buffer with ACPI Start Method",
+ "Reserved",
+ "Reserved",
+ "Command Response Buffer with ARM SMC",
+ "Unknown Subtable Type" /* Reserved */
+};
+
static const char *AcpiDmIvrsSubnames[] =
{
"Hardware Definition Block",
@@ -487,6 +511,7 @@ const ACPI_DMTABLE_DATA AcpiDmTableData[] =
{ACPI_SIG_MTMR, NULL, AcpiDmDumpMtmr, DtCompileMtmr, TemplateMtmr},
{ACPI_SIG_NFIT, AcpiDmTableInfoNfit, AcpiDmDumpNfit, DtCompileNfit, TemplateNfit},
{ACPI_SIG_PCCT, AcpiDmTableInfoPcct, AcpiDmDumpPcct, DtCompilePcct, TemplatePcct},
+ {ACPI_SIG_PDTT, AcpiDmTableInfoPdtt, AcpiDmDumpPdtt, DtCompilePdtt, TemplatePdtt},
{ACPI_SIG_PMTT, NULL, AcpiDmDumpPmtt, DtCompilePmtt, TemplatePmtt},
{ACPI_SIG_PPTT, NULL, AcpiDmDumpPptt, DtCompilePptt, TemplatePptt},
{ACPI_SIG_RASF, AcpiDmTableInfoRasf, NULL, NULL, TemplateRasf},
@@ -494,6 +519,7 @@ const ACPI_DMTABLE_DATA AcpiDmTableData[] =
{ACPI_SIG_S3PT, NULL, NULL, NULL, TemplateS3pt},
{ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst},
{ACPI_SIG_SDEI, AcpiDmTableInfoSdei, NULL, NULL, TemplateSdei},
+ {ACPI_SIG_SDEV, AcpiDmTableInfoSdev, AcpiDmDumpSdev, DtCompileSdev, TemplateSdev},
{ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic},
{ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit},
{ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, NULL, TemplateSpcr},
@@ -501,7 +527,7 @@ const ACPI_DMTABLE_DATA AcpiDmTableData[] =
{ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, DtCompileSrat, TemplateSrat},
{ACPI_SIG_STAO, NULL, AcpiDmDumpStao, DtCompileStao, TemplateStao},
{ACPI_SIG_TCPA, NULL, AcpiDmDumpTcpa, DtCompileTcpa, TemplateTcpa},
- {ACPI_SIG_TPM2, AcpiDmTableInfoTpm2, NULL, NULL, TemplateTpm2},
+ {ACPI_SIG_TPM2, AcpiDmTableInfoTpm2, AcpiDmDumpTpm2, DtCompileTpm2, TemplateTpm2},
{ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, DtCompileUefi, TemplateUefi},
{ACPI_SIG_VRTC, AcpiDmTableInfoVrtc, AcpiDmDumpVrtc, DtCompileVrtc, TemplateVrtc},
{ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, NULL, TemplateWaet},
@@ -917,6 +943,7 @@ AcpiDmDumpTable (
case ACPI_DMT_PCCT:
case ACPI_DMT_PMTT:
case ACPI_DMT_PPTT:
+ case ACPI_DMT_SDEV:
case ACPI_DMT_SRAT:
case ACPI_DMT_ASF:
case ACPI_DMT_HESTNTYP:
@@ -948,6 +975,7 @@ AcpiDmDumpTable (
case ACPI_DMT_NAME4:
case ACPI_DMT_SIG:
case ACPI_DMT_LPIT:
+ case ACPI_DMT_TPM2:
ByteLength = 4;
break;
@@ -1583,6 +1611,20 @@ AcpiDmDumpTable (
CurrentOffset, NULL);
break;
+ case ACPI_DMT_SDEV:
+
+ /* SDEV subtable types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_SDEV_TYPE_RESERVED)
+ {
+ Temp8 = ACPI_SDEV_TYPE_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmSdevSubnames[Temp8]);
+ break;
+
case ACPI_DMT_SRAT:
/* SRAT subtable types */
@@ -1597,6 +1639,21 @@ AcpiDmDumpTable (
AcpiDmSratSubnames[Temp8]);
break;
+ case ACPI_DMT_TPM2:
+
+ /* TPM2 Start Method types */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_TPM2_RESERVED)
+ {
+ Temp8 = ACPI_TPM2_RESERVED;
+ }
+
+ AcpiOsPrintf (UINT8_FORMAT, *Target,
+ AcpiDmTpm2Subnames[Temp8]);
+ break;
+
+
case ACPI_DMT_FADTPM:
/* FADT Preferred PM Profile names */
diff --git a/sys/contrib/dev/acpica/common/dmtables.c b/sys/contrib/dev/acpica/common/dmtables.c
index f1e72ca..2fe26b3 100644
--- a/sys/contrib/dev/acpica/common/dmtables.c
+++ b/sys/contrib/dev/acpica/common/dmtables.c
@@ -314,7 +314,7 @@ AdCreateTableHeader (
/*
* Print comments that come before this definition block.
*/
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
ASL_CV_PRINT_ONE_COMMENT(AcpiGbl_ParseOpRoot,AML_COMMENT_STANDARD, NULL, 0);
}
@@ -517,7 +517,7 @@ AdParseTable (
}
#ifdef ACPI_ASL_COMPILER
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
AcpiGbl_ParseOpRoot->Common.CvFilename = AcpiGbl_FileTreeRoot->Filename;
}
diff --git a/sys/contrib/dev/acpica/common/dmtbdump.c b/sys/contrib/dev/acpica/common/dmtbdump.c
index 5510e36..297455d 100644
--- a/sys/contrib/dev/acpica/common/dmtbdump.c
+++ b/sys/contrib/dev/acpica/common/dmtbdump.c
@@ -623,7 +623,7 @@ AcpiDmDumpAsf (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_HEADER);
- ACPI_ASF_INFO *SubTable;
+ ACPI_ASF_INFO *Subtable;
ACPI_DMTABLE_INFO *InfoTable;
ACPI_DMTABLE_INFO *DataInfoTable = NULL;
UINT8 *DataTable = NULL;
@@ -636,13 +636,13 @@ AcpiDmDumpAsf (
/* No main table, only subtables */
- SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Header.Length, AcpiDmTableInfoAsfHdr);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Header.Length, AcpiDmTableInfoAsfHdr);
if (ACPI_FAILURE (Status))
{
return;
@@ -650,7 +650,7 @@ AcpiDmDumpAsf (
/* The actual type is the lower 7 bits of Type */
- Type = (UINT8) (SubTable->Header.Type & 0x7F);
+ Type = (UINT8) (Subtable->Header.Type & 0x7F);
switch (Type)
{
@@ -663,9 +663,9 @@ AcpiDmDumpAsf (
InfoTable = AcpiDmTableInfoAsf1;
DataInfoTable = AcpiDmTableInfoAsf1a;
- DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ALERT));
- DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->Alerts;
- DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->DataLength;
+ DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ALERT));
+ DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->Alerts;
+ DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->DataLength;
DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
break;
@@ -673,9 +673,9 @@ AcpiDmDumpAsf (
InfoTable = AcpiDmTableInfoAsf2;
DataInfoTable = AcpiDmTableInfoAsf2a;
- DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_REMOTE));
- DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->Controls;
- DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->DataLength;
+ DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_REMOTE));
+ DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->Controls;
+ DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->DataLength;
DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
break;
@@ -687,20 +687,20 @@ AcpiDmDumpAsf (
case ACPI_ASF_TYPE_ADDRESS:
InfoTable = AcpiDmTableInfoAsf4;
- DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ADDRESS));
- DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, SubTable)->Devices;
+ DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ADDRESS));
+ DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, Subtable)->Devices;
DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
break;
default:
AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n",
- SubTable->Header.Type);
+ Subtable->Header.Type);
return;
}
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Header.Length, InfoTable);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Header.Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
@@ -762,15 +762,15 @@ AcpiDmDumpAsf (
/* Point to next subtable */
- if (!SubTable->Header.Length)
+ if (!Subtable->Header.Length)
{
AcpiOsPrintf ("Invalid zero subtable header length\n");
return;
}
- Offset += SubTable->Header.Length;
- SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, SubTable,
- SubTable->Header.Length);
+ Offset += Subtable->Header.Length;
+ Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Subtable,
+ Subtable->Header.Length);
}
}
@@ -793,7 +793,7 @@ AcpiDmDumpCpep (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_CPEP_POLLING *SubTable;
+ ACPI_CPEP_POLLING *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_CPEP);
@@ -808,12 +808,12 @@ AcpiDmDumpCpep (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
while (Offset < Table->Length)
{
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Header.Length, AcpiDmTableInfoCpep0);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Header.Length, AcpiDmTableInfoCpep0);
if (ACPI_FAILURE (Status))
{
return;
@@ -821,9 +821,9 @@ AcpiDmDumpCpep (
/* Point to next subtable */
- Offset += SubTable->Header.Length;
- SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable,
- SubTable->Header.Length);
+ Offset += Subtable->Header.Length;
+ Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Subtable,
+ Subtable->Header.Length);
}
}
@@ -846,9 +846,9 @@ AcpiDmDumpCsrt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_CSRT_GROUP *SubTable;
+ ACPI_CSRT_GROUP *Subtable;
ACPI_CSRT_SHARED_INFO *SharedInfoTable;
- ACPI_CSRT_DESCRIPTOR *SubSubTable;
+ ACPI_CSRT_DESCRIPTOR *SubSubtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_CSRT);
UINT32 SubOffset;
@@ -860,14 +860,14 @@ AcpiDmDumpCsrt (
/* Subtables (Resource Groups) */
- SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
while (Offset < Table->Length)
{
/* Resource group subtable */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoCsrt0);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoCsrt0);
if (ACPI_FAILURE (Status))
{
return;
@@ -887,19 +887,19 @@ AcpiDmDumpCsrt (
return;
}
- SubOffset += SubTable->SharedInfoLength;
+ SubOffset += Subtable->SharedInfoLength;
/* Sub-Subtables (Resource Descriptors) */
- SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
+ SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
Offset + SubOffset);
- while ((SubOffset < SubTable->Length) &&
+ while ((SubOffset < Subtable->Length) &&
((Offset + SubOffset) < Table->Length))
{
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubTable,
- SubSubTable->Length, AcpiDmTableInfoCsrt2);
+ Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubtable,
+ SubSubtable->Length, AcpiDmTableInfoCsrt2);
if (ACPI_FAILURE (Status))
{
return;
@@ -909,7 +909,7 @@ AcpiDmDumpCsrt (
/* Resource-specific info buffer */
- InfoLength = SubSubTable->Length - SubSubOffset;
+ InfoLength = SubSubtable->Length - SubSubOffset;
if (InfoLength)
{
Status = AcpiDmDumpTable (Length,
@@ -924,16 +924,16 @@ AcpiDmDumpCsrt (
/* Point to next sub-subtable */
- SubOffset += SubSubTable->Length;
- SubSubTable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubTable,
- SubSubTable->Length);
+ SubOffset += SubSubtable->Length;
+ SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubtable,
+ SubSubtable->Length);
}
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, SubTable,
- SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Subtable,
+ Subtable->Length);
}
}
@@ -956,7 +956,7 @@ AcpiDmDumpDbg2 (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_DBG2_DEVICE *SubTable;
+ ACPI_DBG2_DEVICE *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_DBG2);
UINT32 i;
@@ -975,12 +975,12 @@ AcpiDmDumpDbg2 (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
while (Offset < Table->Length)
{
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoDbg2Device);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoDbg2Device);
if (ACPI_FAILURE (Status))
{
return;
@@ -988,15 +988,15 @@ AcpiDmDumpDbg2 (
/* Dump the BaseAddress array */
- for (i = 0; i < SubTable->RegisterCount; i++)
+ for (i = 0; i < Subtable->RegisterCount; i++)
{
- ArrayOffset = SubTable->BaseAddressOffset +
+ ArrayOffset = Subtable->BaseAddressOffset +
(sizeof (ACPI_GENERIC_ADDRESS) * i);
AbsoluteOffset = Offset + ArrayOffset;
- Array = (UINT8 *) SubTable + ArrayOffset;
+ Array = (UINT8 *) Subtable + ArrayOffset;
Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
- SubTable->Length, AcpiDmTableInfoDbg2Addr);
+ Subtable->Length, AcpiDmTableInfoDbg2Addr);
if (ACPI_FAILURE (Status))
{
return;
@@ -1005,15 +1005,15 @@ AcpiDmDumpDbg2 (
/* Dump the AddressSize array */
- for (i = 0; i < SubTable->RegisterCount; i++)
+ for (i = 0; i < Subtable->RegisterCount; i++)
{
- ArrayOffset = SubTable->AddressSizeOffset +
+ ArrayOffset = Subtable->AddressSizeOffset +
(sizeof (UINT32) * i);
AbsoluteOffset = Offset + ArrayOffset;
- Array = (UINT8 *) SubTable + ArrayOffset;
+ Array = (UINT8 *) Subtable + ArrayOffset;
Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
- SubTable->Length, AcpiDmTableInfoDbg2Size);
+ Subtable->Length, AcpiDmTableInfoDbg2Size);
if (ACPI_FAILURE (Status))
{
return;
@@ -1023,12 +1023,12 @@ AcpiDmDumpDbg2 (
/* Dump the Namestring (required) */
AcpiOsPrintf ("\n");
- ArrayOffset = SubTable->NamepathOffset;
+ ArrayOffset = Subtable->NamepathOffset;
AbsoluteOffset = Offset + ArrayOffset;
- Array = (UINT8 *) SubTable + ArrayOffset;
+ Array = (UINT8 *) Subtable + ArrayOffset;
Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
- SubTable->Length, AcpiDmTableInfoDbg2Name);
+ Subtable->Length, AcpiDmTableInfoDbg2Name);
if (ACPI_FAILURE (Status))
{
return;
@@ -1036,10 +1036,10 @@ AcpiDmDumpDbg2 (
/* Dump the OemData (optional) */
- if (SubTable->OemDataOffset)
+ if (Subtable->OemDataOffset)
{
- Status = AcpiDmDumpTable (Length, Offset + SubTable->OemDataOffset,
- Table, SubTable->OemDataLength,
+ Status = AcpiDmDumpTable (Length, Offset + Subtable->OemDataOffset,
+ Table, Subtable->OemDataLength,
AcpiDmTableInfoDbg2OemData);
if (ACPI_FAILURE (Status))
{
@@ -1049,9 +1049,9 @@ AcpiDmDumpDbg2 (
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, SubTable,
- SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Subtable,
+ Subtable->Length);
}
}
@@ -1074,7 +1074,7 @@ AcpiDmDumpDmar (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_DMAR_HEADER *SubTable;
+ ACPI_DMAR_HEADER *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_DMAR);
ACPI_DMTABLE_INFO *InfoTable;
@@ -1094,14 +1094,14 @@ AcpiDmDumpDmar (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoDmarHdr);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoDmarHdr);
if (ACPI_FAILURE (Status))
{
return;
@@ -1109,7 +1109,7 @@ AcpiDmDumpDmar (
AcpiOsPrintf ("\n");
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_DMAR_TYPE_HARDWARE_UNIT:
@@ -1144,12 +1144,12 @@ AcpiDmDumpDmar (
default:
AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n",
- SubTable->Type);
+ Subtable->Type);
return;
}
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
@@ -1158,16 +1158,16 @@ AcpiDmDumpDmar (
/*
* Dump the optional device scope entries
*/
- if ((SubTable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
- (SubTable->Type == ACPI_DMAR_TYPE_NAMESPACE))
+ if ((Subtable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
+ (Subtable->Type == ACPI_DMAR_TYPE_NAMESPACE))
{
/* These types do not support device scopes */
goto NextSubtable;
}
- ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, SubTable, ScopeOffset);
- while (ScopeOffset < SubTable->Length)
+ ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable, ScopeOffset);
+ while (ScopeOffset < Subtable->Length)
{
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
@@ -1208,9 +1208,9 @@ AcpiDmDumpDmar (
NextSubtable:
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, SubTable,
- SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Subtable,
+ Subtable->Length);
}
}
@@ -1343,7 +1343,7 @@ AcpiDmDumpEinj (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_WHEA_HEADER *SubTable;
+ ACPI_WHEA_HEADER *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_EINJ);
@@ -1358,11 +1358,11 @@ AcpiDmDumpEinj (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
while (Offset < Table->Length)
{
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
if (ACPI_FAILURE (Status))
{
@@ -1372,7 +1372,7 @@ AcpiDmDumpEinj (
/* Point to next subtable (each subtable is of fixed length) */
Offset += sizeof (ACPI_WHEA_HEADER);
- SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
+ Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
sizeof (ACPI_WHEA_HEADER));
}
}
@@ -1396,7 +1396,7 @@ AcpiDmDumpErst (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_WHEA_HEADER *SubTable;
+ ACPI_WHEA_HEADER *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_ERST);
@@ -1411,11 +1411,11 @@ AcpiDmDumpErst (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
while (Offset < Table->Length)
{
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
if (ACPI_FAILURE (Status))
{
@@ -1425,7 +1425,7 @@ AcpiDmDumpErst (
/* Point to next subtable (each subtable is of fixed length) */
Offset += sizeof (ACPI_WHEA_HEADER);
- SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable,
+ Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
sizeof (ACPI_WHEA_HEADER));
}
}
@@ -1449,7 +1449,7 @@ AcpiDmDumpFpdt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_FPDT_HEADER *SubTable;
+ ACPI_FPDT_HEADER *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_FPDT);
ACPI_DMTABLE_INFO *InfoTable;
@@ -1459,20 +1459,20 @@ AcpiDmDumpFpdt (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoFpdtHdr);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoFpdtHdr);
if (ACPI_FAILURE (Status))
{
return;
}
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_FPDT_TYPE_BOOT:
@@ -1487,31 +1487,31 @@ AcpiDmDumpFpdt (
default:
AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n",
- SubTable->Type);
+ Subtable->Type);
/* Attempt to continue */
- if (!SubTable->Length)
+ if (!Subtable->Length)
{
AcpiOsPrintf ("Invalid zero length subtable\n");
return;
}
- goto NextSubTable;
+ goto NextSubtable;
}
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
}
-NextSubTable:
+NextSubtable:
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable,
- SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable,
+ Subtable->Length);
}
}
@@ -1534,11 +1534,11 @@ AcpiDmDumpGtdt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_GTDT_HEADER *SubTable;
+ ACPI_GTDT_HEADER *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_GTDT);
ACPI_DMTABLE_INFO *InfoTable;
- UINT32 SubTableLength;
+ UINT32 SubtableLength;
UINT32 GtCount;
ACPI_GTDT_TIMER_ENTRY *GtxTable;
@@ -1553,34 +1553,34 @@ AcpiDmDumpGtdt (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoGtdtHdr);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoGtdtHdr);
if (ACPI_FAILURE (Status))
{
return;
}
GtCount = 0;
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_GTDT_TYPE_TIMER_BLOCK:
- SubTableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
+ SubtableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
- SubTable))->TimerCount;
+ Subtable))->TimerCount;
InfoTable = AcpiDmTableInfoGtdt0;
break;
case ACPI_GTDT_TYPE_WATCHDOG:
- SubTableLength = sizeof (ACPI_GTDT_WATCHDOG);
+ SubtableLength = sizeof (ACPI_GTDT_WATCHDOG);
InfoTable = AcpiDmTableInfoGtdt1;
break;
@@ -1590,12 +1590,12 @@ AcpiDmDumpGtdt (
/* Cannot continue on unknown type - no length */
AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n",
- SubTable->Type);
+ Subtable->Type);
return;
}
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
@@ -1603,15 +1603,15 @@ AcpiDmDumpGtdt (
/* Point to end of current subtable (each subtable above is of fixed length) */
- Offset += SubTableLength;
+ Offset += SubtableLength;
/* If there are any Gt Timer Blocks from above, dump them now */
if (GtCount)
{
GtxTable = ACPI_ADD_PTR (
- ACPI_GTDT_TIMER_ENTRY, SubTable, SubTableLength);
- SubTableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
+ ACPI_GTDT_TIMER_ENTRY, Subtable, SubtableLength);
+ SubtableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
while (GtCount)
{
@@ -1630,7 +1630,7 @@ AcpiDmDumpGtdt (
/* Point to next subtable */
- SubTable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, SubTable, SubTableLength);
+ Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Subtable, SubtableLength);
}
}
@@ -1653,11 +1653,11 @@ AcpiDmDumpHest (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_HEST_HEADER *SubTable;
+ ACPI_HEST_HEADER *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_HEST);
ACPI_DMTABLE_INFO *InfoTable;
- UINT32 SubTableLength;
+ UINT32 SubtableLength;
UINT32 BankCount;
ACPI_HEST_IA_ERROR_BANK *BankTable;
@@ -1672,70 +1672,70 @@ AcpiDmDumpHest (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
while (Offset < Table->Length)
{
BankCount = 0;
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_HEST_TYPE_IA32_CHECK:
InfoTable = AcpiDmTableInfoHest0;
- SubTableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
+ SubtableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
- SubTable))->NumHardwareBanks;
+ Subtable))->NumHardwareBanks;
break;
case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
InfoTable = AcpiDmTableInfoHest1;
- SubTableLength = sizeof (ACPI_HEST_IA_CORRECTED);
+ SubtableLength = sizeof (ACPI_HEST_IA_CORRECTED);
BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
- SubTable))->NumHardwareBanks;
+ Subtable))->NumHardwareBanks;
break;
case ACPI_HEST_TYPE_IA32_NMI:
InfoTable = AcpiDmTableInfoHest2;
- SubTableLength = sizeof (ACPI_HEST_IA_NMI);
+ SubtableLength = sizeof (ACPI_HEST_IA_NMI);
break;
case ACPI_HEST_TYPE_AER_ROOT_PORT:
InfoTable = AcpiDmTableInfoHest6;
- SubTableLength = sizeof (ACPI_HEST_AER_ROOT);
+ SubtableLength = sizeof (ACPI_HEST_AER_ROOT);
break;
case ACPI_HEST_TYPE_AER_ENDPOINT:
InfoTable = AcpiDmTableInfoHest7;
- SubTableLength = sizeof (ACPI_HEST_AER);
+ SubtableLength = sizeof (ACPI_HEST_AER);
break;
case ACPI_HEST_TYPE_AER_BRIDGE:
InfoTable = AcpiDmTableInfoHest8;
- SubTableLength = sizeof (ACPI_HEST_AER_BRIDGE);
+ SubtableLength = sizeof (ACPI_HEST_AER_BRIDGE);
break;
case ACPI_HEST_TYPE_GENERIC_ERROR:
InfoTable = AcpiDmTableInfoHest9;
- SubTableLength = sizeof (ACPI_HEST_GENERIC);
+ SubtableLength = sizeof (ACPI_HEST_GENERIC);
break;
case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
InfoTable = AcpiDmTableInfoHest10;
- SubTableLength = sizeof (ACPI_HEST_GENERIC_V2);
+ SubtableLength = sizeof (ACPI_HEST_GENERIC_V2);
break;
case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
InfoTable = AcpiDmTableInfoHest11;
- SubTableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK);
+ SubtableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK);
BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
- SubTable))->NumHardwareBanks;
+ Subtable))->NumHardwareBanks;
break;
default:
@@ -1743,13 +1743,13 @@ AcpiDmDumpHest (
/* Cannot continue on unknown type - no length */
AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n",
- SubTable->Type);
+ Subtable->Type);
return;
}
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTableLength, InfoTable);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ SubtableLength, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
@@ -1757,15 +1757,15 @@ AcpiDmDumpHest (
/* Point to end of current subtable (each subtable above is of fixed length) */
- Offset += SubTableLength;
+ Offset += SubtableLength;
/* If there are any (fixed-length) Error Banks from above, dump them now */
if (BankCount)
{
- BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, SubTable,
- SubTableLength);
- SubTableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
+ BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, Subtable,
+ SubtableLength);
+ SubtableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
while (BankCount)
{
@@ -1785,7 +1785,7 @@ AcpiDmDumpHest (
/* Point to next subtable */
- SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, SubTable, SubTableLength);
+ Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Subtable, SubtableLength);
}
}
@@ -1811,7 +1811,7 @@ AcpiDmDumpHmat (
ACPI_HMAT_LOCALITY *HmatLocality;
ACPI_HMAT_CACHE *HmatCache;
UINT32 Offset;
- UINT32 SubTableOffset;
+ UINT32 SubtableOffset;
UINT32 Length;
ACPI_DMTABLE_INFO *InfoTable;
UINT32 i, j;
@@ -1829,7 +1829,7 @@ AcpiDmDumpHmat (
while (Offset < Table->Length)
{
AcpiOsPrintf ("\n");
- SubTableOffset = 0;
+ SubtableOffset = 0;
/* Dump HMAT structure header */
@@ -1873,7 +1873,7 @@ AcpiDmDumpHmat (
/* Attempt to continue */
- goto NextSubTable;
+ goto NextSubtable;
}
/* Dump HMAT structure body */
@@ -1897,11 +1897,11 @@ AcpiDmDumpHmat (
case ACPI_HMAT_TYPE_LOCALITY:
HmatLocality = ACPI_CAST_PTR (ACPI_HMAT_LOCALITY, HmatStruct);
- SubTableOffset = sizeof (ACPI_HMAT_LOCALITY);
+ SubtableOffset = sizeof (ACPI_HMAT_LOCALITY);
/* Dump initiator proximity domains */
- if ((UINT32)(HmatStruct->Length - SubTableOffset) <
+ if ((UINT32)(HmatStruct->Length - SubtableOffset) <
(UINT32)(HmatLocality->NumberOfInitiatorPDs * 4))
{
AcpiOsPrintf ("Invalid initiator proximity domain number\n");
@@ -1909,15 +1909,15 @@ AcpiDmDumpHmat (
}
for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
{
- Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset,
- ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubTableOffset),
+ Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
+ ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
4, AcpiDmTableInfoHmat1a);
- SubTableOffset += 4;
+ SubtableOffset += 4;
}
/* Dump target proximity domains */
- if ((UINT32)(HmatStruct->Length - SubTableOffset) <
+ if ((UINT32)(HmatStruct->Length - SubtableOffset) <
(UINT32)(HmatLocality->NumberOfTargetPDs * 4))
{
AcpiOsPrintf ("Invalid target proximity domain number\n");
@@ -1925,15 +1925,15 @@ AcpiDmDumpHmat (
}
for (i = 0; i < HmatLocality->NumberOfTargetPDs; i++)
{
- Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset,
- ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubTableOffset),
+ Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
+ ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
4, AcpiDmTableInfoHmat1b);
- SubTableOffset += 4;
+ SubtableOffset += 4;
}
/* Dump latency/bandwidth entris */
- if ((UINT32)(HmatStruct->Length - SubTableOffset) <
+ if ((UINT32)(HmatStruct->Length - SubtableOffset) <
(UINT32)(HmatLocality->NumberOfInitiatorPDs *
HmatLocality->NumberOfTargetPDs * 2))
{
@@ -1944,10 +1944,10 @@ AcpiDmDumpHmat (
{
for (j = 0; j < HmatLocality->NumberOfTargetPDs; j++)
{
- Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset,
- ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubTableOffset),
+ Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
+ ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
2, AcpiDmTableInfoHmat1c);
- SubTableOffset += 2;
+ SubtableOffset += 2;
}
}
break;
@@ -1955,11 +1955,11 @@ AcpiDmDumpHmat (
case ACPI_HMAT_TYPE_CACHE:
HmatCache = ACPI_CAST_PTR (ACPI_HMAT_CACHE, HmatStruct);
- SubTableOffset = sizeof (ACPI_HMAT_CACHE);
+ SubtableOffset = sizeof (ACPI_HMAT_CACHE);
/* Dump SMBIOS handles */
- if ((UINT32)(HmatStruct->Length - SubTableOffset) <
+ if ((UINT32)(HmatStruct->Length - SubtableOffset) <
(UINT32)(HmatCache->NumberOfSMBIOSHandles * 2))
{
AcpiOsPrintf ("Invalid SMBIOS handle number\n");
@@ -1967,10 +1967,10 @@ AcpiDmDumpHmat (
}
for (i = 0; i < HmatCache->NumberOfSMBIOSHandles; i++)
{
- Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset,
- ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubTableOffset),
+ Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
+ ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
2, AcpiDmTableInfoHmat2a);
- SubTableOffset += 2;
+ SubtableOffset += 2;
}
break;
@@ -1979,7 +1979,7 @@ AcpiDmDumpHmat (
break;
}
-NextSubTable:
+NextSubtable:
/* Point to next HMAT structure subtable */
Offset += (HmatStruct->Length);
@@ -2104,7 +2104,7 @@ AcpiDmDumpIort (
AcpiOsPrintf ("Invalid zero length IORT node\n");
return;
}
- goto NextSubTable;
+ goto NextSubtable;
}
/* Dump the node subtable header */
@@ -2227,7 +2227,7 @@ AcpiDmDumpIort (
NodeOffset += Length;
}
-NextSubTable:
+NextSubtable:
/* Point to next node subtable */
Offset += IortNode->Length;
@@ -2260,7 +2260,7 @@ AcpiDmDumpIvrs (
UINT32 EntryLength;
UINT32 EntryType;
ACPI_IVRS_DE_HEADER *DeviceEntry;
- ACPI_IVRS_HEADER *SubTable;
+ ACPI_IVRS_HEADER *Subtable;
ACPI_DMTABLE_INFO *InfoTable;
@@ -2274,20 +2274,20 @@ AcpiDmDumpIvrs (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoIvrsHdr);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoIvrsHdr);
if (ACPI_FAILURE (Status))
{
return;
}
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_IVRS_TYPE_HARDWARE:
@@ -2304,23 +2304,23 @@ AcpiDmDumpIvrs (
default:
AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n",
- SubTable->Type);
+ Subtable->Type);
/* Attempt to continue */
- if (!SubTable->Length)
+ if (!Subtable->Length)
{
AcpiOsPrintf ("Invalid zero length subtable\n");
return;
}
- goto NextSubTable;
+ goto NextSubtable;
}
/* Dump the subtable */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
@@ -2328,13 +2328,13 @@ AcpiDmDumpIvrs (
/* The hardware subtable can contain multiple device entries */
- if (SubTable->Type == ACPI_IVRS_TYPE_HARDWARE)
+ if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE)
{
EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE);
- DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, SubTable,
+ DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable,
sizeof (ACPI_IVRS_HARDWARE));
- while (EntryOffset < (Offset + SubTable->Length))
+ while (EntryOffset < (Offset + Subtable->Length))
{
AcpiOsPrintf ("\n");
/*
@@ -2409,11 +2409,11 @@ AcpiDmDumpIvrs (
}
}
-NextSubTable:
+NextSubtable:
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, SubTable, SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Subtable, Subtable->Length);
}
}
@@ -2438,33 +2438,33 @@ AcpiDmDumpLpit (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_LPIT_HEADER *SubTable;
+ ACPI_LPIT_HEADER *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_LPIT);
ACPI_DMTABLE_INFO *InfoTable;
- UINT32 SubTableLength;
+ UINT32 SubtableLength;
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr);
if (ACPI_FAILURE (Status))
{
return;
}
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_LPIT_TYPE_NATIVE_CSTATE:
InfoTable = AcpiDmTableInfoLpit0;
- SubTableLength = sizeof (ACPI_LPIT_NATIVE);
+ SubtableLength = sizeof (ACPI_LPIT_NATIVE);
break;
default:
@@ -2472,12 +2472,12 @@ AcpiDmDumpLpit (
/* Cannot continue on unknown type - no length */
AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n",
- SubTable->Type);
+ Subtable->Type);
return;
}
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTableLength, InfoTable);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ SubtableLength, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
@@ -2487,8 +2487,8 @@ AcpiDmDumpLpit (
/* Point to next subtable */
- Offset += SubTableLength;
- SubTable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, SubTable, SubTableLength);
+ Offset += SubtableLength;
+ Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Subtable, SubtableLength);
}
}
@@ -2511,7 +2511,7 @@ AcpiDmDumpMadt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_SUBTABLE_HEADER *SubTable;
+ ACPI_SUBTABLE_HEADER *Subtable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_MADT);
ACPI_DMTABLE_INFO *InfoTable;
@@ -2527,20 +2527,20 @@ AcpiDmDumpMadt (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoMadtHdr);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoMadtHdr);
if (ACPI_FAILURE (Status))
{
return;
}
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_MADT_TYPE_LOCAL_APIC:
@@ -2625,32 +2625,32 @@ AcpiDmDumpMadt (
default:
AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n",
- SubTable->Type);
+ Subtable->Type);
/* Attempt to continue */
- if (!SubTable->Length)
+ if (!Subtable->Length)
{
AcpiOsPrintf ("Invalid zero length subtable\n");
return;
}
- goto NextSubTable;
+ goto NextSubtable;
}
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
}
-NextSubTable:
+NextSubtable:
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable,
- SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable,
+ Subtable->Length);
}
}
@@ -2673,7 +2673,7 @@ AcpiDmDumpMcfg (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_MCFG);
- ACPI_MCFG_ALLOCATION *SubTable;
+ ACPI_MCFG_ALLOCATION *Subtable;
/* Main table */
@@ -2686,7 +2686,7 @@ AcpiDmDumpMcfg (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
while (Offset < Table->Length)
{
if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
@@ -2697,7 +2697,7 @@ AcpiDmDumpMcfg (
}
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
if (ACPI_FAILURE (Status))
{
@@ -2707,7 +2707,7 @@ AcpiDmDumpMcfg (
/* Point to next subtable (each subtable is of fixed length) */
Offset += sizeof (ACPI_MCFG_ALLOCATION);
- SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, SubTable,
+ Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Subtable,
sizeof (ACPI_MCFG_ALLOCATION));
}
}
@@ -2731,11 +2731,11 @@ AcpiDmDumpMpst (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_MPST);
- ACPI_MPST_POWER_NODE *SubTable0;
- ACPI_MPST_POWER_STATE *SubTable0A;
- ACPI_MPST_COMPONENT *SubTable0B;
- ACPI_MPST_DATA_HDR *SubTable1;
- ACPI_MPST_POWER_DATA *SubTable2;
+ ACPI_MPST_POWER_NODE *Subtable0;
+ ACPI_MPST_POWER_STATE *Subtable0A;
+ ACPI_MPST_COMPONENT *Subtable0B;
+ ACPI_MPST_DATA_HDR *Subtable1;
+ ACPI_MPST_POWER_DATA *Subtable2;
UINT16 SubtableCount;
UINT32 PowerStateCount;
UINT32 ComponentCount;
@@ -2752,12 +2752,12 @@ AcpiDmDumpMpst (
/* Subtable: Memory Power Node(s) */
SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
- SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
+ Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
while ((Offset < Table->Length) && SubtableCount)
{
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0,
sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
if (ACPI_FAILURE (Status))
{
@@ -2766,33 +2766,33 @@ AcpiDmDumpMpst (
/* Extract the sub-subtable counts */
- PowerStateCount = SubTable0->NumPowerStates;
- ComponentCount = SubTable0->NumPhysicalComponents;
+ PowerStateCount = Subtable0->NumPowerStates;
+ ComponentCount = Subtable0->NumPhysicalComponents;
Offset += sizeof (ACPI_MPST_POWER_NODE);
/* Sub-subtables - Memory Power State Structure(s) */
- SubTable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, SubTable0,
+ Subtable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, Subtable0,
sizeof (ACPI_MPST_POWER_NODE));
while (PowerStateCount)
{
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0A,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0A,
sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
if (ACPI_FAILURE (Status))
{
return;
}
- SubTable0A++;
+ Subtable0A++;
PowerStateCount--;
Offset += sizeof (ACPI_MPST_POWER_STATE);
}
/* Sub-subtables - Physical Component ID Structure(s) */
- SubTable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, SubTable0A);
+ Subtable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, Subtable0A);
if (ComponentCount)
{
@@ -2801,14 +2801,14 @@ AcpiDmDumpMpst (
while (ComponentCount)
{
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0B,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0B,
sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
if (ACPI_FAILURE (Status))
{
return;
}
- SubTable0B++;
+ Subtable0B++;
ComponentCount--;
Offset += sizeof (ACPI_MPST_COMPONENT);
}
@@ -2816,42 +2816,42 @@ AcpiDmDumpMpst (
/* Point to next Memory Power Node subtable */
SubtableCount--;
- SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, SubTable0,
+ Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Subtable0,
sizeof (ACPI_MPST_POWER_NODE) +
- (sizeof (ACPI_MPST_POWER_STATE) * SubTable0->NumPowerStates) +
- (sizeof (ACPI_MPST_COMPONENT) * SubTable0->NumPhysicalComponents));
+ (sizeof (ACPI_MPST_POWER_STATE) * Subtable0->NumPowerStates) +
+ (sizeof (ACPI_MPST_COMPONENT) * Subtable0->NumPhysicalComponents));
}
/* Subtable: Count of Memory Power State Characteristic structures */
AcpiOsPrintf ("\n");
- SubTable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, SubTable0);
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable1,
+ Subtable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable0);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable1,
sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
if (ACPI_FAILURE (Status))
{
return;
}
- SubtableCount = SubTable1->CharacteristicsCount;
+ SubtableCount = Subtable1->CharacteristicsCount;
Offset += sizeof (ACPI_MPST_DATA_HDR);
/* Subtable: Memory Power State Characteristics structure(s) */
- SubTable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, SubTable1,
+ Subtable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, Subtable1,
sizeof (ACPI_MPST_DATA_HDR));
while ((Offset < Table->Length) && SubtableCount)
{
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable2,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable2,
sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
if (ACPI_FAILURE (Status))
{
return;
}
- SubTable2++;
+ Subtable2++;
SubtableCount--;
Offset += sizeof (ACPI_MPST_POWER_DATA);
}
@@ -2876,7 +2876,7 @@ AcpiDmDumpMsct (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_MSCT);
- ACPI_MSCT_PROXIMITY *SubTable;
+ ACPI_MSCT_PROXIMITY *Subtable;
/* Main table */
@@ -2889,13 +2889,13 @@ AcpiDmDumpMsct (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
if (ACPI_FAILURE (Status))
{
@@ -2905,7 +2905,7 @@ AcpiDmDumpMsct (
/* Point to next subtable */
Offset += sizeof (ACPI_MSCT_PROXIMITY);
- SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, SubTable,
+ Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Subtable,
sizeof (ACPI_MSCT_PROXIMITY));
}
}
@@ -2929,7 +2929,7 @@ AcpiDmDumpMtmr (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_MTMR);
- ACPI_MTMR_ENTRY *SubTable;
+ ACPI_MTMR_ENTRY *Subtable;
/* Main table */
@@ -2942,13 +2942,13 @@ AcpiDmDumpMtmr (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
sizeof (ACPI_MTMR_ENTRY), AcpiDmTableInfoMtmr0);
if (ACPI_FAILURE (Status))
{
@@ -2958,7 +2958,7 @@ AcpiDmDumpMtmr (
/* Point to next subtable */
Offset += sizeof (ACPI_MTMR_ENTRY);
- SubTable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, SubTable,
+ Subtable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Subtable,
sizeof (ACPI_MTMR_ENTRY));
}
}
@@ -2984,7 +2984,7 @@ AcpiDmDumpNfit (
UINT32 Offset = sizeof (ACPI_TABLE_NFIT);
UINT32 FieldOffset = 0;
UINT32 Length;
- ACPI_NFIT_HEADER *SubTable;
+ ACPI_NFIT_HEADER *Subtable;
ACPI_DMTABLE_INFO *InfoTable;
ACPI_NFIT_INTERLEAVE *Interleave = NULL;
ACPI_NFIT_SMBIOS *SmbiosInfo = NULL;
@@ -3002,20 +3002,20 @@ AcpiDmDumpNfit (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* NFIT subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoNfitHdr);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoNfitHdr);
if (ACPI_FAILURE (Status))
{
return;
}
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
@@ -3032,13 +3032,13 @@ AcpiDmDumpNfit (
/* Has a variable number of 32-bit values at the end */
InfoTable = AcpiDmTableInfoNfit2;
- Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, SubTable);
+ Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable);
FieldOffset = sizeof (ACPI_NFIT_INTERLEAVE);
break;
case ACPI_NFIT_TYPE_SMBIOS:
- SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, SubTable);
+ SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, Subtable);
InfoTable = AcpiDmTableInfoNfit3;
break;
@@ -3057,27 +3057,32 @@ AcpiDmDumpNfit (
/* Has a variable number of 64-bit addresses at the end */
InfoTable = AcpiDmTableInfoNfit6;
- Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, SubTable);
+ Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable);
FieldOffset = sizeof (ACPI_NFIT_FLUSH_ADDRESS) - sizeof (UINT64);
break;
+ case ACPI_NFIT_TYPE_CAPABILITIES: /* ACPI 6.0A */
+
+ InfoTable = AcpiDmTableInfoNfit7;
+ break;
+
default:
AcpiOsPrintf ("\n**** Unknown NFIT subtable type 0x%X\n",
- SubTable->Type);
+ Subtable->Type);
/* Attempt to continue */
- if (!SubTable->Length)
+ if (!Subtable->Length)
{
AcpiOsPrintf ("Invalid zero length subtable\n");
return;
}
- goto NextSubTable;
+ goto NextSubtable;
}
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
@@ -3085,7 +3090,7 @@ AcpiDmDumpNfit (
/* Per-subtable variable-length fields */
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_NFIT_TYPE_INTERLEAVE:
@@ -3105,7 +3110,7 @@ AcpiDmDumpNfit (
case ACPI_NFIT_TYPE_SMBIOS:
- Length = SubTable->Length -
+ Length = Subtable->Length -
sizeof (ACPI_NFIT_SMBIOS) + sizeof (UINT8);
if (Length)
@@ -3142,11 +3147,11 @@ AcpiDmDumpNfit (
break;
}
-NextSubTable:
+NextSubtable:
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, SubTable, SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Subtable, Subtable->Length);
}
}
@@ -3169,7 +3174,7 @@ AcpiDmDumpPcct (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_PCCT_SUBSPACE *SubTable;
+ ACPI_PCCT_SUBSPACE *Subtable;
ACPI_DMTABLE_INFO *InfoTable;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_PCCT);
@@ -3185,20 +3190,20 @@ AcpiDmDumpPcct (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Header.Length, AcpiDmTableInfoPcctHdr);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Header.Length, AcpiDmTableInfoPcctHdr);
if (ACPI_FAILURE (Status))
{
return;
}
- switch (SubTable->Header.Type)
+ switch (Subtable->Header.Type)
{
case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
@@ -3229,13 +3234,67 @@ AcpiDmDumpPcct (
AcpiOsPrintf (
"\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
- SubTable->Header.Type);
+ Subtable->Header.Type);
return;
}
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Header.Length, InfoTable);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Header.Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Point to next subtable */
+
+ Offset += Subtable->Header.Length;
+ Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Subtable,
+ Subtable->Header.Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpPdtt
+ *
+ * PARAMETERS: Table - A PDTT table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a Pdtt. This is a variable-length
+ * table that contains an open-ended number of IDs
+ * at the end of the table.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpPdtt (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_PDTT_CHANNEL *Subtable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_PDTT);
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPdtt);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables. Currently there is only one type, but can be multiples */
+
+ Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ sizeof (ACPI_PDTT_CHANNEL), AcpiDmTableInfoPdtt0);
if (ACPI_FAILURE (Status))
{
return;
@@ -3243,9 +3302,9 @@ AcpiDmDumpPcct (
/* Point to next subtable */
- Offset += SubTable->Header.Length;
- SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, SubTable,
- SubTable->Header.Length);
+ Offset += sizeof (ACPI_PDTT_CHANNEL);
+ Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Subtable,
+ sizeof (ACPI_PDTT_CHANNEL));
}
}
@@ -3268,9 +3327,9 @@ AcpiDmDumpPmtt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_PMTT_HEADER *SubTable;
- ACPI_PMTT_HEADER *MemSubTable;
- ACPI_PMTT_HEADER *DimmSubTable;
+ ACPI_PMTT_HEADER *Subtable;
+ ACPI_PMTT_HEADER *MemSubtable;
+ ACPI_PMTT_HEADER *DimmSubtable;
ACPI_PMTT_DOMAIN *DomainArray;
UINT32 Length = Table->Length;
UINT32 Offset = sizeof (ACPI_TABLE_PMTT);
@@ -3290,14 +3349,14 @@ AcpiDmDumpPmtt (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoPmttHdr);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoPmttHdr);
if (ACPI_FAILURE (Status))
{
return;
@@ -3305,18 +3364,18 @@ AcpiDmDumpPmtt (
/* Only Socket subtables are expected at this level */
- if (SubTable->Type != ACPI_PMTT_TYPE_SOCKET)
+ if (Subtable->Type != ACPI_PMTT_TYPE_SOCKET)
{
AcpiOsPrintf (
"\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
- SubTable->Type);
+ Subtable->Type);
return;
}
/* Dump the fixed-length portion of the subtable */
- Status = AcpiDmDumpTable (Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoPmtt0);
+ Status = AcpiDmDumpTable (Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoPmtt0);
if (ACPI_FAILURE (Status))
{
return;
@@ -3325,18 +3384,18 @@ AcpiDmDumpPmtt (
/* Walk the memory controller subtables */
MemOffset = sizeof (ACPI_PMTT_SOCKET);
- MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, SubTable,
+ MemSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Subtable,
sizeof (ACPI_PMTT_SOCKET));
while (((Offset + MemOffset) < Table->Length) &&
- (MemOffset < SubTable->Length))
+ (MemOffset < Subtable->Length))
{
/* Common subtable header */
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Length,
- Offset + MemOffset, MemSubTable,
- MemSubTable->Length, AcpiDmTableInfoPmttHdr);
+ Offset + MemOffset, MemSubtable,
+ MemSubtable->Length, AcpiDmTableInfoPmttHdr);
if (ACPI_FAILURE (Status))
{
return;
@@ -3344,19 +3403,19 @@ AcpiDmDumpPmtt (
/* Only memory controller subtables are expected at this level */
- if (MemSubTable->Type != ACPI_PMTT_TYPE_CONTROLLER)
+ if (MemSubtable->Type != ACPI_PMTT_TYPE_CONTROLLER)
{
AcpiOsPrintf (
"\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
- MemSubTable->Type);
+ MemSubtable->Type);
return;
}
/* Dump the fixed-length portion of the controller subtable */
Status = AcpiDmDumpTable (Length,
- Offset + MemOffset, MemSubTable,
- MemSubTable->Length, AcpiDmTableInfoPmtt1);
+ Offset + MemOffset, MemSubtable,
+ MemSubtable->Length, AcpiDmTableInfoPmtt1);
if (ACPI_FAILURE (Status))
{
return;
@@ -3364,13 +3423,13 @@ AcpiDmDumpPmtt (
/* Walk the variable count of proximity domains */
- DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubTable)->DomainCount;
+ DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubtable)->DomainCount;
DomainOffset = sizeof (ACPI_PMTT_CONTROLLER);
- DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubTable,
+ DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubtable,
sizeof (ACPI_PMTT_CONTROLLER));
while (((Offset + MemOffset + DomainOffset) < Table->Length) &&
- ((MemOffset + DomainOffset) < SubTable->Length) &&
+ ((MemOffset + DomainOffset) < Subtable->Length) &&
DomainCount)
{
Status = AcpiDmDumpTable (Length,
@@ -3395,18 +3454,18 @@ AcpiDmDumpPmtt (
/* Walk the physical component (DIMM) subtables */
DimmOffset = DomainOffset;
- DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubTable,
+ DimmSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubtable,
DomainOffset);
while (((Offset + MemOffset + DimmOffset) < Table->Length) &&
- (DimmOffset < MemSubTable->Length))
+ (DimmOffset < MemSubtable->Length))
{
/* Common subtable header */
AcpiOsPrintf ("\n");
Status = AcpiDmDumpTable (Length,
- Offset + MemOffset + DimmOffset, DimmSubTable,
- DimmSubTable->Length, AcpiDmTableInfoPmttHdr);
+ Offset + MemOffset + DimmOffset, DimmSubtable,
+ DimmSubtable->Length, AcpiDmTableInfoPmttHdr);
if (ACPI_FAILURE (Status))
{
return;
@@ -3414,19 +3473,19 @@ AcpiDmDumpPmtt (
/* Only DIMM subtables are expected at this level */
- if (DimmSubTable->Type != ACPI_PMTT_TYPE_DIMM)
+ if (DimmSubtable->Type != ACPI_PMTT_TYPE_DIMM)
{
AcpiOsPrintf (
"\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
- DimmSubTable->Type);
+ DimmSubtable->Type);
return;
}
/* Dump the fixed-length DIMM subtable */
Status = AcpiDmDumpTable (Length,
- Offset + MemOffset + DimmOffset, DimmSubTable,
- DimmSubTable->Length, AcpiDmTableInfoPmtt2);
+ Offset + MemOffset + DimmOffset, DimmSubtable,
+ DimmSubtable->Length, AcpiDmTableInfoPmtt2);
if (ACPI_FAILURE (Status))
{
return;
@@ -3434,23 +3493,23 @@ AcpiDmDumpPmtt (
/* Point to next DIMM subtable */
- DimmOffset += DimmSubTable->Length;
- DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
- DimmSubTable, DimmSubTable->Length);
+ DimmOffset += DimmSubtable->Length;
+ DimmSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
+ DimmSubtable, DimmSubtable->Length);
}
/* Point to next Controller subtable */
- MemOffset += MemSubTable->Length;
- MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
- MemSubTable, MemSubTable->Length);
+ MemOffset += MemSubtable->Length;
+ MemSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
+ MemSubtable, MemSubtable->Length);
}
/* Point to next Socket subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
- SubTable, SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
+ Subtable, Subtable->Length);
}
}
@@ -3473,10 +3532,10 @@ AcpiDmDumpPptt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_SUBTABLE_HEADER *SubTable;
+ ACPI_SUBTABLE_HEADER *Subtable;
ACPI_PPTT_PROCESSOR *PpttProcessor;
UINT8 Length;
- UINT8 SubTableOffset;
+ UINT8 SubtableOffset;
UINT32 Offset = sizeof (ACPI_TABLE_FPDT);
ACPI_DMTABLE_INFO *InfoTable;
UINT32 i;
@@ -3493,20 +3552,20 @@ AcpiDmDumpPptt (
/* Common subtable header */
- SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
- if (SubTable->Length < sizeof (ACPI_SUBTABLE_HEADER))
+ Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
+ if (Subtable->Length < sizeof (ACPI_SUBTABLE_HEADER))
{
AcpiOsPrintf ("Invalid subtable length\n");
return;
}
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoPpttHdr);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoPpttHdr);
if (ACPI_FAILURE (Status))
{
return;
}
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_PPTT_TYPE_PROCESSOR:
@@ -3529,35 +3588,35 @@ AcpiDmDumpPptt (
default:
AcpiOsPrintf ("\n**** Unknown PPTT subtable type 0x%X\n\n",
- SubTable->Type);
+ Subtable->Type);
/* Attempt to continue */
- goto NextSubTable;
+ goto NextSubtable;
}
- if (SubTable->Length < Length)
+ if (Subtable->Length < Length)
{
AcpiOsPrintf ("Invalid subtable length\n");
return;
}
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
}
- SubTableOffset = Length;
+ SubtableOffset = Length;
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_PPTT_TYPE_PROCESSOR:
- PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, SubTable);
+ PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, Subtable);
/* Dump SMBIOS handles */
- if ((UINT8)(SubTable->Length - SubTableOffset) <
+ if ((UINT8)(Subtable->Length - SubtableOffset) <
(UINT8)(PpttProcessor->NumberOfPrivResources * 4))
{
AcpiOsPrintf ("Invalid private resource number\n");
@@ -3565,10 +3624,10 @@ AcpiDmDumpPptt (
}
for (i = 0; i < PpttProcessor->NumberOfPrivResources; i++)
{
- Status = AcpiDmDumpTable (Table->Length, Offset + SubTableOffset,
- ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTableOffset),
+ Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
+ ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
4, AcpiDmTableInfoPptt0a);
- SubTableOffset += 4;
+ SubtableOffset += 4;
}
break;
@@ -3577,10 +3636,10 @@ AcpiDmDumpPptt (
break;
}
-NextSubTable:
+NextSubtable:
/* Point to next subtable */
- Offset += SubTable->Length;
+ Offset += Subtable->Length;
}
}
@@ -3603,7 +3662,7 @@ AcpiDmDumpS3pt (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_S3PT);
- ACPI_FPDT_HEADER *SubTable;
+ ACPI_FPDT_HEADER *Subtable;
ACPI_DMTABLE_INFO *InfoTable;
ACPI_TABLE_S3PT *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
@@ -3616,20 +3675,20 @@ AcpiDmDumpS3pt (
return 0;
}
- SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset);
while (Offset < S3ptTable->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoS3ptHdr);
+ Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoS3ptHdr);
if (ACPI_FAILURE (Status))
{
return 0;
}
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_S3PT_TYPE_RESUME:
@@ -3644,31 +3703,31 @@ AcpiDmDumpS3pt (
default:
AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n",
- SubTable->Type);
+ Subtable->Type);
/* Attempt to continue */
- if (!SubTable->Length)
+ if (!Subtable->Length)
{
AcpiOsPrintf ("Invalid zero length subtable\n");
return 0;
}
- goto NextSubTable;
+ goto NextSubtable;
}
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return 0;
}
-NextSubTable:
+NextSubtable:
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable, SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable, Subtable->Length);
}
return (S3ptTable->Length);
@@ -3677,6 +3736,173 @@ NextSubTable:
/*******************************************************************************
*
+ * FUNCTION: AcpiDmDumpSdev
+ *
+ * PARAMETERS: Table - A SDEV table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a SDEV. This is a variable-length
+ * table that contains variable strings and vendor data.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpSdev (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_SDEV_HEADER *Subtable;
+ ACPI_SDEV_PCIE *Pcie;
+ ACPI_SDEV_NAMESPACE *Namesp;
+ ACPI_DMTABLE_INFO *InfoTable;
+ UINT32 Length = Table->Length;
+ UINT32 Offset = sizeof (ACPI_TABLE_SDEV);
+ UINT16 PathOffset;
+ UINT16 PathLength;
+ UINT16 VendorDataOffset;
+ UINT16 VendorDataLength;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoSdev);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Subtables */
+
+ Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Table, Offset);
+ while (Offset < Table->Length)
+ {
+ /* Common subtable header */
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoSdevHdr);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (Subtable->Type)
+ {
+ case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
+
+ InfoTable = AcpiDmTableInfoSdev0;
+ break;
+
+ case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
+
+ InfoTable = AcpiDmTableInfoSdev1;
+ break;
+
+ default:
+ goto NextSubtable;
+ }
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (Subtable->Type)
+ {
+ case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
+
+ /* Dump the PCIe device ID(s) */
+
+ Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable);
+ PathOffset = Namesp->DeviceIdOffset;
+ PathLength = Namesp->DeviceIdLength;
+
+ if (PathLength)
+ {
+ Status = AcpiDmDumpTable (Table->Length, 0,
+ ACPI_ADD_PTR (UINT8, Namesp, PathOffset),
+ PathLength, AcpiDmTableInfoSdev0a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+
+ /* Dump the vendor-specific data */
+
+ VendorDataLength =
+ Namesp->VendorDataLength;
+ VendorDataOffset =
+ Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
+
+ if (VendorDataLength)
+ {
+ Status = AcpiDmDumpTable (Table->Length, 0,
+ ACPI_ADD_PTR (UINT8, Namesp, VendorDataOffset),
+ VendorDataLength, AcpiDmTableInfoSdev1b);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+ break;
+
+ case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
+
+ /* PCI path substructures */
+
+ Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable);
+ PathOffset = Pcie->PathOffset;
+ PathLength = Pcie->PathLength;
+
+ while (PathLength)
+ {
+ Status = AcpiDmDumpTable (Table->Length,
+ PathOffset + Offset,
+ ACPI_ADD_PTR (UINT8, Pcie, PathOffset),
+ sizeof (ACPI_SDEV_PCIE_PATH), AcpiDmTableInfoSdev1a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ PathOffset += sizeof (ACPI_SDEV_PCIE_PATH);
+ PathLength -= sizeof (ACPI_SDEV_PCIE_PATH);
+ }
+
+ /* VendorData */
+
+ VendorDataLength = Pcie->VendorDataLength;
+ VendorDataOffset = Pcie->PathOffset + Pcie->PathLength;
+
+ if (VendorDataLength)
+ {
+ Status = AcpiDmDumpTable (Table->Length, 0,
+ ACPI_ADD_PTR (UINT8, Pcie, VendorDataOffset),
+ VendorDataLength, AcpiDmTableInfoSdev1b);
+ }
+ break;
+
+ default:
+ goto NextSubtable;
+ }
+
+NextSubtable:
+ /* Point to next subtable */
+
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Subtable,
+ Subtable->Length);
+ }
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiDmDumpSlic
*
* PARAMETERS: Table - A SLIC table
@@ -3794,7 +4020,7 @@ AcpiDmDumpSrat (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_SRAT);
- ACPI_SUBTABLE_HEADER *SubTable;
+ ACPI_SUBTABLE_HEADER *Subtable;
ACPI_DMTABLE_INFO *InfoTable;
@@ -3808,20 +4034,20 @@ AcpiDmDumpSrat (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Length, AcpiDmTableInfoSratHdr);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, AcpiDmTableInfoSratHdr);
if (ACPI_FAILURE (Status))
{
return;
}
- switch (SubTable->Type)
+ switch (Subtable->Type)
{
case ACPI_SRAT_TYPE_CPU_AFFINITY:
@@ -3850,32 +4076,32 @@ AcpiDmDumpSrat (
default:
AcpiOsPrintf ("\n**** Unknown SRAT subtable type 0x%X\n",
- SubTable->Type);
+ Subtable->Type);
/* Attempt to continue */
- if (!SubTable->Length)
+ if (!Subtable->Length)
{
AcpiOsPrintf ("Invalid zero length subtable\n");
return;
}
- goto NextSubTable;
+ goto NextSubtable;
}
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
- SubTable->Length, InfoTable);
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Subtable->Length, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
}
-NextSubTable:
+NextSubtable:
/* Point to next subtable */
- Offset += SubTable->Length;
- SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable,
- SubTable->Length);
+ Offset += Subtable->Length;
+ Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable,
+ Subtable->Length);
}
}
@@ -3954,7 +4180,7 @@ AcpiDmDumpTcpa (
UINT32 Offset = sizeof (ACPI_TABLE_TCPA_HDR);
ACPI_TABLE_TCPA_HDR *CommonHeader = ACPI_CAST_PTR (
ACPI_TABLE_TCPA_HDR, Table);
- ACPI_TABLE_TCPA_HDR *SubTable = ACPI_ADD_PTR (
+ ACPI_TABLE_TCPA_HDR *Subtable = ACPI_ADD_PTR (
ACPI_TABLE_TCPA_HDR, Table, Offset);
ACPI_STATUS Status;
@@ -3976,13 +4202,13 @@ AcpiDmDumpTcpa (
{
case ACPI_TCPA_CLIENT_TABLE:
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
Table->Length - Offset, AcpiDmTableInfoTcpaClient);
break;
case ACPI_TCPA_SERVER_TABLE:
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
Table->Length - Offset, AcpiDmTableInfoTcpaServer);
break;
@@ -4003,6 +4229,64 @@ AcpiDmDumpTcpa (
/*******************************************************************************
*
+ * FUNCTION: AcpiDmDumpTpm2
+ *
+ * PARAMETERS: Table - A TPM2 table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Format the contents of a TPM2.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpTpm2 (
+ ACPI_TABLE_HEADER *Table)
+{
+ UINT32 Offset = sizeof (ACPI_TABLE_TPM2);
+ ACPI_TABLE_TPM2 *CommonHeader = ACPI_CAST_PTR (ACPI_TABLE_TPM2, Table);
+ ACPI_TPM2_TRAILER *Subtable = ACPI_ADD_PTR (ACPI_TPM2_TRAILER, Table, Offset);
+ ACPI_TPM2_ARM_SMC *ArmSubtable;
+ ACPI_STATUS Status;
+
+
+ /* Main table */
+
+ Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoTpm2);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
+ Table->Length - Offset, AcpiDmTableInfoTpm2a);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ switch (CommonHeader->StartMethod)
+ {
+ case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
+
+ ArmSubtable = ACPI_ADD_PTR (ACPI_TPM2_ARM_SMC, Subtable,
+ sizeof (ACPI_TPM2_TRAILER));
+ Offset += sizeof (ACPI_TPM2_TRAILER);
+
+ AcpiOsPrintf ("\n");
+ Status = AcpiDmDumpTable (Table->Length, Offset, ArmSubtable,
+ Table->Length - Offset, AcpiDmTableInfoTpm211);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiDmDumpVrtc
*
* PARAMETERS: Table - A VRTC table
@@ -4019,7 +4303,7 @@ AcpiDmDumpVrtc (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_VRTC);
- ACPI_VRTC_ENTRY *SubTable;
+ ACPI_VRTC_ENTRY *Subtable;
/* Main table */
@@ -4032,13 +4316,13 @@ AcpiDmDumpVrtc (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
sizeof (ACPI_VRTC_ENTRY), AcpiDmTableInfoVrtc0);
if (ACPI_FAILURE (Status))
{
@@ -4048,7 +4332,7 @@ AcpiDmDumpVrtc (
/* Point to next subtable */
Offset += sizeof (ACPI_VRTC_ENTRY);
- SubTable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, SubTable,
+ Subtable = ACPI_ADD_PTR (ACPI_VRTC_ENTRY, Subtable,
sizeof (ACPI_VRTC_ENTRY));
}
}
@@ -4072,7 +4356,7 @@ AcpiDmDumpWdat (
{
ACPI_STATUS Status;
UINT32 Offset = sizeof (ACPI_TABLE_WDAT);
- ACPI_WDAT_ENTRY *SubTable;
+ ACPI_WDAT_ENTRY *Subtable;
/* Main table */
@@ -4085,13 +4369,13 @@ AcpiDmDumpWdat (
/* Subtables */
- SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset);
+ Subtable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset);
while (Offset < Table->Length)
{
/* Common subtable header */
AcpiOsPrintf ("\n");
- Status = AcpiDmDumpTable (Table->Length, Offset, SubTable,
+ Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0);
if (ACPI_FAILURE (Status))
{
@@ -4101,7 +4385,7 @@ AcpiDmDumpWdat (
/* Point to next subtable */
Offset += sizeof (ACPI_WDAT_ENTRY);
- SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, SubTable,
+ Subtable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Subtable,
sizeof (ACPI_WDAT_ENTRY));
}
}
@@ -4125,7 +4409,7 @@ AcpiDmDumpWpbt (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
- ACPI_TABLE_WPBT *SubTable;
+ ACPI_TABLE_WPBT *Subtable;
UINT32 Length = Table->Length;
UINT16 ArgumentsLength;
@@ -4140,8 +4424,8 @@ AcpiDmDumpWpbt (
/* Extract the arguments buffer length from the main table */
- SubTable = ACPI_CAST_PTR (ACPI_TABLE_WPBT, Table);
- ArgumentsLength = SubTable->ArgumentsLength;
+ Subtable = ACPI_CAST_PTR (ACPI_TABLE_WPBT, Table);
+ ArgumentsLength = Subtable->ArgumentsLength;
/* Dump the arguments buffer */
diff --git a/sys/contrib/dev/acpica/common/dmtbinfo.c b/sys/contrib/dev/acpica/common/dmtbinfo.c
index c487fcf..2702e61 100644
--- a/sys/contrib/dev/acpica/common/dmtbinfo.c
+++ b/sys/contrib/dev/acpica/common/dmtbinfo.c
@@ -214,11 +214,13 @@
#define ACPI_MSCT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MSCT,f)
#define ACPI_NFIT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_NFIT,f)
#define ACPI_PCCT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PCCT,f)
+#define ACPI_PDTT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PDTT,f)
#define ACPI_PMTT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PMTT,f)
#define ACPI_RASF_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_RASF,f)
#define ACPI_S3PT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_S3PT,f)
#define ACPI_SBST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SBST,f)
#define ACPI_SDEI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SDEI,f)
+#define ACPI_SDEV_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SDEV,f)
#define ACPI_SLIT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SLIT,f)
#define ACPI_SPCR_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPCR,f)
#define ACPI_SPMI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPMI,f)
@@ -334,11 +336,13 @@
#define ACPI_NFIT4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_CONTROL_REGION,f)
#define ACPI_NFIT5_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_DATA_REGION,f)
#define ACPI_NFIT6_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_FLUSH_ADDRESS,f)
+#define ACPI_NFIT7_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_NFIT_CAPABILITIES,f)
#define ACPI_PCCT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_SUBSPACE,f)
#define ACPI_PCCT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_HW_REDUCED,f)
#define ACPI_PCCT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_HW_REDUCED_TYPE2,f)
#define ACPI_PCCT3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_EXT_PCC_MASTER,f)
#define ACPI_PCCT4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_EXT_PCC_SLAVE,f)
+#define ACPI_PDTT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PDTT_CHANNEL,f)
#define ACPI_PMTT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_SOCKET,f)
#define ACPI_PMTT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_CONTROLLER,f)
#define ACPI_PMTT1A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_DOMAIN,f)
@@ -351,6 +355,10 @@
#define ACPI_S3PTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_FPDT_HEADER,f)
#define ACPI_S3PT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_RESUME,f)
#define ACPI_S3PT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_SUSPEND,f)
+#define ACPI_SDEVH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SDEV_HEADER,f)
+#define ACPI_SDEV0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SDEV_NAMESPACE,f)
+#define ACPI_SDEV1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SDEV_PCIE,f)
+#define ACPI_SDEV1A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SDEV_PCIE_PATH,f)
#define ACPI_SLIC_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SLIC,f)
#define ACPI_SRATH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f)
#define ACPI_SRAT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_CPU_AFFINITY,f)
@@ -360,6 +368,8 @@
#define ACPI_SRAT4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_GIC_ITS_AFFINITY,f)
#define ACPI_TCPA_CLIENT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA_CLIENT,f)
#define ACPI_TCPA_SERVER_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA_SERVER,f)
+#define ACPI_TPM2A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TPM2_TRAILER,f)
+#define ACPI_TPM211_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TPM2_ARM_SMC,f)
#define ACPI_VRTC0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_VRTC_ENTRY,f)
#define ACPI_WDAT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_WDAT_ENTRY,f)
@@ -410,12 +420,15 @@
#define ACPI_NFIT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_NFIT_SYSTEM_ADDRESS,f,o)
#define ACPI_NFIT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_NFIT_MEMORY_MAP,f,o)
#define ACPI_NFIT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_NFIT_CONTROL_REGION,f,o)
+#define ACPI_NFIT7_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_NFIT_CAPABILITIES,f,o)
#define ACPI_PCCT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_PCCT,f,o)
#define ACPI_PCCT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PCCT_HW_REDUCED,f,o)
#define ACPI_PCCT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PCCT_HW_REDUCED_TYPE2,f,o)
#define ACPI_PCCT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PCCT_EXT_PCC_MASTER,f,o)
#define ACPI_PCCT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PCCT_EXT_PCC_SLAVE,f,o)
+#define ACPI_PDTT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PDTT_CHANNEL,f,o)
#define ACPI_PMTTH_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PMTT_HEADER,f,o)
+#define ACPI_SDEVH_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SDEV_HEADER,f,o)
#define ACPI_WDDT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_WDDT,f,o)
#define ACPI_WSMT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_WSMT,f,o)
#define ACPI_EINJ0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_WHEA_HEADER,f,o)
@@ -896,7 +909,6 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt1[] =
ACPI_DMT_TERMINATOR
};
-
/* Resource Descriptor subtable */
ACPI_DMTABLE_INFO AcpiDmTableInfoCsrt2[] =
@@ -1260,6 +1272,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt1[] =
{ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ExitServicesExit), "Exit Services Exit", 0},
#endif
+
/*******************************************************************************
*
* GTDT - Generic Timer Description Table
@@ -1850,9 +1863,11 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoIort4[] =
{ACPI_DMT_UINT8, ACPI_IORT4_OFFSET (Pxm), "Proximity Domain", 0},
{ACPI_DMT_UINT8, ACPI_IORT4_OFFSET (Reserved1), "Reserved", 0},
{ACPI_DMT_UINT16, ACPI_IORT4_OFFSET (Reserved2), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_IORT4_OFFSET (IdMappingIndex), "Device ID Mapping Index", 0},
ACPI_DMT_TERMINATOR
};
+
/*******************************************************************************
*
* IVRS - I/O Virtualization Reporting Structure
@@ -2219,6 +2234,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt15[] =
ACPI_DMT_TERMINATOR
};
+
/*******************************************************************************
*
* MCFG - PCI Memory Mapped Configuration table and Subtable
@@ -2551,6 +2567,18 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6a[] =
ACPI_DMT_TERMINATOR
};
+ACPI_DMTABLE_INFO AcpiDmTableInfoNfit7[] =
+{
+ {ACPI_DMT_UINT8, ACPI_NFIT7_OFFSET (HighestCapability), "Highest Capability", 0},
+ {ACPI_DMT_UINT24, ACPI_NFIT7_OFFSET (Reserved[0]), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_NFIT7_OFFSET (Capabilities), "Capabilities (decoded below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_NFIT7_FLAG_OFFSET (Capabilities,0), "Cache Flush to NVDIMM", 0},
+ {ACPI_DMT_FLAG1, ACPI_NFIT7_FLAG_OFFSET (Capabilities,0), "Memory Flush to MVDIMM", 0},
+ {ACPI_DMT_FLAG2, ACPI_NFIT7_FLAG_OFFSET (Capabilities,0), "Memory Mirroring", 0},
+ {ACPI_DMT_UINT32, ACPI_NFIT7_OFFSET (Reserved2), "Reserved", 0},
+ ACPI_DMT_TERMINATOR
+};
+
/*******************************************************************************
*
@@ -2696,6 +2724,31 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPcct4[] =
ACPI_DMT_TERMINATOR
};
+
+/*******************************************************************************
+ *
+ * PDTT - Platform Debug Trigger Table (ACPI 6.2)
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt[] =
+{
+ {ACPI_DMT_UINT8, ACPI_PDTT_OFFSET (TriggerCount), "Trigger Count", 0},
+ {ACPI_DMT_UINT24, ACPI_PDTT_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_PDTT_OFFSET (ArrayOffset), "Array Offset", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt0[] =
+{
+ {ACPI_DMT_UINT8, ACPI_PDTT0_OFFSET (SubchannelId), "Subchannel Id", 0},
+ {ACPI_DMT_UINT8, ACPI_PDTT0_OFFSET (Flags), "Flags (Decoded Below)", DT_FLAG},
+ {ACPI_DMT_FLAG0, ACPI_PDTT0_FLAG_OFFSET (Flags,0), "Runtime Trigger", 0},
+ {ACPI_DMT_FLAG1, ACPI_PDTT0_FLAG_OFFSET (Flags,0), "Wait for Completion", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+
/*******************************************************************************
*
* PMTT - Platform Memory Topology Table
@@ -2768,16 +2821,6 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt2[] =
ACPI_DMT_TERMINATOR
};
-/*******************************************************************************
- *
- * SDEI - Software Delegated Execption Interface Descriptor Table
- *
- ******************************************************************************/
-
-ACPI_DMTABLE_INFO AcpiDmTableInfoSdei[] =
-{
- ACPI_DMT_TERMINATOR
-};
/*******************************************************************************
*
@@ -2801,7 +2844,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPpttHdr[] =
ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0[] =
{
{ACPI_DMT_UINT16, ACPI_PPTT0_OFFSET (Reserved), "Reserved", 0},
- {ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (Flags), "Flags (decoded below)", 0},
{ACPI_DMT_FLAG0, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "Physical package", 0},
{ACPI_DMT_FLAG1, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "ACPI Processor ID valid", 0},
{ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (Parent), "Parent", 0},
@@ -2821,14 +2864,14 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0a[] =
ACPI_DMTABLE_INFO AcpiDmTableInfoPptt1[] =
{
{ACPI_DMT_UINT16, ACPI_PPTT1_OFFSET (Reserved), "Reserved", 0},
- {ACPI_DMT_UINT32, ACPI_PPTT1_OFFSET (Flags), "Flags", 0},
+ {ACPI_DMT_UINT32, ACPI_PPTT1_OFFSET (Flags), "Flags (decoded below)", 0},
{ACPI_DMT_FLAG0, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Size valid", 0},
{ACPI_DMT_FLAG1, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Number of Sets valid", 0},
{ACPI_DMT_FLAG2, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Associativity valid", 0},
{ACPI_DMT_FLAG3, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Allocation Type valid", 0},
{ACPI_DMT_FLAG4, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Cache Type valid", 0},
{ACPI_DMT_FLAG5, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Write Policy valid", 0},
- {ACPI_DMT_FLAG5, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Line Size valid", 0},
+ {ACPI_DMT_FLAG6, ACPI_PPTT1_FLAG_OFFSET (Flags,0), "Line Size valid", 0},
{ACPI_DMT_UINT32, ACPI_PPTT1_OFFSET (NextLevelOfCache), "Next Level of Cache", 0},
{ACPI_DMT_UINT32, ACPI_PPTT1_OFFSET (Size), "Size", 0},
{ACPI_DMT_UINT32, ACPI_PPTT1_OFFSET (NumberOfSets), "Number of Sets", 0},
@@ -2855,6 +2898,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPptt2[] =
ACPI_DMT_TERMINATOR
};
+
/*******************************************************************************
*
* RASF - RAS Feature table
@@ -2867,6 +2911,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoRasf[] =
ACPI_DMT_TERMINATOR
};
+
/*******************************************************************************
*
* S3PT - S3 Performance Table
@@ -2927,6 +2972,86 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[] =
/*******************************************************************************
*
+ * SDEI - Software Delegated Execption Interface Descriptor Table
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSdei[] =
+{
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
+ * SDEV - Secure Devices Table (ACPI 6.2)
+ *
+ ******************************************************************************/
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSdev[] =
+{
+ ACPI_DMT_TERMINATOR
+};
+
+/* Common Subtable header (one per Subtable) */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSdevHdr[] =
+{
+ {ACPI_DMT_SDEV, ACPI_SDEVH_OFFSET (Type), "Subtable Type", 0},
+ {ACPI_DMT_UINT8, ACPI_SDEVH_OFFSET (Flags), "Flags (decoded below)", 0},
+ {ACPI_DMT_FLAG0, ACPI_SDEVH_FLAG_OFFSET (Flags,0), "Allow handoff to unsecure OS", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEVH_OFFSET (Length), "Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* SDEV Subtables */
+
+/* 0: Namespace Device Based Secure Device Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSdev0[] =
+{
+ {ACPI_DMT_UINT16, ACPI_SDEV0_OFFSET (DeviceIdOffset), "Device ID Offset", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEV0_OFFSET (DeviceIdLength), "Device ID Length", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEV0_OFFSET (VendorDataOffset), "Vendor Data Offset", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEV0_OFFSET (VendorDataLength), "Vendor Data Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSdev0a[] =
+{
+ {ACPI_DMT_STRING, 0, "Namepath", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 1: PCIe Endpoint Device Based Device Structure */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1[] =
+{
+ {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (Segment), "Segment", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (StartBus), "Start Bus", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (PathOffset), "Path Offset", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (PathLength), "Path Length", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (VendorDataOffset), "Vendor Data Offset", 0},
+ {ACPI_DMT_UINT16, ACPI_SDEV1_OFFSET (VendorDataLength), "Vendor Data Length", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1a[] =
+{
+ {ACPI_DMT_UINT8, ACPI_SDEV1A_OFFSET (Device), "Device", 0},
+ {ACPI_DMT_UINT8, ACPI_SDEV1A_OFFSET (Function), "Function", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1b[] =
+{
+ {ACPI_DMT_RAW_BUFFER, 0, "Vendor Data", 0}, /*, DT_OPTIONAL}, */
+ ACPI_DMT_TERMINATOR
+};
+
+
+/*******************************************************************************
+ *
* SLIC - Software Licensing Description Table. This table contains the standard
* ACPI header followed by proprietary data structures
*
@@ -3186,7 +3311,29 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2[] =
{ACPI_DMT_UINT16, ACPI_TPM2_OFFSET (PlatformClass), "Platform Class", 0},
{ACPI_DMT_UINT16, ACPI_TPM2_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT64, ACPI_TPM2_OFFSET (ControlAddress), "Control Address", 0},
- {ACPI_DMT_UINT32, ACPI_TPM2_OFFSET (StartMethod), "Start Method", 0},
+ {ACPI_DMT_TPM2, ACPI_TPM2_OFFSET (StartMethod), "Start Method", 0},
+ ACPI_DMT_TERMINATOR
+};
+
+/* Optional trailer. LogLength and LogAddress are additionally optional */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2a[] =
+{
+ {ACPI_DMT_BUF12, ACPI_TPM2A_OFFSET (MethodParameters), "Method Parameters", DT_OPTIONAL},
+ {ACPI_DMT_UINT32, ACPI_TPM2A_OFFSET (MinimumLogLength), "Minimum Log Length", DT_OPTIONAL},
+ {ACPI_DMT_UINT64, ACPI_TPM2A_OFFSET (LogAddress), "Log Address", DT_OPTIONAL},
+ ACPI_DMT_TERMINATOR
+};
+
+/* 11: Start Method for ARM SMC */
+
+ACPI_DMTABLE_INFO AcpiDmTableInfoTpm211[] =
+{
+ {ACPI_DMT_UINT32, ACPI_TPM211_OFFSET (GlobalInterrupt), "Global Interrupt", 0},
+ {ACPI_DMT_UINT8, ACPI_TPM211_OFFSET (InterruptFlags), "Interrupt Flags", 0},
+ {ACPI_DMT_UINT8, ACPI_TPM211_OFFSET (OperationFlags), "Operation Flags", 0},
+ {ACPI_DMT_UINT16, ACPI_TPM211_OFFSET (Reserved), "Reserved", 0},
+ {ACPI_DMT_UINT32, ACPI_TPM211_OFFSET (FunctionId), "Function ID", 0},
ACPI_DMT_TERMINATOR
};
diff --git a/sys/contrib/dev/acpica/compiler/aslallocate.c b/sys/contrib/dev/acpica/compiler/aslallocate.c
new file mode 100644
index 0000000..e83a01f
--- /dev/null
+++ b/sys/contrib/dev/acpica/compiler/aslallocate.c
@@ -0,0 +1,303 @@
+/******************************************************************************
+ *
+ * Module Name: aslallocate -- Local memory allocation
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights. You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code. No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision. In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change. Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee. Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution. In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government. In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************
+ *
+ * Alternatively, you may choose to be licensed under the terms of the
+ * following license:
+ *
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ *
+ * Alternatively, you may choose to be licensed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ *****************************************************************************/
+
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+
+/*
+ * Local heap allocation wrappers. See aslcache.c for allocation from local
+ * cache alloctions
+ */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtLocalCalloc
+ *
+ * PARAMETERS: Size - Bytes to be allocated
+ *
+ * RETURN: Pointer to the allocated memory. If this function returns
+ * (the compiler is not aborted), the pointer is guaranteed to
+ * be valid.
+ *
+ * DESCRIPTION: Allocate zero-initialized memory. The point of this function
+ * is to abort the compile on an allocation failure, on the
+ * assumption that nothing more can be accomplished.
+ *
+ * NOTE: For allocation from the local caches, see aslcache.c
+ *
+ ******************************************************************************/
+
+void *
+UtLocalCalloc (
+ UINT32 Size)
+{
+ void *Allocated;
+
+
+ Allocated = ACPI_ALLOCATE_ZEROED (Size);
+ if (!Allocated)
+ {
+ AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
+ Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
+ Gbl_InputByteCount, Gbl_CurrentColumn,
+ Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
+
+ CmCleanupAndExit ();
+ exit (1);
+ }
+
+ TotalAllocations++;
+ TotalAllocated += Size;
+ return (Allocated);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: UtExpandLineBuffers
+ *
+ * PARAMETERS: None. Updates global line buffer pointers.
+ *
+ * RETURN: None. Reallocates the global line buffers
+ *
+ * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates
+ * all global line buffers and updates Gbl_LineBufferSize. NOTE:
+ * Also used for the initial allocation of the buffers, when
+ * all of the buffer pointers are NULL. Initial allocations are
+ * of size ASL_DEFAULT_LINE_BUFFER_SIZE
+ *
+ *****************************************************************************/
+
+void
+UtExpandLineBuffers (
+ void)
+{
+ UINT32 NewSize;
+
+
+ /* Attempt to double the size of all line buffers */
+
+ NewSize = Gbl_LineBufferSize * 2;
+ if (Gbl_CurrentLineBuffer)
+ {
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "Increasing line buffer size from %u to %u\n",
+ Gbl_LineBufferSize, NewSize);
+ }
+
+ UtReallocLineBuffers (&Gbl_CurrentLineBuffer, Gbl_LineBufferSize, NewSize);
+ UtReallocLineBuffers (&Gbl_MainTokenBuffer, Gbl_LineBufferSize, NewSize);
+ UtReallocLineBuffers (&Gbl_MacroTokenBuffer, Gbl_LineBufferSize, NewSize);
+ UtReallocLineBuffers (&Gbl_ExpressionTokenBuffer, Gbl_LineBufferSize, NewSize);
+
+ Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
+ Gbl_LineBufferSize = NewSize;
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: UtReallocLineBuffers
+ *
+ * PARAMETERS: Buffer - Buffer to realloc
+ * OldSize - Old size of Buffer
+ * NewSize - New size of Buffer
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Reallocate and initialize Buffer
+ *
+ *****************************************************************************/
+
+void
+UtReallocLineBuffers (
+ char **Buffer,
+ UINT32 OldSize,
+ UINT32 NewSize)
+{
+
+ *Buffer = realloc (*Buffer, NewSize);
+ if (*Buffer)
+ {
+ memset (*Buffer + OldSize, 0, NewSize - OldSize);
+ return;
+ }
+
+ printf ("Could not increase line buffer size from %u to %u\n",
+ OldSize, NewSize);
+
+ AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, NULL, NULL);
+ AslAbort ();
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: UtFreeLineBuffers
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Free all line buffers
+ *
+ *****************************************************************************/
+
+void
+UtFreeLineBuffers (
+ void)
+{
+
+ free (Gbl_CurrentLineBuffer);
+ free (Gbl_MainTokenBuffer);
+ free (Gbl_MacroTokenBuffer);
+ free (Gbl_ExpressionTokenBuffer);
+}
diff --git a/sys/contrib/dev/acpica/compiler/aslcache.c b/sys/contrib/dev/acpica/compiler/aslcache.c
new file mode 100644
index 0000000..1e54a2f
--- /dev/null
+++ b/sys/contrib/dev/acpica/compiler/aslcache.c
@@ -0,0 +1,481 @@
+/******************************************************************************
+ *
+ * Module Name: aslcache -- Local cache support for iASL
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights. You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code. No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision. In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change. Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee. Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution. In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government. In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************
+ *
+ * Alternatively, you may choose to be licensed under the terms of the
+ * following license:
+ *
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ *
+ * Alternatively, you may choose to be licensed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ *****************************************************************************/
+
+#include <contrib/dev/acpica/compiler/aslcompiler.h>
+
+/*
+ * Local caches. The caches are fully deleted after the compilation/disassembly
+ * of each individual input file. Thus, individual allocations from the cache
+ * memory do not need to be freed or even released back into the cache.
+ *
+ * See aslallocate.c for standard heap allocations.
+ */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtLocalCacheCalloc
+ *
+ * PARAMETERS: Length - Size of buffer requested
+ *
+ * RETURN: Pointer to the buffer. Aborts compiler on allocation failure
+ *
+ * DESCRIPTION: Allocate a string buffer. Bypass the local
+ * dynamic memory manager for performance reasons (This has a
+ * major impact on the speed of the compiler.)
+ *
+ ******************************************************************************/
+
+char *
+UtLocalCacheCalloc (
+ UINT32 Length)
+{
+ char *Buffer;
+ ASL_CACHE_INFO *Cache;
+ UINT32 CacheSize = ASL_STRING_CACHE_SIZE;
+
+
+ if (Length > CacheSize)
+ {
+ CacheSize = Length;
+
+ if (Gbl_StringCacheList)
+ {
+ Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
+
+ /* Link new cache buffer just following head of list */
+
+ Cache->Next = Gbl_StringCacheList->Next;
+ Gbl_StringCacheList->Next = Cache;
+
+ /* Leave cache management pointers alone as they pertain to head */
+
+ Gbl_StringCount++;
+ Gbl_StringSize += Length;
+
+ return (Cache->Buffer);
+ }
+ }
+
+ if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
+ {
+ /* Allocate a new buffer */
+
+ Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
+
+ /* Link new cache buffer to head of list */
+
+ Cache->Next = Gbl_StringCacheList;
+ Gbl_StringCacheList = Cache;
+
+ /* Setup cache management pointers */
+
+ Gbl_StringCacheNext = Cache->Buffer;
+ Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize;
+ }
+
+ Gbl_StringCount++;
+ Gbl_StringSize += Length;
+
+ Buffer = Gbl_StringCacheNext;
+ Gbl_StringCacheNext += Length;
+ return (Buffer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtParseOpCacheCalloc
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: New parse op. Aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate a new parse op for the parse tree. Bypass the local
+ * dynamic memory manager for performance reasons (This has a
+ * major impact on the speed of the compiler.)
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT *
+UtParseOpCacheCalloc (
+ void)
+{
+ ASL_CACHE_INFO *Cache;
+
+
+ if (Gbl_ParseOpCacheNext >= Gbl_ParseOpCacheLast)
+ {
+ /* Allocate a new buffer */
+
+ Cache = UtLocalCalloc (sizeof (Cache->Next) +
+ (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE));
+
+ /* Link new cache buffer to head of list */
+
+ Cache->Next = Gbl_ParseOpCacheList;
+ Gbl_ParseOpCacheList = Cache;
+
+ /* Setup cache management pointers */
+
+ Gbl_ParseOpCacheNext = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Cache->Buffer);
+ Gbl_ParseOpCacheLast = Gbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE;
+ }
+
+ Gbl_ParseOpCount++;
+ return (Gbl_ParseOpCacheNext++);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtSubtableCacheCalloc - Data Table compiler
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Pointer to the buffer. Aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate a subtable object buffer. Bypass the local
+ * dynamic memory manager for performance reasons (This has a
+ * major impact on the speed of the compiler.)
+ *
+ ******************************************************************************/
+
+DT_SUBTABLE *
+UtSubtableCacheCalloc (
+ void)
+{
+ ASL_CACHE_INFO *Cache;
+
+
+ if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast)
+ {
+ /* Allocate a new buffer */
+
+ Cache = UtLocalCalloc (sizeof (Cache->Next) +
+ (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE));
+
+ /* Link new cache buffer to head of list */
+
+ Cache->Next = Gbl_SubtableCacheList;
+ Gbl_SubtableCacheList = Cache;
+
+ /* Setup cache management pointers */
+
+ Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer);
+ Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE;
+ }
+
+ Gbl_SubtableCount++;
+ return (Gbl_SubtableCacheNext++);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtFieldCacheCalloc - Data Table compiler
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Pointer to the buffer. Aborts on allocation failure
+ *
+ * DESCRIPTION: Allocate a field object buffer. Bypass the local
+ * dynamic memory manager for performance reasons (This has a
+ * major impact on the speed of the compiler.)
+ *
+ ******************************************************************************/
+
+DT_FIELD *
+UtFieldCacheCalloc (
+ void)
+{
+ ASL_CACHE_INFO *Cache;
+
+
+ if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast)
+ {
+ /* Allocate a new buffer */
+
+ Cache = UtLocalCalloc (sizeof (Cache->Next) +
+ (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE));
+
+ /* Link new cache buffer to head of list */
+
+ Cache->Next = Gbl_FieldCacheList;
+ Gbl_FieldCacheList = Cache;
+
+ /* Setup cache management pointers */
+
+ Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer);
+ Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE;
+ }
+
+ Gbl_FieldCount++;
+ return (Gbl_FieldCacheNext++);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: UtDeleteLocalCaches
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete all local cache buffer blocks
+ *
+ ******************************************************************************/
+
+void
+UtDeleteLocalCaches (
+ void)
+{
+ UINT32 BufferCount;
+ ASL_CACHE_INFO *Next;
+
+
+ /*
+ * Generic cache, arbitrary size allocations
+ */
+ BufferCount = 0;
+ while (Gbl_StringCacheList)
+ {
+ Next = Gbl_StringCacheList->Next;
+ ACPI_FREE (Gbl_StringCacheList);
+ Gbl_StringCacheList = Next;
+ BufferCount++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n",
+ Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount);
+
+ /* Reset cache globals */
+
+ Gbl_StringSize = 0;
+ Gbl_StringCount = 0;
+ Gbl_StringCacheNext = NULL;
+ Gbl_StringCacheLast = NULL;
+
+
+ /*
+ * Parse Op cache
+ */
+ BufferCount = 0;
+ while (Gbl_ParseOpCacheList)
+ {
+ Next = Gbl_ParseOpCacheList->Next;
+ ACPI_FREE (Gbl_ParseOpCacheList);
+ Gbl_ParseOpCacheList = Next;
+ BufferCount++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n",
+ Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE,
+ (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount);
+
+ /* Reset cache globals */
+
+ Gbl_ParseOpCount = 0;
+ Gbl_ParseOpCacheNext = NULL;
+ Gbl_ParseOpCacheLast = NULL;
+ Gbl_ParseTreeRoot = NULL;
+
+
+ /*
+ * Table Compiler - Field cache
+ */
+ BufferCount = 0;
+ while (Gbl_FieldCacheList)
+ {
+ Next = Gbl_FieldCacheList->Next;
+ ACPI_FREE (Gbl_FieldCacheList);
+ Gbl_FieldCacheList = Next;
+ BufferCount++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n",
+ Gbl_FieldCount, ASL_FIELD_CACHE_SIZE,
+ (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount);
+
+ /* Reset cache globals */
+
+ Gbl_FieldCount = 0;
+ Gbl_FieldCacheNext = NULL;
+ Gbl_FieldCacheLast = NULL;
+
+
+ /*
+ * Table Compiler - Subtable cache
+ */
+ BufferCount = 0;
+ while (Gbl_SubtableCacheList)
+ {
+ Next = Gbl_SubtableCacheList->Next;
+ ACPI_FREE (Gbl_SubtableCacheList);
+ Gbl_SubtableCacheList = Next;
+ BufferCount++;
+ }
+
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n",
+ Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE,
+ (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount);
+
+ /* Reset cache globals */
+
+ Gbl_SubtableCount = 0;
+ Gbl_SubtableCacheNext = NULL;
+ Gbl_SubtableCacheLast = NULL;
+}
diff --git a/sys/contrib/dev/acpica/compiler/aslcodegen.c b/sys/contrib/dev/acpica/compiler/aslcodegen.c
index d875f5e..13def09 100644
--- a/sys/contrib/dev/acpica/compiler/aslcodegen.c
+++ b/sys/contrib/dev/acpica/compiler/aslcodegen.c
@@ -370,7 +370,7 @@ CgWriteAmlOpcode (
* Before printing the bytecode, generate comment byte codes
* associated with this node.
*/
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
CgWriteAmlComment(Op);
}
@@ -550,13 +550,13 @@ CgWriteTableHeader (
* "XXXX" table signature prevents this AML file from running on the AML
* interpreter.
*/
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
- strncpy(AcpiGbl_TableSig, Child->Asl.Value.String, 4);
+ strncpy(AcpiGbl_TableSig, Child->Asl.Value.String, ACPI_NAME_SIZE);
Child->Asl.Value.String = ACPI_SIG_XXXX;
}
- strncpy (TableHeader.Signature, Child->Asl.Value.String, 4);
+ strncpy (TableHeader.Signature, Child->Asl.Value.String, ACPI_NAME_SIZE);
/* Revision */
@@ -573,12 +573,12 @@ CgWriteTableHeader (
/* OEMID */
Child = Child->Asl.Next;
- strncpy (TableHeader.OemId, Child->Asl.Value.String, 6);
+ strncpy (TableHeader.OemId, Child->Asl.Value.String, ACPI_OEM_ID_SIZE);
/* OEM TableID */
Child = Child->Asl.Next;
- strncpy (TableHeader.OemTableId, Child->Asl.Value.String, 8);
+ strncpy (TableHeader.OemTableId, Child->Asl.Value.String, ACPI_OEM_TABLE_ID_SIZE);
/* OEM Revision */
@@ -600,7 +600,7 @@ CgWriteTableHeader (
/* Calculate the comment lengths for this definition block parseOp */
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
CvDbgPrint ("Calculating comment lengths for %s in write header\n",
Op->Asl.ParseOpName);
@@ -756,7 +756,8 @@ CgWriteNode (
/* Write all comments here. */
- if (Gbl_CaptureComments)
+
+ if (AcpiGbl_CaptureComments)
{
CgWriteAmlComment(Op);
}
@@ -822,7 +823,7 @@ CgWriteNode (
case PARSEOP_DEFINITION_BLOCK:
CgWriteTableHeader (Op);
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
CgWriteAmlDefBlockComment (Op);
}
diff --git a/sys/contrib/dev/acpica/compiler/aslcompile.c b/sys/contrib/dev/acpica/compiler/aslcompile.c
index 5bd460d..2f2a1b2 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompile.c
+++ b/sys/contrib/dev/acpica/compiler/aslcompile.c
@@ -150,7 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#include <contrib/dev/acpica/include/acnamesp.h>
#include <stdio.h>
@@ -470,7 +469,7 @@ CmDoCompile (
* node during compilation. We take the very last comment and save it in a
* global for it to be used by the disassembler.
*/
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
AcpiGbl_LastListHead = Gbl_ParseTreeRoot->Asl.CommentList;
Gbl_ParseTreeRoot->Asl.CommentList = NULL;
@@ -932,70 +931,7 @@ CmCleanupAndExit (
if (!Gbl_DoAslConversion)
{
- CmDeleteCaches ();
+ UtDeleteLocalCaches ();
}
}
-
-
-/*******************************************************************************
- *
- * FUNCTION: CmDeleteCaches
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Delete all local cache buffer blocks
- *
- ******************************************************************************/
-
-void
-CmDeleteCaches (
- void)
-{
- UINT32 BufferCount;
- ASL_CACHE_INFO *Next;
-
-
- /* Parse Op cache */
-
- BufferCount = 0;
- while (Gbl_ParseOpCacheList)
- {
- Next = Gbl_ParseOpCacheList->Next;
- ACPI_FREE (Gbl_ParseOpCacheList);
- Gbl_ParseOpCacheList = Next;
- BufferCount++;
- }
-
- DbgPrint (ASL_DEBUG_OUTPUT,
- "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n",
- Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE,
- (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount);
-
- Gbl_ParseOpCount = 0;
- Gbl_ParseOpCacheNext = NULL;
- Gbl_ParseOpCacheLast = NULL;
- Gbl_ParseTreeRoot = NULL;
-
- /* Generic string cache */
-
- BufferCount = 0;
- while (Gbl_StringCacheList)
- {
- Next = Gbl_StringCacheList->Next;
- ACPI_FREE (Gbl_StringCacheList);
- Gbl_StringCacheList = Next;
- BufferCount++;
- }
-
- DbgPrint (ASL_DEBUG_OUTPUT,
- "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n",
- Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount);
-
- Gbl_StringSize = 0;
- Gbl_StringCount = 0;
- Gbl_StringCacheNext = NULL;
- Gbl_StringCacheLast = NULL;
-}
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.h b/sys/contrib/dev/acpica/compiler/aslcompiler.h
index 05069ec..96bfc97 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.h
@@ -181,6 +181,7 @@
#include <contrib/dev/acpica/compiler/aslmessages.h>
#include <contrib/dev/acpica/compiler/aslglobal.h>
#include <contrib/dev/acpica/compiler/preprocess.h>
+#include <contrib/dev/acpica/compiler/dtcompiler.h>
/*******************************************************************************
@@ -265,8 +266,50 @@ void
CmCleanupAndExit (
void);
+
+/*
+ * aslallocate - memory allocation
+ */
+void *
+UtLocalCalloc (
+ UINT32 Size);
+
+void
+UtExpandLineBuffers (
+ void);
+
+void
+UtReallocLineBuffers (
+ char **Buffer,
+ UINT32 OldSize,
+ UINT32 NewSize);
+
+void
+UtFreeLineBuffers (
+ void);
+
+
+/*
+ * aslcache - local cache support
+ */
+char *
+UtLocalCacheCalloc (
+ UINT32 Length);
+
+ACPI_PARSE_OBJECT *
+UtParseOpCacheCalloc (
+ void);
+
+DT_SUBTABLE *
+UtSubtableCacheCalloc (
+ void);
+
+DT_FIELD *
+UtFieldCacheCalloc (
+ void);
+
void
-CmDeleteCaches (
+UtDeleteLocalCaches (
void);
@@ -407,6 +450,16 @@ AslAbort (
void);
void
+AslDualParseOpError (
+ UINT8 Level,
+ UINT16 MainMessageId,
+ ACPI_PARSE_OBJECT *MainOp,
+ char *MainMessage,
+ UINT16 SecondMessageId,
+ ACPI_PARSE_OBJECT *SecondOp,
+ char *SecondaryMessage);
+
+void
AslError (
UINT8 Level,
UINT16 MessageId,
@@ -890,6 +943,11 @@ void
TrSetOpCurrentFilename (
ACPI_PARSE_OBJECT *Op);
+void
+TrSetOpIntegerWidth (
+ ACPI_PARSE_OBJECT *TableSignature,
+ ACPI_PARSE_OBJECT *Revision);
+
ACPI_PARSE_OBJECT *
TrLinkOpChildren (
ACPI_PARSE_OBJECT *Op,
@@ -1145,10 +1203,6 @@ void
UtEndEvent (
UINT8 Event);
-void *
-UtLocalCalloc (
- UINT32 Size);
-
void
UtDisplaySummary (
UINT32 FileId);
@@ -1171,18 +1225,6 @@ void
UtSetParseOpName (
ACPI_PARSE_OBJECT *Op);
-char *
-UtStringCacheCalloc (
- UINT32 Length);
-
-void
-UtExpandLineBuffers (
- void);
-
-void
-UtFreeLineBuffers (
- void);
-
ACPI_STATUS
UtInternalizeName (
char *ExternalName,
diff --git a/sys/contrib/dev/acpica/compiler/aslcompiler.l b/sys/contrib/dev/acpica/compiler/aslcompiler.l
index d65968e..38fe15a 100644
--- a/sys/contrib/dev/acpica/compiler/aslcompiler.l
+++ b/sys/contrib/dev/acpica/compiler/aslcompiler.l
@@ -195,6 +195,7 @@ count (int type);
LeadNameChar [A-Za-z_]
DigitChar [0-9]
+OctalChar [0-7]
HexDigitChar [A-Fa-f0-9]
RootChar [\\]
Nothing []
@@ -278,8 +279,7 @@ NamePathTail [.]{NameSeg}
/*
* Begin standard ASL grammar
*/
-0[xX]{HexDigitChar}+ |
-{DigitChar}+ { AslCompilerlval.i = UtDoConstant ((char *) AslCompilertext);
+[0-9][a-zA-Z0-9]* { AslCompilerlval.i = UtDoConstant ((char *) AslCompilertext);
count (1); return (PARSEOP_INTEGER); }
"Include" { count (1); return (PARSEOP_INCLUDE); }
@@ -813,7 +813,7 @@ NamePathTail [.]{NameSeg}
{NameSeg} { char *s;
count (0);
- s=UtStringCacheCalloc (ACPI_NAME_SIZE + 1);
+ s=UtLocalCacheCalloc (ACPI_NAME_SIZE + 1);
if (strcmp (AslCompilertext, "\\"))
{
strcpy (s, "____");
@@ -826,7 +826,7 @@ NamePathTail [.]{NameSeg}
{NameString} { char *s;
count (0);
- s=UtStringCacheCalloc (strlen (AslCompilertext)+1);
+ s=UtLocalCacheCalloc (strlen (AslCompilertext)+1);
AcpiUtStrupr (AslCompilertext);
strcpy (s, AslCompilertext);
AslCompilerlval.s = s;
diff --git a/sys/contrib/dev/acpica/compiler/asldebug.c b/sys/contrib/dev/acpica/compiler/asldebug.c
index 3824a45..42a0736 100644
--- a/sys/contrib/dev/acpica/compiler/asldebug.c
+++ b/sys/contrib/dev/acpica/compiler/asldebug.c
@@ -165,6 +165,10 @@ UtDumpParseOpName (
UINT32 Level,
UINT32 DataLength);
+static char *
+UtCreateEscapeSequences (
+ char *InString);
+
/*******************************************************************************
*
@@ -188,7 +192,7 @@ CvDbgPrint (
va_list Args;
- if (!Gbl_CaptureComments || !AcpiGbl_DebugAslConversion)
+ if (!AcpiGbl_CaptureComments || !AcpiGbl_DebugAslConversion)
{
return;
}
@@ -272,7 +276,6 @@ UtDumpStringOp (
String = Op->Asl.Value.String;
-
if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)
{
/*
@@ -294,6 +297,8 @@ UtDumpStringOp (
return;
}
+ String = UtCreateEscapeSequences (String);
+
/* Emit the ParseOp name, leaving room for the string */
UtDumpParseOpName (Op, Level, strlen (String));
@@ -303,6 +308,86 @@ UtDumpStringOp (
/*******************************************************************************
*
+ * FUNCTION: UtCreateEscapeSequences
+ *
+ * PARAMETERS: InString - ASCII string to be expanded
+ *
+ * RETURN: Expanded string
+ *
+ * DESCRIPTION: Expand all non-printable ASCII bytes (0-0x1F) to escape
+ * sequences. For example, hex 14 becomes \x14
+ *
+ * NOTE: Since this function is used for debug output only, it does
+ * not attempt to translate into the "known" escape sequences
+ * such as \a, \f, \t, etc.
+ *
+ ******************************************************************************/
+
+static char *
+UtCreateEscapeSequences (
+ char *InString)
+{
+ char *String = InString;
+ char *OutString;
+ char *OutStringPtr;
+ UINT32 InStringLength = 0;
+ UINT32 EscapeCount = 0;
+
+
+ /*
+ * Determine up front how many escapes are within the string.
+ * Obtain the input string length while doing so.
+ */
+ while (*String)
+ {
+ if ((*String <= 0x1F) || (*String >= 0x7F))
+ {
+ EscapeCount++;
+ }
+
+ InStringLength++;
+ String++;
+ }
+
+ if (!EscapeCount)
+ {
+ return (InString); /* No escapes, nothing to do */
+ }
+
+ /* New string buffer, 3 extra chars per escape (4 total) */
+
+ OutString = UtLocalCacheCalloc (InStringLength + (EscapeCount * 3));
+ OutStringPtr = OutString;
+
+ /* Convert non-ascii or non-printable chars to escape sequences */
+
+ while (*InString)
+ {
+ if ((*InString <= 0x1F) || (*InString >= 0x7F))
+ {
+ /* Insert a \x hex escape sequence */
+
+ OutStringPtr[0] = '\\';
+ OutStringPtr[1] = 'x';
+ OutStringPtr[2] = AcpiUtHexToAsciiChar (*InString, 4);
+ OutStringPtr[3] = AcpiUtHexToAsciiChar (*InString, 0);
+ OutStringPtr += 4;
+ }
+ else /* Normal ASCII character */
+ {
+ *OutStringPtr = *InString;
+ OutStringPtr++;
+ }
+
+ InString++;
+ }
+
+ return (OutString);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: UtDumpBasicOp
*
* PARAMETERS: Op - Current parse op
diff --git a/sys/contrib/dev/acpica/compiler/asldefine.h b/sys/contrib/dev/acpica/compiler/asldefine.h
index a7d1a28..bcdc8c2 100644
--- a/sys/contrib/dev/acpica/compiler/asldefine.h
+++ b/sys/contrib/dev/acpica/compiler/asldefine.h
@@ -162,7 +162,7 @@
#define ASL_CREATOR_ID "INTL"
#define ASL_DEFINE "__IASL__"
#define ASL_PREFIX "iASL: "
-#define ASL_COMPLIANCE "Supports ACPI Specification Revision 6.2"
+#define ASL_COMPLIANCE "Supports ACPI Specification Revision 6.2A"
/* Configuration constants */
diff --git a/sys/contrib/dev/acpica/compiler/aslerror.c b/sys/contrib/dev/acpica/compiler/aslerror.c
index 43696d9..f8c6c98 100644
--- a/sys/contrib/dev/acpica/compiler/aslerror.c
+++ b/sys/contrib/dev/acpica/compiler/aslerror.c
@@ -170,6 +170,37 @@ AslIsExceptionDisabled (
UINT8 Level,
UINT16 MessageId);
+static void AslInitEnode (
+ ASL_ERROR_MSG **Enode,
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 LineNumber,
+ UINT32 LogicalLineNumber,
+ UINT32 LogicalByteOffset,
+ UINT32 Column,
+ char *Filename,
+ char *Message,
+ char *SourceLine,
+ ASL_ERROR_MSG *SubError);
+
+static void
+AslLogNewError (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 LineNumber,
+ UINT32 LogicalLineNumber,
+ UINT32 LogicalByteOffset,
+ UINT32 Column,
+ char *Filename,
+ char *Message,
+ char *SourceLine,
+ ASL_ERROR_MSG *SubError);
+
+static void
+AePrintSubError (
+ FILE *OutputFile,
+ ASL_ERROR_MSG *Enode);
+
/*******************************************************************************
*
@@ -220,6 +251,7 @@ AeClearErrorLog (
ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
ASL_ERROR_MSG *Next;
+
/* Walk the error node list */
while (Enode)
@@ -270,8 +302,7 @@ AeAddToErrorLog (
Prev = NULL;
Next = Gbl_ErrorLog;
- while ((Next) &&
- (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
+ while ((Next) && (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
{
Prev = Next;
Next = Next->Next;
@@ -294,94 +325,143 @@ AeAddToErrorLog (
/*******************************************************************************
*
- * FUNCTION: AePrintException
+ * FUNCTION: AeDecodeErrorMessageId
*
- * PARAMETERS: FileId - ID of output file
+ * PARAMETERS: OutputFile - Output file
* Enode - Error node to print
- * Header - Additional text before each message
+ * PrematureEOF - True = PrematureEOF has been reached
+ * Total - Total legth of line
*
* RETURN: None
*
- * DESCRIPTION: Print the contents of an error node.
- *
- * NOTE: We don't use the FlxxxFile I/O functions here because on error
- * they abort the compiler and call this function! Since we
- * are reporting errors here, we ignore most output errors and
- * just try to get out as much as we can.
+ * DESCRIPTION: Print the source line of an error.
*
******************************************************************************/
-void
-AePrintException (
- UINT32 FileId,
+static void
+AeDecodeErrorMessageId (
+ FILE *OutputFile,
ASL_ERROR_MSG *Enode,
- char *Header)
+ BOOLEAN PrematureEOF,
+ UINT32 Total)
{
- UINT8 SourceByte;
- int Actual;
- size_t RActual;
UINT32 MsgLength;
const char *MainMessage;
char *ExtraMessage;
UINT32 SourceColumn;
UINT32 ErrorColumn;
- FILE *OutputFile;
- FILE *SourceFile = NULL;
- long FileSize;
- BOOLEAN PrematureEOF = FALSE;
- UINT32 Total = 0;
- if (Gbl_NoErrors)
+ fprintf (OutputFile, "%s %4.4d -",
+ AeDecodeExceptionLevel (Enode->Level),
+ AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
+
+ MainMessage = AeDecodeMessageId (Enode->MessageId);
+ ExtraMessage = Enode->Message;
+
+ /* If a NULL line number, just print the decoded message */
+
+ if (!Enode->LineNumber)
{
+ fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
return;
}
- /*
- * Only listing files have a header, and remarks/optimizations
- * are always output
- */
- if (!Header)
+ MsgLength = strlen (MainMessage);
+ if (MsgLength == 0)
{
- /* Ignore remarks if requested */
+ /* Use the secondary/extra message as main message */
- switch (Enode->Level)
+ MainMessage = Enode->Message;
+ if (!MainMessage)
{
- case ASL_WARNING:
- case ASL_WARNING2:
- case ASL_WARNING3:
+ MainMessage = "";
+ }
- if (!Gbl_DisplayWarnings)
- {
- return;
- }
- break;
+ MsgLength = strlen (MainMessage);
+ ExtraMessage = NULL;
+ }
- case ASL_REMARK:
+ if (Gbl_VerboseErrors && !PrematureEOF)
+ {
+ if (Total >= 256)
+ {
+ fprintf (OutputFile, " %s",
+ MainMessage);
+ }
+ else
+ {
+ SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
+ ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
- if (!Gbl_DisplayRemarks)
+ if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
{
- return;
+ fprintf (OutputFile, "%*s%s",
+ (int) ((SourceColumn - 1) - ErrorColumn),
+ MainMessage, " ^ ");
}
- break;
-
- case ASL_OPTIMIZATION:
-
- if (!Gbl_DisplayOptimizations)
+ else
{
- return;
+ fprintf (OutputFile, "%*s %s",
+ (int) ((SourceColumn - ErrorColumn) + 1), "^",
+ MainMessage);
}
- break;
+ }
+ }
+ else
+ {
+ fprintf (OutputFile, " %s", MainMessage);
+ }
- default:
+ /* Print the extra info message if present */
- break;
- }
+ if (ExtraMessage)
+ {
+ fprintf (OutputFile, " (%s)", ExtraMessage);
}
- /* Get the various required file handles */
+ if (PrematureEOF)
+ {
+ fprintf (OutputFile, " and premature End-Of-File");
+ }
+
+ fprintf (OutputFile, "\n");
+ if (Gbl_VerboseErrors && !Enode->SubError)
+ {
+ fprintf (OutputFile, "\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AePrintErrorSourceLine
+ *
+ * PARAMETERS: OutputFile - Output file
+ * Enode - Error node to print
+ * PrematureEOF - True = PrematureEOF has been reached
+ * Total - amount of characters printed so far
+ *
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Print the source line of an error.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AePrintErrorSourceLine (
+ FILE *OutputFile,
+ ASL_ERROR_MSG *Enode,
+ BOOLEAN *PrematureEOF,
+ UINT32 *Total)
+{
+ UINT8 SourceByte;
+ int Actual;
+ size_t RActual;
+ FILE *SourceFile = NULL;
+ long FileSize;
- OutputFile = Gbl_Files[FileId].Handle;
if (!Enode->SourceLine)
{
@@ -404,213 +484,272 @@ AePrintException (
if ((long) Enode->LogicalByteOffset >= FileSize)
{
- PrematureEOF = TRUE;
+ *PrematureEOF = TRUE;
}
}
- }
-
- if (Header)
- {
- fprintf (OutputFile, "%s", Header);
+ else
+ {
+ fprintf (OutputFile,
+ "[*** iASL: Source File Does not exist ***]\n");
+ return AE_IO_ERROR;
+ }
}
/* Print filename and line number if present and valid */
- if (Enode->Filename)
+ if (Gbl_VerboseErrors)
{
- if (Gbl_VerboseErrors)
+ fprintf (OutputFile, "%-8s", Enode->Filename);
+
+ if (Enode->SourceLine && Enode->LineNumber)
{
- fprintf (OutputFile, "%-8s", Enode->Filename);
+ fprintf (OutputFile, " %6u: %s",
+ Enode->LineNumber, Enode->SourceLine);
+ }
+ else if (Enode->LineNumber)
+ {
+ fprintf (OutputFile, " %6u: ", Enode->LineNumber);
- if (Enode->LineNumber)
+ /*
+ * If not at EOF, get the corresponding source code line
+ * and display it. Don't attempt this if we have a
+ * premature EOF condition.
+ */
+ if (*PrematureEOF)
{
- if (Enode->SourceLine)
- {
- fprintf (OutputFile, " %6u: %s",
- Enode->LineNumber, Enode->SourceLine);
- }
- else
+ fprintf (OutputFile, "\n");
+ return AE_OK;
+ }
+ /*
+ * Seek to the offset in the combined source file,
+ * read the source line, and write it to the output.
+ */
+ Actual = fseek (SourceFile,
+ (long) Enode->LogicalByteOffset, (int) SEEK_SET);
+ if (Actual)
+ {
+ fprintf (OutputFile,
+ "[*** iASL: Seek error on source code temp file %s ***]",
+ Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
+
+ fprintf (OutputFile, "\n");
+ return AE_OK;
+ }
+ RActual = fread (&SourceByte, 1, 1, SourceFile);
+ if (RActual != 1)
+ {
+ fprintf (OutputFile,
+ "[*** iASL: Read error on source code temp file %s ***]",
+ Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
+ return AE_IO_ERROR;
+ }
+ /* Read/write the source line, up to the maximum line length */
+
+ while (RActual && SourceByte && (SourceByte != '\n'))
+ {
+ if (*Total < 256)
{
- fprintf (OutputFile, " %6u: ", Enode->LineNumber);
-
- /*
- * If not at EOF, get the corresponding source code line
- * and display it. Don't attempt this if we have a
- * premature EOF condition.
- */
- if (!PrematureEOF)
+ /* After the max line length, we will just read the line, no write */
+
+ if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
{
- /*
- * Seek to the offset in the combined source file,
- * read the source line, and write it to the output.
- */
- Actual = fseek (SourceFile,
- (long) Enode->LogicalByteOffset, (int) SEEK_SET);
- if (Actual)
- {
- fprintf (OutputFile,
- "[*** iASL: Seek error on source code temp file %s ***]",
- Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
- }
- else
- {
- RActual = fread (&SourceByte, 1, 1, SourceFile);
- if (RActual != 1)
- {
- fprintf (OutputFile,
- "[*** iASL: Read error on source code temp file %s ***]",
- Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
- }
- else
- {
- /* Read/write the source line, up to the maximum line length */
-
- while (RActual && SourceByte && (SourceByte != '\n'))
- {
- if (Total < 256)
- {
- /* After the max line length, we will just read the line, no write */
-
- if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
- {
- printf ("[*** iASL: Write error on output file ***]\n");
- return;
- }
- }
- else if (Total == 256)
- {
- fprintf (OutputFile,
- "\n[*** iASL: Very long input line, message below refers to column %u ***]",
- Enode->Column);
- }
-
- RActual = fread (&SourceByte, 1, 1, SourceFile);
- if (RActual != 1)
- {
- fprintf (OutputFile,
- "[*** iASL: Read error on source code temp file %s ***]",
- Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
- return;
- }
- Total++;
- }
- }
- }
+ printf ("[*** iASL: Write error on output file ***]\n");
+ return AE_IO_ERROR;
}
+ }
+ else if (*Total == 256)
+ {
+ fprintf (OutputFile,
+ "\n[*** iASL: Very long input line, message below refers to column %u ***]",
+ Enode->Column);
+ }
- fprintf (OutputFile, "\n");
+ RActual = fread (&SourceByte, 1, 1, SourceFile);
+ if (RActual != 1)
+ {
+ fprintf (OutputFile,
+ "[*** iASL: Read error on source code temp file %s ***]",
+ Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
+
+ return AE_IO_ERROR;
}
+ *Total += 1;
}
- }
- else
- {
- /*
- * Less verbose version of the error message, enabled via the
- * -vi switch. The format is compatible with MS Visual Studio.
- */
- fprintf (OutputFile, "%s", Enode->Filename);
- if (Enode->LineNumber)
- {
- fprintf (OutputFile, "(%u) : ",
- Enode->LineNumber);
- }
+ fprintf (OutputFile, "\n");
}
}
-
- /* If a NULL message ID, just print the raw message */
-
- if (Enode->MessageId == 0)
+ else
{
- fprintf (OutputFile, "%s\n", Enode->Message);
- return;
+ /*
+ * Less verbose version of the error message, enabled via the
+ * -vi switch. The format is compatible with MS Visual Studio.
+ */
+ fprintf (OutputFile, "%s", Enode->Filename);
+
+ if (Enode->LineNumber)
+ {
+ fprintf (OutputFile, "(%u) : ",
+ Enode->LineNumber);
+ }
}
- /* Decode the message ID */
+ return AE_OK;
+}
- fprintf (OutputFile, "%s %4.4d -",
- AeDecodeExceptionLevel (Enode->Level),
- AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
+/*******************************************************************************
+ *
+ * FUNCTION: AePrintException
+ *
+ * PARAMETERS: FileId - ID of output file
+ * Enode - Error node to print
+ * Header - Additional text before each message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print the contents of an error node.
+ *
+ * NOTE: We don't use the FlxxxFile I/O functions here because on error
+ * they abort the compiler and call this function! Since we
+ * are reporting errors here, we ignore most output errors and
+ * just try to get out as much as we can.
+ *
+ ******************************************************************************/
- MainMessage = AeDecodeMessageId (Enode->MessageId);
- ExtraMessage = Enode->Message;
+void
+AePrintException (
+ UINT32 FileId,
+ ASL_ERROR_MSG *Enode,
+ char *Header)
+{
+ FILE *OutputFile;
+ BOOLEAN PrematureEOF = FALSE;
+ UINT32 Total = 0;
+ ACPI_STATUS Status;
+ ASL_ERROR_MSG *Child = Enode->SubError;
- /* If a NULL line number, just print the decoded message */
- if (!Enode->LineNumber)
+ if (Gbl_NoErrors)
{
- fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
return;
}
- MsgLength = strlen (MainMessage);
- if (MsgLength == 0)
+ /*
+ * Only listing files have a header, and remarks/optimizations
+ * are always output
+ */
+ if (!Header)
{
- /* Use the secondary/extra message as main message */
+ /* Ignore remarks if requested */
- MainMessage = Enode->Message;
- if (!MainMessage)
+ switch (Enode->Level)
{
- MainMessage = "";
- }
+ case ASL_WARNING:
+ case ASL_WARNING2:
+ case ASL_WARNING3:
- MsgLength = strlen (MainMessage);
- ExtraMessage = NULL;
- }
+ if (!Gbl_DisplayWarnings)
+ {
+ return;
+ }
+ break;
- if (Gbl_VerboseErrors && !PrematureEOF)
- {
- if (Total >= 256)
- {
- fprintf (OutputFile, " %s",
- MainMessage);
- }
- else
- {
- SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
- ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
+ case ASL_REMARK:
- if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
+ if (!Gbl_DisplayRemarks)
{
- fprintf (OutputFile, "%*s%s",
- (int) ((SourceColumn - 1) - ErrorColumn),
- MainMessage, " ^ ");
+ return;
}
- else
+ break;
+
+ case ASL_OPTIMIZATION:
+
+ if (!Gbl_DisplayOptimizations)
{
- fprintf (OutputFile, "%*s %s",
- (int) ((SourceColumn - ErrorColumn) + 1), "^",
- MainMessage);
+ return;
}
+ break;
+
+ default:
+
+ break;
}
}
- else
+
+ /* Get the various required file handles */
+
+ OutputFile = Gbl_Files[FileId].Handle;
+
+ if (Header)
{
- fprintf (OutputFile, " %s", MainMessage);
+ fprintf (OutputFile, "%s", Header);
}
- /* Print the extra info message if present */
+ if (!Enode->Filename)
+ {
+ AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total);
+ return;
+ }
- if (ExtraMessage)
+ Status = AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total);
+ if (ACPI_FAILURE (Status))
{
- fprintf (OutputFile, " (%s)", ExtraMessage);
+ return;
}
- if (PrematureEOF)
+ /* If a NULL message ID, just print the raw message */
+
+ if (Enode->MessageId == 0)
{
- fprintf (OutputFile, " and premature End-Of-File");
+ fprintf (OutputFile, "%s\n", Enode->Message);
+ return;
}
- fprintf (OutputFile, "\n");
- if (Gbl_VerboseErrors)
+ AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total);
+
+ while (Child)
{
fprintf (OutputFile, "\n");
+ AePrintSubError (OutputFile, Child);
+ Child = Child->SubError;
}
}
/*******************************************************************************
*
+ * FUNCTION: AePrintSubError
+ *
+ * PARAMETERS: OutputFile - Output file
+ * Enode - Error node to print
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print the contents of an error nodes. This function is tailored
+ * to print error nodes that are SubErrors within ASL_ERROR_MSG
+ *
+ ******************************************************************************/
+
+static void
+AePrintSubError (
+ FILE *OutputFile,
+ ASL_ERROR_MSG *Enode)
+{
+ UINT32 Total = 0;
+ BOOLEAN PrematureEOF = FALSE;
+ const char *MainMessage;
+
+
+ MainMessage = AeDecodeMessageId (Enode->MessageId);
+
+ fprintf (OutputFile, " %s%s", MainMessage, "\n ");
+ (void) AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total);
+ fprintf (OutputFile, "\n");
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AePrintErrorLog
*
* PARAMETERS: FileId - Where to output the error log
@@ -640,54 +779,72 @@ AePrintErrorLog (
/*******************************************************************************
*
- * FUNCTION: AslCommonError2
+ * FUNCTION: AslInitEnode
*
- * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * PARAMETERS: InputEnode - Input Error node to initialize
+ * Level - Seriousness (Warning/error, etc.)
* MessageId - Index into global message buffer
- * LineNumber - Actual file line number
+ * CurrentLineNumber - Actual file line number
+ * LogicalLineNumber - Cumulative line number
+ * LogicalByteOffset - Byte offset in source file
* Column - Column in current line
- * SourceLine - Actual source code line
* Filename - source filename
* ExtraMessage - additional error message
+ * SourceLine - Line of error source code
+ * SubError - SubError of this InputEnode
*
* RETURN: None
*
- * DESCRIPTION: Create a new error node and add it to the error log
+ * DESCRIPTION: Initialize an Error node
*
******************************************************************************/
-void
-AslCommonError2 (
+static void AslInitEnode (
+ ASL_ERROR_MSG **InputEnode,
UINT8 Level,
UINT16 MessageId,
UINT32 LineNumber,
+ UINT32 LogicalLineNumber,
+ UINT32 LogicalByteOffset,
UINT32 Column,
- char *SourceLine,
char *Filename,
- char *ExtraMessage)
+ char *ExtraMessage,
+ char *SourceLine,
+ ASL_ERROR_MSG *SubError)
{
- char *MessageBuffer = NULL;
- char *LineBuffer;
ASL_ERROR_MSG *Enode;
- Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
+ *InputEnode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
+ Enode = *InputEnode;
+ Enode->Level = Level;
+ Enode->MessageId = MessageId;
+ Enode->LineNumber = LineNumber;
+ Enode->LogicalLineNumber = LogicalLineNumber;
+ Enode->LogicalByteOffset = LogicalByteOffset;
+ Enode->Column = Column;
+ Enode->SubError = SubError;
+ Enode->Message = NULL;
+ Enode->SourceLine = NULL;
+ Enode->Filename = NULL;
if (ExtraMessage)
{
/* Allocate a buffer for the message and a new error node */
- MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
+ Enode->Message = UtLocalCacheCalloc (strlen (ExtraMessage) + 1);
/* Keep a copy of the extra message */
- strcpy (MessageBuffer, ExtraMessage);
+ strcpy (Enode->Message, ExtraMessage);
}
- LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
- strcpy (LineBuffer, SourceLine);
+ if (SourceLine)
+ {
+ Enode->SourceLine = UtLocalCalloc (strlen (SourceLine) + 1);
+ strcpy (Enode->SourceLine, SourceLine);
+ }
- /* Initialize the error node */
if (Filename)
{
@@ -698,28 +855,39 @@ AslCommonError2 (
Enode->FilenameLength = 6;
}
}
+}
- Enode->MessageId = MessageId;
- Enode->Level = Level;
- Enode->LineNumber = LineNumber;
- Enode->LogicalLineNumber = LineNumber;
- Enode->LogicalByteOffset = 0;
- Enode->Column = Column;
- Enode->Message = MessageBuffer;
- Enode->SourceLine = LineBuffer;
-
- /* Add the new node to the error node list */
-
- AeAddToErrorLog (Enode);
- if (Gbl_DebugFlag)
- {
- /* stderr is a file, send error to it immediately */
-
- AePrintException (ASL_FILE_STDERR, Enode, NULL);
- }
+/*******************************************************************************
+ *
+ * FUNCTION: AslCommonError2
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ * LineNumber - Actual file line number
+ * Column - Column in current line
+ * SourceLine - Actual source code line
+ * Filename - source filename
+ * ExtraMessage - additional error message
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create a new error node and add it to the error log
+ *
+ ******************************************************************************/
- Gbl_ExceptionCount[Level]++;
+void
+AslCommonError2 (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 LineNumber,
+ UINT32 Column,
+ char *SourceLine,
+ char *Filename,
+ char *ExtraMessage)
+{
+ AslLogNewError (Level, MessageId, LineNumber, LineNumber, 0, Column,
+ Filename, ExtraMessage, SourceLine, NULL);
}
@@ -753,43 +921,51 @@ AslCommonError (
char *Filename,
char *ExtraMessage)
{
- char *MessageBuffer = NULL;
- ASL_ERROR_MSG *Enode;
-
-
- Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
-
- if (ExtraMessage)
- {
- /* Allocate a buffer for the message and a new error node */
-
- MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
-
- /* Keep a copy of the extra message */
+ AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber,
+ LogicalByteOffset, Column, Filename, ExtraMessage,
+ NULL, NULL);
+}
- strcpy (MessageBuffer, ExtraMessage);
- }
- /* Initialize the error node */
+/*******************************************************************************
+ *
+ * FUNCTION: AslLogNewError
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
+ * CurrentLineNumber - Actual file line number
+ * LogicalLineNumber - Cumulative line number
+ * LogicalByteOffset - Byte offset in source file
+ * Column - Column in current line
+ * Filename - source filename
+ * Message - additional error message
+ * SourceLine - Actual line of source code
+ * SubError - Sub-error associated with this error
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create a new error node and add it to the error log
+ *
+ ******************************************************************************/
+static void
+AslLogNewError (
+ UINT8 Level,
+ UINT16 MessageId,
+ UINT32 LineNumber,
+ UINT32 LogicalLineNumber,
+ UINT32 LogicalByteOffset,
+ UINT32 Column,
+ char *Filename,
+ char *Message,
+ char *SourceLine,
+ ASL_ERROR_MSG *SubError)
+{
+ ASL_ERROR_MSG *Enode = NULL;
- if (Filename)
- {
- Enode->Filename = Filename;
- Enode->FilenameLength = strlen (Filename);
- if (Enode->FilenameLength < 6)
- {
- Enode->FilenameLength = 6;
- }
- }
- Enode->MessageId = MessageId;
- Enode->Level = Level;
- Enode->LineNumber = CurrentLineNumber;
- Enode->LogicalLineNumber = LogicalLineNumber;
- Enode->LogicalByteOffset = LogicalByteOffset;
- Enode->Column = Column;
- Enode->Message = MessageBuffer;
- Enode->SourceLine = NULL;
+ AslInitEnode (&Enode, Level, MessageId, LineNumber, LogicalLineNumber,
+ LogicalByteOffset, Column, Filename, Message, SourceLine,
+ SubError);
/* Add the new node to the error node list */
@@ -820,8 +996,8 @@ AslCommonError (
*
* FUNCTION: AslIsExceptionIgnored
*
- * PARAMETERS: Level - Seriousness (Warning/error, etc.)
- * MessageId - Index into global message buffer
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
*
* RETURN: BOOLEAN
*
@@ -835,7 +1011,7 @@ AslIsExceptionIgnored (
UINT8 Level,
UINT16 MessageId)
{
- BOOLEAN ExceptionIgnored;
+ BOOLEAN ExceptionIgnored;
/* Note: this allows exception to be disabled and expected */
@@ -864,7 +1040,8 @@ void
AslCheckExpectedExceptions (
void)
{
- UINT8 i;
+ UINT8 i;
+
for (i = 0; i < Gbl_ExpectedMessagesIndex; ++i)
{
@@ -949,9 +1126,9 @@ AslDisableException (
MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
- if ((MessageId < 2000) || (MessageId > 5999))
+ if ((MessageId < 2000) || (MessageId > 6999))
{
- printf ("\"%s\" is not a valid warning/remark ID\n",
+ printf ("\"%s\" is not a valid warning/remark/error ID\n",
MessageIdString);
return (AE_BAD_PARAMETER);
}
@@ -975,8 +1152,8 @@ AslDisableException (
*
* FUNCTION: AslIsExceptionDisabled
*
- * PARAMETERS: Level - Seriousness (Warning/error, etc.)
- * MessageId - Index into global message buffer
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MessageId - Index into global message buffer
*
* RETURN: TRUE if exception/message should be ignored
*
@@ -994,9 +1171,8 @@ AslIsExceptionExpected (
UINT32 i;
- /*
- * Mark this exception as received
- */
+ /* Mark this exception as received */
+
EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
for (i = 0; i < Gbl_ExpectedMessagesIndex; i++)
{
@@ -1050,8 +1226,9 @@ AslIsExceptionDisabled (
case ASL_WARNING:
case ASL_REMARK:
+ case ASL_ERROR:
/*
- * Ignore this warning/remark if it has been disabled by
+ * Ignore this error/warning/remark if it has been disabled by
* the user (-vw option)
*/
EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
@@ -1076,6 +1253,61 @@ AslIsExceptionDisabled (
/*******************************************************************************
*
+ * FUNCTION: AslDualParseOpError
+ *
+ * PARAMETERS: Level - Seriousness (Warning/error, etc.)
+ * MainMsgId - Index into global message buffer
+ * MainOp - Parse node where error happened
+ * MainMsg - Message pertaining to the MainOp
+ * SubMsgId - Index into global message buffer
+ * SubOp - Additional parse node for better message
+ * SubMsg - Message pertainint to SubOp
+ *
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Main error reporting routine for the ASL compiler for error
+ * messages that point to multiple parse objects.
+ *
+ ******************************************************************************/
+
+void
+AslDualParseOpError (
+ UINT8 Level,
+ UINT16 MainMsgId,
+ ACPI_PARSE_OBJECT *MainOp,
+ char *MainMsg,
+ UINT16 SubMsgId,
+ ACPI_PARSE_OBJECT *SubOp,
+ char *SubMsg)
+{
+ ASL_ERROR_MSG *SubEnode = NULL;
+
+
+ /* Check if user wants to ignore this exception */
+
+ if (AslIsExceptionIgnored (Level, MainMsgId) || !MainOp)
+ {
+ return;
+ }
+
+ if (SubOp)
+ {
+ AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber,
+ SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset,
+ SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg,
+ NULL, NULL);
+ }
+
+ AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber,
+ MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset,
+ MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg,
+ NULL, SubEnode);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AslError
*
* PARAMETERS: Level - Seriousness (Warning/error, etc.)
@@ -1097,14 +1329,6 @@ AslError (
ACPI_PARSE_OBJECT *Op,
char *ExtraMessage)
{
-
- /* Check if user wants to ignore this exception */
-
- if (AslIsExceptionIgnored (Level, MessageId))
- {
- return;
- }
-
if (Op)
{
AslCommonError (Level, MessageId, Op->Asl.LineNumber,
diff --git a/sys/contrib/dev/acpica/compiler/aslfiles.c b/sys/contrib/dev/acpica/compiler/aslfiles.c
index 1ebfb9f..5cb4274 100644
--- a/sys/contrib/dev/acpica/compiler/aslfiles.c
+++ b/sys/contrib/dev/acpica/compiler/aslfiles.c
@@ -151,7 +151,6 @@
#include <contrib/dev/acpica/compiler/aslcompiler.h>
#include <contrib/dev/acpica/include/acapps.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT ACPI_COMPILER
ACPI_MODULE_NAME ("aslfiles")
@@ -326,14 +325,14 @@ FlMergePathnames (
(*FilePathname == '/') ||
(FilePathname[1] == ':'))
{
- Pathname = UtStringCacheCalloc (strlen (FilePathname) + 1);
+ Pathname = UtLocalCacheCalloc (strlen (FilePathname) + 1);
strcpy (Pathname, FilePathname);
goto ConvertBackslashes;
}
/* Need a local copy of the prefix directory path */
- CommonPath = UtStringCacheCalloc (strlen (PrefixDir) + 1);
+ CommonPath = UtLocalCacheCalloc (strlen (PrefixDir) + 1);
strcpy (CommonPath, PrefixDir);
/*
@@ -369,7 +368,7 @@ FlMergePathnames (
/* Build the final merged pathname */
ConcatenatePaths:
- Pathname = UtStringCacheCalloc (
+ Pathname = UtLocalCacheCalloc (
strlen (CommonPath) + strlen (FilePathname) + 2);
if (LastElement && *CommonPath)
{
@@ -619,7 +618,7 @@ FlOpenAmlOutputFile (
if (!Filename)
{
/* Create the output AML filename */
- if (!Gbl_CaptureComments)
+ if (!AcpiGbl_CaptureComments)
{
Filename = FlGenerateFilename (FilenamePrefix, FILE_SUFFIX_AML_CODE);
}
diff --git a/sys/contrib/dev/acpica/compiler/aslhelp.c b/sys/contrib/dev/acpica/compiler/aslhelp.c
index 38e2345..ed3a332 100644
--- a/sys/contrib/dev/acpica/compiler/aslhelp.c
+++ b/sys/contrib/dev/acpica/compiler/aslhelp.c
@@ -173,6 +173,7 @@ void
Usage (
void)
{
+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
printf ("%s\n\n", ASL_COMPLIANCE);
ACPI_USAGE_HEADER ("iasl [Options] [Files]");
@@ -203,7 +204,7 @@ Usage (
ACPI_OPTION ("-ve", "Report only errors (ignore warnings and remarks)");
ACPI_OPTION ("-vi", "Less verbose errors and warnings for use with IDEs");
ACPI_OPTION ("-vr", "Disable remarks");
- ACPI_OPTION ("-vw <messageid>", "Disable specific warning or remark");
+ ACPI_OPTION ("-vw <messageid>", "Ignore specific error, warning or remark");
ACPI_OPTION ("-vx <messageid>", "Expect a specific warning, remark, or error");
ACPI_OPTION ("-w <1|2|3>", "Set warning reporting level");
ACPI_OPTION ("-we", "Report warnings as errors");
diff --git a/sys/contrib/dev/acpica/compiler/aslload.c b/sys/contrib/dev/acpica/compiler/aslload.c
index 7480f23..1986453 100644
--- a/sys/contrib/dev/acpica/compiler/aslload.c
+++ b/sys/contrib/dev/acpica/compiler/aslload.c
@@ -327,8 +327,9 @@ LdLoadFieldElements (
* The name already exists in this scope
* But continue processing the elements
*/
- AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
- Child->Asl.Value.String);
+ AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
+ Child->Asl.Value.String, ASL_MSG_FOUND_HERE, Node->Op,
+ Node->Op->Asl.ExternalName);
}
}
else
@@ -388,8 +389,10 @@ LdLoadResourceElements (
{
/* Actual node causing the error was saved in ParentMethod */
- AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
- (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
+ AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
+ (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod,
+ Op->Asl.Namepath, ASL_MSG_FOUND_HERE, Node->Op,
+ Node->Op->Asl.ExternalName);
return (AE_OK);
}
return (Status);
@@ -805,8 +808,8 @@ LdNamespace1Begin (
/*
* Allow one create on an object or segment that was
* previously declared External only if WalkState->OwnerId and
- * Node->OwnerId are found in different tables (meaning that
- * they have differnt OwnerIds).
+ * Node->OwnerId are different (meaning that the current WalkState
+ * and the Node are in different tables).
*/
Node->Flags &= ~ANOBJ_IS_EXTERNAL;
Node->Type = (UINT8) ObjectType;
@@ -827,8 +830,9 @@ LdNamespace1Begin (
if (Node->OwnerId == WalkState->OwnerId &&
!(Node->Flags & IMPLICIT_EXTERNAL))
{
- AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
- Op->Asl.ExternalName);
+ AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
+ Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op,
+ Node->Op->Asl.ExternalName);
}
if (Node->Flags & IMPLICIT_EXTERNAL)
{
@@ -849,8 +853,9 @@ LdNamespace1Begin (
if (Node->OwnerId == WalkState->OwnerId)
{
- AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
- Op->Asl.ExternalName);
+ AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
+ Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op,
+ Node->Op->Asl.ExternalName);
}
}
else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
@@ -905,8 +910,9 @@ LdNamespace1Begin (
{
/* Valid error, object already exists */
- AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
- Op->Asl.ExternalName);
+ AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
+ Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op,
+ Node->Op->Asl.ExternalName);
return_ACPI_STATUS (AE_OK);
}
}
diff --git a/sys/contrib/dev/acpica/compiler/aslmain.c b/sys/contrib/dev/acpica/compiler/aslmain.c
index 9c73aee..3b939f5 100644
--- a/sys/contrib/dev/acpica/compiler/aslmain.c
+++ b/sys/contrib/dev/acpica/compiler/aslmain.c
@@ -386,11 +386,11 @@ AslInitialize (
AcpiGbl_DmOpt_Verbose = FALSE;
- /* Default integer width is 64 bits */
+ /* Default integer width is 32 bits */
- AcpiGbl_IntegerBitWidth = 64;
- AcpiGbl_IntegerNybbleWidth = 16;
- AcpiGbl_IntegerByteWidth = 8;
+ AcpiGbl_IntegerBitWidth = 32;
+ AcpiGbl_IntegerNybbleWidth = 8;
+ AcpiGbl_IntegerByteWidth = 4;
for (i = 0; i < ASL_NUM_FILES; i++)
{
diff --git a/sys/contrib/dev/acpica/compiler/aslmapenter.c b/sys/contrib/dev/acpica/compiler/aslmapenter.c
index 6e39109..8476654 100644
--- a/sys/contrib/dev/acpica/compiler/aslmapenter.c
+++ b/sys/contrib/dev/acpica/compiler/aslmapenter.c
@@ -332,7 +332,7 @@ MpCreateGpioInfo (
* sorted by both source device name and then the pin number. There is
* one block per pin.
*/
- Buffer = UtStringCacheCalloc (sizeof (ACPI_GPIO_INFO));
+ Buffer = UtLocalCacheCalloc (sizeof (ACPI_GPIO_INFO));
Info = ACPI_CAST_PTR (ACPI_GPIO_INFO, Buffer);
NextGpio = Gbl_GpioList;
@@ -409,7 +409,7 @@ MpCreateSerialInfo (
* Allocate a new info block and insert it into the global Serial list
* sorted by both source device name and then the address.
*/
- Buffer = UtStringCacheCalloc (sizeof (ACPI_SERIAL_INFO));
+ Buffer = UtLocalCacheCalloc (sizeof (ACPI_SERIAL_INFO));
Info = ACPI_CAST_PTR (ACPI_SERIAL_INFO, Buffer);
NextSerial = Gbl_SerialList;
diff --git a/sys/contrib/dev/acpica/compiler/aslmaputils.c b/sys/contrib/dev/acpica/compiler/aslmaputils.c
index c17f090..3733304 100644
--- a/sys/contrib/dev/acpica/compiler/aslmaputils.c
+++ b/sys/contrib/dev/acpica/compiler/aslmaputils.c
@@ -212,7 +212,7 @@ MpGetHidFromParseTree (
/* Convert EISAID to a string */
- HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE);
+ HidString = UtLocalCacheCalloc (ACPI_EISAID_STRING_SIZE);
AcpiExEisaIdToString (HidString, Arg->Asl.Value.Integer);
return (HidString);
@@ -277,7 +277,7 @@ MpGetHidValue (
/* Convert EISAID to a string */
- HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE);
+ HidString = UtLocalCacheCalloc (ACPI_EISAID_STRING_SIZE);
AcpiExEisaIdToString (HidString, HidNode->Object->Integer.Value);
return (HidString);
diff --git a/sys/contrib/dev/acpica/compiler/aslmessages.c b/sys/contrib/dev/acpica/compiler/aslmessages.c
index d3d28c8..1ced654 100644
--- a/sys/contrib/dev/acpica/compiler/aslmessages.c
+++ b/sys/contrib/dev/acpica/compiler/aslmessages.c
@@ -238,7 +238,7 @@ const char *AslCompilerMsgs [] =
/* ASL_MSG_HID_SUFFIX */ "_HID suffix must be all hex digits",
/* ASL_MSG_INCLUDE_FILE_OPEN */ "Could not open include file",
/* ASL_MSG_INPUT_FILE_OPEN */ "Could not open input file",
-/* ASL_MSG_INTEGER_LENGTH */ "64-bit integer in 32-bit table, truncating (DSDT or SSDT version < 2)",
+/* ASL_MSG_INTEGER_LENGTH */ "Truncating 64-bit constant found in 32-bit table",
/* ASL_MSG_INTEGER_OPTIMIZATION */ "Integer optimized to single-byte AML opcode",
/* ASL_MSG_INTERRUPT_LIST */ "Too many interrupts (16 max)",
/* ASL_MSG_INTERRUPT_NUMBER */ "Invalid interrupt number (must be 0-15)",
@@ -349,7 +349,10 @@ const char *AslCompilerMsgs [] =
/* ASL_MSG_ARG_NOT_USED */ "Method Argument is never used",
/* ASL_MSG_CONSTANT_REQUIRED */ "Non-reducible expression",
/* ASL_MSG_CROSS_TABLE_SCOPE */ "Illegal open scope on external object from within DSDT",
-/* ASL_MSG_EXCEPTION_NOT_RECEIVED */ "Expected remark, warning, or error did not occur. Message ID:"
+/* ASL_MSG_EXCEPTION_NOT_RECEIVED */ "Expected remark, warning, or error did not occur. Message ID:",
+/* ASL_MSG_NULL_RESOURCE_TEMPLATE */ "Empty Resource Template (END_TAG only)",
+/* ASL_MSG_FOUND_HERE */ "Original name creation/declaration below: ",
+/* ASL_MSG_ILLEGAL_RECURSION */ "Illegal recursive call to method that creates named objects"
};
/* Table compiler */
diff --git a/sys/contrib/dev/acpica/compiler/aslmessages.h b/sys/contrib/dev/acpica/compiler/aslmessages.h
index 68216e5..a801840 100644
--- a/sys/contrib/dev/acpica/compiler/aslmessages.h
+++ b/sys/contrib/dev/acpica/compiler/aslmessages.h
@@ -352,6 +352,9 @@ typedef enum
ASL_MSG_CONSTANT_REQUIRED,
ASL_MSG_CROSS_TABLE_SCOPE,
ASL_MSG_EXCEPTION_NOT_RECEIVED,
+ ASL_MSG_NULL_RESOURCE_TEMPLATE,
+ ASL_MSG_FOUND_HERE,
+ ASL_MSG_ILLEGAL_RECURSION,
/* These messages are used by the Data Table compiler only */
diff --git a/sys/contrib/dev/acpica/compiler/aslmethod.c b/sys/contrib/dev/acpica/compiler/aslmethod.c
index a4b1c6f..ca48bc8 100644
--- a/sys/contrib/dev/acpica/compiler/aslmethod.c
+++ b/sys/contrib/dev/acpica/compiler/aslmethod.c
@@ -347,10 +347,31 @@ MtMethodAnalysisWalkBegin (
case PARSEOP_METHODCALL:
+ /* Check for a recursive method call */
+
if (MethodInfo &&
(Op->Asl.Node == MethodInfo->Op->Asl.Node))
{
- AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
+ if (MethodInfo->CreatesNamedObjects)
+ {
+ /*
+ * This is an error, as it will fail at runtime on all ACPI
+ * implementations. Any named object declarations will be
+ * executed twice, causing failure the second time. Note,
+ * this is independent of whether the method is declared
+ * Serialized, because the same thread is attempting to
+ * reenter the method, and this will always succeed.
+ */
+ AslDualParseOpError (ASL_ERROR, ASL_MSG_ILLEGAL_RECURSION, Op,
+ Op->Asl.Value.String, ASL_MSG_FOUND_HERE, MethodInfo->Op,
+ MethodInfo->Op->Asl.ExternalName);
+ }
+ else
+ {
+ /* Method does not create objects, issue a remark */
+
+ AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
+ }
}
break;
@@ -622,20 +643,28 @@ MtCheckNamedObjectInMethod (
return;
}
- /* Determine if we are creating a named object */
+ /* Determine if we are creating a named object within a method */
+
+ if (!MethodInfo)
+ {
+ return;
+ }
OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
if (OpInfo->Class == AML_CLASS_NAMED_OBJECT)
{
/*
- * If we have a named object created within a non-serialized method,
- * emit a remark that the method should be serialized.
+ * 1) Mark the method as a method that creates named objects.
+ *
+ * 2) If the method is non-serialized, emit a remark that the method
+ * should be serialized.
*
* Reason: If a thread blocks within the method for any reason, and
- * another thread enters the method, the method will fail because an
- * attempt will be made to create the same object twice.
+ * another thread enters the method, the method will fail because
+ * an attempt will be made to create the same object twice.
*/
- if (MethodInfo && !MethodInfo->ShouldBeSerialized)
+ MethodInfo->CreatesNamedObjects = TRUE;
+ if (!MethodInfo->ShouldBeSerialized)
{
AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op,
"due to creation of named objects within");
diff --git a/sys/contrib/dev/acpica/compiler/asloperands.c b/sys/contrib/dev/acpica/compiler/asloperands.c
index 0a5f144..c6e001f 100644
--- a/sys/contrib/dev/acpica/compiler/asloperands.c
+++ b/sys/contrib/dev/acpica/compiler/asloperands.c
@@ -1037,7 +1037,7 @@ OpnDoDefinitionBlock (
* We will use the AML filename that is embedded in the source file
* for the output filename.
*/
- Filename = UtStringCacheCalloc (strlen (Gbl_DirectoryPath) +
+ Filename = UtLocalCacheCalloc (strlen (Gbl_DirectoryPath) +
strlen ((char *) Child->Asl.Value.Buffer) + 1);
/* Prepend the current directory path */
@@ -1094,7 +1094,7 @@ OpnDoDefinitionBlock (
if (Child->Asl.Value.String)
{
Length = strlen (Child->Asl.Value.String);
- Gbl_TableId = UtStringCacheCalloc (Length + 1);
+ Gbl_TableId = UtLocalCacheCalloc (Length + 1);
strcpy (Gbl_TableId, Child->Asl.Value.String);
/*
diff --git a/sys/contrib/dev/acpica/compiler/aslopt.c b/sys/contrib/dev/acpica/compiler/aslopt.c
index 0019a07..6aaa386 100644
--- a/sys/contrib/dev/acpica/compiler/aslopt.c
+++ b/sys/contrib/dev/acpica/compiler/aslopt.c
@@ -275,7 +275,7 @@ OptSearchToRoot (
/* We must allocate a new string for the name (TargetPath gets deleted) */
- *NewPath = UtStringCacheCalloc (ACPI_NAME_SIZE + 1);
+ *NewPath = UtLocalCacheCalloc (ACPI_NAME_SIZE + 1);
strcpy (*NewPath, Path);
if (strncmp (*NewPath, "_T_", 3))
diff --git a/sys/contrib/dev/acpica/compiler/asloptions.c b/sys/contrib/dev/acpica/compiler/asloptions.c
index a22949b..d792b73 100644
--- a/sys/contrib/dev/acpica/compiler/asloptions.c
+++ b/sys/contrib/dev/acpica/compiler/asloptions.c
@@ -204,7 +204,6 @@ AslCommandLine (
if (argc < 2)
{
- printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
Usage ();
exit (1);
}
@@ -324,7 +323,7 @@ AslDoOptions (
Gbl_IntegerOptimizationFlag = FALSE;
Gbl_ReferenceOptimizationFlag = FALSE;
Gbl_OptimizeTrivialParseNodes = FALSE;
- Gbl_CaptureComments = TRUE;
+ AcpiGbl_CaptureComments = TRUE;
AcpiGbl_DoDisassemblerOptimizations = FALSE;
AcpiGbl_DebugAslConversion = TRUE;
AcpiGbl_DmEmitExternalOpcodes = TRUE;
@@ -392,7 +391,7 @@ AslDoOptions (
Gbl_IntegerOptimizationFlag = FALSE;
Gbl_ReferenceOptimizationFlag = FALSE;
Gbl_OptimizeTrivialParseNodes = FALSE;
- Gbl_CaptureComments = TRUE;
+ AcpiGbl_CaptureComments = TRUE;
AcpiGbl_DoDisassemblerOptimizations = FALSE;
AcpiGbl_DmEmitExternalOpcodes = TRUE;
Gbl_DoExternalsInPlace = TRUE;
@@ -417,25 +416,11 @@ AslDoOptions (
{
case '^':
- /* Get the required argument */
-
- if (AcpiGetoptArgument (argc, argv))
- {
- return (-1);
- }
-
Gbl_DoCompile = FALSE;
break;
case 'a':
- /* Get the required argument */
-
- if (AcpiGetoptArgument (argc, argv))
- {
- return (-1);
- }
-
Gbl_DoCompile = FALSE;
Gbl_DisassembleAll = TRUE;
break;
@@ -538,7 +523,6 @@ AslDoOptions (
{
case '^':
- printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
Usage ();
exit (0);
@@ -798,8 +782,8 @@ AslDoOptions (
Gbl_IntegerOptimizationFlag = FALSE;
Gbl_ReferenceOptimizationFlag = FALSE;
Gbl_OptimizeTrivialParseNodes = FALSE;
- Gbl_CaptureComments = TRUE;
Gbl_DoExternalsInPlace = TRUE;
+ AcpiGbl_CaptureComments = TRUE;
return (0);
case 'r': /* Override revision found in table header */
diff --git a/sys/contrib/dev/acpica/compiler/aslparseop.c b/sys/contrib/dev/acpica/compiler/aslparseop.c
index f23091b..f121401 100644
--- a/sys/contrib/dev/acpica/compiler/aslparseop.c
+++ b/sys/contrib/dev/acpica/compiler/aslparseop.c
@@ -158,13 +158,6 @@
ACPI_MODULE_NAME ("aslparseop")
-/* Local prototypes */
-
-static ACPI_PARSE_OBJECT *
-TrGetOpFromCache (
- void);
-
-
/*******************************************************************************
*
* FUNCTION: TrCreateOp
@@ -276,7 +269,7 @@ TrCreateOp (
* FirstChild place it in the parent. This also means that
* legitimate comments for the child gets put to the parent.
*/
- if (Gbl_CaptureComments &&
+ if (AcpiGbl_CaptureComments &&
((ParseOpcode == PARSEOP_CONNECTION) ||
(ParseOpcode == PARSEOP_EXTERNAL) ||
(ParseOpcode == PARSEOP_OFFSET) ||
@@ -315,7 +308,7 @@ TrCreateOp (
/* Get the comment from last child in the resource template call */
- if (Gbl_CaptureComments &&
+ if (AcpiGbl_CaptureComments &&
(Op->Asl.ParseOpcode == PARSEOP_RESOURCETEMPLATE))
{
CvDbgPrint ("Transferred current comment list to this op.\n");
@@ -490,7 +483,7 @@ TrCreateTargetOp (
return (NULL);
}
- Op = TrGetOpFromCache ();
+ Op = UtParseOpCacheCalloc ();
/* Copy the pertinent values (omit link pointer fields) */
@@ -788,7 +781,7 @@ TrAllocateOp (
ACPI_PARSE_OBJECT *LatestOp;
- Op = TrGetOpFromCache ();
+ Op = UtParseOpCacheCalloc ();
Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
Op->Asl.Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
@@ -801,7 +794,7 @@ TrAllocateOp (
/* The following is for capturing comments */
- if(Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
LatestOp = Gbl_CommentState.LatestParseOp;
Op->Asl.InlineComment = NULL;
@@ -877,50 +870,6 @@ TrAllocateOp (
/*******************************************************************************
*
- * FUNCTION: TrGetOpFromCache
- *
- * PARAMETERS: None
- *
- * RETURN: New parse op. Aborts on allocation failure
- *
- * DESCRIPTION: Allocate a new parse op for the parse tree. Bypass the local
- * dynamic memory manager for performance reasons (This has a
- * major impact on the speed of the compiler.)
- *
- ******************************************************************************/
-
-static ACPI_PARSE_OBJECT *
-TrGetOpFromCache (
- void)
-{
- ASL_CACHE_INFO *Cache;
-
-
- if (Gbl_ParseOpCacheNext >= Gbl_ParseOpCacheLast)
- {
- /* Allocate a new buffer */
-
- Cache = UtLocalCalloc (sizeof (Cache->Next) +
- (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE));
-
- /* Link new cache buffer to head of list */
-
- Cache->Next = Gbl_ParseOpCacheList;
- Gbl_ParseOpCacheList = Cache;
-
- /* Setup cache management pointers */
-
- Gbl_ParseOpCacheNext = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Cache->Buffer);
- Gbl_ParseOpCacheLast = Gbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE;
- }
-
- Gbl_ParseOpCount++;
- return (Gbl_ParseOpCacheNext++);
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: TrPrintOpFlags
*
* PARAMETERS: Flags - Flags word to be decoded
diff --git a/sys/contrib/dev/acpica/compiler/aslprintf.c b/sys/contrib/dev/acpica/compiler/aslprintf.c
index a626f24..00e218d 100644
--- a/sys/contrib/dev/acpica/compiler/aslprintf.c
+++ b/sys/contrib/dev/acpica/compiler/aslprintf.c
@@ -293,7 +293,7 @@ OpcParsePrintf (
if (StringToProcess)
{
- NewString = UtStringCacheCalloc (StringLength + 1);
+ NewString = UtLocalCacheCalloc (StringLength + 1);
strncpy (NewString, StartPosition, StringLength);
NewOp = TrAllocateOp (PARSEOP_STRING_LITERAL);
@@ -382,7 +382,7 @@ OpcParsePrintf (
if (StringToProcess)
{
- NewString = UtStringCacheCalloc (StringLength + 1);
+ NewString = UtLocalCacheCalloc (StringLength + 1);
strncpy (NewString, StartPosition, StringLength);
NewOp = TrAllocateOp (PARSEOP_STRING_LITERAL);
diff --git a/sys/contrib/dev/acpica/compiler/aslresource.c b/sys/contrib/dev/acpica/compiler/aslresource.c
index 7b8b7e6..32a7652 100644
--- a/sys/contrib/dev/acpica/compiler/aslresource.c
+++ b/sys/contrib/dev/acpica/compiler/aslresource.c
@@ -1148,6 +1148,14 @@ RsDoResourceTemplate (
DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
+ /* DEFAULT_ARG indicates null template - ResourceTemplate(){} */
+
+ if (DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
+ {
+ AslError (ASL_WARNING, ASL_MSG_NULL_RESOURCE_TEMPLATE,
+ DescriptorTypeOp, DescriptorTypeOp->Asl.Value.String);
+ }
+
/*
* Process all resource descriptors in the list
* Note: It is assumed that the EndTag node has been automatically
diff --git a/sys/contrib/dev/acpica/compiler/aslrules.y b/sys/contrib/dev/acpica/compiler/aslrules.y
index f26ea87..3b8e4839 100644
--- a/sys/contrib/dev/acpica/compiler/aslrules.y
+++ b/sys/contrib/dev/acpica/compiler/aslrules.y
@@ -199,7 +199,8 @@ DefinitionBlockTerm
String ','
String ','
DWordConst
- PARSEOP_CLOSE_PAREN {TrSetOpEndLineNumber ($<n>3); COMMENT_CAPTURE_ON;}
+ PARSEOP_CLOSE_PAREN {TrSetOpIntegerWidth ($6,$8);
+ TrSetOpEndLineNumber ($<n>3); COMMENT_CAPTURE_ON;}
'{' TermList '}' {$$ = TrLinkOpChildren ($<n>3,7,
$4,$6,$8,$10,$12,$14,$18);}
;
diff --git a/sys/contrib/dev/acpica/compiler/aslstartup.c b/sys/contrib/dev/acpica/compiler/aslstartup.c
index 8ce0375..6a283f0 100644
--- a/sys/contrib/dev/acpica/compiler/aslstartup.c
+++ b/sys/contrib/dev/acpica/compiler/aslstartup.c
@@ -233,11 +233,11 @@ AslInitializeGlobals (
Gbl_Files[i].Filename = NULL;
}
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
Gbl_CommentState.SpacesBefore = 0;
Gbl_CommentState.CommentType = 1;
- Gbl_CommentState.LatestParseOp = NULL;
+ Gbl_CommentState.LatestParseOp = NULL;
Gbl_CommentState.ParsingParenBraceNode = NULL;
Gbl_CommentState.CaptureComments = TRUE;
}
@@ -410,7 +410,7 @@ AslDoDisassembly (
Gbl_Files[ASL_FILE_INPUT].Filename = NULL;
- CmDeleteCaches ();
+ UtDeleteLocalCaches ();
return (AE_OK);
}
@@ -453,7 +453,7 @@ AslDoOneFile (
/* Take a copy of the input filename, convert any backslashes */
Gbl_Files[ASL_FILE_INPUT].Filename =
- UtStringCacheCalloc (strlen (Filename) + 1);
+ UtLocalCacheCalloc (strlen (Filename) + 1);
strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
UtConvertBackslashes (Gbl_Files[ASL_FILE_INPUT].Filename);
diff --git a/sys/contrib/dev/acpica/compiler/aslsupport.l b/sys/contrib/dev/acpica/compiler/aslsupport.l
index 42cee75..db243e4 100644
--- a/sys/contrib/dev/acpica/compiler/aslsupport.l
+++ b/sys/contrib/dev/acpica/compiler/aslsupport.l
@@ -382,7 +382,7 @@ AslPushInputFileStack (
/* Reset the global line count and filename */
Gbl_Files[ASL_FILE_INPUT].Filename =
- UtStringCacheCalloc (strlen (Filename) + 1);
+ UtLocalCacheCalloc (strlen (Filename) + 1);
strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
@@ -496,7 +496,7 @@ AslInsertLineBuffer (
AslResetCurrentLineBuffer ();
}
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
CvProcessCommentState (SourceChar);
}
@@ -525,7 +525,7 @@ static void
count (
int Type)
{
- int i;
+ char *p;
switch (Type)
@@ -547,9 +547,9 @@ count (
break;
}
- for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
+ for (p = yytext; *p != '\0'; p++)
{
- AslInsertLineBuffer (yytext[i]);
+ AslInsertLineBuffer (*p);
*Gbl_LineBufPtr = 0;
}
}
@@ -580,7 +580,7 @@ AslDoComment (
AslInsertLineBuffer ('/');
AslInsertLineBuffer ('*');
- if (Gbl_CaptureComments && CurrentState.CaptureComments)
+ if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
{
*StringBuffer = '/';
++StringBuffer;
@@ -595,7 +595,7 @@ loop:
while (((c = input ()) != '*') && (c != EOF))
{
AslInsertLineBuffer (c);
- if (Gbl_CaptureComments && CurrentState.CaptureComments)
+ if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
{
*StringBuffer = c;
++StringBuffer;
@@ -623,7 +623,7 @@ loop:
/* Comment is closed only if the NEXT character is a slash */
AslInsertLineBuffer (c);
- if (Gbl_CaptureComments && CurrentState.CaptureComments)
+ if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
{
*StringBuffer = c;
++StringBuffer;
@@ -698,7 +698,7 @@ AslDoCommentType2 (
AslInsertLineBuffer ('/');
- if (Gbl_CaptureComments && CurrentState.CaptureComments)
+ if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
{
AslInsertLineBuffer ('*');
*StringBuffer = '/';
@@ -714,7 +714,7 @@ AslDoCommentType2 (
while (((c = input ()) != '\n') && (c != EOF))
{
AslInsertLineBuffer (c);
- if (Gbl_CaptureComments && CurrentState.CaptureComments)
+ if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
{
*StringBuffer = c;
++StringBuffer;
@@ -1009,7 +1009,7 @@ CompletedString:
*/
*StringBuffer = 0;
- CleanString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
+ CleanString = UtLocalCacheCalloc (strlen (MsgBuffer) + 1);
strcpy (CleanString, MsgBuffer);
AslCompilerlval.s = CleanString;
return (TRUE);
diff --git a/sys/contrib/dev/acpica/compiler/asltree.c b/sys/contrib/dev/acpica/compiler/asltree.c
index b510d59..6dc91fb 100644
--- a/sys/contrib/dev/acpica/compiler/asltree.c
+++ b/sys/contrib/dev/acpica/compiler/asltree.c
@@ -253,7 +253,7 @@ TrSetOpIntegerValue (
/* Converter: if this is a method invocation, turn off capture comments */
- if (Gbl_CaptureComments &&
+ if (AcpiGbl_CaptureComments &&
(ParseOpcode == PARSEOP_METHODCALL))
{
Gbl_CommentState.CaptureComments = FALSE;
@@ -378,6 +378,39 @@ TrSetOpCurrentFilename (
/*******************************************************************************
*
+ * FUNCTION: TrSetOpIntegerWidth
+ *
+ * PARAMETERS: Op - An existing parse op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION:
+ *
+ ******************************************************************************/
+
+void
+TrSetOpIntegerWidth (
+ ACPI_PARSE_OBJECT *TableSignatureOp,
+ ACPI_PARSE_OBJECT *RevisionOp)
+{
+
+ /* TBD: Check table sig? (DSDT vs. SSDT) */
+
+ /* Handle command-line version override */
+
+ if (Gbl_RevisionOverride)
+ {
+ AcpiUtSetIntegerWidth (Gbl_RevisionOverride);
+ }
+ else
+ {
+ AcpiUtSetIntegerWidth ((UINT8) RevisionOp->Asl.Value.Integer);
+ }
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: TrSetOpEndLineNumber
*
* PARAMETERS: Op - An existing parse op
@@ -476,7 +509,7 @@ TrLinkOpChildren (
/* The following is for capturing comments */
- if(Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
/*
* If there are "regular comments" detected at this point,
@@ -557,7 +590,7 @@ TrLinkOpChildren (
va_end(ap);
DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
- if(Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
Gbl_CommentState.LatestParseOp = Op;
CvDbgPrint ("TrLinkOpChildren=====Set latest parse op to this op.\n");
@@ -735,7 +768,7 @@ TrLinkChildOp (
* turn on capture comments as it signifies that we are done parsing
* a method call.
*/
- if (Gbl_CaptureComments && Op1)
+ if (AcpiGbl_CaptureComments && Op1)
{
if (Op1->Asl.ParseOpcode == PARSEOP_METHODCALL)
{
diff --git a/sys/contrib/dev/acpica/compiler/asltypes.h b/sys/contrib/dev/acpica/compiler/asltypes.h
index e425087..f72226d 100644
--- a/sys/contrib/dev/acpica/compiler/asltypes.h
+++ b/sys/contrib/dev/acpica/compiler/asltypes.h
@@ -202,6 +202,7 @@ typedef struct asl_method_info
UINT8 ArgInitialized[ACPI_METHOD_NUM_ARGS];
UINT8 HasBeenTyped;
UINT8 ShouldBeSerialized;
+ UINT8 CreatesNamedObjects;
} ASL_METHOD_INFO;
@@ -337,8 +338,11 @@ typedef struct asl_include_dir
} ASL_INCLUDE_DIR;
-/* An entry in the exception list, one for each error/warning */
-
+/*
+ * An entry in the exception list, one for each error/warning
+ * Note: SubError nodes would be treated with the same messageId and Level
+ * as the parent error node.
+ */
typedef struct asl_error_msg
{
UINT32 LineNumber;
@@ -347,6 +351,7 @@ typedef struct asl_error_msg
UINT32 Column;
char *Message;
struct asl_error_msg *Next;
+ struct asl_error_msg *SubError;
char *Filename;
char *SourceLine;
UINT32 FilenameLength;
diff --git a/sys/contrib/dev/acpica/compiler/aslutils.c b/sys/contrib/dev/acpica/compiler/aslutils.c
index e4d8eef..a439db7 100644
--- a/sys/contrib/dev/acpica/compiler/aslutils.c
+++ b/sys/contrib/dev/acpica/compiler/aslutils.c
@@ -174,12 +174,6 @@ UtAttachNameseg (
ACPI_PARSE_OBJECT *Op,
char *Name);
-static void
-UtReallocLineBuffers (
- char **Buffer,
- UINT32 OldSize,
- UINT32 NewSize);
-
/*******************************************************************************
*
@@ -311,45 +305,6 @@ UtDisplayConstantOpcodes (
/*******************************************************************************
*
- * FUNCTION: UtLocalCalloc
- *
- * PARAMETERS: Size - Bytes to be allocated
- *
- * RETURN: Pointer to the allocated memory. Guaranteed to be valid.
- *
- * DESCRIPTION: Allocate zero-initialized memory. Aborts the compile on an
- * allocation failure, on the assumption that nothing more can be
- * accomplished.
- *
- ******************************************************************************/
-
-void *
-UtLocalCalloc (
- UINT32 Size)
-{
- void *Allocated;
-
-
- Allocated = ACPI_ALLOCATE_ZEROED (Size);
- if (!Allocated)
- {
- AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
- Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
- Gbl_InputByteCount, Gbl_CurrentColumn,
- Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
-
- CmCleanupAndExit ();
- exit (1);
- }
-
- TotalAllocations++;
- TotalAllocated += Size;
- return (Allocated);
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: UtBeginEvent
*
* PARAMETERS: Name - Ascii name of this event
@@ -467,7 +422,7 @@ UtSetParseOpName (
ACPI_PARSE_OBJECT *Op)
{
- strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
+ AcpiUtSafeStrncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode),
ACPI_MAX_PARSEOP_NAME);
}
@@ -637,180 +592,6 @@ UtCheckIntegerRange (
/*******************************************************************************
*
- * FUNCTION: UtStringCacheCalloc
- *
- * PARAMETERS: Length - Size of buffer requested
- *
- * RETURN: Pointer to the buffer. Aborts compiler on allocation failure
- *
- * DESCRIPTION: Allocate a string buffer. Bypass the local
- * dynamic memory manager for performance reasons (This has a
- * major impact on the speed of the compiler.)
- *
- ******************************************************************************/
-
-char *
-UtStringCacheCalloc (
- UINT32 Length)
-{
- char *Buffer;
- ASL_CACHE_INFO *Cache;
- UINT32 CacheSize = ASL_STRING_CACHE_SIZE;
-
-
- if (Length > CacheSize)
- {
- CacheSize = Length;
-
- if (Gbl_StringCacheList)
- {
- Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
-
- /* Link new cache buffer just following head of list */
-
- Cache->Next = Gbl_StringCacheList->Next;
- Gbl_StringCacheList->Next = Cache;
-
- /* Leave cache management pointers alone as they pertain to head */
-
- Gbl_StringCount++;
- Gbl_StringSize += Length;
-
- return (Cache->Buffer);
- }
- }
-
- if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast)
- {
- /* Allocate a new buffer */
-
- Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize);
-
- /* Link new cache buffer to head of list */
-
- Cache->Next = Gbl_StringCacheList;
- Gbl_StringCacheList = Cache;
-
- /* Setup cache management pointers */
-
- Gbl_StringCacheNext = Cache->Buffer;
- Gbl_StringCacheLast = Gbl_StringCacheNext + CacheSize;
- }
-
- Gbl_StringCount++;
- Gbl_StringSize += Length;
-
- Buffer = Gbl_StringCacheNext;
- Gbl_StringCacheNext += Length;
- return (Buffer);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: UtExpandLineBuffers
- *
- * PARAMETERS: None. Updates global line buffer pointers.
- *
- * RETURN: None. Reallocates the global line buffers
- *
- * DESCRIPTION: Called if the current line buffer becomes filled. Reallocates
- * all global line buffers and updates Gbl_LineBufferSize. NOTE:
- * Also used for the initial allocation of the buffers, when
- * all of the buffer pointers are NULL. Initial allocations are
- * of size ASL_DEFAULT_LINE_BUFFER_SIZE
- *
- *****************************************************************************/
-
-void
-UtExpandLineBuffers (
- void)
-{
- UINT32 NewSize;
-
-
- /* Attempt to double the size of all line buffers */
-
- NewSize = Gbl_LineBufferSize * 2;
- if (Gbl_CurrentLineBuffer)
- {
- DbgPrint (ASL_DEBUG_OUTPUT,
- "Increasing line buffer size from %u to %u\n",
- Gbl_LineBufferSize, NewSize);
- }
-
- UtReallocLineBuffers (&Gbl_CurrentLineBuffer, Gbl_LineBufferSize, NewSize);
- UtReallocLineBuffers (&Gbl_MainTokenBuffer, Gbl_LineBufferSize, NewSize);
- UtReallocLineBuffers (&Gbl_MacroTokenBuffer, Gbl_LineBufferSize, NewSize);
- UtReallocLineBuffers (&Gbl_ExpressionTokenBuffer, Gbl_LineBufferSize, NewSize);
-
- Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
- Gbl_LineBufferSize = NewSize;
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: UtReallocLineBuffers
- *
- * PARAMETERS: Buffer - Buffer to realloc
- * OldSize - Old size of Buffer
- * NewSize - New size of Buffer
- *
- * RETURN: none
- *
- * DESCRIPTION: Reallocate and initialize Buffer
- *
- *****************************************************************************/
-
-static void
-UtReallocLineBuffers (
- char **Buffer,
- UINT32 OldSize,
- UINT32 NewSize)
-{
-
- *Buffer = realloc (*Buffer, NewSize);
- if (*Buffer)
- {
- memset (*Buffer + OldSize, 0, NewSize - OldSize);
- return;
- }
-
- printf ("Could not increase line buffer size from %u to %u\n",
- OldSize, NewSize);
-
- AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, NULL, NULL);
- AslAbort ();
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: UtFreeLineBuffers
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Free all line buffers
- *
- *****************************************************************************/
-
-void
-UtFreeLineBuffers (
- void)
-{
-
- free (Gbl_CurrentLineBuffer);
- free (Gbl_MainTokenBuffer);
- free (Gbl_MacroTokenBuffer);
- free (Gbl_ExpressionTokenBuffer);
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: UtInternalizeName
*
* PARAMETERS: ExternalName - Name to convert
@@ -843,7 +624,7 @@ UtInternalizeName (
/* We need a segment to store the internal name */
- Info.InternalName = UtStringCacheCalloc (Info.Length);
+ Info.InternalName = UtLocalCacheCalloc (Info.Length);
/* Build the name */
@@ -1004,11 +785,11 @@ UtAttachNamepathToOwner (
*
* FUNCTION: UtDoConstant
*
- * PARAMETERS: String - Hexadecimal or decimal string
+ * PARAMETERS: String - Hex/Decimal/Octal
*
* RETURN: Converted Integer
*
- * DESCRIPTION: Convert a string to an integer, with error checking.
+ * DESCRIPTION: Convert a string to an integer, with overflow/error checking.
*
******************************************************************************/
@@ -1017,17 +798,20 @@ UtDoConstant (
char *String)
{
ACPI_STATUS Status;
- UINT64 Converted;
+ UINT64 ConvertedInteger;
char ErrBuf[64];
- Status = AcpiUtStrtoul64 (String, ACPI_STRTOUL_64BIT, &Converted);
+ Status = AcpiUtStrtoul64 (String, &ConvertedInteger);
if (ACPI_FAILURE (Status))
{
- sprintf (ErrBuf, "%s %s\n", "Conversion error:",
+ sprintf (ErrBuf, "While creating 64-bit constant: %s\n",
AcpiFormatException (Status));
- AslCompilererror (ErrBuf);
+
+ AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
+ Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
+ Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename, ErrBuf);
}
- return (Converted);
+ return (ConvertedInteger);
}
diff --git a/sys/contrib/dev/acpica/compiler/cvcompiler.c b/sys/contrib/dev/acpica/compiler/cvcompiler.c
index 57eef4b..534560a 100644
--- a/sys/contrib/dev/acpica/compiler/cvcompiler.c
+++ b/sys/contrib/dev/acpica/compiler/cvcompiler.c
@@ -186,14 +186,14 @@ CvProcessComment (
char *FinalCommentString;
- if (Gbl_CaptureComments && CurrentState.CaptureComments)
+ if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
{
*StringBuffer = (char) c1;
++StringBuffer;
*StringBuffer = 0;
CvDbgPrint ("Multi-line comment\n");
- CommentString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
+ CommentString = UtLocalCacheCalloc (strlen (MsgBuffer) + 1);
strcpy (CommentString, MsgBuffer);
CvDbgPrint ("CommentString: %s\n", CommentString);
@@ -208,7 +208,7 @@ CvProcessComment (
if (LineToken)
{
- FinalLineToken = UtStringCacheCalloc (strlen (LineToken) + 1);
+ FinalLineToken = UtLocalCacheCalloc (strlen (LineToken) + 1);
strcpy (FinalLineToken, LineToken);
/* Get rid of any carriage returns */
@@ -238,7 +238,7 @@ CvProcessComment (
}
}
- FinalLineToken = UtStringCacheCalloc (strlen (LineToken) + 1);
+ FinalLineToken = UtLocalCacheCalloc (strlen (LineToken) + 1);
strcat (FinalLineToken, LineToken);
/* Get rid of any carriage returns */
@@ -268,7 +268,7 @@ CvProcessComment (
* spacing.
*/
FinalCommentString =
- UtStringCacheCalloc (strlen (CommentString) +
+ UtLocalCacheCalloc (strlen (CommentString) +
CurrentState.SpacesBefore + 1);
for (i = 0; (CurrentState.CommentType != ASL_COMMENT_STANDARD) &&
@@ -309,11 +309,11 @@ CvProcessCommentType2 (
char *FinalCommentString;
- if (Gbl_CaptureComments && CurrentState.CaptureComments)
+ if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
{
*StringBuffer = 0; /* null terminate */
CvDbgPrint ("Single-line comment\n");
- CommentString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
+ CommentString = UtLocalCacheCalloc (strlen (MsgBuffer) + 1);
strcpy (CommentString, MsgBuffer);
/* If this comment lies on the same line as the latest parse op,
@@ -342,7 +342,7 @@ CvProcessCommentType2 (
* [ (spaces) (comment) ( * /) ('\0') ]
*
*/
- FinalCommentString = UtStringCacheCalloc (CurrentState.SpacesBefore +
+ FinalCommentString = UtLocalCacheCalloc (CurrentState.SpacesBefore +
strlen (CommentString) + 3 + 1);
for (i = 0; (CurrentState.CommentType != 1) &&
@@ -395,7 +395,7 @@ CvCalculateCommentLengths(
ACPI_COMMENT_NODE *Current = NULL;
- if (!Gbl_CaptureComments)
+ if (!AcpiGbl_CaptureComments)
{
return (0);
}
@@ -497,7 +497,7 @@ CgWriteAmlDefBlockComment(
char *DirectoryPosition;
- if (!Gbl_CaptureComments ||
+ if (!AcpiGbl_CaptureComments ||
(Op->Asl.ParseOpcode != PARSEOP_DEFINITION_BLOCK))
{
return;
@@ -507,7 +507,7 @@ CgWriteAmlDefBlockComment(
/* First, print the file name comment after changing .asl to .dsl */
- NewFilename = UtStringCacheCalloc (strlen (Op->Asl.Filename));
+ NewFilename = UtLocalCacheCalloc (strlen (Op->Asl.Filename));
strcpy (NewFilename, Op->Asl.Filename);
DirectoryPosition = strrchr (NewFilename, '/');
Position = strrchr (NewFilename, '.');
@@ -615,7 +615,7 @@ CgWriteAmlComment(
if ((Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK) ||
- !Gbl_CaptureComments)
+ !AcpiGbl_CaptureComments)
{
return;
}
@@ -944,7 +944,7 @@ CvAppendInlineComment (
Size = strlen (ToAdd);
Size += strlen (InlineComment);
- Str = UtStringCacheCalloc (Size + 1);
+ Str = UtLocalCacheCalloc (Size + 1);
strcpy (Str, InlineComment);
strcat (Str, ToAdd);
diff --git a/sys/contrib/dev/acpica/compiler/cvdisasm.c b/sys/contrib/dev/acpica/compiler/cvdisasm.c
index 25deb73..93ad510 100644
--- a/sys/contrib/dev/acpica/compiler/cvdisasm.c
+++ b/sys/contrib/dev/acpica/compiler/cvdisasm.c
@@ -352,7 +352,7 @@ CvCloseBraceWriteComment(
UINT32 Level)
{
- if (!Gbl_CaptureComments)
+ if (!AcpiGbl_CaptureComments)
{
AcpiOsPrintf ("}");
return;
@@ -385,7 +385,7 @@ CvCloseParenWriteComment(
UINT32 Level)
{
- if (!Gbl_CaptureComments)
+ if (!AcpiGbl_CaptureComments)
{
AcpiOsPrintf (")");
return;
diff --git a/sys/contrib/dev/acpica/compiler/cvparser.c b/sys/contrib/dev/acpica/compiler/cvparser.c
index eb89c46..0e4dca3 100644
--- a/sys/contrib/dev/acpica/compiler/cvparser.c
+++ b/sys/contrib/dev/acpica/compiler/cvparser.c
@@ -254,7 +254,7 @@ CvInitFileTree (
char *ChildFilename = NULL;
- if (!Gbl_CaptureComments)
+ if (!AcpiGbl_CaptureComments)
{
return;
}
@@ -714,13 +714,13 @@ CvCaptureCommentsOnly (
UINT8 *Aml = ParserState->Aml;
UINT16 Opcode = (UINT16) ACPI_GET8 (Aml);
UINT32 Length = 0;
- UINT8 CommentOption = (UINT16) ACPI_GET8 (Aml+1);
+ UINT8 CommentOption;
BOOLEAN StdDefBlockFlag = FALSE;
ACPI_COMMENT_NODE *CommentNode;
ACPI_FILE_NODE *FileNode;
- if (!Gbl_CaptureComments ||
+ if (!AcpiGbl_CaptureComments ||
Opcode != AML_COMMENT_OP)
{
return;
@@ -973,7 +973,7 @@ CvCaptureComments (
const ACPI_OPCODE_INFO *OpInfo;
- if (!Gbl_CaptureComments)
+ if (!AcpiGbl_CaptureComments)
{
return;
}
diff --git a/sys/contrib/dev/acpica/compiler/dtcompile.c b/sys/contrib/dev/acpica/compiler/dtcompile.c
index 43bc081..bd4afd0 100644
--- a/sys/contrib/dev/acpica/compiler/dtcompile.c
+++ b/sys/contrib/dev/acpica/compiler/dtcompile.c
@@ -152,7 +152,6 @@
#define _DECLARE_DT_GLOBALS
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dtcompile")
@@ -281,7 +280,6 @@ DtDoCompile (
CleanupAndExit:
AcpiUtDeleteCaches ();
- DtDeleteCaches ();
CmCleanupAndExit ();
return (Status);
}
@@ -319,6 +317,8 @@ DtInitialize (
return (Status);
}
+ AcpiUtSetIntegerWidth (2); /* Set width to 64 bits */
+
Gbl_FieldList = NULL;
Gbl_RootTable = NULL;
Gbl_SubtableStack = NULL;
@@ -410,7 +410,7 @@ DtCompileDataTable (
return (AE_ERROR);
}
- Gbl_Signature = UtStringCacheCalloc (strlen (Signature) + 1);
+ Gbl_Signature = UtLocalCacheCalloc (strlen (Signature) + 1);
strcpy (Gbl_Signature, Signature);
/*
@@ -559,10 +559,18 @@ DtCompileTable (
ACPI_STATUS Status = AE_OK;
- if (!Field || !*Field)
+ if (!Field)
{
return (AE_BAD_PARAMETER);
}
+ if (!*Field)
+ {
+ /*
+ * The field list is empty, this means that we are out of fields to
+ * parse. In other words, we are at the end of the table.
+ */
+ return (AE_END_OF_TABLE);
+ }
/* Ignore optional subtable if name does not match */
@@ -583,7 +591,7 @@ DtCompileTable (
if (Length > 0)
{
- String = UtStringCacheCalloc (Length);
+ String = UtLocalCacheCalloc (Length);
Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
}
@@ -826,7 +834,7 @@ DtCompilePadding (
if (Length > 0)
{
- String = UtStringCacheCalloc (Length);
+ String = UtLocalCacheCalloc (Length);
Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
}
diff --git a/sys/contrib/dev/acpica/compiler/dtcompiler.h b/sys/contrib/dev/acpica/compiler/dtcompiler.h
index c2a067e..244784d 100644
--- a/sys/contrib/dev/acpica/compiler/dtcompiler.h
+++ b/sys/contrib/dev/acpica/compiler/dtcompiler.h
@@ -154,7 +154,6 @@
#ifndef _DTCOMPILER
#define _DTCOMPILER
-#include <stdio.h>
#include <contrib/dev/acpica/include/acdisasm.h>
@@ -481,6 +480,10 @@ DtFatal (
DT_FIELD *FieldObject,
char *ExtraMessage);
+UINT64
+DtDoConstant (
+ char *String);
+
char*
DtGetFieldValue (
DT_FIELD *Field);
@@ -506,18 +509,6 @@ void
DtSetTableLength(
void);
-DT_SUBTABLE *
-UtSubtableCacheCalloc (
- void);
-
-DT_FIELD *
-UtFieldCacheCalloc (
- void);
-
-void
-DtDeleteCaches (
- void);
-
/* dttable - individual table compilation */
@@ -618,15 +609,19 @@ DtCompileNfit (
void **PFieldList);
ACPI_STATUS
-DtCompilePmtt (
+DtCompilePcct (
void **PFieldList);
ACPI_STATUS
-DtCompilePptt (
+DtCompilePdtt (
void **PFieldList);
ACPI_STATUS
-DtCompilePcct (
+DtCompilePmtt (
+ void **PFieldList);
+
+ACPI_STATUS
+DtCompilePptt (
void **PFieldList);
ACPI_STATUS
@@ -638,6 +633,10 @@ DtCompileS3pt (
DT_FIELD **PFieldList);
ACPI_STATUS
+DtCompileSdev (
+ void **PFieldList);
+
+ACPI_STATUS
DtCompileSlic (
void **PFieldList);
@@ -658,6 +657,10 @@ DtCompileTcpa (
void **PFieldList);
ACPI_STATUS
+DtCompileTpm2 (
+ void **PFieldList);
+
+ACPI_STATUS
DtCompileUefi (
void **PFieldList);
@@ -720,6 +723,7 @@ extern const unsigned char TemplateMsdm[];
extern const unsigned char TemplateMtmr[];
extern const unsigned char TemplateNfit[];
extern const unsigned char TemplatePcct[];
+extern const unsigned char TemplatePdtt[];
extern const unsigned char TemplatePmtt[];
extern const unsigned char TemplatePptt[];
extern const unsigned char TemplateRasf[];
@@ -727,6 +731,7 @@ extern const unsigned char TemplateRsdt[];
extern const unsigned char TemplateS3pt[];
extern const unsigned char TemplateSbst[];
extern const unsigned char TemplateSdei[];
+extern const unsigned char TemplateSdev[];
extern const unsigned char TemplateSlic[];
extern const unsigned char TemplateSlit[];
extern const unsigned char TemplateSpcr[];
diff --git a/sys/contrib/dev/acpica/compiler/dtexpress.c b/sys/contrib/dev/acpica/compiler/dtexpress.c
index b5ba58b..68211c0 100644
--- a/sys/contrib/dev/acpica/compiler/dtexpress.c
+++ b/sys/contrib/dev/acpica/compiler/dtexpress.c
@@ -150,7 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#include "dtparser.y.h"
#define _COMPONENT DT_COMPILER
diff --git a/sys/contrib/dev/acpica/compiler/dtfield.c b/sys/contrib/dev/acpica/compiler/dtfield.c
index 47641cb..96c3ea9 100644
--- a/sys/contrib/dev/acpica/compiler/dtfield.c
+++ b/sys/contrib/dev/acpica/compiler/dtfield.c
@@ -150,7 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dtfield")
@@ -628,15 +627,9 @@ DtCompileFlag (
UINT64 Value = 0;
UINT32 BitLength = 1;
UINT8 BitPosition = 0;
- ACPI_STATUS Status;
- Status = AcpiUtStrtoul64 (Field->Value,
- (ACPI_STRTOUL_64BIT | ACPI_STRTOUL_BASE16), &Value);
- if (ACPI_FAILURE (Status))
- {
- DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, NULL);
- }
+ Value = AcpiUtImplicitStrtoul64 (Field->Value);
switch (Info->Opcode)
{
diff --git a/sys/contrib/dev/acpica/compiler/dtio.c b/sys/contrib/dev/acpica/compiler/dtio.c
index 90015ac..3b081a0 100644
--- a/sys/contrib/dev/acpica/compiler/dtio.c
+++ b/sys/contrib/dev/acpica/compiler/dtio.c
@@ -150,7 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#include <contrib/dev/acpica/include/acapps.h>
#define _COMPONENT DT_COMPILER
@@ -239,7 +238,7 @@ DtTrim (
if (!strcmp (String, " "))
{
- ReturnString = UtStringCacheCalloc (1);
+ ReturnString = UtLocalCacheCalloc (1);
return (ReturnString);
}
@@ -287,7 +286,7 @@ DtTrim (
/* Create the trimmed return string */
Length = ACPI_PTR_DIFF (End, Start) + 1;
- ReturnString = UtStringCacheCalloc (Length + 1);
+ ReturnString = UtLocalCacheCalloc (Length + 1);
if (strlen (Start))
{
strncpy (ReturnString, Start, Length);
diff --git a/sys/contrib/dev/acpica/compiler/dtparser.y b/sys/contrib/dev/acpica/compiler/dtparser.y
index 8413863..38bc969 100644
--- a/sys/contrib/dev/acpica/compiler/dtparser.y
+++ b/sys/contrib/dev/acpica/compiler/dtparser.y
@@ -151,7 +151,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dtparser")
@@ -275,17 +274,24 @@ Expression
| EXPOP_LABEL { $$ = DtResolveLabel (DtParsertext);}
- /* Default base for a non-prefixed integer is 16 */
+ /*
+ * All constants for the data table compiler are in hex, whether a (optional) 0x
+ * prefix is present or not. For example, these two input strings are equivalent:
+ * 1234
+ * 0x1234
+ */
- | EXPOP_NUMBER { AcpiUtStrtoul64 (DtParsertext, (ACPI_STRTOUL_BASE16 | ACPI_STRTOUL_64BIT), &$$);}
+ /* Non-prefixed hex number */
+
+ | EXPOP_NUMBER { $$ = DtDoConstant (DtParsertext);}
/* Standard hex number (0x1234) */
- | EXPOP_HEX_NUMBER { AcpiUtStrtoul64 (DtParsertext, (ACPI_STRTOUL_BASE16 | ACPI_STRTOUL_64BIT), &$$);}
+ | EXPOP_HEX_NUMBER { $$ = DtDoConstant (DtParsertext);}
- /* TBD: Decimal number with prefix (0d1234) - Not supported by strtoul64 at this time */
+ /* Possible TBD: Decimal number with prefix (0d1234) - Not supported this time */
- | EXPOP_DECIMAL_NUMBER { AcpiUtStrtoul64 (DtParsertext, ACPI_STRTOUL_64BIT, &$$);}
+ | EXPOP_DECIMAL_NUMBER { $$ = DtDoConstant (DtParsertext);}
;
%%
diff --git a/sys/contrib/dev/acpica/compiler/dtsubtable.c b/sys/contrib/dev/acpica/compiler/dtsubtable.c
index d75fa92..a258a61 100644
--- a/sys/contrib/dev/acpica/compiler/dtsubtable.c
+++ b/sys/contrib/dev/acpica/compiler/dtsubtable.c
@@ -150,7 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dtsubtable")
@@ -186,7 +185,7 @@ DtCreateSubtable (
/* Create a new buffer for the subtable data */
- String = UtStringCacheCalloc (Length);
+ String = UtLocalCacheCalloc (Length);
Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
memcpy (Subtable->Buffer, Buffer, Length);
diff --git a/sys/contrib/dev/acpica/compiler/dttable.c b/sys/contrib/dev/acpica/compiler/dttable.c
index 0d1df7f..7c3e9db 100644
--- a/sys/contrib/dev/acpica/compiler/dttable.c
+++ b/sys/contrib/dev/acpica/compiler/dttable.c
@@ -152,7 +152,6 @@
/* Compile routines for the basic ACPI tables */
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dttable")
diff --git a/sys/contrib/dev/acpica/compiler/dttable1.c b/sys/contrib/dev/acpica/compiler/dttable1.c
index 81a61b3..4f31e61 100644
--- a/sys/contrib/dev/acpica/compiler/dttable1.c
+++ b/sys/contrib/dev/acpica/compiler/dttable1.c
@@ -152,7 +152,6 @@
/* Compile all complex data tables, signatures starting with A-I */
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dttable1")
@@ -597,7 +596,13 @@ DtCompileDbg2 (
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
&Subtable, TRUE);
- if (ACPI_FAILURE (Status))
+ if (Status == AE_END_OF_TABLE)
+ {
+ /* optional field was not found and we're at the end of the file */
+
+ goto subtableDone;
+ }
+ else if (ACPI_FAILURE (Status))
{
return (Status);
}
@@ -616,7 +621,7 @@ DtCompileDbg2 (
DtInsertSubtable (ParentTable, Subtable);
}
-
+subtableDone:
SubtableCount--;
DtPopSubtable (); /* Get next Device Information subtable */
}
diff --git a/sys/contrib/dev/acpica/compiler/dttable2.c b/sys/contrib/dev/acpica/compiler/dttable2.c
index 4460394..73f543e 100644
--- a/sys/contrib/dev/acpica/compiler/dttable2.c
+++ b/sys/contrib/dev/acpica/compiler/dttable2.c
@@ -152,7 +152,6 @@
/* Compile all complex data tables, signatures starting with L-Z */
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dttable2")
@@ -698,6 +697,11 @@ DtCompileNfit (
InfoTable = AcpiDmTableInfoNfit6;
break;
+ case ACPI_NFIT_TYPE_CAPABILITIES:
+
+ InfoTable = AcpiDmTableInfoNfit7;
+ break;
+
default:
DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
@@ -741,7 +745,6 @@ DtCompileNfit (
}
Interleave->LineCount = Count;
- DtPopSubtable ();
break;
case ACPI_NFIT_TYPE_SMBIOS:
@@ -787,7 +790,6 @@ DtCompileNfit (
}
Hint->HintCount = (UINT16) Count;
- DtPopSubtable ();
break;
default:
@@ -904,6 +906,66 @@ DtCompilePcct (
/******************************************************************************
*
+ * FUNCTION: DtCompilePdtt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile PDTT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompilePdtt (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ ACPI_TABLE_PDTT *PdttHeader;
+ UINT32 Count = 0;
+
+
+ /* Main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
+ PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
+
+ /* There is only one type of subtable at this time, no need to decode */
+
+ while (*PFieldList)
+ {
+ /* List of subchannel IDs, each 2 bytes */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ Count++;
+ }
+
+ PdttHeader->TriggerCount = (UINT8) Count;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
* FUNCTION: DtCompilePmtt
*
* PARAMETERS: List - Current field list pointer
@@ -1285,6 +1347,219 @@ DtCompileS3pt (
/******************************************************************************
*
+ * FUNCTION: DtCompileSdev
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile SDEV.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileSdev (
+ void **List)
+{
+ ACPI_STATUS Status;
+ ACPI_SDEV_HEADER *SdevHeader;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_SDEV_PCIE *Pcie = NULL;
+ ACPI_SDEV_NAMESPACE *Namesp = NULL;
+ UINT32 EntryCount;
+
+
+ /* Subtables */
+
+ while (*PFieldList)
+ {
+ /* Compile common SDEV subtable header */
+
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
+ SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
+
+ switch (SdevHeader->Type)
+ {
+ case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
+
+ InfoTable = AcpiDmTableInfoSdev0;
+ Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
+ break;
+
+ case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
+
+ InfoTable = AcpiDmTableInfoSdev1;
+ Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
+ return (AE_ERROR);
+ }
+
+ /* Compile SDEV subtable body */
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* Optional data fields are appended to the main subtable body */
+
+ switch (SdevHeader->Type)
+ {
+ case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
+
+ /* Append DeviceId namespace string */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (!Subtable)
+ {
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ Namesp->DeviceIdOffset = sizeof (ACPI_SDEV_NAMESPACE);
+ Namesp->DeviceIdLength = (UINT16) Subtable->Length;
+
+ /* Append Vendor data */
+
+ Namesp->VendorDataLength = 0;
+ Namesp->VendorDataOffset = 0;
+
+ if (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (Subtable)
+ {
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ Namesp->VendorDataOffset =
+ Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
+ Namesp->VendorDataLength =
+ (UINT16) Subtable->Length;
+ }
+ }
+
+ /* Final size of entire namespace structure */
+
+ SdevHeader->Length = (UINT16) (sizeof (ACPI_SDEV_NAMESPACE) +
+ Subtable->Length + Namesp->DeviceIdLength);
+ break;
+
+ case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
+
+ /* Append the PCIe path info first */
+
+ EntryCount = 0;
+ while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
+ &Subtable, FALSE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (!Subtable)
+ {
+ DtPopSubtable ();
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ EntryCount++;
+ }
+
+ /* Path offset will point immediately after the main subtable */
+
+ Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
+ Pcie->PathLength = (UINT16)
+ (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
+
+ /* Append the Vendor Data last */
+
+ Pcie->VendorDataLength = 0;
+ Pcie->VendorDataOffset = 0;
+
+ if (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (Subtable)
+ {
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ Pcie->VendorDataOffset =
+ Pcie->PathOffset + Pcie->PathLength;
+ Pcie->VendorDataLength = (UINT16)
+ Subtable->Length;
+ }
+ }
+
+ SdevHeader->Length =
+ sizeof (ACPI_SDEV_PCIE) +
+ Pcie->PathLength + Pcie->VendorDataLength;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
+ return (AE_ERROR);
+ }
+
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
* FUNCTION: DtCompileSlic
*
* PARAMETERS: List - Current field list pointer
@@ -1603,6 +1878,109 @@ DtCompileTcpa (
/******************************************************************************
*
+ * FUNCTION: DtCompileTpm2
+ *
+ * PARAMETERS: PFieldList - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile TPM2.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileTpm2 (
+ void **List)
+{
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_SUBTABLE *Subtable;
+ ACPI_TABLE_TPM2 *Tpm2Header;
+ DT_SUBTABLE *ParentTable;
+ ACPI_STATUS Status = AE_OK;
+
+
+ /* Compile the main table */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
+
+ /* Method parameters */
+ /* Optional: Log area minimum length */
+ /* Optional: Log area start address */
+ /* TBD: Optional fields above not fully implemented (not optional at this time) */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+
+ /* Subtable type depends on the StartMethod */
+
+ switch (Tpm2Header->StartMethod)
+ {
+ case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
+
+ /* Subtable specific to to ARM_SMC */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
+ &Subtable, TRUE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ break;
+
+ case ACPI_TPM2_START_METHOD:
+ case ACPI_TPM2_MEMORY_MAPPED:
+ case ACPI_TPM2_COMMAND_BUFFER:
+ case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
+ break;
+
+ case ACPI_TPM2_RESERVED1:
+ case ACPI_TPM2_RESERVED3:
+ case ACPI_TPM2_RESERVED4:
+ case ACPI_TPM2_RESERVED5:
+ case ACPI_TPM2_RESERVED9:
+ case ACPI_TPM2_RESERVED10:
+
+ AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
+ Tpm2Header->StartMethod);
+ Status = AE_ERROR;
+ break;
+
+ case ACPI_TPM2_NOT_ALLOWED:
+ default:
+
+ AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
+ Tpm2Header->StartMethod);
+ Status = AE_ERROR;
+ break;
+ }
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
* FUNCTION: DtGetGenericTableInfo
*
* PARAMETERS: Name - Generic type name
diff --git a/sys/contrib/dev/acpica/compiler/dttemplate.c b/sys/contrib/dev/acpica/compiler/dttemplate.c
index 7ece577..309386c 100644
--- a/sys/contrib/dev/acpica/compiler/dttemplate.c
+++ b/sys/contrib/dev/acpica/compiler/dttemplate.c
@@ -151,7 +151,6 @@
#include <contrib/dev/acpica/compiler/aslcompiler.h>
#include <contrib/dev/acpica/include/acapps.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#include <contrib/dev/acpica/compiler/dttemplate.h> /* Contains the hex ACPI table templates */
#define _COMPONENT DT_COMPILER
@@ -315,7 +314,7 @@ Exit:
/* Shutdown ACPICA subsystem */
(void) AcpiTerminate ();
- CmDeleteCaches ();
+ UtDeleteLocalCaches ();
return (Status);
}
diff --git a/sys/contrib/dev/acpica/compiler/dttemplate.h b/sys/contrib/dev/acpica/compiler/dttemplate.h
index 8d27359..4c77afc 100644
--- a/sys/contrib/dev/acpica/compiler/dttemplate.h
+++ b/sys/contrib/dev/acpica/compiler/dttemplate.h
@@ -696,53 +696,56 @@ const unsigned char TemplateHpet[] =
const unsigned char TemplateIort[] =
{
- 0x49,0x4F,0x52,0x54,0x74,0x01,0x00,0x00, /* 00000000 "IORTt..." */
- 0x00,0xD2,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
- 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x49,0x4F,0x52,0x54,0x90,0x01,0x00,0x00, /* 00000000 "IORT...." */
+ 0x00,0x5F,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "._INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
- 0x19,0x01,0x17,0x20,0x05,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x31,0x08,0x17,0x20,0x05,0x00,0x00,0x00, /* 00000020 "1.. ...." */
0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "4......." */
0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00, /* 00000030 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000040 "........" */
- 0x00,0x00,0x00,0x00,0x01,0x44,0x00,0x00, /* 00000048 ".....D.." */
+ 0x00,0x00,0x00,0x00,0x01,0x58,0x00,0x00, /* 00000048 ".....X.." */
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000050 "........" */
- 0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "0......." */
+ 0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000058 "D......." */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 "........" */
0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43, /* 00000068 ".\_SB.PC" */
0x49,0x30,0x2E,0x44,0x45,0x56,0x30,0x00, /* 00000070 "I0.DEV0." */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
- 0x02,0x34,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000090 ".4......" */
- 0x01,0x00,0x00,0x00,0x20,0x00,0x00,0x00, /* 00000098 ".... ..." */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000090 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000098 "........" */
+ 0x00,0x00,0x00,0x00,0x02,0x34,0x00,0x00, /* 000000A0 ".....4.." */
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B0 " ......." */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */
- 0x00,0x00,0x00,0x00,0x03,0x60,0x00,0x00, /* 000000C0 ".....`.." */
- 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000C8 "........" */
- 0x4C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D0 "L......." */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D8 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
- 0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00, /* 000000E8 "....<..." */
- 0x00,0x00,0x00,0x00,0x4C,0x00,0x00,0x00, /* 000000F0 "....L..." */
- 0x00,0x00,0x00,0x00,0x4C,0x00,0x00,0x00, /* 000000F8 "....L..." */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000100 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000108 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000110 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D0 "........" */
+ 0x03,0x60,0x00,0x01,0x00,0x00,0x00,0x00, /* 000000D8 ".`......" */
+ 0x01,0x00,0x00,0x00,0x4C,0x00,0x00,0x00, /* 000000E0 "....L..." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 "........" */
+ 0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000100 "<......." */
+ 0x4C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000108 "L......." */
+ 0x4C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000110 "L......." */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000118 "........" */
- 0x00,0x00,0x00,0x00,0x04,0x50,0x00,0x00, /* 00000120 ".....P.." */
- 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000128 "........" */
- 0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000130 "<......." */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000138 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000140 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000120 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000128 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000130 "........" */
+ 0x04,0x58,0x00,0x01,0x00,0x00,0x00,0x00, /* 00000138 ".X......" */
+ 0x01,0x00,0x00,0x00,0x44,0x00,0x00,0x00, /* 00000140 "....D..." */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000148 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000150 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000158 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000160 "........" */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000168 "........" */
- 0x00,0x00,0x00,0x00 /* 00000170 "...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000170 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000178 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000180 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000188 "........" */
};
const unsigned char TemplateIvrs[] =
@@ -939,11 +942,11 @@ const unsigned char TemplateMsct[] =
const unsigned char TemplateNfit[] =
{
- 0x4E,0x46,0x49,0x54,0x70,0x01,0x00,0x00, /* 00000000 "NFITp..." */
- 0x01,0x53,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".SINTEL " */
+ 0x4E,0x46,0x49,0x54,0x80,0x01,0x00,0x00, /* 00000000 "NFIT...." */
+ 0x01,0x07,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
- 0x10,0x04,0x15,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
+ 0x29,0x09,0x17,0x20,0x00,0x00,0x00,0x00, /* 00000020 ").. ...." */
0x00,0x00,0x38,0x00,0x01,0x00,0x00,0x00, /* 00000028 "..8....." */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
0x30,0x05,0xAF,0x91,0x86,0x5D,0x0E,0x47, /* 00000038 "0....].G" */
@@ -984,7 +987,9 @@ const unsigned char TemplateNfit[] =
0x06,0x00,0x20,0x00,0x01,0x00,0x00,0x00, /* 00000150 ".. ....." */
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000158 "........" */
0x00,0x00,0x00,0x18,0x04,0x00,0x00,0x00, /* 00000160 "........" */
- 0x00,0x00,0x00,0x18,0x06,0x00,0x00,0x00 /* 00000168 "........" */
+ 0x00,0x00,0x00,0x18,0x06,0x00,0x00,0x00, /* 00000168 "........" */
+ 0x07,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 00000170 "........" */
+ 0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 00000178 "........" */
};
const unsigned char TemplateMtmr[] =
@@ -1079,6 +1084,17 @@ const unsigned char TemplatePcct[] =
0x55,0x55,0x55,0x55,0x55,0x55 /* 00000248 "UUUUUU| */
};
+const unsigned char TemplatePdtt[] =
+{
+ 0x50,0x44,0x54,0x54,0x34,0x00,0x00,0x00, /* 00000000 "PDTT4..." */
+ 0x01,0xCB,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x31,0x08,0x17,0x20,0x04,0x00,0x00,0x00, /* 00000020 "1.. ...." */
+ 0x2C,0x00,0x00,0x00,0xAA,0x03,0xBB,0x02, /* 00000028 ",......." */
+ 0xCC,0x01,0xDD,0x00 /* 00000030 "...." */
+};
+
const unsigned char TemplatePmtt[] =
{
0x50,0x4D,0x54,0x54,0xB4,0x00,0x00,0x00, /* 00000000 "PMTT...." */
@@ -1187,6 +1203,25 @@ const unsigned char TemplateSdei[] =
0x30,0x09,0x16,0x20 /* 00000028 "0.. " */
};
+const unsigned char TemplateSdev[] =
+{
+ 0x53,0x44,0x45,0x56,0x72,0x00,0x00,0x00, /* 00000000 "SDEVr..." */
+ 0x01,0x2F,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "./INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
+ 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
+ 0x31,0x08,0x17,0x20,0x00,0x01,0x2A,0x00, /* 00000020 "1.. ..*." */
+ 0x0C,0x00,0x16,0x00,0x22,0x00,0x08,0x00, /* 00000028 "...."..." */
+ 0x5C,0x5C,0x5F,0x53,0x42,0x5F,0x2E,0x50, /* 00000030 "\\_SB_.P" */
+ 0x43,0x49,0x30,0x2E,0x55,0x53,0x42,0x31, /* 00000038 "CI0.USB1" */
+ 0x2E,0x53,0x55,0x42,0x31,0x00,0x00,0x11, /* 00000040 ".SUB1..." */
+ 0x22,0x33,0x44,0x55,0x66,0x77,0x01,0x01, /* 00000048 ""3DUfw.." */
+ 0x24,0x00,0x10,0x00,0x20,0x00,0x10,0x00, /* 00000050 "$... ..." */
+ 0x04,0x00,0x14,0x00,0x10,0x00,0x11,0x22, /* 00000058 "......."" */
+ 0x33,0x44,0xEE,0xDD,0xCC,0xBB,0xAA,0x55, /* 00000060 "3D.....U" */
+ 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD, /* 00000068 "fw......" */
+ 0xEE,0xFF /* 00000070 ".." */
+};
+
const unsigned char TemplateSlic[] =
{
0x53,0x4C,0x49,0x43,0x76,0x01,0x00,0x00, /* 00000000 "SLICv..." */
@@ -1388,13 +1423,17 @@ const unsigned char TemplateTcpa[] =
const unsigned char TemplateTpm2[] =
{
- 0x54,0x50,0x4D,0x32,0x34,0x00,0x00,0x00, /* 00000000 "TPM24..." */
- 0x03,0x42,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".BINTEL " */
- 0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
+ 0x54,0x50,0x4D,0x32,0x58,0x00,0x00,0x00, /* 00000000 "TPM2X..." */
+ 0x03,0xAB,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
+ 0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
- 0x14,0x11,0x12,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
- 0x77,0x66,0x55,0x44,0x33,0x22,0x11,0x00, /* 00000028 "wfUD3".." */
- 0x01,0x00,0x00,0x00 /* 00000030 "...." */
+ 0x31,0x08,0x17,0x20,0x01,0x00,0x00,0x00, /* 00000020 "1.. ...." */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
+ 0x0B,0x00,0x00,0x00,0x01,0x02,0x03,0x04, /* 00000030 "........" */
+ 0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C, /* 00000038 "........" */
+ 0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000040 "........" */
+ 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, /* 00000048 "........" */
+ 0x01,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF /* 00000050 "........" */
};
const unsigned char TemplateUefi[] =
diff --git a/sys/contrib/dev/acpica/compiler/dtutils.c b/sys/contrib/dev/acpica/compiler/dtutils.c
index 031dc2e..54832f7 100644
--- a/sys/contrib/dev/acpica/compiler/dtutils.c
+++ b/sys/contrib/dev/acpica/compiler/dtutils.c
@@ -150,7 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#include <contrib/dev/acpica/include/actables.h>
#define _COMPONENT DT_COMPILER
@@ -303,6 +302,38 @@ DtFatal (
}
+/*******************************************************************************
+ *
+ * FUNCTION: DtDoConstant
+ *
+ * PARAMETERS: String - Only hex constants are supported,
+ * regardless of whether the 0x prefix
+ * is used
+ *
+ * RETURN: Converted Integer
+ *
+ * DESCRIPTION: Convert a string to an integer, with overflow/error checking.
+ *
+ ******************************************************************************/
+
+UINT64
+DtDoConstant (
+ char *String)
+{
+ UINT64 ConvertedInteger;
+
+
+ /*
+ * TBD: The ImplicitStrtoul64 function does not report overflow
+ * conditions. The input string is simply truncated. If it is
+ * desired to report overflow to the table compiler, this should
+ * somehow be added here. Note: integers that are prefixed with 0x
+ * or not are both hex integers.
+ */
+ ConvertedInteger = AcpiUtImplicitStrtoul64 (String);
+ return (ConvertedInteger);
+}
+
/******************************************************************************
*
* FUNCTION: DtGetFieldValue
@@ -538,6 +569,7 @@ DtGetFieldLength (
case ACPI_DMT_PCCT:
case ACPI_DMT_PMTT:
case ACPI_DMT_PPTT:
+ case ACPI_DMT_SDEV:
case ACPI_DMT_SRAT:
case ACPI_DMT_ASF:
case ACPI_DMT_HESTNTYP:
@@ -570,6 +602,7 @@ DtGetFieldLength (
case ACPI_DMT_NAME4:
case ACPI_DMT_SIG:
case ACPI_DMT_LPIT:
+ case ACPI_DMT_TPM2:
ByteLength = 4;
break;
@@ -888,153 +921,3 @@ DtWalkTableTree (
}
}
}
-
-
-/*******************************************************************************
- *
- * FUNCTION: UtSubtableCacheCalloc
- *
- * PARAMETERS: None
- *
- * RETURN: Pointer to the buffer. Aborts on allocation failure
- *
- * DESCRIPTION: Allocate a subtable object buffer. Bypass the local
- * dynamic memory manager for performance reasons (This has a
- * major impact on the speed of the compiler.)
- *
- ******************************************************************************/
-
-DT_SUBTABLE *
-UtSubtableCacheCalloc (
- void)
-{
- ASL_CACHE_INFO *Cache;
-
-
- if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast)
- {
- /* Allocate a new buffer */
-
- Cache = UtLocalCalloc (sizeof (Cache->Next) +
- (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE));
-
- /* Link new cache buffer to head of list */
-
- Cache->Next = Gbl_SubtableCacheList;
- Gbl_SubtableCacheList = Cache;
-
- /* Setup cache management pointers */
-
- Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer);
- Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE;
- }
-
- Gbl_SubtableCount++;
- return (Gbl_SubtableCacheNext++);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: UtFieldCacheCalloc
- *
- * PARAMETERS: None
- *
- * RETURN: Pointer to the buffer. Aborts on allocation failure
- *
- * DESCRIPTION: Allocate a field object buffer. Bypass the local
- * dynamic memory manager for performance reasons (This has a
- * major impact on the speed of the compiler.)
- *
- ******************************************************************************/
-
-DT_FIELD *
-UtFieldCacheCalloc (
- void)
-{
- ASL_CACHE_INFO *Cache;
-
-
- if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast)
- {
- /* Allocate a new buffer */
-
- Cache = UtLocalCalloc (sizeof (Cache->Next) +
- (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE));
-
- /* Link new cache buffer to head of list */
-
- Cache->Next = Gbl_FieldCacheList;
- Gbl_FieldCacheList = Cache;
-
- /* Setup cache management pointers */
-
- Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer);
- Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE;
- }
-
- Gbl_FieldCount++;
- return (Gbl_FieldCacheNext++);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: DtDeleteCaches
- *
- * PARAMETERS: None
- *
- * RETURN: None
- *
- * DESCRIPTION: Delete all local cache buffer blocks
- *
- ******************************************************************************/
-
-void
-DtDeleteCaches (
- void)
-{
- UINT32 BufferCount;
- ASL_CACHE_INFO *Next;
-
-
- /* Field cache */
-
- BufferCount = 0;
- while (Gbl_FieldCacheList)
- {
- Next = Gbl_FieldCacheList->Next;
- ACPI_FREE (Gbl_FieldCacheList);
- Gbl_FieldCacheList = Next;
- BufferCount++;
- }
-
- DbgPrint (ASL_DEBUG_OUTPUT,
- "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n",
- Gbl_FieldCount, ASL_FIELD_CACHE_SIZE,
- (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount);
-
- Gbl_FieldCount = 0;
- Gbl_FieldCacheNext = NULL;
- Gbl_FieldCacheLast = NULL;
-
- /* Subtable cache */
-
- BufferCount = 0;
- while (Gbl_SubtableCacheList)
- {
- Next = Gbl_SubtableCacheList->Next;
- ACPI_FREE (Gbl_SubtableCacheList);
- Gbl_SubtableCacheList = Next;
- BufferCount++;
- }
-
- DbgPrint (ASL_DEBUG_OUTPUT,
- "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n",
- Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE,
- (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount);
-
- Gbl_SubtableCount = 0;
- Gbl_SubtableCacheNext = NULL;
- Gbl_SubtableCacheLast = NULL;
-}
diff --git a/sys/contrib/dev/acpica/compiler/prexpress.c b/sys/contrib/dev/acpica/compiler/prexpress.c
index 892e73d..df2fc46 100644
--- a/sys/contrib/dev/acpica/compiler/prexpress.c
+++ b/sys/contrib/dev/acpica/compiler/prexpress.c
@@ -150,8 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
-
#define _COMPONENT ASL_PREPROCESSOR
ACPI_MODULE_NAME ("prexpress")
diff --git a/sys/contrib/dev/acpica/compiler/prmacros.c b/sys/contrib/dev/acpica/compiler/prmacros.c
index 82b221a..e1aaa3b 100644
--- a/sys/contrib/dev/acpica/compiler/prmacros.c
+++ b/sys/contrib/dev/acpica/compiler/prmacros.c
@@ -150,8 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
-
#define _COMPONENT ASL_PREPROCESSOR
ACPI_MODULE_NAME ("prmacros")
diff --git a/sys/contrib/dev/acpica/compiler/prparser.y b/sys/contrib/dev/acpica/compiler/prparser.y
index a6f789b..ec9c0c5 100644
--- a/sys/contrib/dev/acpica/compiler/prparser.y
+++ b/sys/contrib/dev/acpica/compiler/prparser.y
@@ -151,7 +151,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
#define _COMPONENT ASL_PREPROCESSOR
ACPI_MODULE_NAME ("prparser")
@@ -290,11 +289,11 @@ Expression
/* Default base for a non-prefixed integer is 10 */
- | EXPOP_NUMBER { AcpiUtStrtoul64 (PrParsertext, ACPI_STRTOUL_64BIT, &$$);}
+ | EXPOP_NUMBER { AcpiUtStrtoul64 (PrParsertext, &$$);}
/* Standard hex number (0x1234) */
- | EXPOP_HEX_NUMBER { AcpiUtStrtoul64 (PrParsertext, (ACPI_STRTOUL_BASE16 | ACPI_STRTOUL_64BIT), &$$);}
+ | EXPOP_HEX_NUMBER { AcpiUtStrtoul64 (PrParsertext, &$$);}
;
%%
diff --git a/sys/contrib/dev/acpica/compiler/prscan.c b/sys/contrib/dev/acpica/compiler/prscan.c
index 02df427..d4ee768 100644
--- a/sys/contrib/dev/acpica/compiler/prscan.c
+++ b/sys/contrib/dev/acpica/compiler/prscan.c
@@ -152,7 +152,6 @@
#define _DECLARE_PR_GLOBALS
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
/*
* TBDs:
@@ -1197,7 +1196,7 @@ PrPushDirective (
Info->Next = Gbl_DirectiveStack;
Info->Directive = Directive;
Info->IgnoringThisCodeBlock = Gbl_IgnoringThisCodeBlock;
- strncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH);
+ AcpiUtSafeStrncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH);
DbgPrint (ASL_DEBUG_OUTPUT,
"Pr(%.4u) - [%u %s] %*s Pushed [#%s %s]: IgnoreFlag = %s\n",
diff --git a/sys/contrib/dev/acpica/compiler/prutils.c b/sys/contrib/dev/acpica/compiler/prutils.c
index 45da814..3d7e5fe 100644
--- a/sys/contrib/dev/acpica/compiler/prutils.c
+++ b/sys/contrib/dev/acpica/compiler/prutils.c
@@ -150,8 +150,6 @@
*****************************************************************************/
#include <contrib/dev/acpica/compiler/aslcompiler.h>
-#include <contrib/dev/acpica/compiler/dtcompiler.h>
-
#define _COMPONENT ASL_PREPROCESSOR
ACPI_MODULE_NAME ("prutils")
@@ -514,7 +512,7 @@ PrPushInputFileStack (
/* Reset the global line count and filename */
Gbl_Files[ASL_FILE_INPUT].Filename =
- UtStringCacheCalloc (strlen (Filename) + 1);
+ UtLocalCacheCalloc (strlen (Filename) + 1);
strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
Gbl_Files[ASL_FILE_INPUT].Handle = InputFile;
diff --git a/sys/contrib/dev/acpica/components/debugger/dbconvert.c b/sys/contrib/dev/acpica/components/debugger/dbconvert.c
index 4206e5c..9551f4f 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbconvert.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbconvert.c
@@ -429,9 +429,7 @@ AcpiDbConvertToObject (
default:
Object->Type = ACPI_TYPE_INTEGER;
- Status = AcpiUtStrtoul64 (String,
- (AcpiGbl_IntegerByteWidth | ACPI_STRTOUL_BASE16),
- &Object->Integer.Value);
+ Status = AcpiUtStrtoul64 (String, &Object->Integer.Value);
break;
}
diff --git a/sys/contrib/dev/acpica/components/debugger/dbexec.c b/sys/contrib/dev/acpica/components/debugger/dbexec.c
index 2ca3a12..d6abb9a 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbexec.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbexec.c
@@ -187,6 +187,10 @@ AcpiDbExecutionWalk (
void *Context,
void **ReturnValue);
+static void ACPI_SYSTEM_XFACE
+AcpiDbSingleExecutionThread (
+ void *Context);
+
/*******************************************************************************
*
@@ -366,7 +370,7 @@ AcpiDbExecuteSetup (
ACPI_FUNCTION_NAME (DbExecuteSetup);
- /* Catenate the current scope to the supplied name */
+ /* Concatenate the current scope to the supplied name */
Info->Pathname[0] = 0;
if ((Info->Name[0] != '\\') &&
@@ -791,6 +795,124 @@ AcpiDbMethodThread (
/*******************************************************************************
*
+ * FUNCTION: AcpiDbSingleExecutionThread
+ *
+ * PARAMETERS: Context - Method info struct
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create one thread and execute a method
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+AcpiDbSingleExecutionThread (
+ void *Context)
+{
+ ACPI_DB_METHOD_INFO *Info = Context;
+ ACPI_STATUS Status;
+ ACPI_BUFFER ReturnObj;
+
+
+ AcpiOsPrintf ("\n");
+
+ Status = AcpiDbExecuteMethod (Info, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s During evaluation of %s\n",
+ AcpiFormatException (Status), Info->Pathname);
+ return;
+ }
+
+ /* Display a return object, if any */
+
+ if (ReturnObj.Length)
+ {
+ AcpiOsPrintf ("Evaluation of %s returned object %p, "
+ "external buffer length %X\n",
+ AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer,
+ (UINT32) ReturnObj.Length);
+
+ AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
+ }
+
+ AcpiOsPrintf ("\nBackground thread completed\n%c ",
+ ACPI_DEBUGGER_COMMAND_PROMPT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCreateExecutionThread
+ *
+ * PARAMETERS: MethodNameArg - Control method to execute
+ * Arguments - Array of arguments to the method
+ * Types - Corresponding array of object types
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create a single thread to evaluate a namespace object. Handles
+ * arguments passed on command line for control methods.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCreateExecutionThread (
+ char *MethodNameArg,
+ char **Arguments,
+ ACPI_OBJECT_TYPE *Types)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ memset (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
+ AcpiGbl_DbMethodInfo.Name = MethodNameArg;
+ AcpiGbl_DbMethodInfo.InitArgs = 1;
+ AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments;
+ AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes;
+
+ /* Setup method arguments, up to 7 (0-6) */
+
+ for (i = 0; (i < ACPI_METHOD_NUM_ARGS) && *Arguments; i++)
+ {
+ AcpiGbl_DbMethodInfo.Arguments[i] = *Arguments;
+ Arguments++;
+
+ AcpiGbl_DbMethodInfo.ArgTypes[i] = *Types;
+ Types++;
+ }
+
+ Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Get the NS node, determines existence also */
+
+ Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname,
+ &AcpiGbl_DbMethodInfo.Method);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s Could not get handle for %s\n",
+ AcpiFormatException (Status), AcpiGbl_DbMethodInfo.Pathname);
+ return;
+ }
+
+ Status = AcpiOsExecute (OSL_DEBUGGER_EXEC_THREAD,
+ AcpiDbSingleExecutionThread, &AcpiGbl_DbMethodInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("\nBackground thread started\n");
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiDbCreateExecutionThreads
*
* PARAMETERS: NumThreadsArg - Number of threads to create
diff --git a/sys/contrib/dev/acpica/components/debugger/dbfileio.c b/sys/contrib/dev/acpica/components/debugger/dbfileio.c
index a451272..ac55115 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbfileio.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbfileio.c
@@ -218,7 +218,7 @@ AcpiDbOpenDebugFile (
}
AcpiOsPrintf ("Debug output file %s opened\n", Name);
- strncpy (AcpiGbl_DbDebugFilename, Name,
+ AcpiUtSafeStrncpy (AcpiGbl_DbDebugFilename, Name,
sizeof (AcpiGbl_DbDebugFilename));
AcpiGbl_DbOutputToFile = TRUE;
}
diff --git a/sys/contrib/dev/acpica/components/debugger/dbinput.c b/sys/contrib/dev/acpica/components/debugger/dbinput.c
index 140395d..222f7ce 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbinput.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbinput.c
@@ -258,6 +258,7 @@ enum AcpiExDebuggerCommands
CMD_UNLOAD,
CMD_TERMINATE,
+ CMD_BACKGROUND,
CMD_THREADS,
CMD_TEST,
@@ -336,6 +337,7 @@ static const ACPI_DB_COMMAND_INFO AcpiGbl_DbCommands[] =
{"UNLOAD", 1},
{"TERMINATE", 0},
+ {"BACKGROUND", 1},
{"THREADS", 3},
{"TEST", 1},
@@ -346,102 +348,113 @@ static const ACPI_DB_COMMAND_INFO AcpiGbl_DbCommands[] =
/*
* Help for all debugger commands. First argument is the number of lines
* of help to output for the command.
+ *
+ * Note: Some commands are not supported by the kernel-level version of
+ * the debugger.
*/
static const ACPI_DB_COMMAND_HELP AcpiGbl_DbCommandHelp[] =
{
- {0, "\nGeneral-Purpose Commands:", "\n"},
- {1, " Allocations", "Display list of current memory allocations\n"},
- {2, " Dump <Address>|<Namepath>", "\n"},
- {0, " [Byte|Word|Dword|Qword]", "Display ACPI objects or memory\n"},
- {1, " Handlers", "Info about global handlers\n"},
- {1, " Help [Command]", "This help screen or individual command\n"},
- {1, " History", "Display command history buffer\n"},
- {1, " Level <DebugLevel>] [console]", "Get/Set debug level for file or console\n"},
- {1, " Locks", "Current status of internal mutexes\n"},
- {1, " Osi [Install|Remove <name>]", "Display or modify global _OSI list\n"},
- {1, " Quit or Exit", "Exit this command\n"},
- {8, " Stats <SubCommand>", "Display namespace and memory statistics\n"},
- {1, " Allocations", "Display list of current memory allocations\n"},
- {1, " Memory", "Dump internal memory lists\n"},
- {1, " Misc", "Namespace search and mutex stats\n"},
- {1, " Objects", "Summary of namespace objects\n"},
- {1, " Sizes", "Sizes for each of the internal objects\n"},
- {1, " Stack", "Display CPU stack usage\n"},
- {1, " Tables", "Info about current ACPI table(s)\n"},
- {1, " Tables", "Display info about loaded ACPI tables\n"},
- {1, " ! <CommandNumber>", "Execute command from history buffer\n"},
- {1, " !!", "Execute last command again\n"},
-
- {0, "\nNamespace Access Commands:", "\n"},
- {1, " Businfo", "Display system bus info\n"},
- {1, " Disassemble <Method>", "Disassemble a control method\n"},
- {1, " Find <AcpiName> (? is wildcard)", "Find ACPI name(s) with wildcards\n"},
- {1, " Integrity", "Validate namespace integrity\n"},
- {1, " Methods", "Display list of loaded control methods\n"},
- {1, " Namespace [Object] [Depth]", "Display loaded namespace tree/subtree\n"},
- {1, " Notify <Object> <Value>", "Send a notification on Object\n"},
- {1, " Objects [ObjectType]", "Display summary of all objects or just given type\n"},
- {1, " Owner <OwnerId> [Depth]", "Display loaded namespace by object owner\n"},
- {1, " Paths", "Display full pathnames of namespace objects\n"},
- {1, " Predefined", "Check all predefined names\n"},
- {1, " Prefix [<Namepath>]", "Set or Get current execution prefix\n"},
- {1, " References <Addr>", "Find all references to object at addr\n"},
- {1, " Resources [DeviceName]", "Display Device resources (no arg = all devices)\n"},
- {1, " Set N <NamedObject> <Value>", "Set value for named integer\n"},
- {1, " Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"},
- {1, " Type <Object>", "Display object type\n"},
-
- {0, "\nControl Method Execution Commands:","\n"},
- {1, " Arguments (or Args)", "Display method arguments\n"},
- {1, " Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"},
- {1, " Call", "Run to next control method invocation\n"},
- {1, " Debug <Namepath> [Arguments]", "Single Step a control method\n"},
- {6, " Evaluate", "Synonym for Execute\n"},
- {5, " Execute <Namepath> [Arguments]", "Execute control method\n"},
- {1, " Hex Integer", "Integer method argument\n"},
- {1, " \"Ascii String\"", "String method argument\n"},
- {1, " (Hex Byte List)", "Buffer method argument\n"},
- {1, " [Package Element List]", "Package method argument\n"},
- {5, " Execute predefined", "Execute all predefined (public) methods\n"},
- {1, " Go", "Allow method to run to completion\n"},
- {1, " Information", "Display info about the current method\n"},
- {1, " Into", "Step into (not over) a method call\n"},
- {1, " List [# of Aml Opcodes]", "Display method ASL statements\n"},
- {1, " Locals", "Display method local variables\n"},
- {1, " Results", "Display method result stack\n"},
- {1, " Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"},
- {1, " Stop", "Terminate control method\n"},
- {5, " Trace <State> [<Namepath>] [Once]", "Trace control method execution\n"},
- {1, " Enable", "Enable all messages\n"},
- {1, " Disable", "Disable tracing\n"},
- {1, " Method", "Enable method execution messages\n"},
- {1, " Opcode", "Enable opcode execution messages\n"},
- {1, " Tree", "Display control method calling tree\n"},
- {1, " <Enter>", "Single step next AML opcode (over calls)\n"},
+ {0, "\nNamespace Access:", "\n"},
+ {1, " Businfo", "Display system bus info\n"},
+ {1, " Disassemble <Method>", "Disassemble a control method\n"},
+ {1, " Find <AcpiName> (? is wildcard)", "Find ACPI name(s) with wildcards\n"},
+ {1, " Integrity", "Validate namespace integrity\n"},
+ {1, " Methods", "Display list of loaded control methods\n"},
+ {1, " Namespace [Object] [Depth]", "Display loaded namespace tree/subtree\n"},
+ {1, " Notify <Object> <Value>", "Send a notification on Object\n"},
+ {1, " Objects [ObjectType]", "Display summary of all objects or just given type\n"},
+ {1, " Owner <OwnerId> [Depth]", "Display loaded namespace by object owner\n"},
+ {1, " Paths", "Display full pathnames of namespace objects\n"},
+ {1, " Predefined", "Check all predefined names\n"},
+ {1, " Prefix [<Namepath>]", "Set or Get current execution prefix\n"},
+ {1, " References <Addr>", "Find all references to object at addr\n"},
+ {1, " Resources [DeviceName]", "Display Device resources (no arg = all devices)\n"},
+ {1, " Set N <NamedObject> <Value>", "Set value for named integer\n"},
+ {1, " Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"},
+ {1, " Type <Object>", "Display object type\n"},
+
+ {0, "\nControl Method Execution:", "\n"},
+ {1, " Evaluate <Namepath> [Arguments]", "Evaluate object or control method\n"},
+ {1, " Execute <Namepath> [Arguments]", "Synonym for Evaluate\n"},
+#ifdef ACPI_APPLICATION
+ {1, " Background <Namepath> [Arguments]", "Evaluate object/method in a separate thread\n"},
+ {1, " Thread <Threads><Loops><NamePath>", "Spawn threads to execute method(s)\n"},
+#endif
+ {1, " Debug <Namepath> [Arguments]", "Single-Step a control method\n"},
+ {7, " [Arguments] formats:", "Control method argument formats\n"},
+ {1, " Hex Integer", "Integer\n"},
+ {1, " \"Ascii String\"", "String\n"},
+ {1, " (Hex Byte List)", "Buffer\n"},
+ {1, " (01 42 7A BF)", "Buffer example (4 bytes)\n"},
+ {1, " [Package Element List]", "Package\n"},
+ {1, " [0x01 0x1234 \"string\"]", "Package example (3 elements)\n"},
+
+ {0, "\nMiscellaneous:", "\n"},
+ {1, " Allocations", "Display list of current memory allocations\n"},
+ {2, " Dump <Address>|<Namepath>", "\n"},
+ {0, " [Byte|Word|Dword|Qword]", "Display ACPI objects or memory\n"},
+ {1, " Handlers", "Info about global handlers\n"},
+ {1, " Help [Command]", "This help screen or individual command\n"},
+ {1, " History", "Display command history buffer\n"},
+ {1, " Level <DebugLevel>] [console]", "Get/Set debug level for file or console\n"},
+ {1, " Locks", "Current status of internal mutexes\n"},
+ {1, " Osi [Install|Remove <name>]", "Display or modify global _OSI list\n"},
+ {1, " Quit or Exit", "Exit this command\n"},
+ {8, " Stats <SubCommand>", "Display namespace and memory statistics\n"},
+ {1, " Allocations", "Display list of current memory allocations\n"},
+ {1, " Memory", "Dump internal memory lists\n"},
+ {1, " Misc", "Namespace search and mutex stats\n"},
+ {1, " Objects", "Summary of namespace objects\n"},
+ {1, " Sizes", "Sizes for each of the internal objects\n"},
+ {1, " Stack", "Display CPU stack usage\n"},
+ {1, " Tables", "Info about current ACPI table(s)\n"},
+ {1, " Tables", "Display info about loaded ACPI tables\n"},
+#ifdef ACPI_APPLICATION
+ {1, " Terminate", "Delete namespace and all internal objects\n"},
+#endif
+ {1, " ! <CommandNumber>", "Execute command from history buffer\n"},
+ {1, " !!", "Execute last command again\n"},
+
+ {0, "\nMethod and Namespace Debugging:", "\n"},
+ {5, " Trace <State> [<Namepath>] [Once]", "Trace control method execution\n"},
+ {1, " Enable", "Enable all messages\n"},
+ {1, " Disable", "Disable tracing\n"},
+ {1, " Method", "Enable method execution messages\n"},
+ {1, " Opcode", "Enable opcode execution messages\n"},
+ {3, " Test <TestName>", "Invoke a debug test\n"},
+ {1, " Objects", "Read/write/compare all namespace data objects\n"},
+ {1, " Predefined", "Validate all ACPI predefined names (_STA, etc.)\n"},
+ {1, " Execute predefined", "Execute all predefined (public) methods\n"},
+
+ {0, "\nControl Method Single-Step Execution:","\n"},
+ {1, " Arguments (or Args)", "Display method arguments\n"},
+ {1, " Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"},
+ {1, " Call", "Run to next control method invocation\n"},
+ {1, " Go", "Allow method to run to completion\n"},
+ {1, " Information", "Display info about the current method\n"},
+ {1, " Into", "Step into (not over) a method call\n"},
+ {1, " List [# of Aml Opcodes]", "Display method ASL statements\n"},
+ {1, " Locals", "Display method local variables\n"},
+ {1, " Results", "Display method result stack\n"},
+ {1, " Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"},
+ {1, " Stop", "Terminate control method\n"},
+ {1, " Tree", "Display control method calling tree\n"},
+ {1, " <Enter>", "Single step next AML opcode (over calls)\n"},
#ifdef ACPI_APPLICATION
- {0, "\nHardware Simulation Commands:", "\n"},
- {1, " EnableAcpi", "Enable ACPI (hardware) mode\n"},
- {1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
- {1, " Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"},
- {1, " Gpes", "Display info on all GPE devices\n"},
- {1, " Sci", "Generate an SCI\n"},
- {1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
-
- {0, "\nFile I/O Commands:", "\n"},
- {1, " Close", "Close debug output file\n"},
- {1, " Load <Input Filename>", "Load ACPI table from a file\n"},
- {1, " Open <Output Filename>", "Open a file for debug output\n"},
- {1, " Unload <Namepath>", "Unload an ACPI table via namespace object\n"},
-
- {0, "\nUser Space Commands:", "\n"},
- {1, " Terminate", "Delete namespace and all internal objects\n"},
- {1, " Thread <Threads><Loops><NamePath>", "Spawn threads to execute method(s)\n"},
-
- {0, "\nDebug Test Commands:", "\n"},
- {3, " Test <TestName>", "Invoke a debug test\n"},
- {1, " Objects", "Read/write/compare all namespace data objects\n"},
- {1, " Predefined", "Execute all ACPI predefined names (_STA, etc.)\n"},
+ {0, "\nFile Operations:", "\n"},
+ {1, " Close", "Close debug output file\n"},
+ {1, " Load <Input Filename>", "Load ACPI table from a file\n"},
+ {1, " Open <Output Filename>", "Open a file for debug output\n"},
+ {1, " Unload <Namepath>", "Unload an ACPI table via namespace object\n"},
+
+ {0, "\nHardware Simulation:", "\n"},
+ {1, " EnableAcpi", "Enable ACPI (hardware) mode\n"},
+ {1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
+ {1, " Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"},
+ {1, " Gpes", "Display info on all GPE devices\n"},
+ {1, " Sci", "Generate an SCI\n"},
+ {1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
#endif
{0, NULL, NULL}
};
@@ -571,11 +584,15 @@ AcpiDbDisplayHelp (
{
/* No argument to help, display help for all commands */
+ AcpiOsPrintf ("\nSummary of AML Debugger Commands\n\n");
+
while (Next->Invocation)
{
AcpiOsPrintf ("%-38s%s", Next->Invocation, Next->Description);
Next++;
}
+ AcpiOsPrintf ("\n");
+
}
else
{
@@ -1258,6 +1275,12 @@ AcpiDbCommandDispatch (
/* AcpiInitialize (NULL); */
break;
+ case CMD_BACKGROUND:
+
+ AcpiDbCreateExecutionThread (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2],
+ &AcpiGbl_DbArgTypes[2]);
+ break;
+
case CMD_THREADS:
AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmresrc.c b/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
index 260c23f..4615609 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmresrc.c
@@ -540,6 +540,20 @@ AcpiDmIsResourceTemplate (
BufferLength = NextOp->Common.Value.Size;
/*
+ * Any buffer smaller than one byte cannot possibly be a resource
+ * template. Two bytes could possibly be a "NULL" resource template
+ * with a lone end tag descriptor (as generated via
+ * "ResourceTemplate(){}"), but this would be an extremely unusual
+ * case, as the template would be essentially useless. The disassembler
+ * therefore does not recognize any two-byte buffer as a resource
+ * template.
+ */
+ if (BufferLength <= 2)
+ {
+ return (AE_TYPE);
+ }
+
+ /*
* Not a template if declared buffer length != actual length of the
* intialization byte list. Because the resource macros will create
* a buffer of the exact required length (buffer length will be equal
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmwalk.c b/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
index dceb6bf..f60a8a4 100644
--- a/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
+++ b/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
@@ -527,7 +527,7 @@ AcpiDmDescendingOp (
/* Determine which file this parse node is contained in. */
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
ASL_CV_LABEL_FILENODE (Op);
@@ -1046,7 +1046,7 @@ AcpiDmAscendingOp (
/* Point the Op's filename pointer to the proper file */
- if (Gbl_CaptureComments)
+ if (AcpiGbl_CaptureComments)
{
ASL_CV_LABEL_FILENODE (Op);
@@ -1074,7 +1074,7 @@ AcpiDmAscendingOp (
/* Print any comments that are at the end of the file here */
- if (Gbl_CaptureComments && AcpiGbl_LastListHead)
+ if (AcpiGbl_CaptureComments && AcpiGbl_LastListHead)
{
AcpiOsPrintf ("\n");
ASL_CV_PRINT_ONE_COMMENT_LIST (AcpiGbl_LastListHead, 0);
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c b/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c
index b23a273..b719a67 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dscontrol.c
@@ -234,7 +234,8 @@ AcpiDsExecBeginControlOp (
WalkState->ParserState.PkgEnd;
ControlState->Control.Opcode =
Op->Common.AmlOpcode;
-
+ ControlState->Control.LoopTimeout = AcpiOsGetTimer () +
+ (UINT64) (AcpiGbl_MaxLoopIterations * ACPI_100NSEC_PER_SEC);
/* Push the control state on this walk's control stack */
@@ -327,15 +328,15 @@ AcpiDsExecEndControlOp (
/* Predicate was true, the body of the loop was just executed */
/*
- * This loop counter mechanism allows the interpreter to escape
- * possibly infinite loops. This can occur in poorly written AML
- * when the hardware does not respond within a while loop and the
- * loop does not implement a timeout.
+ * This infinite loop detection mechanism allows the interpreter
+ * to escape possibly infinite loops. This can occur in poorly
+ * written AML when the hardware does not respond within a while
+ * loop and the loop does not implement a timeout.
*/
- ControlState->Control.LoopCount++;
- if (ControlState->Control.LoopCount > AcpiGbl_MaxLoopIterations)
+ if (ACPI_TIME_AFTER (AcpiOsGetTimer (),
+ ControlState->Control.LoopTimeout))
{
- Status = AE_AML_INFINITE_LOOP;
+ Status = AE_AML_LOOP_TIMEOUT;
break;
}
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsfield.c b/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
index a526863..566a396 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsfield.c
@@ -340,7 +340,8 @@ AcpiDsCreateBufferField (
ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Arg->Common.Value.String, Status);
return_ACPI_STATUS (Status);
}
}
@@ -524,7 +525,8 @@ AcpiDsGetFieldNames (
WalkState, &Info->ConnectionNode);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Child->Common.Value.Name, Status);
return_ACPI_STATUS (Status);
}
}
@@ -540,7 +542,8 @@ AcpiDsGetFieldNames (
WalkState, &Info->FieldNode);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ (char *) &Arg->Named.Name, Status);
return_ACPI_STATUS (Status);
}
else
@@ -639,7 +642,8 @@ AcpiDsCreateField (
#endif
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Arg->Common.Value.Name, Status);
return_ACPI_STATUS (Status);
}
}
@@ -769,7 +773,8 @@ AcpiDsInitFieldObjects (
Flags, WalkState, &Node);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ (char *) &Arg->Named.Name, Status);
if (Status != AE_ALREADY_EXISTS)
{
return_ACPI_STATUS (Status);
@@ -834,7 +839,8 @@ AcpiDsCreateBankField (
#endif
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Arg->Common.Value.Name, Status);
return_ACPI_STATUS (Status);
}
}
@@ -847,7 +853,8 @@ AcpiDsCreateBankField (
ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Arg->Common.Value.String, Status);
return_ACPI_STATUS (Status);
}
@@ -920,7 +927,8 @@ AcpiDsCreateIndexField (
ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Arg->Common.Value.String, Status);
return_ACPI_STATUS (Status);
}
@@ -932,7 +940,8 @@ AcpiDsCreateIndexField (
ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Arg->Common.Value.String, Status);
return_ACPI_STATUS (Status);
}
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsobject.c b/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
index 55061de..0e8dc72 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
@@ -223,7 +223,8 @@ AcpiDsBuildInternalObject (
ACPI_NAMESPACE_NODE, &(Op->Common.Node)));
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Op->Common.Value.String, Status);
return_ACPI_STATUS (Status);
}
}
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dspkginit.c b/sys/contrib/dev/acpica/components/dispatcher/dspkginit.c
index b7d45a6..6b42732 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dspkginit.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dspkginit.c
@@ -419,9 +419,12 @@ AcpiDsInitPackageElement (
ACPI_OPERAND_OBJECT **ElementPtr;
+ ACPI_FUNCTION_TRACE (DsInitPackageElement);
+
+
if (!SourceObject)
{
- return (AE_OK);
+ return_ACPI_STATUS (AE_OK);
}
/*
@@ -456,7 +459,7 @@ AcpiDsInitPackageElement (
SourceObject->Package.Flags |= AOPOBJ_DATA_VALID;
}
- return (AE_OK);
+ return_ACPI_STATUS (AE_OK);
}
@@ -481,6 +484,7 @@ AcpiDsResolvePackageElement (
ACPI_GENERIC_STATE ScopeInfo;
ACPI_OPERAND_OBJECT *Element = *ElementPtr;
ACPI_NAMESPACE_NODE *ResolvedNode;
+ ACPI_NAMESPACE_NODE *OriginalNode;
char *ExternalPath = NULL;
ACPI_OBJECT_TYPE Type;
@@ -576,6 +580,7 @@ AcpiDsResolvePackageElement (
* will remain as named references. This behavior is not described
* in the ACPI spec, but it appears to be an oversight.
*/
+ OriginalNode = ResolvedNode;
Status = AcpiExResolveNodeToValue (&ResolvedNode, NULL);
if (ACPI_FAILURE (Status))
{
@@ -607,26 +612,27 @@ AcpiDsResolvePackageElement (
*/
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_THERMAL:
-
- /* TBD: This may not be necesssary */
-
- AcpiUtAddReference (ResolvedNode->Object);
+ case ACPI_TYPE_METHOD:
break;
case ACPI_TYPE_MUTEX:
- case ACPI_TYPE_METHOD:
case ACPI_TYPE_POWER:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_EVENT:
case ACPI_TYPE_REGION:
+ /* AcpiExResolveNodeToValue gave these an extra reference */
+
+ AcpiUtRemoveReference (OriginalNode->Object);
break;
default:
/*
* For all other types - the node was resolved to an actual
- * operand object with a value, return the object
+ * operand object with a value, return the object. Remove
+ * a reference on the existing object.
*/
+ AcpiUtRemoveReference (Element);
*ElementPtr = (ACPI_OPERAND_OBJECT *) ResolvedNode;
break;
}
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsutils.c b/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
index 41583ab..abd55de 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
@@ -732,7 +732,8 @@ AcpiDsCreateOperand (
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (NameString, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ NameString, Status);
}
}
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswexec.c b/sys/contrib/dev/acpica/components/dispatcher/dswexec.c
index 9cdf756..5b165e0 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswexec.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswexec.c
@@ -253,7 +253,7 @@ AcpiDsGetPredicateValue (
* object. Implicitly convert the argument if necessary.
*/
Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc,
- ACPI_STRTOUL_BASE16);
+ ACPI_IMPLICIT_CONVERSION);
if (ACPI_FAILURE (Status))
{
goto Cleanup;
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswload.c b/sys/contrib/dev/acpica/components/dispatcher/dswload.c
index 2ac3d6d..60a4e30 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswload.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswload.c
@@ -325,7 +325,7 @@ AcpiDsLoad1BeginOp (
#endif
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Path, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status);
return_ACPI_STATUS (Status);
}
@@ -495,7 +495,7 @@ AcpiDsLoad1BeginOp (
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Path, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status);
return_ACPI_STATUS (Status);
}
}
diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswload2.c b/sys/contrib/dev/acpica/components/dispatcher/dswload2.c
index f0bcdba..cd691da 100644
--- a/sys/contrib/dev/acpica/components/dispatcher/dswload2.c
+++ b/sys/contrib/dev/acpica/components/dispatcher/dswload2.c
@@ -304,10 +304,12 @@ AcpiDsLoad2BeginOp (
}
else
{
- ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ BufferPtr, Status);
}
#else
- ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ BufferPtr, Status);
#endif
return_ACPI_STATUS (Status);
}
@@ -462,7 +464,8 @@ AcpiDsLoad2BeginOp (
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ BufferPtr, Status);
return_ACPI_STATUS (Status);
}
@@ -844,7 +847,8 @@ AcpiDsLoad2EndOp (
}
else
{
- ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
+ Arg->Common.Value.String, Status);
}
break;
diff --git a/sys/contrib/dev/acpica/components/events/evgpe.c b/sys/contrib/dev/acpica/components/events/evgpe.c
index f491e4b..4bbe9ad 100644
--- a/sys/contrib/dev/acpica/components/events/evgpe.c
+++ b/sys/contrib/dev/acpica/components/events/evgpe.c
@@ -551,8 +551,8 @@ AcpiEvGpeDetect (
ACPI_GPE_HANDLER_INFO *GpeHandlerInfo;
UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED;
UINT8 EnabledStatusByte;
- UINT32 StatusReg;
- UINT32 EnableReg;
+ UINT64 StatusReg;
+ UINT64 EnableReg;
ACPI_CPU_FLAGS Flags;
UINT32 i;
UINT32 j;
@@ -629,7 +629,7 @@ AcpiEvGpeDetect (
"RunEnable=%02X, WakeEnable=%02X\n",
GpeRegisterInfo->BaseGpeNumber,
GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
- StatusReg, EnableReg,
+ (UINT32) StatusReg, (UINT32) EnableReg,
GpeRegisterInfo->EnableForRun,
GpeRegisterInfo->EnableForWake));
diff --git a/sys/contrib/dev/acpica/components/events/evregion.c b/sys/contrib/dev/acpica/components/events/evregion.c
index ac2adc6..7cdd634 100644
--- a/sys/contrib/dev/acpica/components/events/evregion.c
+++ b/sys/contrib/dev/acpica/components/events/evregion.c
@@ -423,6 +423,17 @@ AcpiEvAddressSpaceDispatch (
{
ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]",
AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
+
+ /*
+ * Special case for an EC timeout. These are seen so frequently
+ * that an additional error message is helpful
+ */
+ if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) &&
+ (Status == AE_TIME))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Timeout from EC hardware or EC device driver"));
+ }
}
if (!(HandlerDesc->AddressSpace.HandlerFlags &
diff --git a/sys/contrib/dev/acpica/components/executer/exconcat.c b/sys/contrib/dev/acpica/components/executer/exconcat.c
index 1242af1..829a987 100644
--- a/sys/contrib/dev/acpica/components/executer/exconcat.c
+++ b/sys/contrib/dev/acpica/components/executer/exconcat.c
@@ -274,7 +274,7 @@ AcpiExDoConcatenate (
case ACPI_TYPE_INTEGER:
Status = AcpiExConvertToInteger (LocalOperand1, &TempOperand1,
- ACPI_STRTOUL_BASE16);
+ ACPI_IMPLICIT_CONVERSION);
break;
case ACPI_TYPE_BUFFER:
diff --git a/sys/contrib/dev/acpica/components/executer/exconvrt.c b/sys/contrib/dev/acpica/components/executer/exconvrt.c
index a56be00..d084e11 100644
--- a/sys/contrib/dev/acpica/components/executer/exconvrt.c
+++ b/sys/contrib/dev/acpica/components/executer/exconvrt.c
@@ -172,10 +172,10 @@ AcpiExConvertToAscii (
*
* FUNCTION: AcpiExConvertToInteger
*
- * PARAMETERS: ObjDesc - Object to be converted. Must be an
- * Integer, Buffer, or String
- * ResultDesc - Where the new Integer object is returned
- * Flags - Used for string conversion
+ * PARAMETERS: ObjDesc - Object to be converted. Must be an
+ * Integer, Buffer, or String
+ * ResultDesc - Where the new Integer object is returned
+ * ImplicitConversion - Used for string conversion
*
* RETURN: Status
*
@@ -187,14 +187,13 @@ ACPI_STATUS
AcpiExConvertToInteger (
ACPI_OPERAND_OBJECT *ObjDesc,
ACPI_OPERAND_OBJECT **ResultDesc,
- UINT32 Flags)
+ UINT32 ImplicitConversion)
{
ACPI_OPERAND_OBJECT *ReturnDesc;
UINT8 *Pointer;
UINT64 Result;
UINT32 i;
UINT32 Count;
- ACPI_STATUS Status;
ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc);
@@ -244,12 +243,17 @@ AcpiExConvertToInteger (
* hexadecimal as per the ACPI specification. The only exception (as
* of ACPI 3.0) is that the ToInteger() operator allows both decimal
* and hexadecimal strings (hex prefixed with "0x").
+ *
+ * Explicit conversion is used only by ToInteger.
+ * All other string-to-integer conversions are implicit conversions.
*/
- Status = AcpiUtStrtoul64 (ACPI_CAST_PTR (char, Pointer),
- (AcpiGbl_IntegerByteWidth | Flags), &Result);
- if (ACPI_FAILURE (Status))
+ if (ImplicitConversion)
+ {
+ Result = AcpiUtImplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer));
+ }
+ else
{
- return_ACPI_STATUS (Status);
+ Result = AcpiUtExplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer));
}
break;
@@ -792,7 +796,7 @@ AcpiExConvertToTargetType (
* a Buffer or a String to an Integer if necessary.
*/
Status = AcpiExConvertToInteger (SourceDesc, ResultDesc,
- ACPI_STRTOUL_BASE16);
+ ACPI_IMPLICIT_CONVERSION);
break;
case ACPI_TYPE_STRING:
diff --git a/sys/contrib/dev/acpica/components/executer/exdump.c b/sys/contrib/dev/acpica/components/executer/exdump.c
index 3c67608..5d600e1 100644
--- a/sys/contrib/dev/acpica/components/executer/exdump.c
+++ b/sys/contrib/dev/acpica/components/executer/exdump.c
@@ -747,7 +747,7 @@ AcpiExDumpOperand (
UINT32 Index;
- ACPI_FUNCTION_NAME (ExDumpOperand)
+ ACPI_FUNCTION_NAME (ExDumpOperand);
/* Check if debug output enabled */
@@ -1042,7 +1042,7 @@ AcpiExDumpOperands (
const char *OpcodeName,
UINT32 NumOperands)
{
- ACPI_FUNCTION_NAME (ExDumpOperands);
+ ACPI_FUNCTION_TRACE (ExDumpOperands);
if (!OpcodeName)
@@ -1070,7 +1070,7 @@ AcpiExDumpOperands (
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"**** End operand dump for [%s]\n", OpcodeName));
- return;
+ return_VOID;
}
diff --git a/sys/contrib/dev/acpica/components/executer/exmisc.c b/sys/contrib/dev/acpica/components/executer/exmisc.c
index 6385fc7..f4683ae 100644
--- a/sys/contrib/dev/acpica/components/executer/exmisc.c
+++ b/sys/contrib/dev/acpica/components/executer/exmisc.c
@@ -472,7 +472,7 @@ AcpiExDoLogicalOp (
case ACPI_TYPE_INTEGER:
Status = AcpiExConvertToInteger (Operand1, &LocalOperand1,
- ACPI_STRTOUL_BASE16);
+ ACPI_IMPLICIT_CONVERSION);
break;
case ACPI_TYPE_STRING:
diff --git a/sys/contrib/dev/acpica/components/executer/exresop.c b/sys/contrib/dev/acpica/components/executer/exresop.c
index c1a991d..cb820c7 100644
--- a/sys/contrib/dev/acpica/components/executer/exresop.c
+++ b/sys/contrib/dev/acpica/components/executer/exresop.c
@@ -541,7 +541,7 @@ AcpiExResolveOperands (
* Known as "Implicit Source Operand Conversion"
*/
Status = AcpiExConvertToInteger (ObjDesc, StackPtr,
- ACPI_STRTOUL_BASE16);
+ ACPI_IMPLICIT_CONVERSION);
if (ACPI_FAILURE (Status))
{
if (Status == AE_TYPE)
diff --git a/sys/contrib/dev/acpica/components/hardware/hwgpe.c b/sys/contrib/dev/acpica/components/hardware/hwgpe.c
index 002f336..680a4a9 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwgpe.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwgpe.c
@@ -217,7 +217,7 @@ AcpiHwLowSetGpe (
{
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
ACPI_STATUS Status = AE_OK;
- UINT32 EnableMask;
+ UINT64 EnableMask;
UINT32 RegisterBit;
@@ -342,7 +342,7 @@ AcpiHwGetGpeStatus (
ACPI_GPE_EVENT_INFO *GpeEventInfo,
ACPI_EVENT_STATUS *EventStatus)
{
- UINT32 InByte;
+ UINT64 InByte;
UINT32 RegisterBit;
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
ACPI_EVENT_STATUS LocalEventStatus = 0;
diff --git a/sys/contrib/dev/acpica/components/hardware/hwregs.c b/sys/contrib/dev/acpica/components/hardware/hwregs.c
index af4381c..854bb8f 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwregs.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwregs.c
@@ -355,9 +355,8 @@ AcpiHwValidateRegister (
*
* RETURN: Status
*
- * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
- * version of AcpiRead, used internally since the overhead of
- * 64-bit values is not needed.
+ * DESCRIPTION: Read from either memory or IO space. This is a 64-bit max
+ * version of AcpiRead.
*
* LIMITATIONS: <These limitations also apply to AcpiHwWrite>
* SpaceID must be SystemMemory or SystemIO.
@@ -366,7 +365,7 @@ AcpiHwValidateRegister (
ACPI_STATUS
AcpiHwRead (
- UINT32 *Value,
+ UINT64 *Value,
ACPI_GENERIC_ADDRESS *Reg)
{
UINT64 Address;
@@ -384,18 +383,18 @@ AcpiHwRead (
/* Validate contents of the GAS register */
- Status = AcpiHwValidateRegister (Reg, 32, &Address);
+ Status = AcpiHwValidateRegister (Reg, 64, &Address);
if (ACPI_FAILURE (Status))
{
return (Status);
}
/*
- * Initialize entire 32-bit return value to zero, convert AccessWidth
+ * Initialize entire 64-bit return value to zero, convert AccessWidth
* into number of bits based
*/
*Value = 0;
- AccessWidth = AcpiHwGetAccessBitWidth (Address, Reg, 32);
+ AccessWidth = AcpiHwGetAccessBitWidth (Address, Reg, 64);
BitWidth = Reg->BitOffset + Reg->BitWidth;
BitOffset = Reg->BitOffset;
@@ -408,7 +407,7 @@ AcpiHwRead (
{
if (BitOffset >= AccessWidth)
{
- Value32 = 0;
+ Value64 = 0;
BitOffset -= AccessWidth;
}
else
@@ -418,31 +417,31 @@ AcpiHwRead (
Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
Address + Index * ACPI_DIV_8 (AccessWidth),
&Value64, AccessWidth);
- Value32 = (UINT32) Value64;
}
else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
{
Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
Address + Index * ACPI_DIV_8 (AccessWidth),
&Value32, AccessWidth);
+ Value64 = (UINT64) Value32;
}
}
/*
* Use offset style bit writes because "Index * AccessWidth" is
- * ensured to be less than 32-bits by AcpiHwValidateRegister().
+ * ensured to be less than 64-bits by AcpiHwValidateRegister().
*/
ACPI_SET_BITS (Value, Index * AccessWidth,
- ACPI_MASK_BITS_ABOVE_32 (AccessWidth), Value32);
+ ACPI_MASK_BITS_ABOVE_64 (AccessWidth), Value64);
BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth;
Index++;
}
ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
- *Value, AccessWidth, ACPI_FORMAT_UINT64 (Address),
- AcpiUtGetRegionName (Reg->SpaceId)));
+ "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
+ ACPI_FORMAT_UINT64 (*Value), AccessWidth,
+ ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId)));
return (Status);
}
@@ -457,15 +456,14 @@ AcpiHwRead (
*
* RETURN: Status
*
- * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
- * version of AcpiWrite, used internally since the overhead of
- * 64-bit values is not needed.
+ * DESCRIPTION: Write to either memory or IO space. This is a 64-bit max
+ * version of AcpiWrite.
*
******************************************************************************/
ACPI_STATUS
AcpiHwWrite (
- UINT32 Value,
+ UINT64 Value,
ACPI_GENERIC_ADDRESS *Reg)
{
UINT64 Address;
@@ -473,7 +471,6 @@ AcpiHwWrite (
UINT32 BitWidth;
UINT8 BitOffset;
UINT64 Value64;
- UINT32 Value32;
UINT8 Index;
ACPI_STATUS Status;
@@ -483,7 +480,7 @@ AcpiHwWrite (
/* Validate contents of the GAS register */
- Status = AcpiHwValidateRegister (Reg, 32, &Address);
+ Status = AcpiHwValidateRegister (Reg, 64, &Address);
if (ACPI_FAILURE (Status))
{
return (Status);
@@ -491,7 +488,7 @@ AcpiHwWrite (
/* Convert AccessWidth into number of bits based */
- AccessWidth = AcpiHwGetAccessBitWidth (Address, Reg, 32);
+ AccessWidth = AcpiHwGetAccessBitWidth (Address, Reg, 64);
BitWidth = Reg->BitOffset + Reg->BitWidth;
BitOffset = Reg->BitOffset;
@@ -504,10 +501,10 @@ AcpiHwWrite (
{
/*
* Use offset style bit reads because "Index * AccessWidth" is
- * ensured to be less than 32-bits by AcpiHwValidateRegister().
+ * ensured to be less than 64-bits by AcpiHwValidateRegister().
*/
- Value32 = ACPI_GET_BITS (&Value, Index * AccessWidth,
- ACPI_MASK_BITS_ABOVE_32 (AccessWidth));
+ Value64 = ACPI_GET_BITS (&Value, Index * AccessWidth,
+ ACPI_MASK_BITS_ABOVE_64 (AccessWidth));
if (BitOffset >= AccessWidth)
{
@@ -517,7 +514,6 @@ AcpiHwWrite (
{
if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
{
- Value64 = (UINT64) Value32;
Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
Address + Index * ACPI_DIV_8 (AccessWidth),
Value64, AccessWidth);
@@ -526,7 +522,7 @@ AcpiHwWrite (
{
Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
Address + Index * ACPI_DIV_8 (AccessWidth),
- Value32, AccessWidth);
+ (UINT32) Value64, AccessWidth);
}
}
@@ -539,9 +535,9 @@ AcpiHwWrite (
}
ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
- Value, AccessWidth, ACPI_FORMAT_UINT64 (Address),
- AcpiUtGetRegionName (Reg->SpaceId)));
+ "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
+ ACPI_FORMAT_UINT64 (Value), AccessWidth,
+ ACPI_FORMAT_UINT64 (Address), AcpiUtGetRegionName (Reg->SpaceId)));
return (Status);
}
@@ -688,6 +684,7 @@ AcpiHwRegisterRead (
UINT32 *ReturnValue)
{
UINT32 Value = 0;
+ UINT64 Value64;
ACPI_STATUS Status;
@@ -726,12 +723,14 @@ AcpiHwRegisterRead (
case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock);
+ Status = AcpiHwRead (&Value64, &AcpiGbl_FADT.XPm2ControlBlock);
+ Value = (UINT32) Value64;
break;
case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
- Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock);
+ Status = AcpiHwRead (&Value64, &AcpiGbl_FADT.XPmTimerBlock);
+ Value = (UINT32) Value64;
break;
case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
@@ -749,7 +748,7 @@ AcpiHwRegisterRead (
if (ACPI_SUCCESS (Status))
{
- *ReturnValue = Value;
+ *ReturnValue = (UINT32) Value;
}
return_ACPI_STATUS (Status);
@@ -789,6 +788,7 @@ AcpiHwRegisterWrite (
{
ACPI_STATUS Status;
UINT32 ReadValue;
+ UINT64 ReadValue64;
ACPI_FUNCTION_TRACE (HwRegisterWrite);
@@ -850,11 +850,12 @@ AcpiHwRegisterWrite (
* For control registers, all reserved bits must be preserved,
* as per the ACPI spec.
*/
- Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock);
+ Status = AcpiHwRead (&ReadValue64, &AcpiGbl_FADT.XPm2ControlBlock);
if (ACPI_FAILURE (Status))
{
goto Exit;
}
+ ReadValue = (UINT32) ReadValue64;
/* Insert the bits to be preserved */
@@ -910,26 +911,29 @@ AcpiHwReadMultiple (
{
UINT32 ValueA = 0;
UINT32 ValueB = 0;
+ UINT64 Value64;
ACPI_STATUS Status;
/* The first register is always required */
- Status = AcpiHwRead (&ValueA, RegisterA);
+ Status = AcpiHwRead (&Value64, RegisterA);
if (ACPI_FAILURE (Status))
{
return (Status);
}
+ ValueA = (UINT32) Value64;
/* Second register is optional */
if (RegisterB->Address)
{
- Status = AcpiHwRead (&ValueB, RegisterB);
+ Status = AcpiHwRead (&Value64, RegisterB);
if (ACPI_FAILURE (Status))
{
return (Status);
}
+ ValueB = (UINT32) Value64;
}
/*
diff --git a/sys/contrib/dev/acpica/components/hardware/hwtimer.c b/sys/contrib/dev/acpica/components/hardware/hwtimer.c
index a27c830..22a4a97 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwtimer.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwtimer.c
@@ -215,6 +215,7 @@ AcpiGetTimer (
UINT32 *Ticks)
{
ACPI_STATUS Status;
+ UINT64 TimerValue;
ACPI_FUNCTION_TRACE (AcpiGetTimer);
@@ -232,7 +233,14 @@ AcpiGetTimer (
return_ACPI_STATUS (AE_SUPPORT);
}
- Status = AcpiHwRead (Ticks, &AcpiGbl_FADT.XPmTimerBlock);
+ Status = AcpiHwRead (&TimerValue, &AcpiGbl_FADT.XPmTimerBlock);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* ACPI PM Timer is defined to be 32 bits (PM_TMR_LEN) */
+
+ *Ticks = (UINT32) TimerValue;
+ }
+
return_ACPI_STATUS (Status);
}
@@ -275,7 +283,7 @@ AcpiGetTimerDuration (
UINT32 *TimeElapsed)
{
ACPI_STATUS Status;
- UINT32 DeltaTicks;
+ UINT64 DeltaTicks;
UINT64 Quotient;
@@ -294,34 +302,33 @@ AcpiGetTimerDuration (
return_ACPI_STATUS (AE_SUPPORT);
}
+ if (StartTicks == EndTicks)
+ {
+ *TimeElapsed = 0;
+ return_ACPI_STATUS (AE_OK);
+ }
+
/*
* Compute Tick Delta:
* Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
*/
- if (StartTicks < EndTicks)
- {
- DeltaTicks = EndTicks - StartTicks;
- }
- else if (StartTicks > EndTicks)
+ DeltaTicks = EndTicks;
+ if (StartTicks > EndTicks)
{
if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
{
/* 24-bit Timer */
- DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF);
+ DeltaTicks |= (UINT64) 1 << 24;
}
else
{
/* 32-bit Timer */
- DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks;
+ DeltaTicks |= (UINT64) 1 << 32;
}
}
- else /* StartTicks == EndTicks */
- {
- *TimeElapsed = 0;
- return_ACPI_STATUS (AE_OK);
- }
+ DeltaTicks -= StartTicks;
/*
* Compute Duration (Requires a 64-bit multiply and divide):
@@ -329,7 +336,7 @@ AcpiGetTimerDuration (
* TimeElapsed (microseconds) =
* (DeltaTicks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY;
*/
- Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * ACPI_USEC_PER_SEC,
+ Status = AcpiUtShortDivide (DeltaTicks * ACPI_USEC_PER_SEC,
ACPI_PM_TIMER_FREQUENCY, &Quotient, NULL);
*TimeElapsed = (UINT32) Quotient;
diff --git a/sys/contrib/dev/acpica/components/hardware/hwvalid.c b/sys/contrib/dev/acpica/components/hardware/hwvalid.c
index 4975a58..61cd0e3 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwvalid.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwvalid.c
@@ -245,7 +245,7 @@ AcpiHwValidateIoRequest (
const ACPI_PORT_INFO *PortInfo;
- ACPI_FUNCTION_NAME (HwValidateIoRequest);
+ ACPI_FUNCTION_TRACE (HwValidateIoRequest);
/* Supported widths are 8/16/32 */
@@ -256,14 +256,15 @@ AcpiHwValidateIoRequest (
{
ACPI_ERROR ((AE_INFO,
"Bad BitWidth parameter: %8.8X", BitWidth));
- return (AE_BAD_PARAMETER);
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
}
PortInfo = AcpiProtectedPorts;
ByteWidth = ACPI_DIV_8 (BitWidth);
LastAddress = Address + ByteWidth - 1;
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Address %8.8X%8.8X LastAddress %8.8X%8.8X Length %X",
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "Address %8.8X%8.8X LastAddress %8.8X%8.8X Length %X",
ACPI_FORMAT_UINT64 (Address), ACPI_FORMAT_UINT64 (LastAddress),
ByteWidth));
@@ -274,14 +275,14 @@ AcpiHwValidateIoRequest (
ACPI_ERROR ((AE_INFO,
"Illegal I/O port address/length above 64K: %8.8X%8.8X/0x%X",
ACPI_FORMAT_UINT64 (Address), ByteWidth));
- return (AE_LIMIT);
+ return_ACPI_STATUS (AE_LIMIT);
}
/* Exit if requested address is not within the protected port table */
if (Address > AcpiProtectedPorts[ACPI_PORT_INFO_ENTRIES - 1].End)
{
- return (AE_OK);
+ return_ACPI_STATUS (AE_OK);
}
/* Check request against the list of protected I/O ports */
@@ -303,8 +304,8 @@ AcpiHwValidateIoRequest (
if (AcpiGbl_OsiData >= PortInfo->OsiDependency)
{
- ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)",
+ ACPI_DEBUG_PRINT ((ACPI_DB_VALUES,
+ "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)\n",
ACPI_FORMAT_UINT64 (Address), ByteWidth, PortInfo->Name,
PortInfo->Start, PortInfo->End));
@@ -320,7 +321,7 @@ AcpiHwValidateIoRequest (
}
}
- return (AE_OK);
+ return_ACPI_STATUS (AE_OK);
}
diff --git a/sys/contrib/dev/acpica/components/hardware/hwxface.c b/sys/contrib/dev/acpica/components/hardware/hwxface.c
index b049114..78c2af5 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwxface.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwxface.c
@@ -247,84 +247,14 @@ AcpiRead (
UINT64 *ReturnValue,
ACPI_GENERIC_ADDRESS *Reg)
{
- UINT32 ValueLo;
- UINT32 ValueHi;
- UINT32 Width;
- UINT64 Address;
ACPI_STATUS Status;
ACPI_FUNCTION_NAME (AcpiRead);
- if (!ReturnValue)
- {
- return (AE_BAD_PARAMETER);
- }
-
- /* Validate contents of the GAS register. Allow 64-bit transfers */
-
- Status = AcpiHwValidateRegister (Reg, 64, &Address);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- /*
- * Two address spaces supported: Memory or I/O. PCI_Config is
- * not supported here because the GAS structure is insufficient
- */
- if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
- {
- Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
- Address, ReturnValue, Reg->BitWidth);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
- }
- else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
- {
- ValueLo = 0;
- ValueHi = 0;
-
- Width = Reg->BitWidth;
- if (Width == 64)
- {
- Width = 32; /* Break into two 32-bit transfers */
- }
-
- Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
- Address, &ValueLo, Width);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- if (Reg->BitWidth == 64)
- {
- /* Read the top 32 bits */
-
- Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
- (Address + 4), &ValueHi, 32);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
- }
-
- /* Set the return value only if status is AE_OK */
-
- *ReturnValue = (ValueLo | ((UINT64) ValueHi << 32));
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
- ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
- ACPI_FORMAT_UINT64 (Address),
- AcpiUtGetRegionName (Reg->SpaceId)));
-
- return (AE_OK);
+ Status = AcpiHwRead (ReturnValue, Reg);
+ return (Status);
}
ACPI_EXPORT_SYMBOL (AcpiRead)
@@ -348,67 +278,13 @@ AcpiWrite (
UINT64 Value,
ACPI_GENERIC_ADDRESS *Reg)
{
- UINT32 Width;
- UINT64 Address;
ACPI_STATUS Status;
ACPI_FUNCTION_NAME (AcpiWrite);
- /* Validate contents of the GAS register. Allow 64-bit transfers */
-
- Status = AcpiHwValidateRegister (Reg, 64, &Address);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- /*
- * Two address spaces supported: Memory or IO. PCI_Config is
- * not supported here because the GAS structure is insufficient
- */
- if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
- {
- Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
- Address, Value, Reg->BitWidth);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
- }
- else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
- {
- Width = Reg->BitWidth;
- if (Width == 64)
- {
- Width = 32; /* Break into two 32-bit transfers */
- }
-
- Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
- Address, ACPI_LODWORD (Value), Width);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- if (Reg->BitWidth == 64)
- {
- Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
- (Address + 4), ACPI_HIDWORD (Value), 32);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
- }
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
- ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
- ACPI_FORMAT_UINT64 (Address),
- AcpiUtGetRegionName (Reg->SpaceId)));
-
+ Status = AcpiHwWrite (Value, Reg);
return (Status);
}
diff --git a/sys/contrib/dev/acpica/components/namespace/nsaccess.c b/sys/contrib/dev/acpica/components/namespace/nsaccess.c
index 1d979ce..28c3248 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsaccess.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsaccess.c
@@ -775,19 +775,19 @@ AcpiNsLookup (
ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object;
}
}
-#ifdef ACPI_ASL_COMPILER
- if (!AcpiGbl_DisasmFlag &&
- (ThisNode->Flags & ANOBJ_IS_EXTERNAL))
- {
- ThisNode->Flags |= IMPLICIT_EXTERNAL;
- }
-#endif
}
/* Special handling for the last segment (NumSegments == 0) */
else
{
+#ifdef ACPI_ASL_COMPILER
+ if (!AcpiGbl_DisasmFlag && (ThisNode->Flags & ANOBJ_IS_EXTERNAL))
+ {
+ ThisNode->Flags &= ~IMPLICIT_EXTERNAL;
+ }
+#endif
+
/*
* Sanity typecheck of the target object:
*
diff --git a/sys/contrib/dev/acpica/components/namespace/nsconvert.c b/sys/contrib/dev/acpica/components/namespace/nsconvert.c
index 4ba8b5d..1f8b874 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsconvert.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsconvert.c
@@ -191,8 +191,7 @@ AcpiNsConvertToInteger (
/* String-to-Integer conversion */
- Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer,
- AcpiGbl_IntegerByteWidth, &Value);
+ Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer, &Value);
if (ACPI_FAILURE (Status))
{
return (Status);
@@ -645,7 +644,8 @@ AcpiNsConvertToReference (
{
/* Check if we are resolving a named reference within a package */
- ACPI_ERROR_NAMESPACE (OriginalObject->String.Pointer, Status);
+ ACPI_ERROR_NAMESPACE (&ScopeInfo,
+ OriginalObject->String.Pointer, Status);
goto ErrorExit;
}
diff --git a/sys/contrib/dev/acpica/components/namespace/nsnames.c b/sys/contrib/dev/acpica/components/namespace/nsnames.c
index f122729..389c83d 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsnames.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsnames.c
@@ -158,6 +158,12 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsnames")
+/* Local Prototypes */
+
+static void
+AcpiNsNormalizePathname (
+ char *OriginalPath);
+
/*******************************************************************************
*
@@ -507,3 +513,169 @@ AcpiNsGetNormalizedPathname (
return_PTR (NameBuffer);
}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsBuildPrefixedPathname
+ *
+ * PARAMETERS: PrefixScope - Scope/Path that prefixes the internal path
+ * InternalPath - Name or path of the namespace node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Construct a fully qualified pathname from a concatenation of:
+ * 1) Path associated with the PrefixScope namespace node
+ * 2) External path representation of the Internal path
+ *
+ ******************************************************************************/
+
+char *
+AcpiNsBuildPrefixedPathname (
+ ACPI_GENERIC_STATE *PrefixScope,
+ const char *InternalPath)
+{
+ ACPI_STATUS Status;
+ char *FullPath = NULL;
+ char *ExternalPath = NULL;
+ char *PrefixPath = NULL;
+ UINT32 PrefixPathLength = 0;
+
+
+ /* If there is a prefix, get the pathname to it */
+
+ if (PrefixScope && PrefixScope->Scope.Node)
+ {
+ PrefixPath = AcpiNsGetNormalizedPathname (PrefixScope->Scope.Node, TRUE);
+ if (PrefixPath)
+ {
+ PrefixPathLength = strlen (PrefixPath);
+ }
+ }
+
+ Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
+ NULL, &ExternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Merge the prefix path and the path. 2 is for one dot and trailing null */
+
+ FullPath = ACPI_ALLOCATE_ZEROED (
+ PrefixPathLength + strlen (ExternalPath) + 2);
+ if (!FullPath)
+ {
+ goto Cleanup;
+ }
+
+ /* Don't merge if the External path is already fully qualified */
+
+ if (PrefixPath &&
+ (*ExternalPath != '\\') &&
+ (*ExternalPath != '^'))
+ {
+ strcat (FullPath, PrefixPath);
+ if (PrefixPath[1])
+ {
+ strcat (FullPath, ".");
+ }
+ }
+
+ AcpiNsNormalizePathname (ExternalPath);
+ strcat (FullPath, ExternalPath);
+
+Cleanup:
+ if (PrefixPath)
+ {
+ ACPI_FREE (PrefixPath);
+ }
+ if (ExternalPath)
+ {
+ ACPI_FREE (ExternalPath);
+ }
+
+ return (FullPath);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsNormalizePathname
+ *
+ * PARAMETERS: OriginalPath - Path to be normalized, in External format
+ *
+ * RETURN: The original path is processed in-place
+ *
+ * DESCRIPTION: Remove trailing underscores from each element of a path.
+ *
+ * For example: \A___.B___.C___ becomes \A.B.C
+ *
+ ******************************************************************************/
+
+static void
+AcpiNsNormalizePathname (
+ char *OriginalPath)
+{
+ char *InputPath = OriginalPath;
+ char *NewPathBuffer;
+ char *NewPath;
+ UINT32 i;
+
+
+ /* Allocate a temp buffer in which to construct the new path */
+
+ NewPathBuffer = ACPI_ALLOCATE_ZEROED (strlen (InputPath) + 1);
+ NewPath = NewPathBuffer;
+ if (!NewPathBuffer)
+ {
+ return;
+ }
+
+ /* Special characters may appear at the beginning of the path */
+
+ if (*InputPath == '\\')
+ {
+ *NewPath = *InputPath;
+ NewPath++;
+ InputPath++;
+ }
+
+ while (*InputPath == '^')
+ {
+ *NewPath = *InputPath;
+ NewPath++;
+ InputPath++;
+ }
+
+ /* Remainder of the path */
+
+ while (*InputPath)
+ {
+ /* Do one nameseg at a time */
+
+ for (i = 0; (i < ACPI_NAME_SIZE) && *InputPath; i++)
+ {
+ if ((i == 0) || (*InputPath != '_')) /* First char is allowed to be underscore */
+ {
+ *NewPath = *InputPath;
+ NewPath++;
+ }
+
+ InputPath++;
+ }
+
+ /* Dot means that there are more namesegs to come */
+
+ if (*InputPath == '.')
+ {
+ *NewPath = *InputPath;
+ NewPath++;
+ InputPath++;
+ }
+ }
+
+ *NewPath = 0;
+ strcpy (OriginalPath, NewPathBuffer);
+ ACPI_FREE (NewPathBuffer);
+}
diff --git a/sys/contrib/dev/acpica/components/namespace/nssearch.c b/sys/contrib/dev/acpica/components/namespace/nssearch.c
index 0c6eaf9..8d14d52 100644
--- a/sys/contrib/dev/acpica/components/namespace/nssearch.c
+++ b/sys/contrib/dev/acpica/components/namespace/nssearch.c
@@ -545,6 +545,7 @@ AcpiNsSearchAndEnter (
(WalkState && WalkState->Opcode == AML_SCOPE_OP))
{
NewNode->Flags |= ANOBJ_IS_EXTERNAL;
+ NewNode->Flags |= IMPLICIT_EXTERNAL;
}
#endif
diff --git a/sys/contrib/dev/acpica/components/namespace/nsxfeval.c b/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
index b8590f2..b357245 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
@@ -174,11 +174,11 @@ AcpiNsResolveReferences (
*
* PARAMETERS: Handle - Object handle (optional)
* Pathname - Object pathname (optional)
- * ExternalParams - List of parameters to pass to method,
+ * ExternalParams - List of parameters to pass to a method,
* terminated by NULL. May be NULL
* if no parameters are being passed.
- * ReturnBuffer - Where to put method's return value (if
- * any). If NULL, no value is returned.
+ * ReturnBuffer - Where to put the object return value (if
+ * any). Required.
* ReturnType - Expected type of return object
*
* RETURN: Status
@@ -218,10 +218,16 @@ AcpiEvaluateObjectTyped (
FreeBufferOnError = TRUE;
}
- Status = AcpiGetHandle (Handle, Pathname, &TargetHandle);
- if (ACPI_FAILURE (Status))
+ /* Get a handle here, in order to build an error message if needed */
+
+ TargetHandle = Handle;
+ if (Pathname)
{
- return_ACPI_STATUS (Status);
+ Status = AcpiGetHandle (Handle, Pathname, &TargetHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
}
FullPathname = AcpiNsGetExternalPathname (TargetHandle);
diff --git a/sys/contrib/dev/acpica/components/parser/psargs.c b/sys/contrib/dev/acpica/components/parser/psargs.c
index 32dd906..7bf286c 100644
--- a/sys/contrib/dev/acpica/components/parser/psargs.c
+++ b/sys/contrib/dev/acpica/components/parser/psargs.c
@@ -500,7 +500,7 @@ AcpiPsGetNextNamepath (
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR_NAMESPACE (Path, Status);
+ ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status);
if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
ACPI_PARSE_EXECUTE)
diff --git a/sys/contrib/dev/acpica/components/parser/psobject.c b/sys/contrib/dev/acpica/components/parser/psobject.c
index 73091e3..0260632 100644
--- a/sys/contrib/dev/acpica/components/parser/psobject.c
+++ b/sys/contrib/dev/acpica/components/parser/psobject.c
@@ -500,15 +500,10 @@ AcpiPsCreateOp (
* external declaration opcode. Setting WalkState->Aml to
* WalkState->ParserState.Aml + 2 moves increments the
* WalkState->Aml past the object type and the paramcount of the
- * external opcode. For the error message, only print the AML
- * offset. We could attempt to print the name but this may cause
- * a segmentation fault when printing the namepath because the
- * AML may be incorrect.
+ * external opcode.
*/
- AcpiOsPrintf (
- "// Invalid external declaration at AML offset 0x%x.\n",
- WalkState->Aml - WalkState->ParserState.AmlStart);
WalkState->Aml = WalkState->ParserState.Aml + 2;
+ WalkState->ParserState.Aml = WalkState->Aml;
return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
}
#endif
diff --git a/sys/contrib/dev/acpica/components/parser/psutils.c b/sys/contrib/dev/acpica/components/parser/psutils.c
index c67a7ae..9f34531 100644
--- a/sys/contrib/dev/acpica/components/parser/psutils.c
+++ b/sys/contrib/dev/acpica/components/parser/psutils.c
@@ -213,7 +213,7 @@ AcpiPsInitOp (
Op->Common.DescriptorType = ACPI_DESC_TYPE_PARSER;
Op->Common.AmlOpcode = Opcode;
- ACPI_DISASM_ONLY_MEMBERS (strncpy (Op->Common.AmlOpName,
+ ACPI_DISASM_ONLY_MEMBERS (AcpiUtSafeStrncpy (Op->Common.AmlOpName,
(AcpiPsGetOpcodeInfo (Opcode))->Name,
sizeof (Op->Common.AmlOpName)));
}
@@ -292,11 +292,11 @@ AcpiPsAllocOp (
{
AcpiGbl_CurrentScope = Op;
}
- }
- if (Gbl_CaptureComments)
- {
- ASL_CV_TRANSFER_COMMENTS (Op);
+ if (AcpiGbl_CaptureComments)
+ {
+ ASL_CV_TRANSFER_COMMENTS (Op);
+ }
}
return (Op);
diff --git a/sys/contrib/dev/acpica/components/tables/tbxface.c b/sys/contrib/dev/acpica/components/tables/tbxface.c
index 09e99eb..da550e8 100644
--- a/sys/contrib/dev/acpica/components/tables/tbxface.c
+++ b/sys/contrib/dev/acpica/components/tables/tbxface.c
@@ -300,10 +300,13 @@ AcpiReallocateRootTable (
/*
- * Only reallocate the root table if the host provided a static buffer
- * for the table array in the call to AcpiInitializeTables.
+ * If there are tables unverified, it is required to reallocate the
+ * root table list to clean up invalid table entries. Otherwise only
+ * reallocate the root table list if the host provided a static buffer
+ * for the table array in the call to AcpiInitializeTables().
*/
- if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
+ if ((AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) &&
+ AcpiGbl_EnableTableValidation)
{
return_ACPI_STATUS (AE_SUPPORT);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utdebug.c b/sys/contrib/dev/acpica/components/utilities/utdebug.c
index 70644d7..aa15767 100644
--- a/sys/contrib/dev/acpica/components/utilities/utdebug.c
+++ b/sys/contrib/dev/acpica/components/utilities/utdebug.c
@@ -290,7 +290,9 @@ AcpiDebugPrint (
{
ACPI_THREAD_ID ThreadId;
va_list args;
-
+#ifdef ACPI_APPLICATION
+ int FillCount;
+#endif
/* Check if debug output enabled */
@@ -334,10 +336,21 @@ AcpiDebugPrint (
AcpiOsPrintf ("[%u] ", (UINT32) ThreadId);
}
- AcpiOsPrintf ("[%02ld] ", AcpiGbl_NestingLevel);
-#endif
+ FillCount = 48 - AcpiGbl_NestingLevel -
+ strlen (AcpiUtTrimFunctionName (FunctionName));
+ if (FillCount < 0)
+ {
+ FillCount = 0;
+ }
+ AcpiOsPrintf ("[%02ld] %*s",
+ AcpiGbl_NestingLevel, AcpiGbl_NestingLevel + 1, " ");
+ AcpiOsPrintf ("%s%*s: ",
+ AcpiUtTrimFunctionName (FunctionName), FillCount, " ");
+
+#else
AcpiOsPrintf ("%-22.22s: ", AcpiUtTrimFunctionName (FunctionName));
+#endif
va_start (args, Format);
AcpiOsVprintf (Format, args);
diff --git a/sys/contrib/dev/acpica/components/utilities/utdecode.c b/sys/contrib/dev/acpica/components/utilities/utdecode.c
index 726853d..d77c71f 100644
--- a/sys/contrib/dev/acpica/components/utilities/utdecode.c
+++ b/sys/contrib/dev/acpica/components/utilities/utdecode.c
@@ -558,11 +558,6 @@ AcpiUtGetReferenceName (
}
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-/*
- * Strings and procedures used for debug only
- */
-
/*******************************************************************************
*
* FUNCTION: AcpiUtGetMutexName
@@ -601,6 +596,12 @@ AcpiUtGetMutexName (
}
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/*
+ * Strings and procedures used for debug only
+ */
+
/*******************************************************************************
*
* FUNCTION: AcpiUtGetNotifyName
diff --git a/sys/contrib/dev/acpica/components/utilities/uterror.c b/sys/contrib/dev/acpica/components/utilities/uterror.c
index d386637..3b72808 100644
--- a/sys/contrib/dev/acpica/components/utilities/uterror.c
+++ b/sys/contrib/dev/acpica/components/utilities/uterror.c
@@ -313,6 +313,82 @@ AcpiUtPredefinedBiosError (
/*******************************************************************************
*
+ * FUNCTION: AcpiUtPrefixedNamespaceError
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * PrefixScope - Scope/Path that prefixes the internal path
+ * InternalPath - Name or path of the namespace node
+ * LookupStatus - Exception code from NS lookup
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print error message with the full pathname constructed this way:
+ *
+ * PrefixScopeNodeFullPath.ExternalizedInternalPath
+ *
+ * NOTE: 10/2017: Treat the major NsLookup errors as firmware errors
+ *
+ ******************************************************************************/
+
+void
+AcpiUtPrefixedNamespaceError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ ACPI_GENERIC_STATE *PrefixScope,
+ const char *InternalPath,
+ ACPI_STATUS LookupStatus)
+{
+ char *FullPath;
+ const char *Message;
+
+
+ /*
+ * Main cases:
+ * 1) Object creation, object must not already exist
+ * 2) Object lookup, object must exist
+ */
+ switch (LookupStatus)
+ {
+ case AE_ALREADY_EXISTS:
+
+ AcpiOsPrintf (ACPI_MSG_BIOS_ERROR);
+ Message = "Failure creating";
+ break;
+
+ case AE_NOT_FOUND:
+
+ AcpiOsPrintf (ACPI_MSG_BIOS_ERROR);
+ Message = "Failure looking up";
+ break;
+
+ default:
+
+ AcpiOsPrintf (ACPI_MSG_ERROR);
+ Message = "Failure looking up";
+ break;
+ }
+
+ /* Concatenate the prefix path and the internal path */
+
+ FullPath = AcpiNsBuildPrefixedPathname (PrefixScope, InternalPath);
+
+ AcpiOsPrintf ("%s [%s], %s", Message,
+ FullPath ? FullPath : "Could not get pathname",
+ AcpiFormatException (LookupStatus));
+
+ if (FullPath)
+ {
+ ACPI_FREE (FullPath);
+ }
+
+ ACPI_MSG_SUFFIX;
+}
+
+
+#ifdef __OBSOLETE_FUNCTION
+/*******************************************************************************
+ *
* FUNCTION: AcpiUtNamespaceError
*
* PARAMETERS: ModuleName - Caller's module name (for error output)
@@ -378,7 +454,7 @@ AcpiUtNamespaceError (
ACPI_MSG_SUFFIX;
ACPI_MSG_REDIRECT_END;
}
-
+#endif
/*******************************************************************************
*
diff --git a/sys/contrib/dev/acpica/components/utilities/utinit.c b/sys/contrib/dev/acpica/components/utilities/utinit.c
index f4bd850..357ccd2 100644
--- a/sys/contrib/dev/acpica/components/utilities/utinit.c
+++ b/sys/contrib/dev/acpica/components/utilities/utinit.c
@@ -334,7 +334,6 @@ AcpiUtInitGlobals (
AcpiGbl_NextOwnerIdOffset = 0;
AcpiGbl_DebuggerConfiguration = DEBUGGER_THREADING;
AcpiGbl_OsiMutex = NULL;
- AcpiGbl_MaxLoopIterations = ACPI_MAX_LOOP_COUNT;
/* Hardware oriented */
diff --git a/sys/contrib/dev/acpica/components/utilities/utmath.c b/sys/contrib/dev/acpica/components/utilities/utmath.c
index da5efbc..f9cd2b1 100644
--- a/sys/contrib/dev/acpica/components/utilities/utmath.c
+++ b/sys/contrib/dev/acpica/components/utilities/utmath.c
@@ -260,7 +260,7 @@ AcpiUtShortShiftLeft (
if ((Count & 63) >= 32)
{
OperandOvl.Part.Hi = OperandOvl.Part.Lo;
- OperandOvl.Part.Lo ^= OperandOvl.Part.Lo;
+ OperandOvl.Part.Lo = 0;
Count = (Count & 63) - 32;
}
ACPI_SHIFT_LEFT_64_BY_32 (OperandOvl.Part.Hi,
@@ -305,7 +305,7 @@ AcpiUtShortShiftRight (
if ((Count & 63) >= 32)
{
OperandOvl.Part.Lo = OperandOvl.Part.Hi;
- OperandOvl.Part.Hi ^= OperandOvl.Part.Hi;
+ OperandOvl.Part.Hi = 0;
Count = (Count & 63) - 32;
}
ACPI_SHIFT_RIGHT_64_BY_32 (OperandOvl.Part.Hi,
diff --git a/sys/contrib/dev/acpica/components/utilities/utmutex.c b/sys/contrib/dev/acpica/components/utilities/utmutex.c
index 26160e5..40c0118 100644
--- a/sys/contrib/dev/acpica/components/utilities/utmutex.c
+++ b/sys/contrib/dev/acpica/components/utilities/utmutex.c
@@ -432,8 +432,8 @@ AcpiUtAcquireMutex (
else
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Thread %u could not acquire Mutex [0x%X]",
- (UINT32) ThisThreadId, MutexId));
+ "Thread %u could not acquire Mutex [%s] (0x%X)",
+ (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId), MutexId));
}
return (Status);
@@ -473,7 +473,8 @@ AcpiUtReleaseMutex (
if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED)
{
ACPI_ERROR ((AE_INFO,
- "Mutex [0x%X] is not acquired, cannot release", MutexId));
+ "Mutex [%s] (0x%X) is not acquired, cannot release",
+ AcpiUtGetMutexName (MutexId), MutexId));
return (AE_NOT_ACQUIRED);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utnonansi.c b/sys/contrib/dev/acpica/components/utilities/utnonansi.c
index d3fae92..dc7159f 100644
--- a/sys/contrib/dev/acpica/components/utilities/utnonansi.c
+++ b/sys/contrib/dev/acpica/components/utilities/utnonansi.c
@@ -344,4 +344,17 @@ AcpiUtSafeStrncat (
strncat (Dest, Source, MaxTransferLength);
return (FALSE);
}
+
+void
+AcpiUtSafeStrncpy (
+ char *Dest,
+ char *Source,
+ ACPI_SIZE DestSize)
+{
+ /* Always terminate destination string */
+
+ strncpy (Dest, Source, DestSize);
+ Dest[DestSize - 1] = 0;
+}
+
#endif
diff --git a/sys/contrib/dev/acpica/components/utilities/utosi.c b/sys/contrib/dev/acpica/components/utilities/utosi.c
index 2fd1f45..e19e211 100644
--- a/sys/contrib/dev/acpica/components/utilities/utosi.c
+++ b/sys/contrib/dev/acpica/components/utilities/utosi.c
@@ -214,6 +214,8 @@ static ACPI_INTERFACE_INFO AcpiDefaultSupportedInterfaces[] =
{"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */
{"Windows 2013", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */
{"Windows 2015", NULL, 0, ACPI_OSI_WIN_10}, /* Windows 10 - Added 03/2015 */
+ {"Windows 2016", NULL, 0, ACPI_OSI_WIN_10_RS1}, /* Windows 10 version 1607 - Added 12/2017 */
+ {"Windows 2017", NULL, 0, ACPI_OSI_WIN_10_RS2}, /* Windows 10 version 1703 - Added 12/2017 */
/* Feature Group Strings */
diff --git a/sys/contrib/dev/acpica/components/utilities/utstrsuppt.c b/sys/contrib/dev/acpica/components/utilities/utstrsuppt.c
new file mode 100644
index 0000000..00d4cd6
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/utilities/utstrsuppt.c
@@ -0,0 +1,621 @@
+/*******************************************************************************
+ *
+ * Module Name: utstrsuppt - Support functions for string-to-integer conversion
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights. You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code. No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision. In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change. Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee. Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution. In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government. In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************
+ *
+ * Alternatively, you may choose to be licensed under the terms of the
+ * following license:
+ *
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ *
+ * Alternatively, you may choose to be licensed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ *****************************************************************************/
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utstrsuppt")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiUtInsertDigit (
+ UINT64 *AccumulatedValue,
+ UINT32 Base,
+ int AsciiDigit);
+
+static ACPI_STATUS
+AcpiUtStrtoulMultiply64 (
+ UINT64 Multiplicand,
+ UINT32 Base,
+ UINT64 *OutProduct);
+
+static ACPI_STATUS
+AcpiUtStrtoulAdd64 (
+ UINT64 Addend1,
+ UINT32 Digit,
+ UINT64 *OutSum);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtConvertOctalString
+ *
+ * PARAMETERS: String - Null terminated input string
+ * ReturnValuePtr - Where the converted value is returned
+ *
+ * RETURN: Status and 64-bit converted integer
+ *
+ * DESCRIPTION: Performs a base 8 conversion of the input string to an
+ * integer value, either 32 or 64 bits.
+ *
+ * NOTE: Maximum 64-bit unsigned octal value is 01777777777777777777777
+ * Maximum 32-bit unsigned octal value is 037777777777
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtConvertOctalString (
+ char *String,
+ UINT64 *ReturnValuePtr)
+{
+ UINT64 AccumulatedValue = 0;
+ ACPI_STATUS Status = AE_OK;
+
+
+ /* Convert each ASCII byte in the input string */
+
+ while (*String)
+ {
+ /* Character must be ASCII 0-7, otherwise terminate with no error */
+
+ if (!(ACPI_IS_OCTAL_DIGIT (*String)))
+ {
+ break;
+ }
+
+ /* Convert and insert this octal digit into the accumulator */
+
+ Status = AcpiUtInsertDigit (&AccumulatedValue, 8, *String);
+ if (ACPI_FAILURE (Status))
+ {
+ Status = AE_OCTAL_OVERFLOW;
+ break;
+ }
+
+ String++;
+ }
+
+ /* Always return the value that has been accumulated */
+
+ *ReturnValuePtr = AccumulatedValue;
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtConvertDecimalString
+ *
+ * PARAMETERS: String - Null terminated input string
+ * ReturnValuePtr - Where the converted value is returned
+ *
+ * RETURN: Status and 64-bit converted integer
+ *
+ * DESCRIPTION: Performs a base 10 conversion of the input string to an
+ * integer value, either 32 or 64 bits.
+ *
+ * NOTE: Maximum 64-bit unsigned decimal value is 18446744073709551615
+ * Maximum 32-bit unsigned decimal value is 4294967295
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtConvertDecimalString (
+ char *String,
+ UINT64 *ReturnValuePtr)
+{
+ UINT64 AccumulatedValue = 0;
+ ACPI_STATUS Status = AE_OK;
+
+
+ /* Convert each ASCII byte in the input string */
+
+ while (*String)
+ {
+ /* Character must be ASCII 0-9, otherwise terminate with no error */
+
+ if (!isdigit (*String))
+ {
+ break;
+ }
+
+ /* Convert and insert this decimal digit into the accumulator */
+
+ Status = AcpiUtInsertDigit (&AccumulatedValue, 10, *String);
+ if (ACPI_FAILURE (Status))
+ {
+ Status = AE_DECIMAL_OVERFLOW;
+ break;
+ }
+
+ String++;
+ }
+
+ /* Always return the value that has been accumulated */
+
+ *ReturnValuePtr = AccumulatedValue;
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtConvertHexString
+ *
+ * PARAMETERS: String - Null terminated input string
+ * ReturnValuePtr - Where the converted value is returned
+ *
+ * RETURN: Status and 64-bit converted integer
+ *
+ * DESCRIPTION: Performs a base 16 conversion of the input string to an
+ * integer value, either 32 or 64 bits.
+ *
+ * NOTE: Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF
+ * Maximum 32-bit unsigned hex value is 0xFFFFFFFF
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUtConvertHexString (
+ char *String,
+ UINT64 *ReturnValuePtr)
+{
+ UINT64 AccumulatedValue = 0;
+ ACPI_STATUS Status = AE_OK;
+
+
+ /* Convert each ASCII byte in the input string */
+
+ while (*String)
+ {
+ /* Must be ASCII A-F, a-f, or 0-9, otherwise terminate with no error */
+
+ if (!isxdigit (*String))
+ {
+ break;
+ }
+
+ /* Convert and insert this hex digit into the accumulator */
+
+ Status = AcpiUtInsertDigit (&AccumulatedValue, 16, *String);
+ if (ACPI_FAILURE (Status))
+ {
+ Status = AE_HEX_OVERFLOW;
+ break;
+ }
+
+ String++;
+ }
+
+ /* Always return the value that has been accumulated */
+
+ *ReturnValuePtr = AccumulatedValue;
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtRemoveLeadingZeros
+ *
+ * PARAMETERS: String - Pointer to input ASCII string
+ *
+ * RETURN: Next character after any leading zeros. This character may be
+ * used by the caller to detect end-of-string.
+ *
+ * DESCRIPTION: Remove any leading zeros in the input string. Return the
+ * next character after the final ASCII zero to enable the caller
+ * to check for the end of the string (NULL terminator).
+ *
+ ******************************************************************************/
+
+char
+AcpiUtRemoveLeadingZeros (
+ char **String)
+{
+
+ while (**String == ACPI_ASCII_ZERO)
+ {
+ *String += 1;
+ }
+
+ return (**String);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtRemoveWhitespace
+ *
+ * PARAMETERS: String - Pointer to input ASCII string
+ *
+ * RETURN: Next character after any whitespace. This character may be
+ * used by the caller to detect end-of-string.
+ *
+ * DESCRIPTION: Remove any leading whitespace in the input string. Return the
+ * next character after the final ASCII zero to enable the caller
+ * to check for the end of the string (NULL terminator).
+ *
+ ******************************************************************************/
+
+char
+AcpiUtRemoveWhitespace (
+ char **String)
+{
+
+ while (isspace ((UINT8) **String))
+ {
+ *String += 1;
+ }
+
+ return (**String);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDetectHexPrefix
+ *
+ * PARAMETERS: String - Pointer to input ASCII string
+ *
+ * RETURN: TRUE if a "0x" prefix was found at the start of the string
+ *
+ * DESCRIPTION: Detect and remove a hex "0x" prefix
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiUtDetectHexPrefix (
+ char **String)
+{
+
+ if ((**String == ACPI_ASCII_ZERO) &&
+ (tolower ((int) *(*String + 1)) == 'x'))
+ {
+ *String += 2; /* Go past the leading 0x */
+ return (TRUE);
+ }
+
+ return (FALSE); /* Not a hex string */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtDetectOctalPrefix
+ *
+ * PARAMETERS: String - Pointer to input ASCII string
+ *
+ * RETURN: True if an octal "0" prefix was found at the start of the
+ * string
+ *
+ * DESCRIPTION: Detect and remove an octal prefix (zero)
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiUtDetectOctalPrefix (
+ char **String)
+{
+
+ if (**String == ACPI_ASCII_ZERO)
+ {
+ *String += 1; /* Go past the leading 0 */
+ return (TRUE);
+ }
+
+ return (FALSE); /* Not an octal string */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtInsertDigit
+ *
+ * PARAMETERS: AccumulatedValue - Current value of the integer value
+ * accumulator. The new value is
+ * returned here.
+ * Base - Radix, either 8/10/16
+ * AsciiDigit - ASCII single digit to be inserted
+ *
+ * RETURN: Status and result of the convert/insert operation. The only
+ * possible returned exception code is numeric overflow of
+ * either the multiply or add conversion operations.
+ *
+ * DESCRIPTION: Generic conversion and insertion function for all bases:
+ *
+ * 1) Multiply the current accumulated/converted value by the
+ * base in order to make room for the new character.
+ *
+ * 2) Convert the new character to binary and add it to the
+ * current accumulated value.
+ *
+ * Note: The only possible exception indicates an integer
+ * overflow (AE_NUMERIC_OVERFLOW)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtInsertDigit (
+ UINT64 *AccumulatedValue,
+ UINT32 Base,
+ int AsciiDigit)
+{
+ ACPI_STATUS Status;
+ UINT64 Product;
+
+
+ /* Make room in the accumulated value for the incoming digit */
+
+ Status = AcpiUtStrtoulMultiply64 (*AccumulatedValue, Base, &Product);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Add in the new digit, and store the sum to the accumulated value */
+
+ Status = AcpiUtStrtoulAdd64 (Product, AcpiUtAsciiCharToHex (AsciiDigit),
+ AccumulatedValue);
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtStrtoulMultiply64
+ *
+ * PARAMETERS: Multiplicand - Current accumulated converted integer
+ * Base - Base/Radix
+ * OutProduct - Where the product is returned
+ *
+ * RETURN: Status and 64-bit product
+ *
+ * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as
+ * well as 32-bit overflow if necessary (if the current global
+ * integer width is 32).
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtStrtoulMultiply64 (
+ UINT64 Multiplicand,
+ UINT32 Base,
+ UINT64 *OutProduct)
+{
+ UINT64 Product;
+ UINT64 Quotient;
+
+
+ /* Exit if either operand is zero */
+
+ *OutProduct = 0;
+ if (!Multiplicand || !Base)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Check for 64-bit overflow before the actual multiplication.
+ *
+ * Notes: 64-bit division is often not supported on 32-bit platforms
+ * (it requires a library function), Therefore ACPICA has a local
+ * 64-bit divide function. Also, Multiplier is currently only used
+ * as the radix (8/10/16), to the 64/32 divide will always work.
+ */
+ AcpiUtShortDivide (ACPI_UINT64_MAX, Base, &Quotient, NULL);
+ if (Multiplicand > Quotient)
+ {
+ return (AE_NUMERIC_OVERFLOW);
+ }
+
+ Product = Multiplicand * Base;
+
+ /* Check for 32-bit overflow if necessary */
+
+ if ((AcpiGbl_IntegerBitWidth == 32) && (Product > ACPI_UINT32_MAX))
+ {
+ return (AE_NUMERIC_OVERFLOW);
+ }
+
+ *OutProduct = Product;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtStrtoulAdd64
+ *
+ * PARAMETERS: Addend1 - Current accumulated converted integer
+ * Digit - New hex value/char
+ * OutSum - Where sum is returned (Accumulator)
+ *
+ * RETURN: Status and 64-bit sum
+ *
+ * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as
+ * well as 32-bit overflow if necessary (if the current global
+ * integer width is 32).
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiUtStrtoulAdd64 (
+ UINT64 Addend1,
+ UINT32 Digit,
+ UINT64 *OutSum)
+{
+ UINT64 Sum;
+
+
+ /* Check for 64-bit overflow before the actual addition */
+
+ if ((Addend1 > 0) && (Digit > (ACPI_UINT64_MAX - Addend1)))
+ {
+ return (AE_NUMERIC_OVERFLOW);
+ }
+
+ Sum = Addend1 + Digit;
+
+ /* Check for 32-bit overflow if necessary */
+
+ if ((AcpiGbl_IntegerBitWidth == 32) && (Sum > ACPI_UINT32_MAX))
+ {
+ return (AE_NUMERIC_OVERFLOW);
+ }
+
+ *OutSum = Sum;
+ return (AE_OK);
+}
diff --git a/sys/contrib/dev/acpica/components/utilities/utstrtoul64.c b/sys/contrib/dev/acpica/components/utilities/utstrtoul64.c
index faee601..1e7f430 100644
--- a/sys/contrib/dev/acpica/components/utilities/utstrtoul64.c
+++ b/sys/contrib/dev/acpica/components/utilities/utstrtoul64.c
@@ -1,6 +1,7 @@
/*******************************************************************************
*
- * Module Name: utstrtoul64 - string to 64-bit integer support
+ * Module Name: utstrtoul64 - String-to-integer conversion support for both
+ * 64-bit and 32-bit integers
*
******************************************************************************/
@@ -152,84 +153,47 @@
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
-
-/*******************************************************************************
- *
- * The functions in this module satisfy the need for 64-bit string-to-integer
- * conversions on both 32-bit and 64-bit platforms.
- *
- ******************************************************************************/
-
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utstrtoul64")
-/* Local prototypes */
-
-static UINT64
-AcpiUtStrtoulBase10 (
- char *String,
- UINT32 Flags);
-
-static UINT64
-AcpiUtStrtoulBase16 (
- char *String,
- UINT32 Flags);
-
/*******************************************************************************
*
- * String conversion rules as written in the ACPI specification. The error
- * conditions and behavior are different depending on the type of conversion.
- *
- *
- * Implicit data type conversion: string-to-integer
- * --------------------------------------------------
- *
- * Base is always 16. This is the ACPI_STRTOUL_BASE16 case.
- *
- * Example:
- * Add ("BA98", Arg0, Local0)
- *
- * The integer is initialized to the value zero.
- * The ASCII string is interpreted as a hexadecimal constant.
- *
- * 1) A "0x" prefix is not allowed. However, ACPICA allows this for
- * compatibility with previous ACPICA. (NO ERROR)
- *
- * 2) Terminates when the size of an integer is reached (32 or 64 bits).
- * (NO ERROR)
- *
- * 3) The first non-hex character terminates the conversion without error.
- * (NO ERROR)
- *
- * 4) Conversion of a null (zero-length) string to an integer is not
- * allowed. However, ACPICA allows this for compatibility with previous
- * ACPICA. This conversion returns the value 0. (NO ERROR)
+ * This module contains the top-level string to 64/32-bit unsigned integer
+ * conversion functions:
*
+ * 1) A standard strtoul() function that supports 64-bit integers, base
+ * 8/10/16, with integer overflow support. This is used mainly by the
+ * iASL compiler, which implements tighter constraints on integer
+ * constants than the runtime (interpreter) integer-to-string conversions.
+ * 2) Runtime "Explicit conversion" as defined in the ACPI specification.
+ * 3) Runtime "Implicit conversion" as defined in the ACPI specification.
*
- * Explicit data type conversion: ToInteger() with string operand
- * ---------------------------------------------------------------
+ * Current users of this module:
*
- * Base is either 10 (default) or 16 (with 0x prefix)
- *
- * Examples:
- * ToInteger ("1000")
- * ToInteger ("0xABCD")
- *
- * 1) Can be (must be) either a decimal or hexadecimal numeric string.
- * A hex value must be prefixed by "0x" or it is interpreted as a decimal.
+ * iASL - Preprocessor (constants and math expressions)
+ * iASL - Main parser, conversion of constants to integers
+ * iASL - Data Table Compiler parser (constants and math expressions)
+ * Interpreter - Implicit and explicit conversions, GPE method names
+ * Interpreter - Repair code for return values from predefined names
+ * Debugger - Command line input string conversion
+ * AcpiDump - ACPI table physical addresses
+ * AcpiExec - Support for namespace overrides
*
- * 2) The value must not exceed the maximum of an integer value. ACPI spec
- * states the behavior is "unpredictable", so ACPICA matches the behavior
- * of the implicit conversion case.(NO ERROR)
+ * Notes concerning users of these interfaces:
*
- * 3) Behavior on the first non-hex character is not specified by the ACPI
- * spec, so ACPICA matches the behavior of the implicit conversion case
- * and terminates. (NO ERROR)
+ * AcpiGbl_IntegerByteWidth is used to set the 32/64 bit limit for explicit
+ * and implicit conversions. This global must be set to the proper width.
+ * For the core ACPICA code, the width depends on the DSDT version. For the
+ * AcpiUtStrtoul64 interface, all conversions are 64 bits. This interface is
+ * used primarily for iASL, where the default width is 64 bits for all parsers,
+ * but error checking is performed later to flag cases where a 64-bit constant
+ * is wrongly defined in a 32-bit DSDT/SSDT.
*
- * 4) A null (zero-length) string is illegal.
- * However, ACPICA allows this for compatibility with previous ACPICA.
- * This conversion returns the value 0. (NO ERROR)
+ * In ACPI, the only place where octal numbers are supported is within
+ * the ASL language itself. This is implemented via the main AcpiUtStrtoul64
+ * interface. According the ACPI specification, there is no ACPI runtime
+ * support (explicit/implicit) for octal string conversions.
*
******************************************************************************/
@@ -238,261 +202,301 @@ AcpiUtStrtoulBase16 (
*
* FUNCTION: AcpiUtStrtoul64
*
- * PARAMETERS: String - Null terminated input string
- * Flags - Conversion info, see below
+ * PARAMETERS: String - Null terminated input string,
+ * must be a valid pointer
* ReturnValue - Where the converted integer is
- * returned
- *
- * RETURN: Status and Converted value
+ * returned. Must be a valid pointer
*
- * DESCRIPTION: Convert a string into an unsigned value. Performs either a
- * 32-bit or 64-bit conversion, depending on the input integer
- * size in Flags (often the current mode of the interpreter).
+ * RETURN: Status and converted integer. Returns an exception on a
+ * 64-bit numeric overflow
*
- * Values for Flags:
- * ACPI_STRTOUL_32BIT - Max integer value is 32 bits
- * ACPI_STRTOUL_64BIT - Max integer value is 64 bits
- * ACPI_STRTOUL_BASE16 - Input string is hexadecimal. Default
- * is 10/16 based on string prefix (0x).
+ * DESCRIPTION: Convert a string into an unsigned integer. Always performs a
+ * full 64-bit conversion, regardless of the current global
+ * integer width. Supports Decimal, Hex, and Octal strings.
*
- * NOTES:
- * Negative numbers are not supported, as they are not supported by ACPI.
+ * Current users of this function:
*
- * Supports only base 16 or base 10 strings/values. Does not
- * support Octal strings, as these are not supported by ACPI.
- *
- * Current users of this support:
- *
- * Interpreter - Implicit and explicit conversions, GPE method names
- * Debugger - Command line input string conversion
- * iASL - Main parser, conversion of constants to integers
- * iASL - Data Table Compiler parser (constant math expressions)
- * iASL - Preprocessor (constant math expressions)
- * AcpiDump - Input table addresses
- * AcpiExec - Testing of the AcpiUtStrtoul64 function
- *
- * Note concerning callers:
- * AcpiGbl_IntegerByteWidth can be used to set the 32/64 limit. If used,
- * this global should be set to the proper width. For the core ACPICA code,
- * this width depends on the DSDT version. For iASL, the default byte
- * width is always 8 for the parser, but error checking is performed later
- * to flag cases where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
+ * iASL - Preprocessor (constants and math expressions)
+ * iASL - Main ASL parser, conversion of ASL constants to integers
+ * iASL - Data Table Compiler parser (constants and math expressions)
+ * Interpreter - Repair code for return values from predefined names
+ * AcpiDump - ACPI table physical addresses
+ * AcpiExec - Support for namespace overrides
*
******************************************************************************/
ACPI_STATUS
AcpiUtStrtoul64 (
char *String,
- UINT32 Flags,
UINT64 *ReturnValue)
{
ACPI_STATUS Status = AE_OK;
- UINT32 Base;
+ UINT8 OriginalBitWidth;
+ UINT32 Base = 10; /* Default is decimal */
ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String);
- /* Parameter validation */
-
- if (!String || !ReturnValue)
- {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
*ReturnValue = 0;
- /* Check for zero-length string, returns 0 */
+ /* A NULL return string returns a value of zero */
if (*String == 0)
{
return_ACPI_STATUS (AE_OK);
}
- /* Skip over any white space at start of string */
-
- while (isspace ((int) *String))
- {
- String++;
- }
-
- /* End of string? return 0 */
-
- if (*String == 0)
+ if (!AcpiUtRemoveWhitespace (&String))
{
return_ACPI_STATUS (AE_OK);
}
/*
- * 1) The "0x" prefix indicates base 16. Per the ACPI specification,
- * the "0x" prefix is only allowed for implicit (non-strict) conversions.
- * However, we always allow it for compatibility with older ACPICA.
+ * 1) Check for a hex constant. A "0x" prefix indicates base 16.
*/
- if ((*String == ACPI_ASCII_ZERO) &&
- (tolower ((int) *(String + 1)) == 'x'))
+ if (AcpiUtDetectHexPrefix (&String))
{
- String += 2; /* Go past the 0x */
- if (*String == 0)
- {
- return_ACPI_STATUS (AE_OK); /* Return value 0 */
- }
-
Base = 16;
}
- /* 2) Force to base 16 (implicit conversion case) */
-
- else if (Flags & ACPI_STRTOUL_BASE16)
+ /*
+ * 2) Check for an octal constant, defined to be a leading zero
+ * followed by sequence of octal digits (0-7)
+ */
+ else if (AcpiUtDetectOctalPrefix (&String))
{
- Base = 16;
+ Base = 8;
}
- /* 3) Default fallback is to Base 10 */
-
- else
+ if (!AcpiUtRemoveLeadingZeros (&String))
{
- Base = 10;
+ return_ACPI_STATUS (AE_OK); /* Return value 0 */
}
- /* Skip all leading zeros */
+ /*
+ * Force a full 64-bit conversion. The caller (usually iASL) must
+ * check for a 32-bit overflow later as necessary (If current mode
+ * is 32-bit, meaning a 32-bit DSDT).
+ */
+ OriginalBitWidth = AcpiGbl_IntegerBitWidth;
+ AcpiGbl_IntegerBitWidth = 64;
- while (*String == ACPI_ASCII_ZERO)
+ /*
+ * Perform the base 8, 10, or 16 conversion. A 64-bit numeric overflow
+ * will return an exception (to allow iASL to flag the statement).
+ */
+ switch (Base)
{
- String++;
- if (*String == 0)
- {
- return_ACPI_STATUS (AE_OK); /* Return value 0 */
- }
+ case 8:
+ Status = AcpiUtConvertOctalString (String, ReturnValue);
+ break;
+
+ case 10:
+ Status = AcpiUtConvertDecimalString (String, ReturnValue);
+ break;
+
+ case 16:
+ default:
+ Status = AcpiUtConvertHexString (String, ReturnValue);
+ break;
}
- /* Perform the base 16 or 10 conversion */
-
- if (Base == 16)
- {
- *ReturnValue = AcpiUtStrtoulBase16 (String, Flags);
- }
- else
- {
- *ReturnValue = AcpiUtStrtoulBase10 (String, Flags);
- }
+ /* Only possible exception from above is a 64-bit overflow */
+ AcpiGbl_IntegerBitWidth = OriginalBitWidth;
return_ACPI_STATUS (Status);
}
/*******************************************************************************
*
- * FUNCTION: AcpiUtStrtoulBase10
+ * FUNCTION: AcpiUtImplicitStrtoul64
+ *
+ * PARAMETERS: String - Null terminated input string,
+ * must be a valid pointer
+ *
+ * RETURN: Converted integer
+ *
+ * DESCRIPTION: Perform a 64-bit conversion with restrictions placed upon
+ * an "implicit conversion" by the ACPI specification. Used by
+ * many ASL operators that require an integer operand, and support
+ * an automatic (implicit) conversion from a string operand
+ * to the final integer operand. The major restriction is that
+ * only hex strings are supported.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Base is always 16, either with or without the 0x prefix. Decimal and
+ * Octal strings are not supported, as per the ACPI specification.
+ *
+ * Examples (both are hex values):
+ * Add ("BA98", Arg0, Local0)
+ * Subtract ("0x12345678", Arg1, Local1)
+ *
+ * Conversion rules as extracted from the ACPI specification:
+ *
+ * The converted integer is initialized to the value zero.
+ * The ASCII string is always interpreted as a hexadecimal constant.
+ *
+ * 1) According to the ACPI specification, a "0x" prefix is not allowed.
+ * However, ACPICA allows this as an ACPI extension on general
+ * principle. (NO ERROR)
+ *
+ * 2) The conversion terminates when the size of an integer is reached
+ * (32 or 64 bits). There are no numeric overflow conditions. (NO ERROR)
+ *
+ * 3) The first non-hex character terminates the conversion and returns
+ * the current accumulated value of the converted integer (NO ERROR).
*
- * PARAMETERS: String - Null terminated input string
- * Flags - Conversion info
+ * 4) Conversion of a null (zero-length) string to an integer is
+ * technically not allowed. However, ACPICA allows this as an ACPI
+ * extension. The conversion returns the value 0. (NO ERROR)
*
- * RETURN: 64-bit converted integer
+ * NOTE: There are no error conditions returned by this function. At
+ * the minimum, a value of zero is returned.
*
- * DESCRIPTION: Performs a base 10 conversion of the input string to an
- * integer value, either 32 or 64 bits.
- * Note: String must be valid and non-null.
+ * Current users of this function:
+ *
+ * Interpreter - All runtime implicit conversions, as per ACPI specification
+ * iASL - Data Table Compiler parser (constants and math expressions)
*
******************************************************************************/
-static UINT64
-AcpiUtStrtoulBase10 (
- char *String,
- UINT32 Flags)
+UINT64
+AcpiUtImplicitStrtoul64 (
+ char *String)
{
- int AsciiDigit;
- UINT64 NextValue;
- UINT64 ReturnValue = 0;
+ UINT64 ConvertedInteger = 0;
- /* Main loop: convert each ASCII byte in the input string */
-
- while (*String)
- {
- AsciiDigit = *String;
- if (!isdigit (AsciiDigit))
- {
- /* Not ASCII 0-9, terminate */
+ ACPI_FUNCTION_TRACE_STR (UtImplicitStrtoul64, String);
- goto Exit;
- }
- /* Convert and insert (add) the decimal digit */
-
- AcpiUtShortMultiply (ReturnValue, 10, &NextValue);
- NextValue += (AsciiDigit - ACPI_ASCII_ZERO);
-
- /* Check for overflow (32 or 64 bit) - return current converted value */
+ if (!AcpiUtRemoveWhitespace (&String))
+ {
+ return_VALUE (0);
+ }
- if (((Flags & ACPI_STRTOUL_32BIT) && (NextValue > ACPI_UINT32_MAX)) ||
- (NextValue < ReturnValue)) /* 64-bit overflow case */
- {
- goto Exit;
- }
+ /*
+ * Per the ACPI specification, only hexadecimal is supported for
+ * implicit conversions, and the "0x" prefix is "not allowed".
+ * However, allow a "0x" prefix as an ACPI extension.
+ */
+ AcpiUtDetectHexPrefix (&String);
- ReturnValue = NextValue;
- String++;
+ if (!AcpiUtRemoveLeadingZeros (&String))
+ {
+ return_VALUE (0);
}
-Exit:
- return (ReturnValue);
+ /*
+ * Ignore overflow as per the ACPI specification. This is implemented by
+ * ignoring the return status from the conversion function called below.
+ * On overflow, the input string is simply truncated.
+ */
+ AcpiUtConvertHexString (String, &ConvertedInteger);
+ return_VALUE (ConvertedInteger);
}
/*******************************************************************************
*
- * FUNCTION: AcpiUtStrtoulBase16
+ * FUNCTION: AcpiUtExplicitStrtoul64
+ *
+ * PARAMETERS: String - Null terminated input string,
+ * must be a valid pointer
*
- * PARAMETERS: String - Null terminated input string
- * Flags - conversion info
+ * RETURN: Converted integer
*
- * RETURN: 64-bit converted integer
+ * DESCRIPTION: Perform a 64-bit conversion with the restrictions placed upon
+ * an "explicit conversion" by the ACPI specification. The
+ * main restriction is that only hex and decimal are supported.
*
- * DESCRIPTION: Performs a base 16 conversion of the input string to an
- * integer value, either 32 or 64 bits.
- * Note: String must be valid and non-null.
+ * -----------------------------------------------------------------------------
+ *
+ * Base is either 10 (default) or 16 (with 0x prefix). Octal (base 8) strings
+ * are not supported, as per the ACPI specification.
+ *
+ * Examples:
+ * ToInteger ("1000") Decimal
+ * ToInteger ("0xABCD") Hex
+ *
+ * Conversion rules as extracted from the ACPI specification:
+ *
+ * 1) The input string is either a decimal or hexadecimal numeric string.
+ * A hex value must be prefixed by "0x" or it is interpreted as decimal.
+ *
+ * 2) The value must not exceed the maximum of an integer value
+ * (32 or 64 bits). The ACPI specification states the behavior is
+ * "unpredictable", so ACPICA matches the behavior of the implicit
+ * conversion case. There are no numeric overflow conditions. (NO ERROR)
+ *
+ * 3) Behavior on the first non-hex character is not defined by the ACPI
+ * specification (for the ToInteger operator), so ACPICA matches the
+ * behavior of the implicit conversion case. It terminates the
+ * conversion and returns the current accumulated value of the converted
+ * integer. (NO ERROR)
+ *
+ * 4) Conversion of a null (zero-length) string to an integer is
+ * technically not allowed. However, ACPICA allows this as an ACPI
+ * extension. The conversion returns the value 0. (NO ERROR)
+ *
+ * NOTE: There are no error conditions returned by this function. At the
+ * minimum, a value of zero is returned.
+ *
+ * Current users of this function:
+ *
+ * Interpreter - Runtime ASL ToInteger operator, as per the ACPI specification
*
******************************************************************************/
-static UINT64
-AcpiUtStrtoulBase16 (
- char *String,
- UINT32 Flags)
+UINT64
+AcpiUtExplicitStrtoul64 (
+ char *String)
{
- int AsciiDigit;
- UINT32 ValidDigits = 1;
- UINT64 ReturnValue = 0;
-
+ UINT64 ConvertedInteger = 0;
+ UINT32 Base = 10; /* Default is decimal */
- /* Main loop: convert each ASCII byte in the input string */
- while (*String)
- {
- /* Check for overflow (32 or 64 bit) - return current converted value */
+ ACPI_FUNCTION_TRACE_STR (UtExplicitStrtoul64, String);
- if ((ValidDigits > 16) ||
- ((ValidDigits > 8) && (Flags & ACPI_STRTOUL_32BIT)))
- {
- goto Exit;
- }
- AsciiDigit = *String;
- if (!isxdigit (AsciiDigit))
- {
- /* Not Hex ASCII A-F, a-f, or 0-9, terminate */
-
- goto Exit;
- }
+ if (!AcpiUtRemoveWhitespace (&String))
+ {
+ return_VALUE (0);
+ }
- /* Convert and insert the hex digit */
+ /*
+ * Only Hex and Decimal are supported, as per the ACPI specification.
+ * A "0x" prefix indicates hex; otherwise decimal is assumed.
+ */
+ if (AcpiUtDetectHexPrefix (&String))
+ {
+ Base = 16;
+ }
- AcpiUtShortShiftLeft (ReturnValue, 4, &ReturnValue);
- ReturnValue |= AcpiUtAsciiCharToHex (AsciiDigit);
+ if (!AcpiUtRemoveLeadingZeros (&String))
+ {
+ return_VALUE (0);
+ }
- String++;
- ValidDigits++;
+ /*
+ * Ignore overflow as per the ACPI specification. This is implemented by
+ * ignoring the return status from the conversion functions called below.
+ * On overflow, the input string is simply truncated.
+ */
+ switch (Base)
+ {
+ case 10:
+ default:
+ AcpiUtConvertDecimalString (String, &ConvertedInteger);
+ break;
+
+ case 16:
+ AcpiUtConvertHexString (String, &ConvertedInteger);
+ break;
}
-Exit:
- return (ReturnValue);
+ return_VALUE (ConvertedInteger);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/uttrack.c b/sys/contrib/dev/acpica/components/utilities/uttrack.c
index 41538b5..ece7312 100644
--- a/sys/contrib/dev/acpica/components/utilities/uttrack.c
+++ b/sys/contrib/dev/acpica/components/utilities/uttrack.c
@@ -557,8 +557,7 @@ AcpiUtTrackAllocation (
Allocation->Component = Component;
Allocation->Line = Line;
- strncpy (Allocation->Module, Module, ACPI_MAX_MODULE_NAME);
- Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0;
+ AcpiUtSafeStrncpy (Allocation->Module, (char *) Module, ACPI_MAX_MODULE_NAME);
if (!Element)
{
@@ -891,7 +890,7 @@ Exit:
}
else
{
- ACPI_ERROR ((AE_INFO, "%u(0x%X) Outstanding allocations",
+ ACPI_ERROR ((AE_INFO, "%u (0x%X) Outstanding cache allocations",
NumOutstanding, NumOutstanding));
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utxferror.c b/sys/contrib/dev/acpica/components/utilities/utxferror.c
index 9c1799c..75eea31 100644
--- a/sys/contrib/dev/acpica/components/utilities/utxferror.c
+++ b/sys/contrib/dev/acpica/components/utilities/utxferror.c
@@ -214,8 +214,8 @@ ACPI_EXPORT_SYMBOL (AcpiError)
*
* RETURN: None
*
- * DESCRIPTION: Print "ACPI Exception" message with module/line/version info
- * and decoded ACPI_STATUS.
+ * DESCRIPTION: Print an "ACPI Error" message with module/line/version
+ * info as well as decoded ACPI_STATUS.
*
******************************************************************************/
@@ -236,12 +236,12 @@ AcpiException (
if (ACPI_SUCCESS (Status))
{
- AcpiOsPrintf (ACPI_MSG_EXCEPTION);
+ AcpiOsPrintf (ACPI_MSG_ERROR);
}
else
{
- AcpiOsPrintf (ACPI_MSG_EXCEPTION "%s, ",
+ AcpiOsPrintf (ACPI_MSG_ERROR "%s, ",
AcpiFormatException (Status));
}
diff --git a/sys/contrib/dev/acpica/include/acapps.h b/sys/contrib/dev/acpica/include/acapps.h
index 4ca3e80..faae2fb 100644
--- a/sys/contrib/dev/acpica/include/acapps.h
+++ b/sys/contrib/dev/acpica/include/acapps.h
@@ -188,6 +188,9 @@
Prefix, ACPICA_COPYRIGHT, \
Prefix
+#define ACPI_COMMON_BUILD_TIME \
+ "Build date/time: %s %s\n", __DATE__, __TIME__
+
/* Macros for usage messages */
#define ACPI_USAGE_HEADER(Usage) \
diff --git a/sys/contrib/dev/acpica/include/acconfig.h b/sys/contrib/dev/acpica/include/acconfig.h
index 6fc0436..7cff063 100644
--- a/sys/contrib/dev/acpica/include/acconfig.h
+++ b/sys/contrib/dev/acpica/include/acconfig.h
@@ -255,9 +255,9 @@
#define ACPI_ADDRESS_RANGE_MAX 2
-/* Maximum number of While() loops before abort */
+/* Maximum time (default 30s) of While() loops before abort */
-#define ACPI_MAX_LOOP_COUNT 0x000FFFFF
+#define ACPI_MAX_LOOP_TIMEOUT 30
/******************************************************************************
diff --git a/sys/contrib/dev/acpica/include/acdebug.h b/sys/contrib/dev/acpica/include/acdebug.h
index ae176c2..0a27841 100644
--- a/sys/contrib/dev/acpica/include/acdebug.h
+++ b/sys/contrib/dev/acpica/include/acdebug.h
@@ -452,6 +452,12 @@ AcpiDbExecute (
UINT32 Flags);
void
+AcpiDbCreateExecutionThread (
+ char *MethodNameArg,
+ char **Arguments,
+ ACPI_OBJECT_TYPE *Types);
+
+void
AcpiDbCreateExecutionThreads (
char *NumThreadsArg,
char *NumLoopsArg,
diff --git a/sys/contrib/dev/acpica/include/acdisasm.h b/sys/contrib/dev/acpica/include/acdisasm.h
index 5d7140f..5f2030e 100644
--- a/sys/contrib/dev/acpica/include/acdisasm.h
+++ b/sys/contrib/dev/acpica/include/acdisasm.h
@@ -272,8 +272,10 @@ typedef enum
ACPI_DMT_PMTT,
ACPI_DMT_PPTT,
ACPI_DMT_SDEI,
+ ACPI_DMT_SDEV,
ACPI_DMT_SLIC,
ACPI_DMT_SRAT,
+ ACPI_DMT_TPM2,
/* Special opcodes */
@@ -502,6 +504,8 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit4[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit5[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit6a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoNfit7[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt0[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1[];
@@ -515,6 +519,7 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct1[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct2[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct3[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPcct4[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt0[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0a[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoPptt1[];
@@ -529,6 +534,13 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt0[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt1[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdei[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdevHdr[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev0[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev0a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoSdev1b[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoSlic[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoSlit[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoSpcr[];
@@ -546,6 +558,8 @@ extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaHdr[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaClient[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoTcpaServer[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoTpm2a[];
+extern ACPI_DMTABLE_INFO AcpiDmTableInfoTpm211[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoUefi[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoVrtc[];
extern ACPI_DMTABLE_INFO AcpiDmTableInfoVrtc0[];
@@ -586,7 +600,7 @@ AcpiDmDumpTable (
UINT32 TableLength,
UINT32 TableOffset,
void *Table,
- UINT32 SubTableLength,
+ UINT32 SubtableLength,
ACPI_DMTABLE_INFO *Info);
void
@@ -713,6 +727,10 @@ AcpiDmDumpPcct (
ACPI_TABLE_HEADER *Table);
void
+AcpiDmDumpPdtt (
+ ACPI_TABLE_HEADER *Table);
+
+void
AcpiDmDumpPmtt (
ACPI_TABLE_HEADER *Table);
@@ -733,6 +751,10 @@ AcpiDmDumpS3pt (
ACPI_TABLE_HEADER *Table);
void
+AcpiDmDumpSdev (
+ ACPI_TABLE_HEADER *Table);
+
+void
AcpiDmDumpSlic (
ACPI_TABLE_HEADER *Table);
@@ -753,6 +775,10 @@ AcpiDmDumpTcpa (
ACPI_TABLE_HEADER *Table);
void
+AcpiDmDumpTpm2 (
+ ACPI_TABLE_HEADER *Table);
+
+void
AcpiDmDumpVrtc (
ACPI_TABLE_HEADER *Table);
diff --git a/sys/contrib/dev/acpica/include/acexcep.h b/sys/contrib/dev/acpica/include/acexcep.h
index 1405e41..16d3698 100644
--- a/sys/contrib/dev/acpica/include/acexcep.h
+++ b/sys/contrib/dev/acpica/include/acexcep.h
@@ -237,8 +237,13 @@ typedef struct acpi_exception_info
#define AE_NOT_CONFIGURED EXCEP_ENV (0x001C)
#define AE_ACCESS EXCEP_ENV (0x001D)
#define AE_IO_ERROR EXCEP_ENV (0x001E)
+#define AE_NUMERIC_OVERFLOW EXCEP_ENV (0x001F)
+#define AE_HEX_OVERFLOW EXCEP_ENV (0x0020)
+#define AE_DECIMAL_OVERFLOW EXCEP_ENV (0x0021)
+#define AE_OCTAL_OVERFLOW EXCEP_ENV (0x0022)
+#define AE_END_OF_TABLE EXCEP_ENV (0x0023)
-#define AE_CODE_ENV_MAX 0x001E
+#define AE_CODE_ENV_MAX 0x0023
/*
@@ -305,7 +310,7 @@ typedef struct acpi_exception_info
#define AE_AML_CIRCULAR_REFERENCE EXCEP_AML (0x001E)
#define AE_AML_BAD_RESOURCE_LENGTH EXCEP_AML (0x001F)
#define AE_AML_ILLEGAL_ADDRESS EXCEP_AML (0x0020)
-#define AE_AML_INFINITE_LOOP EXCEP_AML (0x0021)
+#define AE_AML_LOOP_TIMEOUT EXCEP_AML (0x0021)
#define AE_AML_UNINITIALIZED_NODE EXCEP_AML (0x0022)
#define AE_AML_TARGET_TYPE EXCEP_AML (0x0023)
@@ -371,7 +376,12 @@ static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Env[] =
EXCEP_TXT ("AE_OWNER_ID_LIMIT", "There are no more Owner IDs available for ACPI tables or control methods"),
EXCEP_TXT ("AE_NOT_CONFIGURED", "The interface is not part of the current subsystem configuration"),
EXCEP_TXT ("AE_ACCESS", "Permission denied for the requested operation"),
- EXCEP_TXT ("AE_IO_ERROR", "An I/O error occurred")
+ EXCEP_TXT ("AE_IO_ERROR", "An I/O error occurred"),
+ EXCEP_TXT ("AE_NUMERIC_OVERFLOW", "Overflow during string-to-integer conversion"),
+ EXCEP_TXT ("AE_HEX_OVERFLOW", "Overflow during ASCII hex-to-binary conversion"),
+ EXCEP_TXT ("AE_DECIMAL_OVERFLOW", "Overflow during ASCII decimal-to-binary conversion"),
+ EXCEP_TXT ("AE_OCTAL_OVERFLOW", "Overflow during ASCII octal-to-binary conversion"),
+ EXCEP_TXT ("AE_END_OF_TABLE", "Reached the end of table")
};
static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Pgm[] =
@@ -433,7 +443,7 @@ static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Aml[] =
EXCEP_TXT ("AE_AML_CIRCULAR_REFERENCE", "Two references refer to each other"),
EXCEP_TXT ("AE_AML_BAD_RESOURCE_LENGTH", "The length of a Resource Descriptor in the AML is incorrect"),
EXCEP_TXT ("AE_AML_ILLEGAL_ADDRESS", "A memory, I/O, or PCI configuration address is invalid"),
- EXCEP_TXT ("AE_AML_INFINITE_LOOP", "An apparent infinite AML While loop, method was aborted"),
+ EXCEP_TXT ("AE_AML_LOOP_TIMEOUT", "An AML While loop exceeded the maximum execution time"),
EXCEP_TXT ("AE_AML_UNINITIALIZED_NODE", "A namespace node is uninitialized or unresolved"),
EXCEP_TXT ("AE_AML_TARGET_TYPE", "A target operand of an incorrect type was encountered")
};
diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h
index 686dcd8..d295869 100644
--- a/sys/contrib/dev/acpica/include/acglobal.h
+++ b/sys/contrib/dev/acpica/include/acglobal.h
@@ -155,7 +155,7 @@
/*****************************************************************************
*
- * Globals related to the ACPI tables
+ * Globals related to the incoming ACPI tables
*
****************************************************************************/
@@ -197,7 +197,7 @@ ACPI_GLOBAL (UINT8, AcpiGbl_IntegerNybbleWidth);
/*****************************************************************************
*
- * Mutual exclusion within ACPICA subsystem
+ * Mutual exclusion within the ACPICA subsystem
*
****************************************************************************/
@@ -278,7 +278,7 @@ ACPI_GLOBAL (UINT8, AcpiGbl_NextOwnerIdOffset);
ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_NamespaceInitialized, FALSE);
-/* Misc */
+/* Miscellaneous */
ACPI_GLOBAL (UINT32, AcpiGbl_OriginalMode);
ACPI_GLOBAL (UINT32, AcpiGbl_NsLookupCount);
@@ -301,11 +301,9 @@ extern const char AcpiGbl_LowerHexDigits[];
extern const char AcpiGbl_UpperHexDigits[];
extern const ACPI_OPCODE_INFO AcpiGbl_AmlOpInfo[AML_NUM_OPCODES];
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
-
/* Lists for tracking memory allocations (debug only) */
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
ACPI_GLOBAL (ACPI_MEMORY_LIST *, AcpiGbl_GlobalList);
ACPI_GLOBAL (ACPI_MEMORY_LIST *, AcpiGbl_NsNodeList);
ACPI_GLOBAL (BOOLEAN, AcpiGbl_DisplayFinalMemStats);
@@ -315,7 +313,7 @@ ACPI_GLOBAL (BOOLEAN, AcpiGbl_DisableMemTracking);
/*****************************************************************************
*
- * Namespace globals
+ * ACPI Namespace
*
****************************************************************************/
@@ -330,7 +328,6 @@ ACPI_GLOBAL (ACPI_NAMESPACE_NODE *, AcpiGbl_RootNode);
ACPI_GLOBAL (ACPI_NAMESPACE_NODE *, AcpiGbl_FadtGpeDevice);
ACPI_GLOBAL (ACPI_OPERAND_OBJECT *, AcpiGbl_ModuleCodeList);
-
extern const UINT8 AcpiGbl_NsProperties [ACPI_NUM_NS_TYPES];
extern const ACPI_PREDEFINED_NAMES AcpiGbl_PreDefinedNames [NUM_PREDEFINED_NAMES];
@@ -347,15 +344,20 @@ ACPI_INIT_GLOBAL (UINT32, AcpiGbl_NestingLevel, 0);
/*****************************************************************************
*
- * Interpreter globals
+ * Interpreter/Parser globals
*
****************************************************************************/
-ACPI_GLOBAL (ACPI_THREAD_STATE *, AcpiGbl_CurrentWalkList);
-
/* Control method single step flag */
ACPI_GLOBAL (UINT8, AcpiGbl_CmSingleStep);
+ACPI_GLOBAL (ACPI_THREAD_STATE *, AcpiGbl_CurrentWalkList);
+ACPI_INIT_GLOBAL (ACPI_PARSE_OBJECT, *AcpiGbl_CurrentScope, NULL);
+
+/* ASL/ASL+ converter */
+
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_CaptureComments, FALSE);
+ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_LastListHead, NULL);
/*****************************************************************************
@@ -365,7 +367,6 @@ ACPI_GLOBAL (UINT8, AcpiGbl_CmSingleStep);
****************************************************************************/
extern ACPI_BIT_REGISTER_INFO AcpiGbl_BitRegisterInfo[ACPI_NUM_BITREG];
-
ACPI_GLOBAL (UINT8, AcpiGbl_SleepTypeA);
ACPI_GLOBAL (UINT8, AcpiGbl_SleepTypeB);
@@ -377,18 +378,16 @@ ACPI_GLOBAL (UINT8, AcpiGbl_SleepTypeB);
****************************************************************************/
#if (!ACPI_REDUCED_HARDWARE)
-
ACPI_GLOBAL (UINT8, AcpiGbl_AllGpesInitialized);
ACPI_GLOBAL (ACPI_GPE_XRUPT_INFO *, AcpiGbl_GpeXruptListHead);
ACPI_GLOBAL (ACPI_GPE_BLOCK_INFO *, AcpiGbl_GpeFadtBlocks[ACPI_MAX_GPE_BLOCKS]);
ACPI_GLOBAL (ACPI_GBL_EVENT_HANDLER, AcpiGbl_GlobalEventHandler);
ACPI_GLOBAL (void *, AcpiGbl_GlobalEventHandlerContext);
ACPI_GLOBAL (ACPI_FIXED_EVENT_HANDLER, AcpiGbl_FixedEventHandlers[ACPI_NUM_FIXED_EVENTS]);
-
extern ACPI_FIXED_EVENT_INFO AcpiGbl_FixedEventInfo[ACPI_NUM_FIXED_EVENTS];
-
#endif /* !ACPI_REDUCED_HARDWARE */
+
/*****************************************************************************
*
* Debug support
@@ -402,7 +401,7 @@ ACPI_GLOBAL (UINT32, AcpiGpeCount);
ACPI_GLOBAL (UINT32, AcpiSciCount);
ACPI_GLOBAL (UINT32, AcpiFixedEventCount[ACPI_NUM_FIXED_EVENTS]);
-/* Support for dynamic control method tracing mechanism */
+/* Dynamic control method tracing mechanism */
ACPI_GLOBAL (UINT32, AcpiGbl_OriginalDbgLevel);
ACPI_GLOBAL (UINT32, AcpiGbl_OriginalDbgLayer);
@@ -410,12 +409,13 @@ ACPI_GLOBAL (UINT32, AcpiGbl_OriginalDbgLayer);
/*****************************************************************************
*
- * Debugger and Disassembler globals
+ * Debugger and Disassembler
*
****************************************************************************/
ACPI_INIT_GLOBAL (UINT8, AcpiGbl_DbOutputFlags, ACPI_DB_CONSOLE_OUTPUT);
+
#ifdef ACPI_DISASSEMBLER
/* Do not disassemble buffers to resource descriptors */
@@ -427,7 +427,7 @@ ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_ForceAmlDisassembly, FALSE);
ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Verbose, TRUE);
ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DmEmitExternalOpcodes, FALSE);
ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DoDisassemblerOptimizations, TRUE);
-ACPI_INIT_GLOBAL (ACPI_PARSE_OBJECT_LIST, *AcpiGbl_TempListHead, NULL);
+ACPI_INIT_GLOBAL (ACPI_PARSE_OBJECT_LIST, *AcpiGbl_TempListHead, NULL);
ACPI_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Disasm);
ACPI_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Listing);
@@ -438,7 +438,6 @@ ACPI_GLOBAL (ACPI_EXTERNAL_FILE *, AcpiGbl_ExternalFileList);
#endif
#ifdef ACPI_DEBUGGER
-
ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_AbortMethod, FALSE);
ACPI_INIT_GLOBAL (ACPI_THREAD_ID, AcpiGbl_DbThreadId, ACPI_INVALID_THREAD_ID);
@@ -452,7 +451,6 @@ ACPI_GLOBAL (UINT32, AcpiGbl_DbConsoleDebugLevel);
ACPI_GLOBAL (ACPI_NAMESPACE_NODE *, AcpiGbl_DbScopeNode);
ACPI_GLOBAL (BOOLEAN, AcpiGbl_DbTerminateLoop);
ACPI_GLOBAL (BOOLEAN, AcpiGbl_DbThreadsTerminated);
-
ACPI_GLOBAL (char *, AcpiGbl_DbArgs[ACPI_DEBUGGER_MAX_ARGS]);
ACPI_GLOBAL (ACPI_OBJECT_TYPE, AcpiGbl_DbArgTypes[ACPI_DEBUGGER_MAX_ARGS]);
@@ -462,81 +460,66 @@ ACPI_GLOBAL (char, AcpiGbl_DbParsedBuf[ACPI_DB_LINE_BUFFER_
ACPI_GLOBAL (char, AcpiGbl_DbScopeBuf[ACPI_DB_LINE_BUFFER_SIZE]);
ACPI_GLOBAL (char, AcpiGbl_DbDebugFilename[ACPI_DB_LINE_BUFFER_SIZE]);
-/*
- * Statistic globals
- */
+/* Statistics globals */
+
ACPI_GLOBAL (UINT16, AcpiGbl_ObjTypeCount[ACPI_TOTAL_TYPES]);
ACPI_GLOBAL (UINT16, AcpiGbl_NodeTypeCount[ACPI_TOTAL_TYPES]);
ACPI_GLOBAL (UINT16, AcpiGbl_ObjTypeCountMisc);
ACPI_GLOBAL (UINT16, AcpiGbl_NodeTypeCountMisc);
ACPI_GLOBAL (UINT32, AcpiGbl_NumNodes);
ACPI_GLOBAL (UINT32, AcpiGbl_NumObjects);
-
#endif /* ACPI_DEBUGGER */
#if defined (ACPI_DISASSEMBLER) || defined (ACPI_ASL_COMPILER)
-
-ACPI_GLOBAL (const char, *AcpiGbl_PldPanelList[]);
-ACPI_GLOBAL (const char, *AcpiGbl_PldVerticalPositionList[]);
-ACPI_GLOBAL (const char, *AcpiGbl_PldHorizontalPositionList[]);
-ACPI_GLOBAL (const char, *AcpiGbl_PldShapeList[]);
-
+ACPI_GLOBAL (const char, *AcpiGbl_PldPanelList[]);
+ACPI_GLOBAL (const char, *AcpiGbl_PldVerticalPositionList[]);
+ACPI_GLOBAL (const char, *AcpiGbl_PldHorizontalPositionList[]);
+ACPI_GLOBAL (const char, *AcpiGbl_PldShapeList[]);
ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DisasmFlag, FALSE);
-
#endif
-/*
- * Meant for the -ca option.
- */
-ACPI_INIT_GLOBAL (char*, AcpiGbl_CurrentInlineComment, NULL);
-ACPI_INIT_GLOBAL (char*, AcpiGbl_CurrentEndNodeComment, NULL);
-ACPI_INIT_GLOBAL (char*, AcpiGbl_CurrentOpenBraceComment, NULL);
-ACPI_INIT_GLOBAL (char*, AcpiGbl_CurrentCloseBraceComment, NULL);
-ACPI_INIT_GLOBAL (char*, AcpiGbl_RootFilename, NULL);
-ACPI_INIT_GLOBAL (char*, AcpiGbl_CurrentFilename, NULL);
-ACPI_INIT_GLOBAL (char*, AcpiGbl_CurrentParentFilename, NULL);
-ACPI_INIT_GLOBAL (char*, AcpiGbl_CurrentIncludeFilename, NULL);
+/*****************************************************************************
+ *
+ * ACPICA application-specific globals
+ *
+ ****************************************************************************/
+
+/* ASL-to-ASL+ conversion utility (implemented within the iASL compiler) */
-ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_LastListHead, NULL);
+#ifdef ACPI_ASL_COMPILER
+ACPI_INIT_GLOBAL (char *, AcpiGbl_CurrentInlineComment, NULL);
+ACPI_INIT_GLOBAL (char *, AcpiGbl_CurrentEndNodeComment, NULL);
+ACPI_INIT_GLOBAL (char *, AcpiGbl_CurrentOpenBraceComment, NULL);
+ACPI_INIT_GLOBAL (char *, AcpiGbl_CurrentCloseBraceComment, NULL);
+
+ACPI_INIT_GLOBAL (char *, AcpiGbl_RootFilename, NULL);
+ACPI_INIT_GLOBAL (char *, AcpiGbl_CurrentFilename, NULL);
+ACPI_INIT_GLOBAL (char *, AcpiGbl_CurrentParentFilename, NULL);
+ACPI_INIT_GLOBAL (char *, AcpiGbl_CurrentIncludeFilename, NULL);
ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_DefBlkCommentListHead, NULL);
ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_DefBlkCommentListTail, NULL);
-
ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_RegCommentListHead, NULL);
ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_RegCommentListTail, NULL);
-
ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_IncCommentListHead, NULL);
ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_IncCommentListTail, NULL);
-
ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_EndBlkCommentListHead, NULL);
ACPI_INIT_GLOBAL (ACPI_COMMENT_NODE, *AcpiGbl_EndBlkCommentListTail, NULL);
-ACPI_INIT_GLOBAL (ACPI_COMMENT_ADDR_NODE, *AcpiGbl_CommentAddrListHead, NULL);
-
-ACPI_INIT_GLOBAL (ACPI_PARSE_OBJECT, *AcpiGbl_CurrentScope, NULL);
-
+ACPI_INIT_GLOBAL (ACPI_COMMENT_ADDR_NODE, *AcpiGbl_CommentAddrListHead, NULL);
ACPI_INIT_GLOBAL (ACPI_FILE_NODE, *AcpiGbl_FileTreeRoot, NULL);
ACPI_GLOBAL (ACPI_CACHE_T *, AcpiGbl_RegCommentCache);
ACPI_GLOBAL (ACPI_CACHE_T *, AcpiGbl_CommentAddrCache);
ACPI_GLOBAL (ACPI_CACHE_T *, AcpiGbl_FileCache);
-ACPI_INIT_GLOBAL (BOOLEAN, Gbl_CaptureComments, FALSE);
-
-ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DebugAslConversion, FALSE);
-ACPI_INIT_GLOBAL (ACPI_FILE, AcpiGbl_ConvDebugFile, NULL);
-
-ACPI_GLOBAL (char, AcpiGbl_TableSig[4]);
-
-/*****************************************************************************
- *
- * Application globals
- *
- ****************************************************************************/
+ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DebugAslConversion, FALSE);
+ACPI_INIT_GLOBAL (ACPI_FILE, AcpiGbl_ConvDebugFile, NULL);
+ACPI_GLOBAL (char, AcpiGbl_TableSig[4]);
+#endif
#ifdef ACPI_APPLICATION
-
ACPI_INIT_GLOBAL (ACPI_FILE, AcpiGbl_DebugFile, NULL);
ACPI_INIT_GLOBAL (ACPI_FILE, AcpiGbl_OutputFile, NULL);
ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DebugTimeout, FALSE);
@@ -545,18 +528,6 @@ ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DebugTimeout, FALSE);
ACPI_GLOBAL (ACPI_SPINLOCK, AcpiGbl_PrintLock); /* For print buffer */
ACPI_GLOBAL (char, AcpiGbl_PrintBuffer[1024]);
-
#endif /* ACPI_APPLICATION */
-
-/*****************************************************************************
- *
- * Info/help support
- *
- ****************************************************************************/
-
-extern const AH_PREDEFINED_NAME AslPredefinedInfo[];
-extern const AH_DEVICE_ID AslDeviceIds[];
-
-
#endif /* __ACGLOBAL_H__ */
diff --git a/sys/contrib/dev/acpica/include/achware.h b/sys/contrib/dev/acpica/include/achware.h
index f33be8c..c3bf8f1 100644
--- a/sys/contrib/dev/acpica/include/achware.h
+++ b/sys/contrib/dev/acpica/include/achware.h
@@ -185,12 +185,12 @@ AcpiHwValidateRegister (
ACPI_STATUS
AcpiHwRead (
- UINT32 *Value,
+ UINT64 *Value,
ACPI_GENERIC_ADDRESS *Reg);
ACPI_STATUS
AcpiHwWrite (
- UINT32 Value,
+ UINT64 Value,
ACPI_GENERIC_ADDRESS *Reg);
ACPI_BIT_REGISTER_INFO *
diff --git a/sys/contrib/dev/acpica/include/acinterp.h b/sys/contrib/dev/acpica/include/acinterp.h
index dd98f01..d68058c 100644
--- a/sys/contrib/dev/acpica/include/acinterp.h
+++ b/sys/contrib/dev/acpica/include/acinterp.h
@@ -214,7 +214,7 @@ ACPI_STATUS
AcpiExConvertToInteger (
ACPI_OPERAND_OBJECT *ObjDesc,
ACPI_OPERAND_OBJECT **ResultDesc,
- UINT32 Flags);
+ UINT32 ImplicitConversion);
ACPI_STATUS
AcpiExConvertToBuffer (
@@ -683,9 +683,6 @@ AcpiExStoreObjectToNode (
ACPI_WALK_STATE *WalkState,
UINT8 ImplicitConversion);
-#define ACPI_IMPLICIT_CONVERSION TRUE
-#define ACPI_NO_IMPLICIT_CONVERSION FALSE
-
/*
* exstoren - resolve/store object
diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h
index 00be20e..5ad3190 100644
--- a/sys/contrib/dev/acpica/include/aclocal.h
+++ b/sys/contrib/dev/acpica/include/aclocal.h
@@ -834,7 +834,7 @@ typedef struct acpi_control_state
union acpi_parse_object *PredicateOp;
UINT8 *AmlPredicateStart; /* Start of if/while predicate */
UINT8 *PackageEnd; /* End of if/while block */
- UINT32 LoopCount; /* While() loop counter */
+ UINT64 LoopTimeout; /* While() loop timeout */
} ACPI_CONTROL_STATE;
@@ -1532,16 +1532,17 @@ typedef struct acpi_db_method_info
ACPI_OBJECT_TYPE *Types;
/*
- * Arguments to be passed to method for the command
- * Threads -
- * the Number of threads, ID of current thread and
- * Index of current thread inside all them created.
+ * Arguments to be passed to method for the commands Threads and
+ * Background. Note, ACPI specifies a maximum of 7 arguments (0 - 6).
+ *
+ * For the Threads command, the Number of threads, ID of current
+ * thread and Index of current thread inside all them created.
*/
char InitArgs;
#ifdef ACPI_DEBUGGER
- ACPI_OBJECT_TYPE ArgTypes[4];
+ ACPI_OBJECT_TYPE ArgTypes[ACPI_METHOD_NUM_ARGS];
#endif
- char *Arguments[4];
+ char *Arguments[ACPI_METHOD_NUM_ARGS];
char NumThreadsStr[11];
char IdOfThreadStr[11];
char IndexOfThreadStr[11];
diff --git a/sys/contrib/dev/acpica/include/acmacros.h b/sys/contrib/dev/acpica/include/acmacros.h
index 9d7ed06..feb4593 100644
--- a/sys/contrib/dev/acpica/include/acmacros.h
+++ b/sys/contrib/dev/acpica/include/acmacros.h
@@ -567,7 +567,7 @@
* the plist contains a set of parens to allow variable-length lists.
* These macros are used for both the debug and non-debug versions of the code.
*/
-#define ACPI_ERROR_NAMESPACE(s, e) AcpiUtNamespaceError (AE_INFO, s, e);
+#define ACPI_ERROR_NAMESPACE(s, p, e) AcpiUtPrefixedNamespaceError (AE_INFO, s, p, e);
#define ACPI_ERROR_METHOD(s, n, p, e) AcpiUtMethodError (AE_INFO, s, n, p, e);
#define ACPI_WARN_PREDEFINED(plist) AcpiUtPredefinedWarning plist
#define ACPI_INFO_PREDEFINED(plist) AcpiUtPredefinedInfo plist
diff --git a/sys/contrib/dev/acpica/include/acnamesp.h b/sys/contrib/dev/acpica/include/acnamesp.h
index 990309e..4340271 100644
--- a/sys/contrib/dev/acpica/include/acnamesp.h
+++ b/sys/contrib/dev/acpica/include/acnamesp.h
@@ -489,6 +489,11 @@ AcpiNsGetNormalizedPathname (
BOOLEAN NoTrailing);
char *
+AcpiNsBuildPrefixedPathname (
+ ACPI_GENERIC_STATE *PrefixScope,
+ const char *InternalPath);
+
+char *
AcpiNsNameOfCurrentScope (
ACPI_WALK_STATE *WalkState);
diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h
index fc486d5..482662f 100644
--- a/sys/contrib/dev/acpica/include/acpixf.h
+++ b/sys/contrib/dev/acpica/include/acpixf.h
@@ -154,7 +154,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20170728
+#define ACPI_CA_VERSION 0x20171214
#include <contrib/dev/acpica/include/acconfig.h>
#include <contrib/dev/acpica/include/actypes.h>
@@ -370,11 +370,11 @@ ACPI_INIT_GLOBAL (UINT8, AcpiGbl_OsiData, 0);
ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_ReducedHardware, FALSE);
/*
- * Maximum number of While() loop iterations before forced method abort.
+ * Maximum timeout for While() loop iterations before forced method abort.
* This mechanism is intended to prevent infinite loops during interpreter
* execution within a host kernel.
*/
-ACPI_INIT_GLOBAL (UINT32, AcpiGbl_MaxLoopIterations, ACPI_MAX_LOOP_COUNT);
+ACPI_INIT_GLOBAL (UINT32, AcpiGbl_MaxLoopIterations, ACPI_MAX_LOOP_TIMEOUT);
/*
* This mechanism is used to trace a specified AML method. The method is
diff --git a/sys/contrib/dev/acpica/include/actbl1.h b/sys/contrib/dev/acpica/include/actbl1.h
index da6b561..6d0f5c8 100644
--- a/sys/contrib/dev/acpica/include/actbl1.h
+++ b/sys/contrib/dev/acpica/include/actbl1.h
@@ -179,8 +179,10 @@
#define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */
#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */
#define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */
+#define ACPI_SIG_PDTT "PDTT" /* Platform Debug Trigger Table */
#define ACPI_SIG_PPTT "PPTT" /* Processor Properties Topology Table */
#define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */
+#define ACPI_SIG_SDEV "SDEV" /* Secure Devices table */
#define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */
#define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */
#define ACPI_SIG_NFIT "NFIT" /* NVDIMM Firmware Interface Table */
@@ -1447,7 +1449,8 @@ enum AcpiNfitType
ACPI_NFIT_TYPE_CONTROL_REGION = 4,
ACPI_NFIT_TYPE_DATA_REGION = 5,
ACPI_NFIT_TYPE_FLUSH_ADDRESS = 6,
- ACPI_NFIT_TYPE_RESERVED = 7 /* 7 and greater are reserved */
+ ACPI_NFIT_TYPE_CAPABILITIES = 7,
+ ACPI_NFIT_TYPE_RESERVED = 8 /* 8 and greater are reserved */
};
/*
@@ -1461,7 +1464,7 @@ typedef struct acpi_nfit_system_address
ACPI_NFIT_HEADER Header;
UINT16 RangeIndex;
UINT16 Flags;
- UINT32 Reserved; /* Reseved, must be zero */
+ UINT32 Reserved; /* Reserved, must be zero */
UINT32 ProximityDomain;
UINT8 RangeGuid[16];
UINT64 Address;
@@ -1600,6 +1603,110 @@ typedef struct acpi_nfit_flush_address
} ACPI_NFIT_FLUSH_ADDRESS;
+/* 7: Platform Capabilities Structure */
+
+typedef struct acpi_nfit_capabilities
+{
+ ACPI_NFIT_HEADER Header;
+ UINT8 HighestCapability;
+ UINT8 Reserved[3]; /* Reserved, must be zero */
+ UINT32 Capabilities;
+ UINT32 Reserved2;
+
+} ACPI_NFIT_CAPABILITIES;
+
+/* Capabilities Flags */
+
+#define ACPI_NFIT_CAPABILITY_CACHE_FLUSH (1) /* 00: Cache Flush to NVDIMM capable */
+#define ACPI_NFIT_CAPABILITY_MEM_FLUSH (1<<1) /* 01: Memory Flush to NVDIMM capable */
+#define ACPI_NFIT_CAPABILITY_MEM_MIRRORING (1<<2) /* 02: Memory Mirroring capable */
+
+
+/*
+ * NFIT/DVDIMM device handle support - used as the _ADR for each NVDIMM
+ */
+typedef struct nfit_device_handle
+{
+ UINT32 Handle;
+
+} NFIT_DEVICE_HANDLE;
+
+/* Device handle construction and extraction macros */
+
+#define ACPI_NFIT_DIMM_NUMBER_MASK 0x0000000F
+#define ACPI_NFIT_CHANNEL_NUMBER_MASK 0x000000F0
+#define ACPI_NFIT_MEMORY_ID_MASK 0x00000F00
+#define ACPI_NFIT_SOCKET_ID_MASK 0x0000F000
+#define ACPI_NFIT_NODE_ID_MASK 0x0FFF0000
+
+#define ACPI_NFIT_DIMM_NUMBER_OFFSET 0
+#define ACPI_NFIT_CHANNEL_NUMBER_OFFSET 4
+#define ACPI_NFIT_MEMORY_ID_OFFSET 8
+#define ACPI_NFIT_SOCKET_ID_OFFSET 12
+#define ACPI_NFIT_NODE_ID_OFFSET 16
+
+/* Macro to construct a NFIT/NVDIMM device handle */
+
+#define ACPI_NFIT_BUILD_DEVICE_HANDLE(dimm, channel, memory, socket, node) \
+ ((dimm) | \
+ ((channel) << ACPI_NFIT_CHANNEL_NUMBER_OFFSET) | \
+ ((memory) << ACPI_NFIT_MEMORY_ID_OFFSET) | \
+ ((socket) << ACPI_NFIT_SOCKET_ID_OFFSET) | \
+ ((node) << ACPI_NFIT_NODE_ID_OFFSET))
+
+/* Macros to extract individual fields from a NFIT/NVDIMM device handle */
+
+#define ACPI_NFIT_GET_DIMM_NUMBER(handle) \
+ ((handle) & ACPI_NFIT_DIMM_NUMBER_MASK)
+
+#define ACPI_NFIT_GET_CHANNEL_NUMBER(handle) \
+ (((handle) & ACPI_NFIT_CHANNEL_NUMBER_MASK) >> ACPI_NFIT_CHANNEL_NUMBER_OFFSET)
+
+#define ACPI_NFIT_GET_MEMORY_ID(handle) \
+ (((handle) & ACPI_NFIT_MEMORY_ID_MASK) >> ACPI_NFIT_MEMORY_ID_OFFSET)
+
+#define ACPI_NFIT_GET_SOCKET_ID(handle) \
+ (((handle) & ACPI_NFIT_SOCKET_ID_MASK) >> ACPI_NFIT_SOCKET_ID_OFFSET)
+
+#define ACPI_NFIT_GET_NODE_ID(handle) \
+ (((handle) & ACPI_NFIT_NODE_ID_MASK) >> ACPI_NFIT_NODE_ID_OFFSET)
+
+
+/*******************************************************************************
+ *
+ * PDTT - Platform Debug Trigger Table (ACPI 6.2)
+ * Version 0
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_pdtt
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+ UINT8 TriggerCount;
+ UINT8 Reserved[3];
+ UINT32 ArrayOffset;
+
+} ACPI_TABLE_PDTT;
+
+
+/*
+ * PDTT Communication Channel Identifier Structure.
+ * The number of these structures is defined by TriggerCount above,
+ * starting at ArrayOffset.
+ */
+typedef struct acpi_pdtt_channel
+{
+ UINT8 SubchannelId;
+ UINT8 Flags;
+
+} ACPI_PDTT_CHANNEL;
+
+/* Flags for above */
+
+#define ACPI_PDTT_RUNTIME_TRIGGER (1)
+#define ACPI_PDTT_WAIT_COMPLETION (1<<1)
+
+
/*******************************************************************************
*
* PPTT - Processor Properties Topology Table (ACPI 6.2)
@@ -1626,7 +1733,8 @@ enum AcpiPpttType
/* 0: Processor Hierarchy Node Structure */
-typedef struct acpi_pptt_processor {
+typedef struct acpi_pptt_processor
+{
ACPI_SUBTABLE_HEADER Header;
UINT16 Reserved;
UINT32 Flags;
@@ -1644,7 +1752,8 @@ typedef struct acpi_pptt_processor {
/* 1: Cache Type Structure */
-typedef struct acpi_pptt_cache {
+typedef struct acpi_pptt_cache
+{
ACPI_SUBTABLE_HEADER Header;
UINT16 Reserved;
UINT32 Flags;
@@ -1673,10 +1782,24 @@ typedef struct acpi_pptt_cache {
#define ACPI_PPTT_MASK_CACHE_TYPE (0x0C) /* Cache type */
#define ACPI_PPTT_MASK_WRITE_POLICY (0x10) /* Write policy */
+/* Attributes describing cache */
+#define ACPI_PPTT_CACHE_READ_ALLOCATE (0x0) /* Cache line is allocated on read */
+#define ACPI_PPTT_CACHE_WRITE_ALLOCATE (0x01) /* Cache line is allocated on write */
+#define ACPI_PPTT_CACHE_RW_ALLOCATE (0x02) /* Cache line is allocated on read and write */
+#define ACPI_PPTT_CACHE_RW_ALLOCATE_ALT (0x03) /* Alternate representation of above */
+
+#define ACPI_PPTT_CACHE_TYPE_DATA (0x0) /* Data cache */
+#define ACPI_PPTT_CACHE_TYPE_INSTR (1<<2) /* Instruction cache */
+#define ACPI_PPTT_CACHE_TYPE_UNIFIED (2<<2) /* Unified I & D cache */
+#define ACPI_PPTT_CACHE_TYPE_UNIFIED_ALT (3<<2) /* Alternate representation of above */
+
+#define ACPI_PPTT_CACHE_POLICY_WB (0x0) /* Cache is write back */
+#define ACPI_PPTT_CACHE_POLICY_WT (1<<4) /* Cache is write through */
/* 2: ID Structure */
-typedef struct acpi_pptt_id {
+typedef struct acpi_pptt_id
+{
ACPI_SUBTABLE_HEADER Header;
UINT16 Reserved;
UINT32 VendorId;
@@ -1708,6 +1831,82 @@ typedef struct acpi_table_sbst
/*******************************************************************************
*
+ * SDEV - Secure Devices Table (ACPI 6.2)
+ * Version 1
+ *
+ ******************************************************************************/
+
+typedef struct acpi_table_sdev
+{
+ ACPI_TABLE_HEADER Header; /* Common ACPI table header */
+
+} ACPI_TABLE_SDEV;
+
+
+typedef struct acpi_sdev_header
+{
+ UINT8 Type;
+ UINT8 Flags;
+ UINT16 Length;
+
+} ACPI_SDEV_HEADER;
+
+
+/* Values for subtable type above */
+
+enum AcpiSdevType
+{
+ ACPI_SDEV_TYPE_NAMESPACE_DEVICE = 0,
+ ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE = 1,
+ ACPI_SDEV_TYPE_RESERVED = 2 /* 2 and greater are reserved */
+};
+
+/* Values for flags above */
+
+#define ACPI_SDEV_HANDOFF_TO_UNSECURE_OS (1)
+
+/*
+ * SDEV subtables
+ */
+
+/* 0: Namespace Device Based Secure Device Structure */
+
+typedef struct acpi_sdev_namespace
+{
+ ACPI_SDEV_HEADER Header;
+ UINT16 DeviceIdOffset;
+ UINT16 DeviceIdLength;
+ UINT16 VendorDataOffset;
+ UINT16 VendorDataLength;
+
+} ACPI_SDEV_NAMESPACE;
+
+/* 1: PCIe Endpoint Device Based Device Structure */
+
+typedef struct acpi_sdev_pcie
+{
+ ACPI_SDEV_HEADER Header;
+ UINT16 Segment;
+ UINT16 StartBus;
+ UINT16 PathOffset;
+ UINT16 PathLength;
+ UINT16 VendorDataOffset;
+ UINT16 VendorDataLength;
+
+} ACPI_SDEV_PCIE;
+
+/* 1a: PCIe Endpoint path entry */
+
+typedef struct acpi_sdev_pcie_path
+{
+ UINT8 Device;
+ UINT8 Function;
+
+} ACPI_SDEV_PCIE_PATH;
+
+
+/*******************************************************************************
+ *
* SLIT - System Locality Distance Information Table
* Version 1
*
diff --git a/sys/contrib/dev/acpica/include/actbl2.h b/sys/contrib/dev/acpica/include/actbl2.h
index 18cfdd4..cdf7ac0 100644
--- a/sys/contrib/dev/acpica/include/actbl2.h
+++ b/sys/contrib/dev/acpica/include/actbl2.h
@@ -1030,6 +1030,7 @@ typedef struct acpi_iort_smmu_gsi
UINT32 NSgIrptFlags;
UINT32 NSgCfgIrpt;
UINT32 NSgCfgIrptFlags;
+
} ACPI_IORT_SMMU_GSI;
@@ -1047,6 +1048,7 @@ typedef struct acpi_iort_smmu_v3
UINT8 Pxm;
UINT8 Reserved1;
UINT16 Reserved2;
+ UINT32 IdMappingIndex;
} ACPI_IORT_SMMU_V3;
@@ -1549,6 +1551,8 @@ enum AcpiSpmiInterfaceTypes
* TCPA - Trusted Computing Platform Alliance table
* Version 2
*
+ * TCG Hardware Interface Table for TPM 1.2 Clients and Servers
+ *
* Conforms to "TCG ACPI Specification, Family 1.2 and 2.0",
* Version 1.2, Revision 8
* February 27, 2017
@@ -1621,6 +1625,8 @@ typedef struct acpi_table_tcpa_server
* TPM2 - Trusted Platform Module (TPM) 2.0 Hardware Interface Table
* Version 4
*
+ * TCG Hardware Interface Table for TPM 2.0 Clients and Servers
+ *
* Conforms to "TCG ACPI Specification, Family 1.2 and 2.0",
* Version 1.2, Revision 8
* February 27, 2017
@@ -1642,17 +1648,25 @@ typedef struct acpi_table_tpm2
/* Values for StartMethod above */
#define ACPI_TPM2_NOT_ALLOWED 0
+#define ACPI_TPM2_RESERVED1 1
#define ACPI_TPM2_START_METHOD 2
+#define ACPI_TPM2_RESERVED3 3
+#define ACPI_TPM2_RESERVED4 4
+#define ACPI_TPM2_RESERVED5 5
#define ACPI_TPM2_MEMORY_MAPPED 6
#define ACPI_TPM2_COMMAND_BUFFER 7
#define ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD 8
+#define ACPI_TPM2_RESERVED9 9
+#define ACPI_TPM2_RESERVED10 10
#define ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC 11 /* V1.2 Rev 8 */
+#define ACPI_TPM2_RESERVED 12
-/* Trailer appears after any StartMethod subtables */
+/* Optional trailer appears after any StartMethod subtables */
typedef struct acpi_tpm2_trailer
{
+ UINT8 MethodParameters[12];
UINT32 MinimumLogLength; /* Minimum length for the event log area */
UINT64 LogAddress; /* Address of the event log area */
diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h
index 1839f93..2d71de5 100644
--- a/sys/contrib/dev/acpica/include/actypes.h
+++ b/sys/contrib/dev/acpica/include/actypes.h
@@ -586,6 +586,8 @@ typedef void * ACPI_HANDLE; /* Actually a ptr to a N
#define ACPI_NSEC_PER_MSEC 1000000L
#define ACPI_NSEC_PER_SEC 1000000000L
+#define ACPI_TIME_AFTER(a, b) ((INT64)((b) - (a)) < 0)
+
/* Owner IDs are used to track namespace nodes for selective deletion */
@@ -1507,6 +1509,8 @@ typedef enum
#define ACPI_OSI_WIN_7 0x0B
#define ACPI_OSI_WIN_8 0x0C
#define ACPI_OSI_WIN_10 0x0D
+#define ACPI_OSI_WIN_10_RS1 0x0E
+#define ACPI_OSI_WIN_10_RS2 0x0F
/* Definitions of getopt */
diff --git a/sys/contrib/dev/acpica/include/acutils.h b/sys/contrib/dev/acpica/include/acutils.h
index f6cfe08..f28e039 100644
--- a/sys/contrib/dev/acpica/include/acutils.h
+++ b/sys/contrib/dev/acpica/include/acutils.h
@@ -227,9 +227,6 @@ extern const char *AcpiGbl_PtypDecode[];
#ifndef ACPI_MSG_ERROR
#define ACPI_MSG_ERROR "ACPI Error: "
#endif
-#ifndef ACPI_MSG_EXCEPTION
-#define ACPI_MSG_EXCEPTION "ACPI Exception: "
-#endif
#ifndef ACPI_MSG_WARNING
#define ACPI_MSG_WARNING "ACPI Warning: "
#endif
@@ -238,10 +235,10 @@ extern const char *AcpiGbl_PtypDecode[];
#endif
#ifndef ACPI_MSG_BIOS_ERROR
-#define ACPI_MSG_BIOS_ERROR "ACPI BIOS Error (bug): "
+#define ACPI_MSG_BIOS_ERROR "Firmware Error (ACPI): "
#endif
#ifndef ACPI_MSG_BIOS_WARNING
-#define ACPI_MSG_BIOS_WARNING "ACPI BIOS Warning (bug): "
+#define ACPI_MSG_BIOS_WARNING "Firmware Warning (ACPI): "
#endif
/*
@@ -250,6 +247,10 @@ extern const char *AcpiGbl_PtypDecode[];
#define ACPI_MSG_SUFFIX \
AcpiOsPrintf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, ModuleName, LineNumber)
+/* Flags to indicate implicit or explicit string-to-integer conversion */
+
+#define ACPI_IMPLICIT_CONVERSION TRUE
+#define ACPI_NO_IMPLICIT_CONVERSION FALSE
/* Types for Resource descriptor entries */
@@ -330,19 +331,57 @@ AcpiUtStricmp (
char *String1,
char *String2);
+
+/*
+ * utstrsuppt - string-to-integer conversion support functions
+ */
ACPI_STATUS
-AcpiUtStrtoul64 (
+AcpiUtConvertOctalString (
char *String,
- UINT32 Flags,
- UINT64 *RetInteger);
+ UINT64 *ReturnValue);
+
+ACPI_STATUS
+AcpiUtConvertDecimalString (
+ char *String,
+ UINT64 *ReturnValuePtr);
+
+ACPI_STATUS
+AcpiUtConvertHexString (
+ char *String,
+ UINT64 *ReturnValuePtr);
+
+char
+AcpiUtRemoveWhitespace (
+ char **String);
+
+char
+AcpiUtRemoveLeadingZeros (
+ char **String);
+
+BOOLEAN
+AcpiUtDetectHexPrefix (
+ char **String);
+
+BOOLEAN
+AcpiUtDetectOctalPrefix (
+ char **String);
+
/*
- * Values for Flags above
- * Note: LIMIT values correspond to AcpiGbl_IntegerByteWidth values (4/8)
+ * utstrtoul64 - string-to-integer conversion functions
*/
-#define ACPI_STRTOUL_32BIT 0x04 /* 4 bytes */
-#define ACPI_STRTOUL_64BIT 0x08 /* 8 bytes */
-#define ACPI_STRTOUL_BASE16 0x10 /* Default: Base10/16 */
+ACPI_STATUS
+AcpiUtStrtoul64 (
+ char *String,
+ UINT64 *RetInteger);
+
+UINT64
+AcpiUtExplicitStrtoul64 (
+ char *String);
+
+UINT64
+AcpiUtImplicitStrtoul64 (
+ char *String);
/*
@@ -352,12 +391,12 @@ ACPI_STATUS
AcpiUtInitGlobals (
void);
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-
const char *
AcpiUtGetMutexName (
UINT32 MutexId);
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
const char *
AcpiUtGetNotifyName (
UINT32 NotifyValue,
@@ -1020,6 +1059,12 @@ AcpiUtSafeStrcpy (
ACPI_SIZE DestSize,
char *Source);
+void
+AcpiUtSafeStrncpy (
+ char *Dest,
+ char *Source,
+ ACPI_SIZE DestSize);
+
BOOLEAN
AcpiUtSafeStrcat (
char *Dest,
@@ -1173,9 +1218,10 @@ AcpiUtPredefinedBiosError (
...);
void
-AcpiUtNamespaceError (
+AcpiUtPrefixedNamespaceError (
const char *ModuleName,
UINT32 LineNumber,
+ ACPI_GENERIC_STATE *PrefixScope,
const char *InternalName,
ACPI_STATUS LookupStatus);
diff --git a/sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c b/sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c
index 7413c15..56d4681 100644
--- a/sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c
+++ b/sys/contrib/dev/acpica/os_specific/service_layers/osgendbg.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Module Name: osgendbg - Generic debugger command singalling
+ * Module Name: osgendbg - Generic debugger command signalling
*
*****************************************************************************/
@@ -169,6 +169,7 @@ static ACPI_MUTEX AcpiGbl_DbCommandReady;
static ACPI_MUTEX AcpiGbl_DbCommandComplete;
static BOOLEAN AcpiGbl_DbCommandSignalsInitialized = FALSE;
+
/******************************************************************************
*
* FUNCTION: AcpiDbRunRemoteDebugger
@@ -213,7 +214,7 @@ AcpiDbRunRemoteDebugger (
Ptr++;
}
- strncpy (AcpiGbl_DbLineBuf, Cmd, ACPI_DB_LINE_BUFFER_SIZE);
+ AcpiUtSafeStrncpy (AcpiGbl_DbLineBuf, Cmd, ACPI_DB_LINE_BUFFER_SIZE);
Ptr++;
Cmd = Ptr;
}
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index 35ef8c0..17eab66 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -483,7 +483,7 @@ ipf_state_soft_fini(softc, arg)
/* ------------------------------------------------------------------------ */
-/* Function: ipf_state_set_lock */
+/* Function: ipf_state_setlock */
/* Returns: Nil */
/* Parameters: arg(I) - pointer to local context to use */
/* tmp(I) - new value for lock */
diff --git a/sys/dev/acpica/Osd/OsdSchedule.c b/sys/dev/acpica/Osd/OsdSchedule.c
index 8e38102..8330c37 100644
--- a/sys/dev/acpica/Osd/OsdSchedule.c
+++ b/sys/dev/acpica/Osd/OsdSchedule.c
@@ -274,9 +274,6 @@ AcpiOsGetTimer(void)
struct bintime bt;
UINT64 t;
- /* XXX During early boot there is no (decent) timer available yet. */
- KASSERT(cold == 0, ("acpi: timer op not yet supported during boot"));
-
binuptime(&bt);
t = (uint64_t)bt.sec * 10000000;
t += ((uint64_t)10000000 * (uint32_t)(bt.frac >> 32)) >> 32;
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index abcc582..dd425cb 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -1174,7 +1174,7 @@ acpi_cpu_idle(sbintime_t sbt)
* is the only reliable time source.
*/
if (cx_next->type == ACPI_STATE_C3) {
- AcpiHwRead(&start_time, &AcpiGbl_FADT.XPmTimerBlock);
+ AcpiGetTimer(&start_time);
cputicks = 0;
} else {
start_time = 0;
@@ -1191,10 +1191,10 @@ acpi_cpu_idle(sbintime_t sbt)
* the processor has stopped. Doing it again provides enough
* margin that we are certain to have a correct value.
*/
- AcpiHwRead(&end_time, &AcpiGbl_FADT.XPmTimerBlock);
+ AcpiGetTimer(&end_time);
if (cx_next->type == ACPI_STATE_C3) {
- AcpiHwRead(&end_time, &AcpiGbl_FADT.XPmTimerBlock);
- end_time = acpi_TimerDelta(end_time, start_time);
+ AcpiGetTimer(&end_time);
+ AcpiGetTimerDuration(start_time, end_time, &end_time);
} else
end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate();
diff --git a/sys/dev/ahci/ahci_pci.c b/sys/dev/ahci/ahci_pci.c
index fee890b..ca73b52 100644
--- a/sys/dev/ahci/ahci_pci.c
+++ b/sys/dev/ahci/ahci_pci.c
@@ -68,6 +68,7 @@ static const struct {
AHCI_Q_ATI_PMP_BUG | AHCI_Q_1MSI},
/* Not sure SB8x0/SB9x0 needs this quirk. Be conservative though */
{0x43951002, 0x00, "AMD SB8x0/SB9x0", AHCI_Q_ATI_PMP_BUG},
+ {0x43b71022, 0x00, "AMD 300 Series", 0},
{0x78001022, 0x00, "AMD Hudson-2", 0},
{0x78011022, 0x00, "AMD Hudson-2", 0},
{0x78021022, 0x00, "AMD Hudson-2", 0},
diff --git a/sys/dev/ffec/if_ffec.c b/sys/dev/ffec/if_ffec.c
index e18e3f1..d93547a 100644
--- a/sys/dev/ffec/if_ffec.c
+++ b/sys/dev/ffec/if_ffec.c
@@ -97,16 +97,21 @@ enum {
FECTYPE_NONE,
FECTYPE_GENERIC,
FECTYPE_IMX53,
- FECTYPE_IMX6,
+ FECTYPE_IMX6, /* imx6 and imx7 */
FECTYPE_MVF,
};
/*
* Flags that describe general differences between the FEC hardware in various
- * SoCs. These are ORed into the FECTYPE enum values.
+ * SoCs. These are ORed into the FECTYPE enum values in the ofw_compat_data, so
+ * the low 8 bits are reserved for the type enum. In the softc, the type and
+ * flags are put into separate members, so that you don't need to mask the flags
+ * out of the type to compare it.
*/
-#define FECTYPE_MASK 0x0000ffff
-#define FECFLAG_GBE (0x0001 << 16)
+#define FECTYPE_MASK 0x000000ff
+#define FECFLAG_GBE (1 << 8)
+#define FECFLAG_AVB (1 << 9)
+#define FECFLAG_RACC (1 << 10)
/*
* Table of supported FDT compat strings and their associated FECTYPE values.
@@ -114,9 +119,11 @@ enum {
static struct ofw_compat_data compat_data[] = {
{"fsl,imx51-fec", FECTYPE_GENERIC},
{"fsl,imx53-fec", FECTYPE_IMX53},
- {"fsl,imx6q-fec", FECTYPE_IMX6 | FECFLAG_GBE},
- {"fsl,imx6ul-fec", FECTYPE_IMX6},
- {"fsl,mvf600-fec", FECTYPE_MVF},
+ {"fsl,imx6q-fec", FECTYPE_IMX6 | FECFLAG_RACC | FECFLAG_GBE },
+ {"fsl,imx6ul-fec", FECTYPE_IMX6 | FECFLAG_RACC },
+ {"fsl,imx7d-fec", FECTYPE_IMX6 | FECFLAG_RACC | FECFLAG_GBE |
+ FECFLAG_AVB },
+ {"fsl,mvf600-fec", FECTYPE_MVF | FECFLAG_RACC },
{"fsl,mvf-fec", FECTYPE_MVF},
{NULL, FECTYPE_NONE},
};
@@ -131,6 +138,8 @@ static struct ofw_compat_data compat_data[] = {
#define WATCHDOG_TIMEOUT_SECS 5
+#define MAX_IRQ_COUNT 3
+
struct ffec_bufmap {
struct mbuf *mbuf;
bus_dmamap_t map;
@@ -143,16 +152,19 @@ struct ffec_softc {
struct ifnet *ifp;
int if_flags;
struct mtx mtx;
- struct resource *irq_res;
+ struct resource *irq_res[MAX_IRQ_COUNT];
struct resource *mem_res;
- void * intr_cookie;
+ void * intr_cookie[MAX_IRQ_COUNT];
struct callout ffec_callout;
mii_contype_t phy_conn_type;
+ uint32_t fecflags;
uint8_t fectype;
boolean_t link_is_up;
boolean_t is_attached;
boolean_t is_detaching;
int tx_watchdog_count;
+ int rxbuf_align;
+ int txbuf_align;
bus_dma_tag_t rxdesc_tag;
bus_dmamap_t rxdesc_map;
@@ -173,6 +185,13 @@ struct ffec_softc {
int txcount;
};
+static struct resource_spec irq_res_spec[MAX_IRQ_COUNT + 1] = {
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 1, RF_ACTIVE | RF_OPTIONAL },
+ { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL },
+ RESOURCE_SPEC_END
+};
+
#define FFEC_LOCK(sc) mtx_lock(&(sc)->mtx)
#define FFEC_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
#define FFEC_LOCK_INIT(sc) mtx_init(&(sc)->mtx, \
@@ -246,7 +265,7 @@ ffec_miigasket_setup(struct ffec_softc *sc)
* We only need the gasket for MII and RMII connections on certain SoCs.
*/
- switch (sc->fectype & FECTYPE_MASK)
+ switch (sc->fectype)
{
case FECTYPE_IMX53:
break;
@@ -747,14 +766,17 @@ ffec_setup_rxbuf(struct ffec_softc *sc, int idx, struct mbuf * m)
int error, nsegs;
struct bus_dma_segment seg;
- /*
- * We need to leave at least ETHER_ALIGN bytes free at the beginning of
- * the buffer to allow the data to be re-aligned after receiving it (by
- * copying it backwards ETHER_ALIGN bytes in the same buffer). We also
- * have to ensure that the beginning of the buffer is aligned to the
- * hardware's requirements.
- */
- m_adj(m, roundup(ETHER_ALIGN, FEC_RXBUF_ALIGN));
+ if (!(sc->fecflags & FECFLAG_RACC)) {
+ /*
+ * The RACC[SHIFT16] feature is not available. So, we need to
+ * leave at least ETHER_ALIGN bytes free at the beginning of the
+ * buffer to allow the data to be re-aligned after receiving it
+ * (by copying it backwards ETHER_ALIGN bytes in the same
+ * buffer). We also have to ensure that the beginning of the
+ * buffer is aligned to the hardware's requirements.
+ */
+ m_adj(m, roundup(ETHER_ALIGN, sc->rxbuf_align));
+ }
error = bus_dmamap_load_mbuf_sg(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
m, &seg, &nsegs, 0);
@@ -802,23 +824,6 @@ ffec_rxfinish_onebuf(struct ffec_softc *sc, int len)
return;
}
- /*
- * Unfortunately, the protocol headers need to be aligned on a 32-bit
- * boundary for the upper layers. The hardware requires receive
- * buffers to be 16-byte aligned. The ethernet header is 14 bytes,
- * leaving the protocol header unaligned. We used m_adj() after
- * allocating the buffer to leave empty space at the start of the
- * buffer, now we'll use the alignment agnostic bcopy() routine to
- * shuffle all the data backwards 2 bytes and adjust m_data.
- *
- * XXX imx6 hardware is able to do this 2-byte alignment by setting the
- * SHIFT16 bit in the RACC register. Older hardware doesn't have that
- * feature, but for them could we speed this up by copying just the
- * protocol headers into their own small mbuf then chaining the cluster
- * to it? That way we'd only need to copy like 64 bytes or whatever
- * the biggest header is, instead of the whole 1530ish-byte frame.
- */
-
FFEC_UNLOCK(sc);
bmap = &sc->rxbuf_map[sc->rx_idx];
@@ -831,10 +836,24 @@ ffec_rxfinish_onebuf(struct ffec_softc *sc, int len)
m->m_pkthdr.len = len;
m->m_pkthdr.rcvif = sc->ifp;
- src = mtod(m, uint8_t*);
- dst = src - ETHER_ALIGN;
- bcopy(src, dst, len);
- m->m_data = dst;
+ /*
+ * Align the protocol headers in the receive buffer on a 32-bit
+ * boundary. Newer hardware does the alignment for us. On hardware
+ * that doesn't support this feature, we have to copy-align the data.
+ *
+ * XXX for older hardware, could we speed this up by copying just the
+ * protocol headers into their own small mbuf then chaining the cluster
+ * to it? That way we'd only need to copy like 64 bytes or whatever the
+ * biggest header is, instead of the whole 1530ish-byte frame.
+ */
+ if (sc->fecflags & FECFLAG_RACC) {
+ m->m_data = mtod(m, uint8_t *) + 2;
+ } else {
+ src = mtod(m, uint8_t*);
+ dst = src - ETHER_ALIGN;
+ bcopy(src, dst, len);
+ m->m_data = dst;
+ }
sc->ifp->if_input(sc->ifp, m);
FFEC_LOCK(sc);
@@ -1098,7 +1117,7 @@ ffec_init_locked(struct ffec_softc *sc)
* when we support jumbo frames and receiving fragments of them into
* separate buffers.
*/
- maxbuf = MCLBYTES - roundup(ETHER_ALIGN, FEC_RXBUF_ALIGN);
+ maxbuf = MCLBYTES - roundup(ETHER_ALIGN, sc->rxbuf_align);
maxfl = min(maxbuf, 0x7ff);
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
@@ -1208,6 +1227,14 @@ ffec_init_locked(struct ffec_softc *sc)
ffec_clear_stats(sc);
WR4(sc, FEC_MIBC_REG, regval & ~FEC_MIBC_DIS);
+ if (sc->fecflags & FECFLAG_RACC) {
+ /*
+ * RACC - Receive Accelerator Function Configuration.
+ */
+ regval = RD4(sc, FEC_RACC_REG);
+ WR4(sc, FEC_RACC_REG, regval | FEC_RACC_SHIFT16);
+ }
+
/*
* ECR - Ethernet control register.
*
@@ -1360,7 +1387,7 @@ ffec_detach(device_t dev)
{
struct ffec_softc *sc;
bus_dmamap_t map;
- int idx;
+ int idx, irq;
/*
* NB: This function can be called internally to unwind a failure to
@@ -1411,14 +1438,16 @@ ffec_detach(device_t dev)
bus_dmamap_destroy(sc->txdesc_tag, sc->txdesc_map);
}
if (sc->txdesc_tag != NULL)
- bus_dma_tag_destroy(sc->txdesc_tag);
+ bus_dma_tag_destroy(sc->txdesc_tag);
/* Release bus resources. */
- if (sc->intr_cookie)
- bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie);
-
- if (sc->irq_res != NULL)
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
+ for (irq = 0; irq < MAX_IRQ_COUNT; ++irq) {
+ if (sc->intr_cookie[irq] != NULL) {
+ bus_teardown_intr(dev, sc->irq_res[irq],
+ sc->intr_cookie[irq]);
+ }
+ }
+ bus_release_resources(dev, irq_res_spec, sc->irq_res);
if (sc->mem_res != NULL)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
@@ -1434,10 +1463,11 @@ ffec_attach(device_t dev)
struct ifnet *ifp = NULL;
struct mbuf *m;
void *dummy;
+ uintptr_t typeflags;
phandle_t ofw_node;
- int error, phynum, rid;
- uint8_t eaddr[ETHER_ADDR_LEN];
uint32_t idx, mscr;
+ int error, phynum, rid, irq;
+ uint8_t eaddr[ETHER_ADDR_LEN];
sc = device_get_softc(dev);
sc->dev = dev;
@@ -1448,7 +1478,17 @@ ffec_attach(device_t dev)
* There are differences in the implementation and features of the FEC
* hardware on different SoCs, so figure out what type we are.
*/
- sc->fectype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+ typeflags = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+ sc->fectype = (uint8_t)(typeflags & FECTYPE_MASK);
+ sc->fecflags = (uint32_t)(typeflags & ~FECTYPE_MASK);
+
+ if (sc->fecflags & FECFLAG_AVB) {
+ sc->rxbuf_align = 64;
+ sc->txbuf_align = 1;
+ } else {
+ sc->rxbuf_align = 16;
+ sc->txbuf_align = 16;
+ }
/*
* We have to be told what kind of electrical connection exists between
@@ -1478,12 +1518,10 @@ ffec_attach(device_t dev)
error = ENOMEM;
goto out;
}
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(dev, "could not allocate interrupt resources.\n");
- error = ENOMEM;
+
+ error = bus_alloc_resources(dev, irq_res_spec, sc->irq_res);
+ if (error != 0) {
+ device_printf(dev, "could not allocate interrupt resources\n");
goto out;
}
@@ -1525,7 +1563,7 @@ ffec_attach(device_t dev)
error = bus_dma_tag_create(
bus_get_dma_tag(dev), /* Parent tag. */
- FEC_TXBUF_ALIGN, 0, /* alignment, boundary */
+ sc->txbuf_align, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
@@ -1627,15 +1665,34 @@ ffec_attach(device_t dev)
/* Try to get the MAC address from the hardware before resetting it. */
ffec_get_hwaddr(sc, eaddr);
- /* Reset the hardware. Disables all interrupts. */
- WR4(sc, FEC_ECR_REG, FEC_ECR_RESET);
+ /*
+ * Reset the hardware. Disables all interrupts.
+ *
+ * When the FEC is connected to the AXI bus (indicated by AVB flag), a
+ * MAC reset while a bus transaction is pending can hang the bus.
+ * Instead of resetting, turn off the ENABLE bit, which allows the
+ * hardware to complete any in-progress transfers (appending a bad CRC
+ * to any partial packet) and release the AXI bus. This could probably
+ * be done unconditionally for all hardware variants, but that hasn't
+ * been tested.
+ */
+ if (sc->fecflags & FECFLAG_AVB)
+ WR4(sc, FEC_ECR_REG, 0);
+ else
+ WR4(sc, FEC_ECR_REG, FEC_ECR_RESET);
/* Setup interrupt handler. */
- error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
- NULL, ffec_intr, sc, &sc->intr_cookie);
- if (error != 0) {
- device_printf(dev, "could not setup interrupt handler.\n");
- goto out;
+ for (irq = 0; irq < MAX_IRQ_COUNT; ++irq) {
+ if (sc->irq_res[irq] != NULL) {
+ error = bus_setup_intr(dev, sc->irq_res[irq],
+ INTR_TYPE_NET | INTR_MPSAFE, NULL, ffec_intr, sc,
+ &sc->intr_cookie[irq]);
+ if (error != 0) {
+ device_printf(dev,
+ "could not setup interrupt handler.\n");
+ goto out;
+ }
+ }
}
/*
@@ -1701,7 +1758,7 @@ ffec_attach(device_t dev)
}
error = mii_attach(dev, &sc->miibus, ifp, ffec_media_change,
ffec_media_status, BMSR_DEFCAPMASK, phynum, MII_OFFSET_ANY,
- (sc->fectype & FECTYPE_MVF) ? MIIF_FORCEANEG : 0);
+ (sc->fecflags & FECTYPE_MVF) ? MIIF_FORCEANEG : 0);
if (error != 0) {
device_printf(dev, "PHY attach failed\n");
goto out;
diff --git a/sys/dev/ffec/if_ffecreg.h b/sys/dev/ffec/if_ffecreg.h
index bc44af3..bb1d197 100644
--- a/sys/dev/ffec/if_ffecreg.h
+++ b/sys/dev/ffec/if_ffecreg.h
@@ -317,8 +317,6 @@ struct ffec_hwdesc
* The hardware imposes alignment restrictions on various objects involved in
* DMA transfers. These values are expressed in bytes (not bits).
*/
-#define FEC_DESC_RING_ALIGN 16
-#define FEC_RXBUF_ALIGN 16
-#define FEC_TXBUF_ALIGN 16
+#define FEC_DESC_RING_ALIGN 64
#endif /* IF_FFECREG_H */
diff --git a/sys/dev/hpt27xx/hpt27xx_osm_bsd.c b/sys/dev/hpt27xx/hpt27xx_osm_bsd.c
index b2e9ed2..3a04711 100644
--- a/sys/dev/hpt27xx/hpt27xx_osm_bsd.c
+++ b/sys/dev/hpt27xx/hpt27xx_osm_bsd.c
@@ -1402,7 +1402,7 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru
{
PHPT_IOCTL_PARAM piop=(PHPT_IOCTL_PARAM)data;
IOCTL_ARG ioctl_args;
- HPT_U32 bytesReturned;
+ HPT_U32 bytesReturned = 0;
switch (cmd){
case HPT_DO_IOCONTROL:
@@ -1432,7 +1432,7 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru
}
if (ioctl_args.nOutBufferSize) {
- ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK);
+ ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK | M_ZERO);
if (!ioctl_args.lpOutBuffer)
goto invalid;
}
diff --git a/sys/dev/hptnr/hptnr_osm_bsd.c b/sys/dev/hptnr/hptnr_osm_bsd.c
index 4d712b3..4629053 100644
--- a/sys/dev/hptnr/hptnr_osm_bsd.c
+++ b/sys/dev/hptnr/hptnr_osm_bsd.c
@@ -1584,7 +1584,7 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru
{
PHPT_IOCTL_PARAM piop=(PHPT_IOCTL_PARAM)data;
IOCTL_ARG ioctl_args;
- HPT_U32 bytesReturned;
+ HPT_U32 bytesReturned = 0;
switch (cmd){
case HPT_DO_IOCONTROL:
@@ -1614,7 +1614,7 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru
}
if (ioctl_args.nOutBufferSize) {
- ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK);
+ ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK | M_ZERO);
if (!ioctl_args.lpOutBuffer)
goto invalid;
}
diff --git a/sys/dev/hptrr/hptrr_osm_bsd.c b/sys/dev/hptrr/hptrr_osm_bsd.c
index d2c58d4..b87613b 100644
--- a/sys/dev/hptrr/hptrr_osm_bsd.c
+++ b/sys/dev/hptrr/hptrr_osm_bsd.c
@@ -1231,7 +1231,7 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru
{
PHPT_IOCTL_PARAM piop=(PHPT_IOCTL_PARAM)data;
IOCTL_ARG ioctl_args;
- HPT_U32 bytesReturned;
+ HPT_U32 bytesReturned = 0;
switch (cmd){
case HPT_DO_IOCONTROL:
@@ -1261,7 +1261,7 @@ static int hpt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, stru
}
if (ioctl_args.nOutBufferSize) {
- ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK);
+ ioctl_args.lpOutBuffer = malloc(ioctl_args.nOutBufferSize, M_DEVBUF, M_WAITOK | M_ZERO);
if (!ioctl_args.lpOutBuffer)
goto invalid;
}
diff --git a/sys/dev/iicbus/ds3231.c b/sys/dev/iicbus/ds3231.c
index eb9a5ee..263733f 100644
--- a/sys/dev/iicbus/ds3231.c
+++ b/sys/dev/iicbus/ds3231.c
@@ -427,12 +427,18 @@ ds3231_start(void *xdev)
device_printf(sc->sc_dev,
"WARNING: RTC clock stopped, check the battery.\n");
}
- /* Ack any pending alarm interrupt. */
- if (ds3231_status_write(sc, 1, 1) != 0)
- return;
- /* Always enable the oscillator. */
- if (ds3231_ctrl_write(sc) != 0)
- return;
+
+ /*
+ * Ack any pending alarm interrupts and clear the EOSC bit to ensure the
+ * clock runs even when on battery power. Do not give up if these
+ * writes fail, because a factory-fresh chip is in a special mode that
+ * disables much of the chip to save battery power, and the only thing
+ * that gets it out of that mode is writing to the time registers. In
+ * these pristine chips, the EOSC and alarm bits are zero already, so
+ * the first valid write of time will get everything running properly.
+ */
+ ds3231_status_write(sc, 1, 1);
+ ds3231_ctrl_write(sc);
/* Temperature. */
SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature",
@@ -568,7 +574,7 @@ ds3231_settime(device_t dev, struct timespec *ts)
data[DS3231_MINS] = TOBCD(ct.min);
data[DS3231_HOUR] = TOBCD(ct.hour) | pmflags;
data[DS3231_DATE] = TOBCD(ct.day);
- data[DS3231_WEEKDAY] = ct.dow;
+ data[DS3231_WEEKDAY] = ct.dow + 1;
data[DS3231_MONTH] = TOBCD(ct.mon);
data[DS3231_YEAR] = TOBCD(ct.year % 100);
if (sc->sc_last_c)
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 4c54af3..2656760 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -1755,10 +1755,16 @@ md_preloaded(u_char *image, size_t length, const char *name)
sc->pl_ptr = image;
sc->pl_len = length;
sc->start = mdstart_preload;
-#if defined(MD_ROOT) && !defined(ROOTDEVNAME)
- if (sc->unit == 0)
+#ifdef MD_ROOT
+ if (sc->unit == 0) {
+#ifndef ROOTDEVNAME
rootdevnames[0] = MD_ROOT_FSTYPE ":/dev/md0";
#endif
+#ifdef MD_ROOT_READONLY
+ sc->flags |= MD_READONLY;
+#endif
+ }
+#endif
mdinit(sc);
if (name != NULL) {
printf("%s%d: Preloaded image <%s> %zd bytes at %p\n",
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
index 62189d4..fda3a73 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
@@ -90,7 +90,7 @@ mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
}
/* ensure wqes are visible to device before updating doorbell record */
- wmb();
+ atomic_thread_fence_rel();
mlx5_wq_ll_update_db_record(&rq->wq);
}
@@ -391,7 +391,7 @@ wq_ll_pop:
mlx5_cqwq_update_db_record(&rq->cq.wq);
/* ensure cq space is freed before enabling more cqes */
- wmb();
+ atomic_thread_fence_rel();
return (i);
}
diff --git a/sys/dev/sdhci/fsl_sdhci.c b/sys/dev/sdhci/fsl_sdhci.c
index 788ec58..c8a2627 100644
--- a/sys/dev/sdhci/fsl_sdhci.c
+++ b/sys/dev/sdhci/fsl_sdhci.c
@@ -807,9 +807,26 @@ fsl_sdhci_get_platform_clock(device_t dev)
static int
fsl_sdhci_detach(device_t dev)
{
+ struct fsl_sdhci_softc *sc = device_get_softc(dev);
+
+ if (sc->gpio != NULL)
+ sdhci_fdt_gpio_teardown(sc->gpio);
+
+ callout_drain(&sc->r1bfix_callout);
- /* sdhci_fdt_gpio_teardown(sc->gpio); */
- return (EBUSY);
+ if (sc->intr_cookie != NULL)
+ bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie);
+ if (sc->irq_res != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ,
+ rman_get_rid(sc->irq_res), sc->irq_res);
+
+ if (sc->mem_res != NULL) {
+ sdhci_cleanup_slot(&sc->slot);
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ rman_get_rid(sc->mem_res), sc->mem_res);
+ }
+
+ return (0);
}
static int
@@ -922,13 +939,7 @@ fsl_sdhci_attach(device_t dev)
return (0);
fail:
- if (sc->intr_cookie)
- bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie);
- if (sc->irq_res)
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
- if (sc->mem_res)
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
-
+ fsl_sdhci_detach(dev);
return (err);
}
@@ -936,7 +947,7 @@ static int
fsl_sdhci_probe(device_t dev)
{
- if (!ofw_bus_status_okay(dev))
+ if (!ofw_bus_status_okay(dev))
return (ENXIO);
switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 4da024f..d569e14 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -1801,7 +1801,7 @@ hdac_find_stream(struct hdac_softc *sc, int dir, int stream)
int i, ss;
ss = -1;
- /* Allocate ISS/BSS first. */
+ /* Allocate ISS/OSS first. */
if (dir == 0) {
for (i = 0; i < sc->num_iss; i++) {
if (sc->streams[i].stream == stream) {
@@ -1869,7 +1869,7 @@ hdac_stream_alloc(device_t dev, device_t child, int dir, int format, int stripe,
/* Allocate stream number */
if (ss >= sc->num_iss + sc->num_oss)
- stream = 15 - (ss - sc->num_iss + sc->num_oss);
+ stream = 15 - (ss - sc->num_iss - sc->num_oss);
else if (ss >= sc->num_iss)
stream = ss - sc->num_iss + 1;
else
diff --git a/sys/dev/txp/if_txp.c b/sys/dev/txp/if_txp.c
index 8e0b91c..8f63f19 100644
--- a/sys/dev/txp/if_txp.c
+++ b/sys/dev/txp/if_txp.c
@@ -371,7 +371,7 @@ txp_attach(device_t dev)
* diagnose sleep image specific issues.
*/
rsp = NULL;
- if (txp_ext_command(sc, TXP_CMD_READ_VERSION, 0, 0, 0, NULL, 0,
+ if (txp_ext_command(sc, TXP_CMD_VERSIONS_READ, 0, 0, 0, NULL, 0,
&rsp, TXP_CMD_WAIT)) {
device_printf(dev, "can not read sleep image version\n");
error = ENXIO;
diff --git a/sys/dev/txp/if_txpreg.h b/sys/dev/txp/if_txpreg.h
index cfd211c..0937deb 100644
--- a/sys/dev/txp/if_txpreg.h
+++ b/sys/dev/txp/if_txpreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_txpreg.h,v 1.30 2001/06/23 04:18:02 jason Exp $ */
+/* $OpenBSD: if_txpreg.h,v 1.34 2001/11/05 17:25:58 art Exp $ */
/* $FreeBSD$ */
/*-
@@ -164,7 +164,7 @@
#define TXP_CMD_FILTER_TABLE_MODE_WRITE 0x3d
#define TXP_CMD_FILTER_TCL_WRITE 0x3e
#define TXP_CMD_FILTER_TBL_READ 0x3f
-#define TXP_CMD_READ_VERSION 0x43
+#define TXP_CMD_VERSIONS_READ 0x43
#define TXP_CMD_FILTER_DEFINE 0x45
#define TXP_CMD_ADD_WAKEUP_PKT 0x46
#define TXP_CMD_ADD_SLEEP_PKT 0x47
@@ -382,6 +382,7 @@ struct txp_frag_desc {
#define FRAG_FLAGS_TYPE_OPT 0x03 /* type: options */
#define FRAG_FLAGS_TYPE_RX 0x04 /* type: command */
#define FRAG_FLAGS_TYPE_RESP 0x05 /* type: response */
+#define FRAG_FLAGS_VALID 0x80 /* valid descriptor */
struct txp_opt_desc {
uint8_t opt_desctype:3,
diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c
index 8015b71..44e6cbe 100644
--- a/sys/dev/usb/controller/xhci_pci.c
+++ b/sys/dev/usb/controller/xhci_pci.c
@@ -95,6 +95,10 @@ xhci_pci_match(device_t self)
uint32_t device_id = pci_get_devid(self);
switch (device_id) {
+ case 0x145c1022:
+ return ("AMD KERNCZ USB 3.0 controller");
+ case 0x43bb1022:
+ return ("AMD 300 Series USB 3.0 controller");
case 0x78141022:
return ("AMD FCH USB 3.0 controller");
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index c84d2e0..3e3488c 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -880,6 +880,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
struct devfs_dirent *de, *dd;
struct devfs_dirent **dde;
struct devfs_mount *dmp;
+ struct mount *mp;
struct cdev *cdev;
int error, flags, nameiop, dvplocked;
char specname[SPECNAMELEN + 1], *pname;
@@ -891,7 +892,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
td = cnp->cn_thread;
flags = cnp->cn_flags;
nameiop = cnp->cn_nameiop;
- dmp = VFSTODEVFS(dvp->v_mount);
+ mp = dvp->v_mount;
+ dmp = VFSTODEVFS(mp);
dd = dvp->v_data;
*vpp = NULLVP;
@@ -924,8 +926,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
return (ENOENT);
dvplocked = VOP_ISLOCKED(dvp);
VOP_UNLOCK(dvp, 0);
- error = devfs_allocv(de, dvp->v_mount,
- cnp->cn_lkflags & LK_TYPE_MASK, vpp);
+ error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK,
+ vpp);
*dm_unlock = 0;
vn_lock(dvp, dvplocked | LK_RETRY);
return (error);
@@ -1010,8 +1012,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
return (0);
}
}
- error = devfs_allocv(de, dvp->v_mount, cnp->cn_lkflags & LK_TYPE_MASK,
- vpp);
+ error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, vpp);
*dm_unlock = 0;
return (error);
}
diff --git a/sys/fs/ext2fs/ext2_extattr.c b/sys/fs/ext2fs/ext2_extattr.c
index d19d4a0..98ee396 100644
--- a/sys/fs/ext2fs/ext2_extattr.c
+++ b/sys/fs/ext2fs/ext2_extattr.c
@@ -218,9 +218,10 @@ ext2_extattr_inode_list(struct inode *ip, int attrnamespace,
return (ENOTSUP);
}
- if (uio == NULL)
+ if (size != NULL)
*size += name_len + 1;
- else {
+
+ if (uio != NULL) {
char *name = malloc(name_len + 1, M_TEMP, M_WAITOK);
name[0] = name_len;
memcpy(&name[1], attr_name, name_len);
@@ -284,9 +285,10 @@ ext2_extattr_block_list(struct inode *ip, int attrnamespace,
return (ENOTSUP);
}
- if (uio == NULL)
+ if (size != NULL)
*size += name_len + 1;
- else {
+
+ if (uio != NULL) {
char *name = malloc(name_len + 1, M_TEMP, M_WAITOK);
name[0] = name_len;
memcpy(&name[1], attr_name, name_len);
@@ -359,12 +361,12 @@ ext2_extattr_inode_get(struct inode *ip, int attrnamespace,
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len)) {
- if (uio == NULL)
+ if (size != NULL)
*size += entry->e_value_size;
- else {
+
+ if (uio != NULL)
error = uiomove(((char *)EXT2_IFIRST(header)) +
entry->e_value_offs, entry->e_value_size, uio);
- }
brelse(bp);
return (error);
@@ -426,12 +428,12 @@ ext2_extattr_block_get(struct inode *ip, int attrnamespace,
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len)) {
- if (uio == NULL)
+ if (size != NULL)
*size += entry->e_value_size;
- else {
+
+ if (uio != NULL)
error = uiomove(bp->b_data + entry->e_value_offs,
entry->e_value_size, uio);
- }
brelse(bp);
return (error);
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index 2066c7f..ade5436 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -69,6 +69,7 @@ int nfsrv_lease = NFSRV_LEASE;
int ncl_mbuf_mlen = MLEN;
int nfsd_enable_stringtouid = 0;
static int nfs_enable_uidtostring = 0;
+static int nfs_suppress_32bits_warning = 0;
NFSNAMEIDMUTEX;
NFSSOCKMUTEX;
extern int nfsrv_lughashsize;
@@ -76,6 +77,8 @@ extern int nfsrv_lughashsize;
SYSCTL_DECL(_vfs_nfs);
SYSCTL_INT(_vfs_nfs, OID_AUTO, enable_uidtostring, CTLFLAG_RW,
&nfs_enable_uidtostring, 0, "Make nfs always send numeric owner_names");
+SYSCTL_INT(_vfs_nfs, OID_AUTO, suppress_32bits_warning, CTLFLAG_RW,
+ &nfs_suppress_32bits_warning, 0, "Suppress \"> 32 bits\" warnings");
/*
* This array of structures indicates, for V4:
@@ -836,7 +839,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
static size_t count64fileid;
static struct timeval last64mountfileid;
static size_t count64mountfileid;
- static struct timeval warninterval = { 60, 0 };
+ struct timeval warninterval =
+ { nfs_suppress_32bits_warning ? 86400 : 60, 0 };
if (compare) {
retnotsup = 0;
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 4771602..afaadaf 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -93,6 +93,7 @@ static time_t nfsrvboottime;
static int nfsrv_returnoldstateid = 0, nfsrv_clients = 0;
static int nfsrv_clienthighwater = NFSRV_CLIENTHIGHWATER;
static int nfsrv_nogsscallback = 0;
+static volatile int nfsrv_writedelegcnt = 0;
/* local functions */
static void nfsrv_dumpaclient(struct nfsclient *clp,
@@ -1261,6 +1262,8 @@ nfsrv_freedeleg(struct nfsstate *stp)
LIST_REMOVE(stp, ls_hash);
LIST_REMOVE(stp, ls_list);
LIST_REMOVE(stp, ls_file);
+ if ((stp->ls_flags & NFSLCK_DELEGWRITE) != 0)
+ nfsrv_writedelegcnt--;
lfp = stp->ls_lfp;
if (LIST_EMPTY(&lfp->lf_open) &&
LIST_EMPTY(&lfp->lf_lock) && LIST_EMPTY(&lfp->lf_deleg) &&
@@ -2905,6 +2908,7 @@ tryagain:
new_deleg->ls_flags = (NFSLCK_DELEGWRITE |
NFSLCK_READACCESS | NFSLCK_WRITEACCESS);
*rflagsp |= NFSV4OPEN_WRITEDELEGATE;
+ nfsrv_writedelegcnt++;
} else {
new_deleg->ls_flags = (NFSLCK_DELEGREAD |
NFSLCK_READACCESS);
@@ -3035,6 +3039,7 @@ tryagain:
new_deleg->ls_clp = clp;
new_deleg->ls_filerev = filerev;
new_deleg->ls_compref = nd->nd_compref;
+ nfsrv_writedelegcnt++;
LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file);
LIST_INSERT_HEAD(NFSSTATEHASH(clp,
new_deleg->ls_stateid), new_deleg, ls_hash);
@@ -3092,6 +3097,7 @@ tryagain:
new_deleg->ls_flags = (NFSLCK_DELEGWRITE |
NFSLCK_READACCESS | NFSLCK_WRITEACCESS);
*rflagsp |= NFSV4OPEN_WRITEDELEGATE;
+ nfsrv_writedelegcnt++;
} else {
new_deleg->ls_flags = (NFSLCK_DELEGREAD |
NFSLCK_READACCESS);
@@ -3168,6 +3174,7 @@ tryagain:
NFSLCK_READACCESS |
NFSLCK_WRITEACCESS);
*rflagsp |= NFSV4OPEN_WRITEDELEGATE;
+ nfsrv_writedelegcnt++;
} else {
new_deleg->ls_flags =
(NFSLCK_DELEGREAD |
@@ -5298,6 +5305,8 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
NFSCBGETATTR_ATTRBIT(attrbitp, &cbbits);
if (!NFSNONZERO_ATTRBIT(&cbbits))
goto out;
+ if (nfsrv_writedelegcnt == 0)
+ goto out;
/*
* Get the lock file structure.
diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
index b00aac3..9fb4638 100644
--- a/sys/fs/procfs/procfs_map.c
+++ b/sys/fs/procfs/procfs_map.c
@@ -82,12 +82,17 @@ procfs_doprocmap(PFS_FILL_ARGS)
vm_map_t map;
vm_map_entry_t entry, tmp_entry;
struct vnode *vp;
- char *fullpath, *freepath;
+ char *fullpath, *freepath, *type;
struct ucred *cred;
- int error;
+ vm_object_t obj, tobj, lobj;
+ int error, privateresident, ref_count, resident, shadow_count, flags;
+ vm_offset_t e_start, e_end;
+ vm_eflags_t e_eflags;
+ vm_prot_t e_prot;
unsigned int last_timestamp;
+ bool super;
#ifdef COMPAT_FREEBSD32
- int wrap32 = 0;
+ bool wrap32;
#endif
PROC_LOCK(p);
@@ -100,11 +105,12 @@ procfs_doprocmap(PFS_FILL_ARGS)
return (EOPNOTSUPP);
#ifdef COMPAT_FREEBSD32
- if (SV_CURPROC_FLAG(SV_ILP32)) {
- if (!(SV_PROC_FLAG(p, SV_ILP32)))
- return (EOPNOTSUPP);
- wrap32 = 1;
- }
+ wrap32 = false;
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ if (!(SV_PROC_FLAG(p, SV_ILP32)))
+ return (EOPNOTSUPP);
+ wrap32 = true;
+ }
#endif
vm = vmspace_acquire_ref(p);
@@ -114,14 +120,6 @@ procfs_doprocmap(PFS_FILL_ARGS)
vm_map_lock_read(map);
for (entry = map->header.next; entry != &map->header;
entry = entry->next) {
- vm_object_t obj, tobj, lobj;
- int ref_count, shadow_count, flags;
- vm_offset_t e_start, e_end, addr;
- int resident, privateresident;
- char *type;
- vm_eflags_t e_eflags;
- vm_prot_t e_prot;
-
if (entry->eflags & MAP_ENTRY_IS_SUB_MAP)
continue;
@@ -130,6 +128,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
e_start = entry->start;
e_end = entry->end;
privateresident = 0;
+ resident = 0;
obj = entry->object.vm_object;
if (obj != NULL) {
VM_OBJECT_RLOCK(obj);
@@ -138,21 +137,18 @@ procfs_doprocmap(PFS_FILL_ARGS)
}
cred = (entry->cred) ? entry->cred : (obj ? obj->cred : NULL);
- resident = 0;
- addr = entry->start;
- while (addr < entry->end) {
- if (pmap_extract(map->pmap, addr))
- resident++;
- addr += PAGE_SIZE;
- }
-
- for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) {
+ for (lobj = tobj = obj; tobj != NULL;
+ tobj = tobj->backing_object) {
if (tobj != obj)
VM_OBJECT_RLOCK(tobj);
- if (lobj != obj)
- VM_OBJECT_RUNLOCK(lobj);
lobj = tobj;
}
+ if (obj != NULL)
+ kern_proc_vmmap_resident(map, entry, &resident, &super);
+ for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) {
+ if (tobj != obj && tobj != lobj)
+ VM_OBJECT_RUNLOCK(tobj);
+ }
last_timestamp = map->timestamp;
vm_map_unlock_read(map);
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index d247fbf..91077e6 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -350,7 +350,8 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node,
case VREG:
uobj = node->tn_reg.tn_aobj;
if (uobj != NULL) {
- atomic_subtract_long(&tmp->tm_pages_used, uobj->size);
+ if (uobj->size != 0)
+ atomic_subtract_long(&tmp->tm_pages_used, uobj->size);
KASSERT((uobj->flags & OBJ_TMPFS) == 0,
("leaked OBJ_TMPFS node %p vm_obj %p", node, uobj));
vm_object_deallocate(uobj);
@@ -1375,6 +1376,12 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr)
oldpages = OFF_TO_IDX(oldsize + PAGE_MASK);
MPASS(oldpages == uobj->size);
newpages = OFF_TO_IDX(newsize + PAGE_MASK);
+
+ if (__predict_true(newpages == oldpages && newsize >= oldsize)) {
+ node->tn_size = newsize;
+ return (0);
+ }
+
if (newpages > oldpages &&
tmpfs_pages_check_avail(tmp, newpages - oldpages) == 0)
return (ENOSPC);
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c
index 4a5f542..bffd5b4 100644
--- a/sys/geom/mirror/g_mirror.c
+++ b/sys/geom/mirror/g_mirror.c
@@ -69,6 +69,10 @@ SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, disconnect_on_failure, CTLFLAG_RWTUN,
static u_int g_mirror_syncreqs = 2;
SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, sync_requests, CTLFLAG_RDTUN,
&g_mirror_syncreqs, 0, "Parallel synchronization I/O requests.");
+static u_int g_mirror_sync_period = 5;
+SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, sync_update_period, CTLFLAG_RWTUN,
+ &g_mirror_sync_period, 0,
+ "Metadata update period during synchronization, in seconds");
#define MSLEEP(ident, mtx, priority, wmesg, timeout) do { \
G_MIRROR_DEBUG(4, "%s: Sleeping %p.", __func__, (ident)); \
@@ -213,7 +217,7 @@ g_mirror_event_send(void *arg, int state, int flags)
}
static struct g_mirror_event *
-g_mirror_event_get(struct g_mirror_softc *sc)
+g_mirror_event_first(struct g_mirror_softc *sc)
{
struct g_mirror_event *ep;
@@ -301,7 +305,7 @@ g_mirror_nrequests(struct g_mirror_softc *sc, struct g_consumer *cp)
u_int nreqs = 0;
mtx_lock(&sc->sc_queue_mtx);
- TAILQ_FOREACH(bp, &sc->sc_queue.queue, bio_queue) {
+ TAILQ_FOREACH(bp, &sc->sc_queue, bio_queue) {
if (bp->bio_from == cp)
nreqs++;
}
@@ -463,6 +467,7 @@ g_mirror_init_disk(struct g_mirror_softc *sc, struct g_provider *pp,
disk->d_sync.ds_consumer = NULL;
disk->d_sync.ds_offset = md->md_sync_offset;
disk->d_sync.ds_offset_done = md->md_sync_offset;
+ disk->d_sync.ds_update_ts = time_uptime;
disk->d_genid = md->md_genid;
disk->d_sync.ds_syncid = md->md_syncid;
if (errorp != NULL)
@@ -548,7 +553,7 @@ g_mirror_destroy_device(struct g_mirror_softc *sc)
g_mirror_update_metadata(disk);
g_mirror_destroy_disk(disk);
}
- while ((ep = g_mirror_event_get(sc)) != NULL) {
+ while ((ep = g_mirror_event_first(sc)) != NULL) {
g_mirror_event_remove(sc, ep);
if ((ep->e_flags & G_MIRROR_EVENT_DONTWAIT) != 0)
g_mirror_event_free(ep);
@@ -913,7 +918,7 @@ g_mirror_done(struct bio *bp)
sc = bp->bio_from->geom->softc;
bp->bio_cflags = G_MIRROR_BIO_FLAG_REGULAR;
mtx_lock(&sc->sc_queue_mtx);
- bioq_insert_tail(&sc->sc_queue, bp);
+ TAILQ_INSERT_TAIL(&sc->sc_queue, bp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
wakeup(sc);
}
@@ -930,7 +935,7 @@ g_mirror_regular_request(struct bio *bp)
pbp = bp->bio_parent;
sc = pbp->bio_to->private;
bp->bio_from->index--;
- if (bp->bio_cmd == BIO_WRITE)
+ if (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_DELETE)
sc->sc_writes--;
disk = bp->bio_from->private;
if (disk == NULL) {
@@ -958,7 +963,7 @@ g_mirror_regular_request(struct bio *bp)
pbp->bio_completed = pbp->bio_length;
if (pbp->bio_cmd == BIO_WRITE ||
pbp->bio_cmd == BIO_DELETE) {
- bioq_remove(&sc->sc_inflight, pbp);
+ TAILQ_REMOVE(&sc->sc_inflight, pbp, bio_queue);
/* Release delayed sync requests if possible. */
g_mirror_sync_release(sc);
}
@@ -1013,7 +1018,7 @@ g_mirror_regular_request(struct bio *bp)
else {
pbp->bio_error = 0;
mtx_lock(&sc->sc_queue_mtx);
- bioq_insert_tail(&sc->sc_queue, pbp);
+ TAILQ_INSERT_TAIL(&sc->sc_queue, pbp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc);
wakeup(sc);
@@ -1033,7 +1038,7 @@ g_mirror_regular_request(struct bio *bp)
pbp->bio_error = 0;
pbp->bio_completed = pbp->bio_length;
}
- bioq_remove(&sc->sc_inflight, pbp);
+ TAILQ_REMOVE(&sc->sc_inflight, pbp, bio_queue);
/* Release delayed sync requests if possible. */
g_mirror_sync_release(sc);
g_io_deliver(pbp, pbp->bio_error);
@@ -1053,7 +1058,7 @@ g_mirror_sync_done(struct bio *bp)
sc = bp->bio_from->geom->softc;
bp->bio_cflags = G_MIRROR_BIO_FLAG_SYNC;
mtx_lock(&sc->sc_queue_mtx);
- bioq_insert_tail(&sc->sc_queue, bp);
+ TAILQ_INSERT_TAIL(&sc->sc_queue, bp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
wakeup(sc);
}
@@ -1110,30 +1115,33 @@ g_mirror_kernel_dump(struct bio *bp)
static void
g_mirror_flush(struct g_mirror_softc *sc, struct bio *bp)
{
- struct bio_queue_head queue;
+ struct bio_queue queue;
struct g_mirror_disk *disk;
struct g_consumer *cp;
struct bio *cbp;
- bioq_init(&queue);
+ TAILQ_INIT(&queue);
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
continue;
cbp = g_clone_bio(bp);
if (cbp == NULL) {
- while ((cbp = bioq_takefirst(&queue)) != NULL)
+ while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
+ TAILQ_REMOVE(&queue, cbp, bio_queue);
g_destroy_bio(cbp);
+ }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_io_deliver(bp, bp->bio_error);
return;
}
- bioq_insert_tail(&queue, cbp);
+ TAILQ_INSERT_TAIL(&queue, cbp, bio_queue);
cbp->bio_done = g_mirror_flush_done;
cbp->bio_caller1 = disk;
cbp->bio_to = disk->d_consumer->provider;
}
- while ((cbp = bioq_takefirst(&queue)) != NULL) {
+ while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
+ TAILQ_REMOVE(&queue, cbp, bio_queue);
G_MIRROR_LOGREQ(3, cbp, "Sending request.");
disk = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
@@ -1187,7 +1195,7 @@ g_mirror_start(struct bio *bp)
g_io_deliver(bp, bp->bio_to->error);
return;
}
- bioq_insert_tail(&sc->sc_queue, bp);
+ TAILQ_INSERT_TAIL(&sc->sc_queue, bp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc);
wakeup(sc);
@@ -1197,7 +1205,7 @@ g_mirror_start(struct bio *bp)
* Return TRUE if the given request is colliding with a in-progress
* synchronization request.
*/
-static int
+static bool
g_mirror_sync_collision(struct g_mirror_softc *sc, struct bio *bp)
{
struct g_mirror_disk *disk;
@@ -1206,7 +1214,7 @@ g_mirror_sync_collision(struct g_mirror_softc *sc, struct bio *bp)
u_int i;
if (sc->sc_sync.ds_ndisks == 0)
- return (0);
+ return (false);
rstart = bp->bio_offset;
rend = bp->bio_offset + bp->bio_length;
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
@@ -1219,33 +1227,33 @@ g_mirror_sync_collision(struct g_mirror_softc *sc, struct bio *bp)
sstart = sbp->bio_offset;
send = sbp->bio_offset + sbp->bio_length;
if (rend > sstart && rstart < send)
- return (1);
+ return (true);
}
}
- return (0);
+ return (false);
}
/*
* Return TRUE if the given sync request is colliding with a in-progress regular
* request.
*/
-static int
+static bool
g_mirror_regular_collision(struct g_mirror_softc *sc, struct bio *sbp)
{
off_t rstart, rend, sstart, send;
struct bio *bp;
if (sc->sc_sync.ds_ndisks == 0)
- return (0);
+ return (false);
sstart = sbp->bio_offset;
send = sbp->bio_offset + sbp->bio_length;
- TAILQ_FOREACH(bp, &sc->sc_inflight.queue, bio_queue) {
+ TAILQ_FOREACH(bp, &sc->sc_inflight, bio_queue) {
rstart = bp->bio_offset;
rend = bp->bio_offset + bp->bio_length;
if (rend > sstart && rstart < send)
- return (1);
+ return (true);
}
- return (0);
+ return (false);
}
/*
@@ -1256,7 +1264,7 @@ g_mirror_regular_delay(struct g_mirror_softc *sc, struct bio *bp)
{
G_MIRROR_LOGREQ(2, bp, "Delaying request.");
- bioq_insert_head(&sc->sc_regular_delayed, bp);
+ TAILQ_INSERT_HEAD(&sc->sc_regular_delayed, bp, bio_queue);
}
/*
@@ -1267,7 +1275,7 @@ g_mirror_sync_delay(struct g_mirror_softc *sc, struct bio *bp)
{
G_MIRROR_LOGREQ(2, bp, "Delaying synchronization request.");
- bioq_insert_tail(&sc->sc_sync_delayed, bp);
+ TAILQ_INSERT_TAIL(&sc->sc_sync_delayed, bp, bio_queue);
}
/*
@@ -1279,13 +1287,13 @@ g_mirror_regular_release(struct g_mirror_softc *sc)
{
struct bio *bp, *bp2;
- TAILQ_FOREACH_SAFE(bp, &sc->sc_regular_delayed.queue, bio_queue, bp2) {
+ TAILQ_FOREACH_SAFE(bp, &sc->sc_regular_delayed, bio_queue, bp2) {
if (g_mirror_sync_collision(sc, bp))
continue;
- bioq_remove(&sc->sc_regular_delayed, bp);
+ TAILQ_REMOVE(&sc->sc_regular_delayed, bp, bio_queue);
G_MIRROR_LOGREQ(2, bp, "Releasing delayed request (%p).", bp);
mtx_lock(&sc->sc_queue_mtx);
- bioq_insert_head(&sc->sc_queue, bp);
+ TAILQ_INSERT_HEAD(&sc->sc_queue, bp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
}
}
@@ -1299,10 +1307,10 @@ g_mirror_sync_release(struct g_mirror_softc *sc)
{
struct bio *bp, *bp2;
- TAILQ_FOREACH_SAFE(bp, &sc->sc_sync_delayed.queue, bio_queue, bp2) {
+ TAILQ_FOREACH_SAFE(bp, &sc->sc_sync_delayed, bio_queue, bp2) {
if (g_mirror_regular_collision(sc, bp))
continue;
- bioq_remove(&sc->sc_sync_delayed, bp);
+ TAILQ_REMOVE(&sc->sc_sync_delayed, bp, bio_queue);
G_MIRROR_LOGREQ(2, bp,
"Releasing delayed synchronization request.");
g_io_request(bp, bp->bio_from);
@@ -1457,10 +1465,11 @@ g_mirror_sync_request(struct bio *bp)
if (bp != NULL && bp->bio_offset < offset)
offset = bp->bio_offset;
}
- if (sync->ds_offset_done + (MAXPHYS * 100) < offset) {
- /* Update offset_done on every 100 blocks. */
+ if (g_mirror_sync_period > 0 &&
+ time_uptime - sync->ds_update_ts > g_mirror_sync_period) {
sync->ds_offset_done = offset;
g_mirror_update_metadata(disk);
+ sync->ds_update_ts = time_uptime;
}
return;
}
@@ -1607,7 +1616,7 @@ g_mirror_request_load(struct g_mirror_softc *sc, struct bio *bp)
static void
g_mirror_request_split(struct g_mirror_softc *sc, struct bio *bp)
{
- struct bio_queue_head queue;
+ struct bio_queue queue;
struct g_mirror_disk *disk;
struct g_consumer *cp;
struct bio *cbp;
@@ -1631,20 +1640,22 @@ g_mirror_request_split(struct g_mirror_softc *sc, struct bio *bp)
left = bp->bio_length;
offset = bp->bio_offset;
data = bp->bio_data;
- bioq_init(&queue);
+ TAILQ_INIT(&queue);
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
continue;
cbp = g_clone_bio(bp);
if (cbp == NULL) {
- while ((cbp = bioq_takefirst(&queue)) != NULL)
+ while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
+ TAILQ_REMOVE(&queue, cbp, bio_queue);
g_destroy_bio(cbp);
+ }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_io_deliver(bp, bp->bio_error);
return;
}
- bioq_insert_tail(&queue, cbp);
+ TAILQ_INSERT_TAIL(&queue, cbp, bio_queue);
cbp->bio_done = g_mirror_done;
cbp->bio_caller1 = disk;
cbp->bio_to = disk->d_consumer->provider;
@@ -1657,7 +1668,8 @@ g_mirror_request_split(struct g_mirror_softc *sc, struct bio *bp)
offset += cbp->bio_length;
data += cbp->bio_length;
}
- while ((cbp = bioq_takefirst(&queue)) != NULL) {
+ while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
+ TAILQ_REMOVE(&queue, cbp, bio_queue);
G_MIRROR_LOGREQ(3, cbp, "Sending request.");
disk = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
@@ -1696,9 +1708,9 @@ g_mirror_register_request(struct bio *bp)
case BIO_WRITE:
case BIO_DELETE:
{
+ struct bio_queue queue;
struct g_mirror_disk *disk;
struct g_mirror_disk_sync *sync;
- struct bio_queue_head queue;
struct g_consumer *cp;
struct bio *cbp;
@@ -1728,7 +1740,7 @@ g_mirror_register_request(struct bio *bp)
* Allocate all bios before sending any request, so we can
* return ENOMEM in nice and clean way.
*/
- bioq_init(&queue);
+ TAILQ_INIT(&queue);
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
sync = &disk->d_sync;
switch (disk->d_state) {
@@ -1746,14 +1758,16 @@ g_mirror_register_request(struct bio *bp)
continue;
cbp = g_clone_bio(bp);
if (cbp == NULL) {
- while ((cbp = bioq_takefirst(&queue)) != NULL)
+ while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
+ TAILQ_REMOVE(&queue, cbp, bio_queue);
g_destroy_bio(cbp);
+ }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_io_deliver(bp, bp->bio_error);
return;
}
- bioq_insert_tail(&queue, cbp);
+ TAILQ_INSERT_TAIL(&queue, cbp, bio_queue);
cbp->bio_done = g_mirror_done;
cp = disk->d_consumer;
cbp->bio_caller1 = cp;
@@ -1762,12 +1776,13 @@ g_mirror_register_request(struct bio *bp)
("Consumer %s not opened (r%dw%de%d).",
cp->provider->name, cp->acr, cp->acw, cp->ace));
}
- if (bioq_first(&queue) == NULL) {
+ if (TAILQ_EMPTY(&queue)) {
g_io_deliver(bp, EOPNOTSUPP);
return;
}
- while ((cbp = bioq_takefirst(&queue)) != NULL) {
+ while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
G_MIRROR_LOGREQ(3, cbp, "Sending request.");
+ TAILQ_REMOVE(&queue, cbp, bio_queue);
cp = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
cp->index++;
@@ -1778,7 +1793,7 @@ g_mirror_register_request(struct bio *bp)
* Put request onto inflight queue, so we can check if new
* synchronization requests don't collide with it.
*/
- bioq_insert_tail(&sc->sc_inflight, bp);
+ TAILQ_INSERT_TAIL(&sc->sc_inflight, bp, bio_queue);
return;
}
default:
@@ -1869,7 +1884,7 @@ g_mirror_worker(void *arg)
* First take a look at events.
* This is important to handle events before any I/O requests.
*/
- ep = g_mirror_event_get(sc);
+ ep = g_mirror_event_first(sc);
if (ep != NULL) {
g_mirror_event_remove(sc, ep);
if ((ep->e_flags & G_MIRROR_EVENT_DEVICE) != 0) {
@@ -1921,8 +1936,10 @@ g_mirror_worker(void *arg)
*/
/* Get first request from the queue. */
mtx_lock(&sc->sc_queue_mtx);
- bp = bioq_takefirst(&sc->sc_queue);
- if (bp == NULL) {
+ bp = TAILQ_FIRST(&sc->sc_queue);
+ if (bp != NULL)
+ TAILQ_REMOVE(&sc->sc_queue, bp, bio_queue);
+ else {
if ((sc->sc_flags &
G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
mtx_unlock(&sc->sc_queue_mtx);
@@ -1932,21 +1949,14 @@ g_mirror_worker(void *arg)
kproc_exit(0);
}
mtx_lock(&sc->sc_queue_mtx);
- if (bioq_first(&sc->sc_queue) != NULL) {
+ if (!TAILQ_EMPTY(&sc->sc_queue)) {
mtx_unlock(&sc->sc_queue_mtx);
continue;
}
}
+ if (g_mirror_event_first(sc) != NULL)
+ continue;
sx_xunlock(&sc->sc_lock);
- /*
- * XXX: We can miss an event here, because an event
- * can be added without sx-device-lock and without
- * mtx-queue-lock. Maybe I should just stop using
- * dedicated mutex for events synchronization and
- * stick with the queue lock?
- * The event will hang here until next I/O request
- * or next event is received.
- */
MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "m:w1",
timeout * hz);
sx_xlock(&sc->sc_lock);
@@ -2189,7 +2199,8 @@ g_mirror_destroy_provider(struct g_mirror_softc *sc)
g_topology_lock();
g_error_provider(sc->sc_provider, ENXIO);
mtx_lock(&sc->sc_queue_mtx);
- while ((bp = bioq_takefirst(&sc->sc_queue)) != NULL) {
+ while ((bp = TAILQ_FIRST(&sc->sc_queue)) != NULL) {
+ TAILQ_REMOVE(&sc->sc_queue, bp, bio_queue);
/*
* Abort any pending I/O that wasn't generated by us.
* Synchronization requests and requests destined for individual
@@ -3008,11 +3019,11 @@ g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md,
sc->sc_writes = 0;
sc->sc_refcnt = 1;
sx_init(&sc->sc_lock, "gmirror:lock");
- bioq_init(&sc->sc_queue);
+ TAILQ_INIT(&sc->sc_queue);
mtx_init(&sc->sc_queue_mtx, "gmirror:queue", NULL, MTX_DEF);
- bioq_init(&sc->sc_regular_delayed);
- bioq_init(&sc->sc_inflight);
- bioq_init(&sc->sc_sync_delayed);
+ TAILQ_INIT(&sc->sc_regular_delayed);
+ TAILQ_INIT(&sc->sc_inflight);
+ TAILQ_INIT(&sc->sc_sync_delayed);
LIST_INIT(&sc->sc_disks);
TAILQ_INIT(&sc->sc_events);
mtx_init(&sc->sc_events_mtx, "gmirror:events", NULL, MTX_DEF);
diff --git a/sys/geom/mirror/g_mirror.h b/sys/geom/mirror/g_mirror.h
index 3b96640..1cd7737 100644
--- a/sys/geom/mirror/g_mirror.h
+++ b/sys/geom/mirror/g_mirror.h
@@ -108,6 +108,7 @@ struct g_mirror_disk_sync {
off_t ds_offset; /* Offset of next request to send. */
off_t ds_offset_done; /* Offset of already synchronized
region. */
+ time_t ds_update_ts; /* Time of last metadata update. */
u_int ds_syncid; /* Disk's synchronization ID. */
u_int ds_inflight; /* Number of in-flight sync requests. */
struct bio **ds_bios; /* BIOs for synchronization I/O. */
@@ -190,17 +191,14 @@ struct g_mirror_softc {
uint32_t sc_id; /* Mirror unique ID. */
struct sx sc_lock;
- struct bio_queue_head sc_queue;
+ struct bio_queue sc_queue;
struct mtx sc_queue_mtx;
struct proc *sc_worker;
- struct bio_queue_head sc_regular_delayed; /* Delayed I/O requests due
- collision with sync
- requests. */
- struct bio_queue_head sc_inflight; /* In-flight regular write
- requests. */
- struct bio_queue_head sc_sync_delayed; /* Delayed sync requests due
- collision with regular
- requests. */
+ struct bio_queue sc_inflight; /* In-flight regular write requests. */
+ struct bio_queue sc_regular_delayed; /* Delayed I/O requests due to
+ collision with sync requests. */
+ struct bio_queue sc_sync_delayed; /* Delayed sync requests due to
+ collision with regular requests. */
LIST_HEAD(, g_mirror_disk) sc_disks;
u_int sc_ndisks; /* Number of disks. */
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index b8baea2..38bddf6 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -175,9 +175,6 @@ SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RW,
void
trap(struct trapframe *frame)
{
-#ifdef KDTRACE_HOOKS
- struct reg regs;
-#endif
ksiginfo_t ksi;
struct thread *td;
struct proc *p;
@@ -325,9 +322,8 @@ trap(struct trapframe *frame)
enable_intr();
#ifdef KDTRACE_HOOKS
if (type == T_BPTFLT) {
- fill_frame_regs(frame, &regs);
if (dtrace_pid_probe_ptr != NULL &&
- dtrace_pid_probe_ptr(&regs) == 0)
+ dtrace_pid_probe_ptr(frame) == 0)
return;
}
#endif
@@ -495,9 +491,8 @@ user_trctrap_out:
#ifdef KDTRACE_HOOKS
case T_DTRACE_RET:
enable_intr();
- fill_frame_regs(frame, &regs);
if (dtrace_return_probe_ptr != NULL)
- dtrace_return_probe_ptr(&regs);
+ dtrace_return_probe_ptr(frame);
return;
#endif
}
@@ -747,7 +742,6 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva)
td = curthread;
p = td->td_proc;
- rv = 0;
if (__predict_false((td->td_pflags & TDP_NOFAULTING) != 0)) {
/*
@@ -808,7 +802,7 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva)
return (-2);
#endif
if (usermode)
- goto nogo;
+ return (SIGSEGV);
map = kernel_map;
} else {
@@ -865,7 +859,6 @@ trap_pfault(struct trapframe *frame, int usermode, vm_offset_t eva)
#endif
return (0);
}
-nogo:
if (!usermode) {
if (td->td_intr_nesting_level == 0 &&
curpcb->pcb_onfault != NULL) {
diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h
index c8242ca..bb7a57e 100644
--- a/sys/i386/include/atomic.h
+++ b/sys/i386/include/atomic.h
@@ -32,6 +32,8 @@
#error this file needs sys/cdefs.h as a prerequisite
#endif
+#include <sys/atomic_common.h>
+
#ifdef _KERNEL
#include <machine/md_var.h>
#include <machine/specialreg.h>
diff --git a/sys/kern/kern_dtrace.c b/sys/kern/kern_dtrace.c
index f5f14b7..adc36a8 100644
--- a/sys/kern/kern_dtrace.c
+++ b/sys/kern/kern_dtrace.c
@@ -54,7 +54,7 @@ dtrace_doubletrap_func_t dtrace_doubletrap_func;
dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr;
dtrace_return_probe_ptr_t dtrace_return_probe_ptr;
-systrace_probe_func_t systrace_probe_func;
+systrace_probe_func_t __read_frequently systrace_probe_func;
/* Return the DTrace process data size compiled in the kernel hooks. */
size_t
diff --git a/sys/kern/kern_lockstat.c b/sys/kern/kern_lockstat.c
index 679a01c..77e5526 100644
--- a/sys/kern/kern_lockstat.c
+++ b/sys/kern/kern_lockstat.c
@@ -62,7 +62,7 @@ SDT_PROBE_DEFINE1(lockstat, , , sx__downgrade, "struct sx *");
SDT_PROBE_DEFINE2(lockstat, , , thread__spin, "struct mtx *", "uint64_t");
-volatile int __read_mostly lockstat_enabled;
+volatile int __read_frequently lockstat_enabled;
uint64_t
lockstat_nsecs(struct lock_object *lo)
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
index e93cd0e..8fafd14 100644
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -140,7 +140,7 @@ struct lock_class lock_class_mtx_spin = {
#ifdef ADAPTIVE_MUTEXES
static SYSCTL_NODE(_debug, OID_AUTO, mtx, CTLFLAG_RD, NULL, "mtx debugging");
-static struct lock_delay_config __read_mostly mtx_delay;
+static struct lock_delay_config __read_frequently mtx_delay;
SYSCTL_INT(_debug_mtx, OID_AUTO, delay_base, CTLFLAG_RW, &mtx_delay.base,
0, "");
@@ -153,7 +153,7 @@ LOCK_DELAY_SYSINIT_DEFAULT(mtx_delay);
static SYSCTL_NODE(_debug, OID_AUTO, mtx_spin, CTLFLAG_RD, NULL,
"mtx spin debugging");
-static struct lock_delay_config __read_mostly mtx_spin_delay;
+static struct lock_delay_config __read_frequently mtx_spin_delay;
SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_base, CTLFLAG_RW,
&mtx_spin_delay.base, 0, "");
@@ -168,6 +168,8 @@ LOCK_DELAY_SYSINIT_DEFAULT(mtx_spin_delay);
struct mtx blocked_lock;
struct mtx Giant;
+static void _mtx_lock_indefinite_check(struct mtx *, struct lock_delay_arg *);
+
void
assert_mtx(const struct lock_object *lock, int what)
{
@@ -217,7 +219,7 @@ owner_mtx(const struct lock_object *lock, struct thread **owner)
m = (const struct mtx *)lock;
x = m->mtx_lock;
*owner = (struct thread *)(x & ~MTX_FLAGMASK);
- return (x != MTX_UNOWNED);
+ return (*owner != NULL);
}
#endif
@@ -248,7 +250,7 @@ __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file, int line)
tid = (uintptr_t)curthread;
v = MTX_UNOWNED;
if (!_mtx_obtain_lock_fetch(m, &v, tid))
- _mtx_lock_sleep(m, v, tid, opts, file, line);
+ _mtx_lock_sleep(m, v, opts, file, line);
else
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(adaptive__acquire,
m, 0, 0, file, line);
@@ -277,7 +279,7 @@ __mtx_unlock_flags(volatile uintptr_t *c, int opts, const char *file, int line)
mtx_assert(m, MA_OWNED);
#ifdef LOCK_PROFILING
- __mtx_unlock_sleep(c, opts, file, line);
+ __mtx_unlock_sleep(c, (uintptr_t)curthread, opts, file, line);
#else
__mtx_unlock(m, curthread, opts, file, line);
#endif
@@ -289,9 +291,9 @@ __mtx_lock_spin_flags(volatile uintptr_t *c, int opts, const char *file,
int line)
{
struct mtx *m;
-
- if (SCHEDULER_STOPPED())
- return;
+#ifdef SMP
+ uintptr_t tid, v;
+#endif
m = mtxlock2mtx(c);
@@ -308,7 +310,18 @@ __mtx_lock_spin_flags(volatile uintptr_t *c, int opts, const char *file,
opts &= ~MTX_RECURSE;
WITNESS_CHECKORDER(&m->lock_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
file, line, NULL);
+#ifdef SMP
+ spinlock_enter();
+ tid = (uintptr_t)curthread;
+ v = MTX_UNOWNED;
+ if (!_mtx_obtain_lock_fetch(m, &v, tid))
+ _mtx_lock_spin(m, v, opts, file, line);
+ else
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(spin__acquire,
+ m, 0, 0, file, line);
+#else
__mtx_lock_spin(m, curthread, opts, file, line);
+#endif
LOCK_LOG_LOCK("LOCK", &m->lock_object, opts, m->mtx_recurse, file,
line);
WITNESS_LOCK(&m->lock_object, opts | LOP_EXCLUSIVE, file, line);
@@ -348,9 +361,6 @@ __mtx_unlock_spin_flags(volatile uintptr_t *c, int opts, const char *file,
{
struct mtx *m;
- if (SCHEDULER_STOPPED())
- return;
-
m = mtxlock2mtx(c);
KASSERT(m->mtx_lock != MTX_DESTROYED,
@@ -372,9 +382,8 @@ __mtx_unlock_spin_flags(volatile uintptr_t *c, int opts, const char *file,
* is already owned, it will recursively acquire the lock.
*/
int
-_mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line)
+_mtx_trylock_flags_int(struct mtx *m, int opts LOCK_FILE_LINE_ARG_DEF)
{
- struct mtx *m;
struct thread *td;
uintptr_t tid, v;
#ifdef LOCK_PROFILING
@@ -389,8 +398,6 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line)
if (SCHEDULER_STOPPED_TD(td))
return (1);
- m = mtxlock2mtx(c);
-
KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(td),
("mtx_trylock() by idle thread %p on sleep mutex %s @ %s:%d",
curthread, m->lock_object.lo_name, file, line));
@@ -435,6 +442,15 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line)
return (rval);
}
+int
+_mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line)
+{
+ struct mtx *m;
+
+ m = mtxlock2mtx(c);
+ return (_mtx_trylock_flags_int(m, opts LOCK_FILE_LINE_ARG));
+}
+
/*
* __mtx_lock_sleep: the tougher part of acquiring an MTX_DEF lock.
*
@@ -443,18 +459,18 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line)
*/
#if LOCK_DEBUG > 0
void
-__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts,
- const char *file, int line)
+__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, int opts, const char *file,
+ int line)
#else
void
-__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid)
+__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v)
#endif
{
+ struct thread *td;
struct mtx *m;
struct turnstile *ts;
-#ifdef ADAPTIVE_MUTEXES
- volatile struct thread *owner;
-#endif
+ uintptr_t tid;
+ struct thread *owner;
#ifdef KTR
int cont_logged = 0;
#endif
@@ -473,8 +489,9 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid)
#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
int doing_lockprof;
#endif
-
- if (SCHEDULER_STOPPED())
+ td = curthread;
+ tid = (uintptr_t)td;
+ if (SCHEDULER_STOPPED_TD(td))
return;
#if defined(ADAPTIVE_MUTEXES)
@@ -486,7 +503,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid)
if (__predict_false(v == MTX_UNOWNED))
v = MTX_READ_VALUE(m);
- if (__predict_false(lv_mtx_owner(v) == (struct thread *)tid)) {
+ if (__predict_false(lv_mtx_owner(v) == td)) {
KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0 ||
(opts & MTX_RECURSE) != 0,
("_mtx_lock_sleep: recursed on non-recursive mutex %s @ %s:%d\n",
@@ -618,7 +635,11 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid)
#ifdef KDTRACE_HOOKS
sleep_time -= lockstat_nsecs(&m->lock_object);
#endif
- turnstile_wait(ts, mtx_owner(m), TS_EXCLUSIVE_QUEUE);
+#ifndef ADAPTIVE_MUTEXES
+ owner = mtx_owner(m);
+#endif
+ MPASS(owner == mtx_owner(m));
+ turnstile_wait(ts, owner, TS_EXCLUSIVE_QUEUE);
#ifdef KDTRACE_HOOKS
sleep_time += lockstat_nsecs(&m->lock_object);
sleep_cnt++;
@@ -653,25 +674,6 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid)
#endif
}
-static void
-_mtx_lock_spin_failed(struct mtx *m)
-{
- struct thread *td;
-
- td = mtx_owner(m);
-
- /* If the mutex is unlocked, try again. */
- if (td == NULL)
- return;
-
- printf( "spin lock %p (%s) held by %p (tid %d) too long\n",
- m, m->lock_object.lo_name, td, td->td_tid);
-#ifdef WITNESS
- witness_display_spinlock(&m->lock_object, td, printf);
-#endif
- panic("spin lock held too long");
-}
-
#ifdef SMP
/*
* _mtx_lock_spin_cookie: the tougher part of acquiring an MTX_SPIN lock.
@@ -679,12 +681,18 @@ _mtx_lock_spin_failed(struct mtx *m)
* This is only called if we need to actually spin for the lock. Recursion
* is handled inline.
*/
+#if LOCK_DEBUG > 0
+void
+_mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, int opts,
+ const char *file, int line)
+#else
void
-_mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
- int opts, const char *file, int line)
+_mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v)
+#endif
{
struct mtx *m;
struct lock_delay_arg lda;
+ uintptr_t tid;
#ifdef LOCK_PROFILING
int contested = 0;
uint64_t waittime = 0;
@@ -696,10 +704,7 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
int doing_lockprof;
#endif
- if (SCHEDULER_STOPPED())
- return;
-
- lock_delay_arg_init(&lda, &mtx_spin_delay);
+ tid = (uintptr_t)curthread;
m = mtxlock2mtx(c);
if (__predict_false(v == MTX_UNOWNED))
@@ -710,6 +715,11 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
return;
}
+ if (SCHEDULER_STOPPED())
+ return;
+
+ lock_delay_arg_init(&lda, &mtx_spin_delay);
+
if (LOCK_LOG_TEST(&m->lock_object, opts))
CTR1(KTR_LOCK, "_mtx_lock_spin: %p spinning", m);
KTR_STATE1(KTR_SCHED, "thread", sched_tdname((struct thread *)tid),
@@ -735,16 +745,10 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
/* Give interrupts a chance while we spin. */
spinlock_exit();
do {
- if (lda.spin_cnt < 10000000) {
+ if (__predict_true(lda.spin_cnt < 10000000)) {
lock_delay(&lda);
} else {
- lda.spin_cnt++;
- if (lda.spin_cnt < 60000000 || kdb_active ||
- panicstr != NULL)
- DELAY(1);
- else
- _mtx_lock_spin_failed(m);
- cpu_spinwait();
+ _mtx_lock_indefinite_check(m, &lda);
}
v = MTX_READ_VALUE(m);
} while (v != MTX_UNOWNED);
@@ -772,6 +776,73 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
}
#endif /* SMP */
+#ifdef INVARIANTS
+static void
+thread_lock_validate(struct mtx *m, int opts, const char *file, int line)
+{
+
+ KASSERT(m->mtx_lock != MTX_DESTROYED,
+ ("thread_lock() of destroyed mutex @ %s:%d", file, line));
+ KASSERT(LOCK_CLASS(&m->lock_object) == &lock_class_mtx_spin,
+ ("thread_lock() of sleep mutex %s @ %s:%d",
+ m->lock_object.lo_name, file, line));
+ if (mtx_owned(m))
+ KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0,
+ ("thread_lock: recursed on non-recursive mutex %s @ %s:%d\n",
+ m->lock_object.lo_name, file, line));
+ WITNESS_CHECKORDER(&m->lock_object,
+ opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL);
+}
+#else
+#define thread_lock_validate(m, opts, file, line) do { } while (0)
+#endif
+
+#ifndef LOCK_PROFILING
+#if LOCK_DEBUG > 0
+void
+_thread_lock(struct thread *td, int opts, const char *file, int line)
+#else
+void
+_thread_lock(struct thread *td)
+#endif
+{
+ struct mtx *m;
+ uintptr_t tid, v;
+
+ tid = (uintptr_t)curthread;
+
+ if (__predict_false(LOCKSTAT_PROFILE_ENABLED(spin__acquire)))
+ goto slowpath_noirq;
+ spinlock_enter();
+ m = td->td_lock;
+ thread_lock_validate(m, 0, file, line);
+ v = MTX_READ_VALUE(m);
+ if (__predict_true(v == MTX_UNOWNED)) {
+ if (__predict_false(!_mtx_obtain_lock(m, tid)))
+ goto slowpath_unlocked;
+ } else if (v == tid) {
+ m->mtx_recurse++;
+ } else
+ goto slowpath_unlocked;
+ if (__predict_true(m == td->td_lock)) {
+ WITNESS_LOCK(&m->lock_object, LOP_EXCLUSIVE, file, line);
+ return;
+ }
+ if (m->mtx_recurse != 0)
+ m->mtx_recurse--;
+ else
+ _mtx_release_lock_quick(m);
+slowpath_unlocked:
+ spinlock_exit();
+slowpath_noirq:
+#if LOCK_DEBUG > 0
+ thread_lock_flags_(td, opts, file, line);
+#else
+ thread_lock_flags_(td, 0, 0, 0);
+#endif
+}
+#endif
+
void
thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
{
@@ -803,6 +874,10 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
lock_delay_arg_init(&lda, &mtx_spin_delay);
+#ifdef HWPMC_HOOKS
+ PMC_SOFT_CALL( , , lock, failed);
+#endif
+
#ifdef LOCK_PROFILING
doing_lockprof = 1;
#elif defined(KDTRACE_HOOKS)
@@ -812,47 +887,29 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
#endif
for (;;) {
retry:
- v = MTX_UNOWNED;
spinlock_enter();
m = td->td_lock;
- KASSERT(m->mtx_lock != MTX_DESTROYED,
- ("thread_lock() of destroyed mutex @ %s:%d", file, line));
- KASSERT(LOCK_CLASS(&m->lock_object) == &lock_class_mtx_spin,
- ("thread_lock() of sleep mutex %s @ %s:%d",
- m->lock_object.lo_name, file, line));
- if (mtx_owned(m))
- KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0,
- ("thread_lock: recursed on non-recursive mutex %s @ %s:%d\n",
- m->lock_object.lo_name, file, line));
- WITNESS_CHECKORDER(&m->lock_object,
- opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL);
+ thread_lock_validate(m, opts, file, line);
+ v = MTX_READ_VALUE(m);
for (;;) {
- if (_mtx_obtain_lock_fetch(m, &v, tid))
- break;
- if (v == MTX_UNOWNED)
+ if (v == MTX_UNOWNED) {
+ if (_mtx_obtain_lock_fetch(m, &v, tid))
+ break;
continue;
+ }
if (v == tid) {
m->mtx_recurse++;
break;
}
-#ifdef HWPMC_HOOKS
- PMC_SOFT_CALL( , , lock, failed);
-#endif
lock_profile_obtain_lock_failed(&m->lock_object,
&contested, &waittime);
/* Give interrupts a chance while we spin. */
spinlock_exit();
do {
- if (lda.spin_cnt < 10000000) {
+ if (__predict_true(lda.spin_cnt < 10000000)) {
lock_delay(&lda);
} else {
- lda.spin_cnt++;
- if (lda.spin_cnt < 60000000 ||
- kdb_active || panicstr != NULL)
- DELAY(1);
- else
- _mtx_lock_spin_failed(m);
- cpu_spinwait();
+ _mtx_lock_indefinite_check(m, &lda);
}
if (m != td->td_lock)
goto retry;
@@ -925,24 +982,27 @@ thread_lock_set(struct thread *td, struct mtx *new)
*/
#if LOCK_DEBUG > 0
void
-__mtx_unlock_sleep(volatile uintptr_t *c, int opts, const char *file, int line)
+__mtx_unlock_sleep(volatile uintptr_t *c, uintptr_t v, int opts,
+ const char *file, int line)
#else
void
-__mtx_unlock_sleep(volatile uintptr_t *c)
+__mtx_unlock_sleep(volatile uintptr_t *c, uintptr_t v)
#endif
{
struct mtx *m;
struct turnstile *ts;
- uintptr_t tid, v;
+ uintptr_t tid;
if (SCHEDULER_STOPPED())
return;
tid = (uintptr_t)curthread;
m = mtxlock2mtx(c);
- v = MTX_READ_VALUE(m);
- if (v & MTX_RECURSED) {
+ if (__predict_false(v == tid))
+ v = MTX_READ_VALUE(m);
+
+ if (__predict_false(v & MTX_RECURSED)) {
if (--(m->mtx_recurse) == 0)
atomic_clear_ptr(&m->mtx_lock, MTX_RECURSED);
if (LOCK_LOG_TEST(&m->lock_object, opts))
@@ -959,12 +1019,12 @@ __mtx_unlock_sleep(volatile uintptr_t *c)
* can be removed from the hash list if it is empty.
*/
turnstile_chain_lock(&m->lock_object);
+ _mtx_release_lock_quick(m);
ts = turnstile_lookup(&m->lock_object);
+ MPASS(ts != NULL);
if (LOCK_LOG_TEST(&m->lock_object, opts))
CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p contested", m);
- MPASS(ts != NULL);
turnstile_broadcast(ts, TS_EXCLUSIVE_QUEUE);
- _mtx_release_lock_quick(m);
/*
* This turnstile is now no longer associated with the mutex. We can
@@ -1140,6 +1200,31 @@ mutex_init(void)
mtx_lock(&Giant);
}
+static void __noinline
+_mtx_lock_indefinite_check(struct mtx *m, struct lock_delay_arg *ldap)
+{
+ struct thread *td;
+
+ ldap->spin_cnt++;
+ if (ldap->spin_cnt < 60000000 || kdb_active || panicstr != NULL)
+ DELAY(1);
+ else {
+ td = mtx_owner(m);
+
+ /* If the mutex is unlocked, try again. */
+ if (td == NULL)
+ return;
+
+ printf( "spin lock %p (%s) held by %p (tid %d) too long\n",
+ m, m->lock_object.lo_name, td, td->td_tid);
+#ifdef WITNESS
+ witness_display_spinlock(&m->lock_object, td, printf);
+#endif
+ panic("spin lock held too long");
+ }
+ cpu_spinwait();
+}
+
#ifdef DDB
void
db_show_mtx(const struct lock_object *lock)
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 40f4a5f..13d9533 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -131,9 +131,9 @@ struct pgrphashhead *pgrphashtbl;
u_long pgrphash;
struct proclist allproc;
struct proclist zombproc;
-struct sx allproc_lock;
-struct sx proctree_lock;
-struct mtx ppeers_lock;
+struct sx __exclusive_cache_line allproc_lock;
+struct sx __exclusive_cache_line proctree_lock;
+struct mtx __exclusive_cache_line ppeers_lock;
uma_zone_t proc_zone;
/*
@@ -2256,9 +2256,9 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS)
CTASSERT(sizeof(struct kinfo_vmentry) == KINFO_VMENTRY_SIZE);
#endif
-static void
+void
kern_proc_vmmap_resident(vm_map_t map, vm_map_entry_t entry,
- struct kinfo_vmentry *kve)
+ int *resident_count, bool *super)
{
vm_object_t obj, tobj;
vm_page_t m, m_adv;
@@ -2266,6 +2266,11 @@ kern_proc_vmmap_resident(vm_map_t map, vm_map_entry_t entry,
vm_paddr_t locked_pa;
vm_pindex_t pi, pi_adv, pindex;
+ *super = false;
+ *resident_count = 0;
+ if (vmmap_skip_res_cnt)
+ return;
+
locked_pa = 0;
obj = entry->object.vm_object;
addr = entry->start;
@@ -2298,7 +2303,7 @@ kern_proc_vmmap_resident(vm_map_t map, vm_map_entry_t entry,
(addr & (pagesizes[1] - 1)) == 0 &&
(pmap_mincore(map->pmap, addr, &locked_pa) &
MINCORE_SUPER) != 0) {
- kve->kve_flags |= KVME_FLAG_SUPER;
+ *super = true;
pi_adv = atop(pagesizes[1]);
} else {
/*
@@ -2310,7 +2315,7 @@ kern_proc_vmmap_resident(vm_map_t map, vm_map_entry_t entry,
*/
pi_adv = 1;
}
- kve->kve_resident += pi_adv;
+ *resident_count += pi_adv;
next:;
}
PA_UNLOCK_COND(locked_pa);
@@ -2334,6 +2339,7 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen, int flags)
vm_offset_t addr;
unsigned int last_timestamp;
int error;
+ bool super;
PROC_LOCK_ASSERT(p, MA_OWNED);
@@ -2366,8 +2372,10 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen, int flags)
if (obj->backing_object == NULL)
kve->kve_private_resident =
obj->resident_page_count;
- if (!vmmap_skip_res_cnt)
- kern_proc_vmmap_resident(map, entry, kve);
+ kern_proc_vmmap_resident(map, entry,
+ &kve->kve_resident, &super);
+ if (super)
+ kve->kve_flags |= KVME_FLAG_SUPER;
for (tobj = obj; tobj != NULL;
tobj = tobj->backing_object) {
if (tobj != obj && tobj != lobj)
@@ -3077,6 +3085,7 @@ resume_all_proc(void)
cp = curproc;
sx_xlock(&allproc_lock);
+again:
LIST_REMOVE(cp, p_list);
LIST_INSERT_HEAD(&allproc, cp, p_list);
for (;;) {
@@ -3097,6 +3106,12 @@ resume_all_proc(void)
PROC_UNLOCK(p);
}
}
+ /* Did the loop above missed any stopped process ? */
+ LIST_FOREACH(p, &allproc, p_list) {
+ /* No need for proc lock. */
+ if ((p->p_flag & P_TOTAL_STOP) != 0)
+ goto again;
+ }
sx_xunlock(&allproc_lock);
}
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index 4c8e9bd..7bc0b2f 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -93,14 +93,14 @@ struct lock_class lock_class_rw = {
};
#ifdef ADAPTIVE_RWLOCKS
-static int rowner_retries = 10;
-static int rowner_loops = 10000;
+static int __read_frequently rowner_retries = 10;
+static int __read_frequently rowner_loops = 10000;
static SYSCTL_NODE(_debug, OID_AUTO, rwlock, CTLFLAG_RD, NULL,
"rwlock debugging");
SYSCTL_INT(_debug_rwlock, OID_AUTO, retry, CTLFLAG_RW, &rowner_retries, 0, "");
SYSCTL_INT(_debug_rwlock, OID_AUTO, loops, CTLFLAG_RW, &rowner_loops, 0, "");
-static struct lock_delay_config __read_mostly rw_delay;
+static struct lock_delay_config __read_frequently rw_delay;
SYSCTL_INT(_debug_rwlock, OID_AUTO, delay_base, CTLFLAG_RW, &rw_delay.base,
0, "");
@@ -273,7 +273,7 @@ _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line)
tid = (uintptr_t)curthread;
v = RW_UNLOCKED;
if (!_rw_write_lock_fetch(rw, &v, tid))
- _rw_wlock_hard(rw, v, tid, file, line);
+ _rw_wlock_hard(rw, v, file, line);
else
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw,
0, 0, file, line, LOCKSTAT_WRITER);
@@ -284,9 +284,8 @@ _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line)
}
int
-__rw_try_wlock(volatile uintptr_t *c, const char *file, int line)
+__rw_try_wlock_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF)
{
- struct rwlock *rw;
struct thread *td;
uintptr_t tid, v;
int rval;
@@ -297,8 +296,6 @@ __rw_try_wlock(volatile uintptr_t *c, const char *file, int line)
if (SCHEDULER_STOPPED_TD(td))
return (1);
- rw = rwlock2rw(c);
-
KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(td),
("rw_try_wlock() by idle thread %p on rwlock %s @ %s:%d",
curthread, rw->lock_object.lo_name, file, line));
@@ -334,6 +331,15 @@ __rw_try_wlock(volatile uintptr_t *c, const char *file, int line)
return (rval);
}
+int
+__rw_try_wlock(volatile uintptr_t *c, const char *file, int line)
+{
+ struct rwlock *rw;
+
+ rw = rwlock2rw(c);
+ return (__rw_try_wlock_int(rw LOCK_FILE_LINE_ARG));
+}
+
void
_rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line)
{
@@ -364,14 +370,21 @@ _rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line)
* is unlocked and has no writer waiters or spinners. Failing otherwise
* prioritizes writers before readers.
*/
-#define RW_CAN_READ(td, _rw) \
- (((td)->td_rw_rlocks && (_rw) & RW_LOCK_READ) || ((_rw) & \
- (RW_LOCK_READ | RW_LOCK_WRITE_WAITERS | RW_LOCK_WRITE_SPINNER)) == \
- RW_LOCK_READ)
+static bool __always_inline
+__rw_can_read(struct thread *td, uintptr_t v, bool fp)
+{
+
+ if ((v & (RW_LOCK_READ | RW_LOCK_WRITE_WAITERS | RW_LOCK_WRITE_SPINNER))
+ == RW_LOCK_READ)
+ return (true);
+ if (!fp && td->td_rw_rlocks && (v & RW_LOCK_READ))
+ return (true);
+ return (false);
+}
static bool __always_inline
-__rw_rlock_try(struct rwlock *rw, struct thread *td, uintptr_t *vp,
- const char *file, int line)
+__rw_rlock_try(struct rwlock *rw, struct thread *td, uintptr_t *vp, bool fp
+ LOCK_FILE_LINE_ARG_DEF)
{
/*
@@ -384,7 +397,7 @@ __rw_rlock_try(struct rwlock *rw, struct thread *td, uintptr_t *vp,
* completely unlocked rwlock since such a lock is encoded
* as a read lock with no waiters.
*/
- while (RW_CAN_READ(td, *vp)) {
+ while (__rw_can_read(td, *vp, fp)) {
if (atomic_fcmpset_acq_ptr(&rw->rw_lock, vp,
*vp + RW_ONE_READER)) {
if (LOCK_LOG_TEST(&rw->lock_object, 0))
@@ -400,15 +413,14 @@ __rw_rlock_try(struct rwlock *rw, struct thread *td, uintptr_t *vp,
}
static void __noinline
-__rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
- const char *file, int line)
+__rw_rlock_hard(struct rwlock *rw, struct thread *td, uintptr_t v
+ LOCK_FILE_LINE_ARG_DEF)
{
- struct rwlock *rw;
struct turnstile *ts;
+ struct thread *owner;
#ifdef ADAPTIVE_RWLOCKS
- volatile struct thread *owner;
int spintries = 0;
- int i;
+ int i, n;
#endif
#ifdef LOCK_PROFILING
uint64_t waittime = 0;
@@ -418,11 +430,14 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
struct lock_delay_arg lda;
#endif
#ifdef KDTRACE_HOOKS
- uintptr_t state;
u_int sleep_cnt = 0;
int64_t sleep_time = 0;
int64_t all_time = 0;
#endif
+#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
+ uintptr_t state;
+ int doing_lockprof;
+#endif
if (SCHEDULER_STOPPED())
return;
@@ -432,25 +447,30 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
#elif defined(KDTRACE_HOOKS)
lock_delay_arg_init(&lda, NULL);
#endif
- rw = rwlock2rw(c);
-#ifdef KDTRACE_HOOKS
- all_time -= lockstat_nsecs(&rw->lock_object);
+#ifdef HWPMC_HOOKS
+ PMC_SOFT_CALL( , , lock, failed);
#endif
-#ifdef KDTRACE_HOOKS
+ lock_profile_obtain_lock_failed(&rw->lock_object,
+ &contested, &waittime);
+
+#ifdef LOCK_PROFILING
+ doing_lockprof = 1;
state = v;
+#elif defined(KDTRACE_HOOKS)
+ doing_lockprof = lockstat_enabled;
+ if (__predict_false(doing_lockprof)) {
+ all_time -= lockstat_nsecs(&rw->lock_object);
+ state = v;
+ }
#endif
+
for (;;) {
- if (__rw_rlock_try(rw, td, &v, file, line))
+ if (__rw_rlock_try(rw, td, &v, false LOCK_FILE_LINE_ARG))
break;
#ifdef KDTRACE_HOOKS
lda.spin_cnt++;
#endif
-#ifdef HWPMC_HOOKS
- PMC_SOFT_CALL( , , lock, failed);
-#endif
- lock_profile_obtain_lock_failed(&rw->lock_object,
- &contested, &waittime);
#ifdef ADAPTIVE_RWLOCKS
/*
@@ -482,19 +502,19 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
KTR_STATE1(KTR_SCHED, "thread", sched_tdname(curthread),
"spinning", "lockname:\"%s\"",
rw->lock_object.lo_name);
- for (i = 0; i < rowner_loops; i++) {
+ for (i = 0; i < rowner_loops; i += n) {
+ n = RW_READERS(v);
+ lock_delay_spin(n);
v = RW_READ_VALUE(rw);
- if ((v & RW_LOCK_READ) == 0 || RW_CAN_READ(td, v))
+ if ((v & RW_LOCK_READ) == 0 || __rw_can_read(td, v, false))
break;
- cpu_spinwait();
}
- v = RW_READ_VALUE(rw);
#ifdef KDTRACE_HOOKS
lda.spin_cnt += rowner_loops - i;
#endif
KTR_STATE0(KTR_SCHED, "thread", sched_tdname(curthread),
"running");
- if (i != rowner_loops)
+ if (i < rowner_loops)
continue;
}
#endif
@@ -512,11 +532,14 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
* recheck its state and restart the loop if needed.
*/
v = RW_READ_VALUE(rw);
- if (RW_CAN_READ(td, v)) {
+retry_ts:
+ if (__rw_can_read(td, v, false)) {
turnstile_cancel(ts);
continue;
}
+ owner = lv_rw_wowner(v);
+
#ifdef ADAPTIVE_RWLOCKS
/*
* The current lock owner might have started executing
@@ -525,8 +548,7 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
* chain lock. If so, drop the turnstile lock and try
* again.
*/
- if ((v & RW_LOCK_READ) == 0) {
- owner = (struct thread *)RW_OWNER(v);
+ if (owner != NULL) {
if (TD_IS_RUNNING(owner)) {
turnstile_cancel(ts);
continue;
@@ -537,7 +559,7 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
/*
* The lock is held in write mode or it already has waiters.
*/
- MPASS(!RW_CAN_READ(td, v));
+ MPASS(!__rw_can_read(td, v, false));
/*
* If the RW_LOCK_READ_WAITERS flag is already set, then
@@ -546,12 +568,9 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
* lock and restart the loop.
*/
if (!(v & RW_LOCK_READ_WAITERS)) {
- if (!atomic_cmpset_ptr(&rw->rw_lock, v,
- v | RW_LOCK_READ_WAITERS)) {
- turnstile_cancel(ts);
- v = RW_READ_VALUE(rw);
- continue;
- }
+ if (!atomic_fcmpset_ptr(&rw->rw_lock, &v,
+ v | RW_LOCK_READ_WAITERS))
+ goto retry_ts;
if (LOCK_LOG_TEST(&rw->lock_object, 0))
CTR2(KTR_LOCK, "%s: %p set read waiters flag",
__func__, rw);
@@ -567,7 +586,8 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
#ifdef KDTRACE_HOOKS
sleep_time -= lockstat_nsecs(&rw->lock_object);
#endif
- turnstile_wait(ts, rw_owner(rw), TS_SHARED_QUEUE);
+ MPASS(owner == rw_owner(rw));
+ turnstile_wait(ts, owner, TS_SHARED_QUEUE);
#ifdef KDTRACE_HOOKS
sleep_time += lockstat_nsecs(&rw->lock_object);
sleep_cnt++;
@@ -577,6 +597,10 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
__func__, rw);
v = RW_READ_VALUE(rw);
}
+#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
+ if (__predict_true(!doing_lockprof))
+ return;
+#endif
#ifdef KDTRACE_HOOKS
all_time += lockstat_nsecs(&rw->lock_object);
if (sleep_time)
@@ -600,14 +624,12 @@ __rw_rlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
}
void
-__rw_rlock(volatile uintptr_t *c, const char *file, int line)
+__rw_rlock_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF)
{
- struct rwlock *rw;
struct thread *td;
uintptr_t v;
td = curthread;
- rw = rwlock2rw(c);
KASSERT(kdb_active != 0 || SCHEDULER_STOPPED_TD(td) ||
!TD_IS_IDLETHREAD(td),
@@ -622,25 +644,31 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
v = RW_READ_VALUE(rw);
if (__predict_false(LOCKSTAT_OOL_PROFILE_ENABLED(rw__acquire) ||
- !__rw_rlock_try(rw, td, &v, file, line)))
- __rw_rlock_hard(c, td, v, file, line);
+ !__rw_rlock_try(rw, td, &v, true LOCK_FILE_LINE_ARG)))
+ __rw_rlock_hard(rw, td, v LOCK_FILE_LINE_ARG);
LOCK_LOG_LOCK("RLOCK", &rw->lock_object, 0, 0, file, line);
WITNESS_LOCK(&rw->lock_object, 0, file, line);
TD_LOCKS_INC(curthread);
}
-int
-__rw_try_rlock(volatile uintptr_t *c, const char *file, int line)
+void
+__rw_rlock(volatile uintptr_t *c, const char *file, int line)
{
struct rwlock *rw;
+
+ rw = rwlock2rw(c);
+ __rw_rlock_int(rw LOCK_FILE_LINE_ARG);
+}
+
+int
+__rw_try_rlock_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF)
+{
uintptr_t x;
if (SCHEDULER_STOPPED())
return (1);
- rw = rwlock2rw(c);
-
KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread),
("rw_try_rlock() by idle thread %p on rwlock %s @ %s:%d",
curthread, rw->lock_object.lo_name, file, line));
@@ -667,6 +695,15 @@ __rw_try_rlock(volatile uintptr_t *c, const char *file, int line)
return (0);
}
+int
+__rw_try_rlock(volatile uintptr_t *c, const char *file, int line)
+{
+ struct rwlock *rw;
+
+ rw = rwlock2rw(c);
+ return (__rw_try_rlock_int(rw LOCK_FILE_LINE_ARG));
+}
+
static bool __always_inline
__rw_runlock_try(struct rwlock *rw, struct thread *td, uintptr_t *vp)
{
@@ -712,18 +749,15 @@ __rw_runlock_try(struct rwlock *rw, struct thread *td, uintptr_t *vp)
}
static void __noinline
-__rw_runlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
- const char *file, int line)
+__rw_runlock_hard(struct rwlock *rw, struct thread *td, uintptr_t v
+ LOCK_FILE_LINE_ARG_DEF)
{
- struct rwlock *rw;
struct turnstile *ts;
- uintptr_t x, queue;
+ uintptr_t setv, queue;
if (SCHEDULER_STOPPED())
return;
- rw = rwlock2rw(c);
-
for (;;) {
if (__rw_runlock_try(rw, td, &v))
break;
@@ -733,7 +767,14 @@ __rw_runlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
* last reader, so grab the turnstile lock.
*/
turnstile_chain_lock(&rw->lock_object);
- v = rw->rw_lock & (RW_LOCK_WAITERS | RW_LOCK_WRITE_SPINNER);
+ v = RW_READ_VALUE(rw);
+retry_ts:
+ if (__predict_false(RW_READERS(v) > 1)) {
+ turnstile_chain_unlock(&rw->lock_object);
+ continue;
+ }
+
+ v &= (RW_LOCK_WAITERS | RW_LOCK_WRITE_SPINNER);
MPASS(v & RW_LOCK_WAITERS);
/*
@@ -752,18 +793,15 @@ __rw_runlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
* acquired a read lock, so drop the turnstile lock and
* restart.
*/
- x = RW_UNLOCKED;
+ setv = RW_UNLOCKED;
+ queue = TS_SHARED_QUEUE;
if (v & RW_LOCK_WRITE_WAITERS) {
queue = TS_EXCLUSIVE_QUEUE;
- x |= (v & RW_LOCK_READ_WAITERS);
- } else
- queue = TS_SHARED_QUEUE;
- if (!atomic_cmpset_rel_ptr(&rw->rw_lock, RW_READERS_LOCK(1) | v,
- x)) {
- turnstile_chain_unlock(&rw->lock_object);
- v = RW_READ_VALUE(rw);
- continue;
+ setv |= (v & RW_LOCK_READ_WAITERS);
}
+ v |= RW_READERS_LOCK(1);
+ if (!atomic_fcmpset_rel_ptr(&rw->rw_lock, &v, setv))
+ goto retry_ts;
if (LOCK_LOG_TEST(&rw->lock_object, 0))
CTR2(KTR_LOCK, "%s: %p last succeeded with waiters",
__func__, rw);
@@ -787,17 +825,14 @@ __rw_runlock_hard(volatile uintptr_t *c, struct thread *td, uintptr_t v,
}
void
-_rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
+_rw_runlock_cookie_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF)
{
- struct rwlock *rw;
struct thread *td;
uintptr_t v;
- rw = rwlock2rw(c);
-
KASSERT(rw->rw_lock != RW_DESTROYED,
("rw_runlock() of destroyed rwlock @ %s:%d", file, line));
- __rw_assert(c, RA_RLOCKED, file, line);
+ __rw_assert(&rw->rw_lock, RA_RLOCKED, file, line);
WITNESS_UNLOCK(&rw->lock_object, 0, file, line);
LOCK_LOG_LOCK("RUNLOCK", &rw->lock_object, 0, 0, file, line);
@@ -806,26 +841,36 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
if (__predict_false(LOCKSTAT_OOL_PROFILE_ENABLED(rw__release) ||
!__rw_runlock_try(rw, td, &v)))
- __rw_runlock_hard(c, td, v, file, line);
+ __rw_runlock_hard(rw, td, v LOCK_FILE_LINE_ARG);
TD_LOCKS_DEC(curthread);
}
+void
+_rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line)
+{
+ struct rwlock *rw;
+
+ rw = rwlock2rw(c);
+ _rw_runlock_cookie_int(rw LOCK_FILE_LINE_ARG);
+}
+
/*
* This function is called when we are unable to obtain a write lock on the
* first try. This means that at least one other thread holds either a
* read or write lock.
*/
void
-__rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
- const char *file, int line)
+__rw_wlock_hard(volatile uintptr_t *c, uintptr_t v LOCK_FILE_LINE_ARG_DEF)
{
+ uintptr_t tid;
struct rwlock *rw;
struct turnstile *ts;
+ struct thread *owner;
#ifdef ADAPTIVE_RWLOCKS
- volatile struct thread *owner;
int spintries = 0;
- int i;
+ int i, n;
+ int sleep_reason = 0;
#endif
uintptr_t x;
#ifdef LOCK_PROFILING
@@ -836,12 +881,16 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
struct lock_delay_arg lda;
#endif
#ifdef KDTRACE_HOOKS
- uintptr_t state;
u_int sleep_cnt = 0;
int64_t sleep_time = 0;
int64_t all_time = 0;
#endif
+#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
+ uintptr_t state;
+ int doing_lockprof;
+#endif
+ tid = (uintptr_t)curthread;
if (SCHEDULER_STOPPED())
return;
@@ -869,10 +918,23 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
CTR5(KTR_LOCK, "%s: %s contested (lock=%p) at %s:%d", __func__,
rw->lock_object.lo_name, (void *)rw->rw_lock, file, line);
-#ifdef KDTRACE_HOOKS
- all_time -= lockstat_nsecs(&rw->lock_object);
+#ifdef HWPMC_HOOKS
+ PMC_SOFT_CALL( , , lock, failed);
+#endif
+ lock_profile_obtain_lock_failed(&rw->lock_object,
+ &contested, &waittime);
+
+#ifdef LOCK_PROFILING
+ doing_lockprof = 1;
state = v;
+#elif defined(KDTRACE_HOOKS)
+ doing_lockprof = lockstat_enabled;
+ if (__predict_false(doing_lockprof)) {
+ all_time -= lockstat_nsecs(&rw->lock_object);
+ state = v;
+ }
#endif
+
for (;;) {
if (v == RW_UNLOCKED) {
if (_rw_write_lock_fetch(rw, &v, tid))
@@ -882,17 +944,14 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
#ifdef KDTRACE_HOOKS
lda.spin_cnt++;
#endif
-#ifdef HWPMC_HOOKS
- PMC_SOFT_CALL( , , lock, failed);
-#endif
- lock_profile_obtain_lock_failed(&rw->lock_object,
- &contested, &waittime);
+
#ifdef ADAPTIVE_RWLOCKS
/*
* If the lock is write locked and the owner is
* running on another CPU, spin until the owner stops
* running or the state of the lock changes.
*/
+ sleep_reason = 1;
owner = lv_rw_wowner(v);
if (!(v & RW_LOCK_READ) && TD_IS_RUNNING(owner)) {
if (LOCK_LOG_TEST(&rw->lock_object, 0))
@@ -913,9 +972,8 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
if ((v & RW_LOCK_READ) && RW_READERS(v) &&
spintries < rowner_retries) {
if (!(v & RW_LOCK_WRITE_SPINNER)) {
- if (!atomic_cmpset_ptr(&rw->rw_lock, v,
+ if (!atomic_fcmpset_ptr(&rw->rw_lock, &v,
v | RW_LOCK_WRITE_SPINNER)) {
- v = RW_READ_VALUE(rw);
continue;
}
}
@@ -923,23 +981,27 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
KTR_STATE1(KTR_SCHED, "thread", sched_tdname(curthread),
"spinning", "lockname:\"%s\"",
rw->lock_object.lo_name);
- for (i = 0; i < rowner_loops; i++) {
- if ((rw->rw_lock & RW_LOCK_WRITE_SPINNER) == 0)
+ for (i = 0; i < rowner_loops; i += n) {
+ n = RW_READERS(v);
+ lock_delay_spin(n);
+ v = RW_READ_VALUE(rw);
+ if ((v & RW_LOCK_WRITE_SPINNER) == 0)
break;
- cpu_spinwait();
}
KTR_STATE0(KTR_SCHED, "thread", sched_tdname(curthread),
"running");
- v = RW_READ_VALUE(rw);
#ifdef KDTRACE_HOOKS
lda.spin_cnt += rowner_loops - i;
#endif
- if (i != rowner_loops)
+ if (i < rowner_loops)
continue;
+ sleep_reason = 2;
}
#endif
ts = turnstile_trywait(&rw->lock_object);
v = RW_READ_VALUE(rw);
+retry_ts:
+ owner = lv_rw_wowner(v);
#ifdef ADAPTIVE_RWLOCKS
/*
@@ -949,12 +1011,14 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
* chain lock. If so, drop the turnstile lock and try
* again.
*/
- if (!(v & RW_LOCK_READ)) {
- owner = (struct thread *)RW_OWNER(v);
+ if (owner != NULL) {
if (TD_IS_RUNNING(owner)) {
turnstile_cancel(ts);
continue;
}
+ } else if (RW_READERS(v) > 0 && sleep_reason == 1) {
+ turnstile_cancel(ts);
+ continue;
}
#endif
/*
@@ -967,16 +1031,14 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
x = v & (RW_LOCK_WAITERS | RW_LOCK_WRITE_SPINNER);
if ((v & ~x) == RW_UNLOCKED) {
x &= ~RW_LOCK_WRITE_SPINNER;
- if (atomic_cmpset_acq_ptr(&rw->rw_lock, v, tid | x)) {
+ if (atomic_fcmpset_acq_ptr(&rw->rw_lock, &v, tid | x)) {
if (x)
turnstile_claim(ts);
else
turnstile_cancel(ts);
break;
}
- turnstile_cancel(ts);
- v = RW_READ_VALUE(rw);
- continue;
+ goto retry_ts;
}
/*
* If the RW_LOCK_WRITE_WAITERS flag isn't set, then try to
@@ -984,12 +1046,9 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
* again.
*/
if (!(v & RW_LOCK_WRITE_WAITERS)) {
- if (!atomic_cmpset_ptr(&rw->rw_lock, v,
- v | RW_LOCK_WRITE_WAITERS)) {
- turnstile_cancel(ts);
- v = RW_READ_VALUE(rw);
- continue;
- }
+ if (!atomic_fcmpset_ptr(&rw->rw_lock, &v,
+ v | RW_LOCK_WRITE_WAITERS))
+ goto retry_ts;
if (LOCK_LOG_TEST(&rw->lock_object, 0))
CTR2(KTR_LOCK, "%s: %p set write waiters flag",
__func__, rw);
@@ -1004,7 +1063,8 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
#ifdef KDTRACE_HOOKS
sleep_time -= lockstat_nsecs(&rw->lock_object);
#endif
- turnstile_wait(ts, rw_owner(rw), TS_EXCLUSIVE_QUEUE);
+ MPASS(owner == rw_owner(rw));
+ turnstile_wait(ts, owner, TS_EXCLUSIVE_QUEUE);
#ifdef KDTRACE_HOOKS
sleep_time += lockstat_nsecs(&rw->lock_object);
sleep_cnt++;
@@ -1017,6 +1077,10 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
#endif
v = RW_READ_VALUE(rw);
}
+#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
+ if (__predict_true(!doing_lockprof))
+ return;
+#endif
#ifdef KDTRACE_HOOKS
all_time += lockstat_nsecs(&rw->lock_object);
if (sleep_time)
@@ -1041,19 +1105,21 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
* on this lock.
*/
void
-__rw_wunlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
- int line)
+__rw_wunlock_hard(volatile uintptr_t *c, uintptr_t v LOCK_FILE_LINE_ARG_DEF)
{
struct rwlock *rw;
struct turnstile *ts;
- uintptr_t v;
+ uintptr_t tid, setv;
int queue;
+ tid = (uintptr_t)curthread;
if (SCHEDULER_STOPPED())
return;
rw = rwlock2rw(c);
- v = RW_READ_VALUE(rw);
+ if (__predict_false(v == tid))
+ v = RW_READ_VALUE(rw);
+
if (v & RW_LOCK_WRITER_RECURSED) {
if (--(rw->rw_recurse) == 0)
atomic_clear_ptr(&rw->rw_lock, RW_LOCK_WRITER_RECURSED);
@@ -1073,8 +1139,6 @@ __rw_wunlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
CTR2(KTR_LOCK, "%s: %p contested", __func__, rw);
turnstile_chain_lock(&rw->lock_object);
- ts = turnstile_lookup(&rw->lock_object);
- MPASS(ts != NULL);
/*
* Use the same algo as sx locks for now. Prefer waking up shared
@@ -1092,19 +1156,23 @@ __rw_wunlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
* there that could be worked around either by waking both queues
* of waiters or doing some complicated lock handoff gymnastics.
*/
- v = RW_UNLOCKED;
- if (rw->rw_lock & RW_LOCK_WRITE_WAITERS) {
+ setv = RW_UNLOCKED;
+ v = RW_READ_VALUE(rw);
+ queue = TS_SHARED_QUEUE;
+ if (v & RW_LOCK_WRITE_WAITERS) {
queue = TS_EXCLUSIVE_QUEUE;
- v |= (rw->rw_lock & RW_LOCK_READ_WAITERS);
- } else
- queue = TS_SHARED_QUEUE;
+ setv |= (v & RW_LOCK_READ_WAITERS);
+ }
+ atomic_store_rel_ptr(&rw->rw_lock, setv);
/* Wake up all waiters for the specific queue. */
if (LOCK_LOG_TEST(&rw->lock_object, 0))
CTR3(KTR_LOCK, "%s: %p waking up %s waiters", __func__, rw,
queue == TS_SHARED_QUEUE ? "read" : "write");
+
+ ts = turnstile_lookup(&rw->lock_object);
+ MPASS(ts != NULL);
turnstile_broadcast(ts, queue);
- atomic_store_rel_ptr(&rw->rw_lock, v);
turnstile_unpend(ts, TS_EXCLUSIVE_LOCK);
turnstile_chain_unlock(&rw->lock_object);
}
@@ -1115,9 +1183,8 @@ __rw_wunlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
* lock. Returns true if the upgrade succeeded and false otherwise.
*/
int
-__rw_try_upgrade(volatile uintptr_t *c, const char *file, int line)
+__rw_try_upgrade_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF)
{
- struct rwlock *rw;
uintptr_t v, x, tid;
struct turnstile *ts;
int success;
@@ -1125,11 +1192,9 @@ __rw_try_upgrade(volatile uintptr_t *c, const char *file, int line)
if (SCHEDULER_STOPPED())
return (1);
- rw = rwlock2rw(c);
-
KASSERT(rw->rw_lock != RW_DESTROYED,
("rw_try_upgrade() of destroyed rwlock @ %s:%d", file, line));
- __rw_assert(c, RA_RLOCKED, file, line);
+ __rw_assert(&rw->rw_lock, RA_RLOCKED, file, line);
/*
* Attempt to switch from one reader to a writer. If there
@@ -1187,13 +1252,21 @@ __rw_try_upgrade(volatile uintptr_t *c, const char *file, int line)
return (success);
}
+int
+__rw_try_upgrade(volatile uintptr_t *c, const char *file, int line)
+{
+ struct rwlock *rw;
+
+ rw = rwlock2rw(c);
+ return (__rw_try_upgrade_int(rw LOCK_FILE_LINE_ARG));
+}
+
/*
* Downgrade a write lock into a single read lock.
*/
void
-__rw_downgrade(volatile uintptr_t *c, const char *file, int line)
+__rw_downgrade_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF)
{
- struct rwlock *rw;
struct turnstile *ts;
uintptr_t tid, v;
int rwait, wwait;
@@ -1201,11 +1274,9 @@ __rw_downgrade(volatile uintptr_t *c, const char *file, int line)
if (SCHEDULER_STOPPED())
return;
- rw = rwlock2rw(c);
-
KASSERT(rw->rw_lock != RW_DESTROYED,
("rw_downgrade() of destroyed rwlock @ %s:%d", file, line));
- __rw_assert(c, RA_WLOCKED | RA_NOTRECURSED, file, line);
+ __rw_assert(&rw->rw_lock, RA_WLOCKED | RA_NOTRECURSED, file, line);
#ifndef INVARIANTS
if (rw_recursed(rw))
panic("downgrade of a recursed lock");
@@ -1257,6 +1328,15 @@ out:
LOCKSTAT_RECORD0(rw__downgrade, rw);
}
+void
+__rw_downgrade(volatile uintptr_t *c, const char *file, int line)
+{
+ struct rwlock *rw;
+
+ rw = rwlock2rw(c);
+ __rw_downgrade_int(rw LOCK_FILE_LINE_ARG);
+}
+
#ifdef INVARIANT_SUPPORT
#ifndef INVARIANTS
#undef __rw_assert
diff --git a/sys/kern/kern_sdt.c b/sys/kern/kern_sdt.c
index 5191a88..ebbf04e 100644
--- a/sys/kern/kern_sdt.c
+++ b/sys/kern/kern_sdt.c
@@ -37,6 +37,7 @@ SDT_PROVIDER_DEFINE(sdt);
* dtrace_probe() when it loads.
*/
sdt_probe_func_t sdt_probe_func = sdt_probe_stub;
+volatile bool __read_frequently sdt_probes_enabled;
/*
* This is a stub for probe calls in case kernel DTrace support isn't
diff --git a/sys/kern/kern_switch.c b/sys/kern/kern_switch.c
index f58acd5..2cdec8d 100644
--- a/sys/kern/kern_switch.c
+++ b/sys/kern/kern_switch.c
@@ -150,22 +150,21 @@ SYSCTL_PROC(_kern_sched_stats, OID_AUTO, reset, CTLTYPE_INT | CTLFLAG_WR, NULL,
/*
* Select the thread that will be run next.
*/
-struct thread *
-choosethread(void)
-{
- struct thread *td;
-retry:
- td = sched_choose();
+static __noinline struct thread *
+choosethread_panic(struct thread *td)
+{
/*
* If we are in panic, only allow system threads,
* plus the one we are running in, to be run.
*/
- if (panicstr && ((td->td_proc->p_flag & P_SYSTEM) == 0 &&
+retry:
+ if (((td->td_proc->p_flag & P_SYSTEM) == 0 &&
(td->td_flags & TDF_INPANIC) == 0)) {
/* note that it is no longer on the run queue */
TD_SET_CAN_RUN(td);
+ td = sched_choose();
goto retry;
}
@@ -173,6 +172,20 @@ retry:
return (td);
}
+struct thread *
+choosethread(void)
+{
+ struct thread *td;
+
+ td = sched_choose();
+
+ if (__predict_false(panicstr != NULL))
+ return (choosethread_panic(td));
+
+ TD_SET_RUNNING(td);
+ return (td);
+}
+
/*
* Kernel thread preemption implementation. Critical sections mark
* regions of code in which preemptions are not allowed.
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index 1446543..1acf666 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -88,8 +88,9 @@ PMC_SOFT_DECLARE( , , lock, failed);
int _giantcnt = 0; \
WITNESS_SAVE_DECL(Giant) \
-#define GIANT_SAVE() do { \
- if (mtx_owned(&Giant)) { \
+#define GIANT_SAVE(work) do { \
+ if (__predict_false(mtx_owned(&Giant))) { \
+ work++; \
WITNESS_SAVE(&Giant.lock_object, Giant); \
while (mtx_owned(&Giant)) { \
_giantcnt++; \
@@ -142,13 +143,13 @@ struct lock_class lock_class_sx = {
#endif
#ifdef ADAPTIVE_SX
-static u_int asx_retries = 10;
-static u_int asx_loops = 10000;
+static __read_frequently u_int asx_retries = 10;
+static __read_frequently u_int asx_loops = 10000;
static SYSCTL_NODE(_debug, OID_AUTO, sx, CTLFLAG_RD, NULL, "sxlock debugging");
SYSCTL_UINT(_debug_sx, OID_AUTO, retries, CTLFLAG_RW, &asx_retries, 0, "");
SYSCTL_UINT(_debug_sx, OID_AUTO, loops, CTLFLAG_RW, &asx_loops, 0, "");
-static struct lock_delay_config __read_mostly sx_delay;
+static struct lock_delay_config __read_frequently sx_delay;
SYSCTL_INT(_debug_sx, OID_AUTO, delay_base, CTLFLAG_RW, &sx_delay.base,
0, "");
@@ -197,12 +198,14 @@ unlock_sx(struct lock_object *lock)
int
owner_sx(const struct lock_object *lock, struct thread **owner)
{
- const struct sx *sx = (const struct sx *)lock;
- uintptr_t x = sx->sx_lock;
+ const struct sx *sx;
+ uintptr_t x;
- *owner = (struct thread *)SX_OWNER(x);
- return ((x & SX_LOCK_SHARED) != 0 ? (SX_SHARERS(x) != 0) :
- (*owner != NULL));
+ sx = (const struct sx *)lock;
+ x = sx->sx_lock;
+ *owner = NULL;
+ return ((x & SX_LOCK_SHARED) != 0 ? (SX_SHARERS(x) != 0) :
+ ((*owner = (struct thread *)SX_OWNER(x)) != NULL));
}
#endif
@@ -256,7 +259,7 @@ sx_destroy(struct sx *sx)
}
int
-sx_try_slock_(struct sx *sx, const char *file, int line)
+sx_try_slock_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF)
{
uintptr_t x;
@@ -288,6 +291,13 @@ sx_try_slock_(struct sx *sx, const char *file, int line)
}
int
+sx_try_slock_(struct sx *sx, const char *file, int line)
+{
+
+ return (sx_try_slock_int(sx LOCK_FILE_LINE_ARG));
+}
+
+int
_sx_xlock(struct sx *sx, int opts, const char *file, int line)
{
uintptr_t tid, x;
@@ -304,7 +314,7 @@ _sx_xlock(struct sx *sx, int opts, const char *file, int line)
tid = (uintptr_t)curthread;
x = SX_LOCK_UNLOCKED;
if (!atomic_fcmpset_acq_ptr(&sx->sx_lock, &x, tid))
- error = _sx_xlock_hard(sx, x, tid, opts, file, line);
+ error = _sx_xlock_hard(sx, x, opts LOCK_FILE_LINE_ARG);
else
LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
0, 0, file, line, LOCKSTAT_WRITER);
@@ -319,7 +329,7 @@ _sx_xlock(struct sx *sx, int opts, const char *file, int line)
}
int
-sx_try_xlock_(struct sx *sx, const char *file, int line)
+sx_try_xlock_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF)
{
struct thread *td;
uintptr_t tid, x;
@@ -367,6 +377,13 @@ sx_try_xlock_(struct sx *sx, const char *file, int line)
return (rval);
}
+int
+sx_try_xlock_(struct sx *sx, const char *file, int line)
+{
+
+ return (sx_try_xlock_int(sx LOCK_FILE_LINE_ARG));
+}
+
void
_sx_xunlock(struct sx *sx, const char *file, int line)
{
@@ -391,7 +408,7 @@ _sx_xunlock(struct sx *sx, const char *file, int line)
* Return 1 if if the upgrade succeed, 0 otherwise.
*/
int
-sx_try_upgrade_(struct sx *sx, const char *file, int line)
+sx_try_upgrade_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF)
{
uintptr_t x;
int success;
@@ -420,11 +437,18 @@ sx_try_upgrade_(struct sx *sx, const char *file, int line)
return (success);
}
+int
+sx_try_upgrade_(struct sx *sx, const char *file, int line)
+{
+
+ return (sx_try_upgrade_int(sx LOCK_FILE_LINE_ARG));
+}
+
/*
* Downgrade an unrecursed exclusive lock into a single shared lock.
*/
void
-sx_downgrade_(struct sx *sx, const char *file, int line)
+sx_downgrade_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF)
{
uintptr_t x;
int wakeup_swapper;
@@ -486,6 +510,13 @@ out:
LOCKSTAT_RECORD0(sx__downgrade, sx);
}
+void
+sx_downgrade_(struct sx *sx, const char *file, int line)
+{
+
+ sx_downgrade_int(sx LOCK_FILE_LINE_ARG);
+}
+
/*
* This function represents the so-called 'hard case' for sx_xlock
* operation. All 'easy case' failures are redirected to this. Note
@@ -493,13 +524,15 @@ out:
* accessible from at least sx.h.
*/
int
-_sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
- const char *file, int line)
+_sx_xlock_hard(struct sx *sx, uintptr_t x, int opts LOCK_FILE_LINE_ARG_DEF)
{
GIANT_DECLARE;
+ uintptr_t tid;
#ifdef ADAPTIVE_SX
volatile struct thread *owner;
- u_int i, spintries = 0;
+ u_int i, n, spintries = 0;
+ bool adaptive;
+ int sleep_reason = 0;
#endif
#ifdef LOCK_PROFILING
uint64_t waittime = 0;
@@ -510,12 +543,16 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
struct lock_delay_arg lda;
#endif
#ifdef KDTRACE_HOOKS
- uintptr_t state;
u_int sleep_cnt = 0;
int64_t sleep_time = 0;
int64_t all_time = 0;
#endif
+#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
+ uintptr_t state;
+#endif
+ int extra_work = 0;
+ tid = (uintptr_t)curthread;
if (SCHEDULER_STOPPED())
return (0);
@@ -544,84 +581,103 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
CTR5(KTR_LOCK, "%s: %s contested (lock=%p) at %s:%d", __func__,
sx->lock_object.lo_name, (void *)sx->sx_lock, file, line);
-#ifdef KDTRACE_HOOKS
- all_time -= lockstat_nsecs(&sx->lock_object);
+#ifdef ADAPTIVE_SX
+ adaptive = ((sx->lock_object.lo_flags & SX_NOADAPTIVE) != 0);
+#endif
+
+#ifdef HWPMC_HOOKS
+ PMC_SOFT_CALL( , , lock, failed);
+#endif
+ lock_profile_obtain_lock_failed(&sx->lock_object, &contested,
+ &waittime);
+
+#ifdef LOCK_PROFILING
+ extra_work = 1;
state = x;
+#elif defined(KDTRACE_HOOKS)
+ extra_work = lockstat_enabled;
+ if (__predict_false(extra_work)) {
+ all_time -= lockstat_nsecs(&sx->lock_object);
+ state = x;
+ }
+#endif
+#ifndef INVARIANTS
+ GIANT_SAVE(extra_work);
#endif
+
for (;;) {
if (x == SX_LOCK_UNLOCKED) {
if (atomic_fcmpset_acq_ptr(&sx->sx_lock, &x, tid))
break;
continue;
}
+#ifdef INVARIANTS
+ GIANT_SAVE(extra_work);
+#endif
#ifdef KDTRACE_HOOKS
lda.spin_cnt++;
#endif
-#ifdef HWPMC_HOOKS
- PMC_SOFT_CALL( , , lock, failed);
-#endif
- lock_profile_obtain_lock_failed(&sx->lock_object, &contested,
- &waittime);
#ifdef ADAPTIVE_SX
+ if (__predict_false(!adaptive))
+ goto sleepq;
/*
* If the lock is write locked and the owner is
* running on another CPU, spin until the owner stops
* running or the state of the lock changes.
*/
- if ((sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) {
- if ((x & SX_LOCK_SHARED) == 0) {
- owner = lv_sx_owner(x);
- if (TD_IS_RUNNING(owner)) {
- if (LOCK_LOG_TEST(&sx->lock_object, 0))
- CTR3(KTR_LOCK,
- "%s: spinning on %p held by %p",
- __func__, sx, owner);
- KTR_STATE1(KTR_SCHED, "thread",
- sched_tdname(curthread), "spinning",
- "lockname:\"%s\"",
- sx->lock_object.lo_name);
- GIANT_SAVE();
- do {
- lock_delay(&lda);
- x = SX_READ_VALUE(sx);
- owner = lv_sx_owner(x);
- } while (owner != NULL &&
- TD_IS_RUNNING(owner));
- KTR_STATE0(KTR_SCHED, "thread",
- sched_tdname(curthread), "running");
- continue;
- }
- } else if (SX_SHARERS(x) && spintries < asx_retries) {
+ if ((x & SX_LOCK_SHARED) == 0) {
+ owner = lv_sx_owner(x);
+ if (TD_IS_RUNNING(owner)) {
+ if (LOCK_LOG_TEST(&sx->lock_object, 0))
+ CTR3(KTR_LOCK,
+ "%s: spinning on %p held by %p",
+ __func__, sx, owner);
KTR_STATE1(KTR_SCHED, "thread",
sched_tdname(curthread), "spinning",
- "lockname:\"%s\"", sx->lock_object.lo_name);
- GIANT_SAVE();
- spintries++;
- for (i = 0; i < asx_loops; i++) {
- if (LOCK_LOG_TEST(&sx->lock_object, 0))
- CTR4(KTR_LOCK,
- "%s: shared spinning on %p with %u and %u",
- __func__, sx, spintries, i);
- x = sx->sx_lock;
- if ((x & SX_LOCK_SHARED) == 0 ||
- SX_SHARERS(x) == 0)
- break;
- cpu_spinwait();
-#ifdef KDTRACE_HOOKS
- lda.spin_cnt++;
-#endif
- }
+ "lockname:\"%s\"",
+ sx->lock_object.lo_name);
+ do {
+ lock_delay(&lda);
+ x = SX_READ_VALUE(sx);
+ owner = lv_sx_owner(x);
+ } while (owner != NULL &&
+ TD_IS_RUNNING(owner));
KTR_STATE0(KTR_SCHED, "thread",
sched_tdname(curthread), "running");
+ continue;
+ }
+ sleep_reason = 1;
+ } else if (SX_SHARERS(x) && spintries < asx_retries) {
+ KTR_STATE1(KTR_SCHED, "thread",
+ sched_tdname(curthread), "spinning",
+ "lockname:\"%s\"", sx->lock_object.lo_name);
+ spintries++;
+ for (i = 0; i < asx_loops; i += n) {
+ if (LOCK_LOG_TEST(&sx->lock_object, 0))
+ CTR4(KTR_LOCK,
+ "%s: shared spinning on %p with %u and %u",
+ __func__, sx, spintries, i);
+ n = SX_SHARERS(x);
+ lock_delay_spin(n);
x = SX_READ_VALUE(sx);
- if (i != asx_loops)
- continue;
+ if ((x & SX_LOCK_SHARED) == 0 ||
+ SX_SHARERS(x) == 0)
+ break;
}
+#ifdef KDTRACE_HOOKS
+ lda.spin_cnt += i;
+#endif
+ KTR_STATE0(KTR_SCHED, "thread",
+ sched_tdname(curthread), "running");
+ if (i < asx_loops)
+ continue;
+ sleep_reason = 2;
}
+sleepq:
#endif
-
sleepq_lock(&sx->lock_object);
x = SX_READ_VALUE(sx);
+retry_sleepq:
/*
* If the lock was released while spinning on the
@@ -640,10 +696,14 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
* chain lock. If so, drop the sleep queue lock and try
* again.
*/
- if (!(x & SX_LOCK_SHARED) &&
- (sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) {
- owner = (struct thread *)SX_OWNER(x);
- if (TD_IS_RUNNING(owner)) {
+ if (adaptive) {
+ if (!(x & SX_LOCK_SHARED)) {
+ owner = (struct thread *)SX_OWNER(x);
+ if (TD_IS_RUNNING(owner)) {
+ sleepq_release(&sx->lock_object);
+ continue;
+ }
+ } else if (SX_SHARERS(x) > 0 && sleep_reason == 1) {
sleepq_release(&sx->lock_object);
continue;
}
@@ -661,17 +721,13 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
* fail, restart the loop.
*/
if (x == (SX_LOCK_UNLOCKED | SX_LOCK_EXCLUSIVE_WAITERS)) {
- if (atomic_cmpset_acq_ptr(&sx->sx_lock,
- SX_LOCK_UNLOCKED | SX_LOCK_EXCLUSIVE_WAITERS,
- tid | SX_LOCK_EXCLUSIVE_WAITERS)) {
- sleepq_release(&sx->lock_object);
- CTR2(KTR_LOCK, "%s: %p claimed by new writer",
- __func__, sx);
- break;
- }
+ if (!atomic_fcmpset_acq_ptr(&sx->sx_lock, &x,
+ tid | SX_LOCK_EXCLUSIVE_WAITERS))
+ goto retry_sleepq;
sleepq_release(&sx->lock_object);
- x = SX_READ_VALUE(sx);
- continue;
+ CTR2(KTR_LOCK, "%s: %p claimed by new writer",
+ __func__, sx);
+ break;
}
/*
@@ -679,11 +735,9 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
* than loop back and retry.
*/
if (!(x & SX_LOCK_EXCLUSIVE_WAITERS)) {
- if (!atomic_cmpset_ptr(&sx->sx_lock, x,
+ if (!atomic_fcmpset_ptr(&sx->sx_lock, &x,
x | SX_LOCK_EXCLUSIVE_WAITERS)) {
- sleepq_release(&sx->lock_object);
- x = SX_READ_VALUE(sx);
- continue;
+ goto retry_sleepq;
}
if (LOCK_LOG_TEST(&sx->lock_object, 0))
CTR2(KTR_LOCK, "%s: %p set excl waiters flag",
@@ -702,7 +756,6 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
#ifdef KDTRACE_HOOKS
sleep_time -= lockstat_nsecs(&sx->lock_object);
#endif
- GIANT_SAVE();
sleepq_add(&sx->lock_object, NULL, sx->lock_object.lo_name,
SLEEPQ_SX | ((opts & SX_INTERRUPTIBLE) ?
SLEEPQ_INTERRUPTIBLE : 0), SQ_EXCLUSIVE_QUEUE);
@@ -726,6 +779,10 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
__func__, sx);
x = SX_READ_VALUE(sx);
}
+#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
+ if (__predict_true(!extra_work))
+ return (error);
+#endif
#ifdef KDTRACE_HOOKS
all_time += lockstat_nsecs(&sx->lock_object);
if (sleep_time)
@@ -751,18 +808,22 @@ _sx_xlock_hard(struct sx *sx, uintptr_t x, uintptr_t tid, int opts,
* accessible from at least sx.h.
*/
void
-_sx_xunlock_hard(struct sx *sx, uintptr_t tid, const char *file, int line)
+_sx_xunlock_hard(struct sx *sx, uintptr_t x LOCK_FILE_LINE_ARG_DEF)
{
- uintptr_t x;
+ uintptr_t tid, setx;
int queue, wakeup_swapper;
if (SCHEDULER_STOPPED())
return;
- MPASS(!(sx->sx_lock & SX_LOCK_SHARED));
+ tid = (uintptr_t)curthread;
+
+ if (__predict_false(x == tid))
+ x = SX_READ_VALUE(sx);
- x = SX_READ_VALUE(sx);
- if (x & SX_LOCK_RECURSED) {
+ MPASS(!(x & SX_LOCK_SHARED));
+
+ if (__predict_false(x & SX_LOCK_RECURSED)) {
/* The lock is recursed, unrecurse one level. */
if ((--sx->sx_recurse) == 0)
atomic_clear_ptr(&sx->sx_lock, SX_LOCK_RECURSED);
@@ -776,13 +837,12 @@ _sx_xunlock_hard(struct sx *sx, uintptr_t tid, const char *file, int line)
atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED))
return;
- MPASS(sx->sx_lock & (SX_LOCK_SHARED_WAITERS |
- SX_LOCK_EXCLUSIVE_WAITERS));
if (LOCK_LOG_TEST(&sx->lock_object, 0))
CTR2(KTR_LOCK, "%s: %p contested", __func__, sx);
sleepq_lock(&sx->lock_object);
- x = SX_LOCK_UNLOCKED;
+ x = SX_READ_VALUE(sx);
+ MPASS(x & (SX_LOCK_SHARED_WAITERS | SX_LOCK_EXCLUSIVE_WAITERS));
/*
* The wake up algorithm here is quite simple and probably not
@@ -793,19 +853,21 @@ _sx_xunlock_hard(struct sx *sx, uintptr_t tid, const char *file, int line)
* starvation for the threads sleeping on the exclusive queue by giving
* them precedence and cleaning up the shared waiters bit anyway.
*/
- if ((sx->sx_lock & SX_LOCK_SHARED_WAITERS) != 0 &&
+ setx = SX_LOCK_UNLOCKED;
+ queue = SQ_EXCLUSIVE_QUEUE;
+ if ((x & SX_LOCK_SHARED_WAITERS) != 0 &&
sleepq_sleepcnt(&sx->lock_object, SQ_SHARED_QUEUE) != 0) {
queue = SQ_SHARED_QUEUE;
- x |= (sx->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS);
- } else
- queue = SQ_EXCLUSIVE_QUEUE;
+ setx |= (x & SX_LOCK_EXCLUSIVE_WAITERS);
+ }
+ atomic_store_rel_ptr(&sx->sx_lock, setx);
/* Wake up all the waiters for the specific queue. */
if (LOCK_LOG_TEST(&sx->lock_object, 0))
CTR3(KTR_LOCK, "%s: %p waking up all threads on %s queue",
__func__, sx, queue == SQ_SHARED_QUEUE ? "shared" :
"exclusive");
- atomic_store_rel_ptr(&sx->sx_lock, x);
+
wakeup_swapper = sleepq_broadcast(&sx->lock_object, SLEEPQ_SX, 0,
queue);
sleepq_release(&sx->lock_object);
@@ -814,7 +876,7 @@ _sx_xunlock_hard(struct sx *sx, uintptr_t tid, const char *file, int line)
}
static bool __always_inline
-__sx_slock_try(struct sx *sx, uintptr_t *xp, const char *file, int line)
+__sx_slock_try(struct sx *sx, uintptr_t *xp LOCK_FILE_LINE_ARG_DEF)
{
/*
@@ -838,11 +900,12 @@ __sx_slock_try(struct sx *sx, uintptr_t *xp, const char *file, int line)
}
static int __noinline
-_sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
+_sx_slock_hard(struct sx *sx, int opts, uintptr_t x LOCK_FILE_LINE_ARG_DEF)
{
GIANT_DECLARE;
#ifdef ADAPTIVE_SX
volatile struct thread *owner;
+ bool adaptive;
#endif
#ifdef LOCK_PROFILING
uint64_t waittime = 0;
@@ -853,11 +916,14 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
struct lock_delay_arg lda;
#endif
#ifdef KDTRACE_HOOKS
- uintptr_t state;
u_int sleep_cnt = 0;
int64_t sleep_time = 0;
int64_t all_time = 0;
#endif
+#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
+ uintptr_t state;
+#endif
+ int extra_work = 0;
if (SCHEDULER_STOPPED())
return (0);
@@ -867,9 +933,29 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
#elif defined(KDTRACE_HOOKS)
lock_delay_arg_init(&lda, NULL);
#endif
-#ifdef KDTRACE_HOOKS
- all_time -= lockstat_nsecs(&sx->lock_object);
+
+#ifdef ADAPTIVE_SX
+ adaptive = ((sx->lock_object.lo_flags & SX_NOADAPTIVE) != 0);
+#endif
+
+#ifdef HWPMC_HOOKS
+ PMC_SOFT_CALL( , , lock, failed);
+#endif
+ lock_profile_obtain_lock_failed(&sx->lock_object, &contested,
+ &waittime);
+
+#ifdef LOCK_PROFILING
+ extra_work = 1;
state = x;
+#elif defined(KDTRACE_HOOKS)
+ extra_work = lockstat_enabled;
+ if (__predict_false(extra_work)) {
+ all_time -= lockstat_nsecs(&sx->lock_object);
+ state = x;
+ }
+#endif
+#ifndef INVARIANTS
+ GIANT_SAVE(extra_work);
#endif
/*
@@ -877,45 +963,42 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
* shared locks once there is an exclusive waiter.
*/
for (;;) {
- if (__sx_slock_try(sx, &x, file, line))
+ if (__sx_slock_try(sx, &x LOCK_FILE_LINE_ARG))
break;
+#ifdef INVARIANTS
+ GIANT_SAVE(extra_work);
+#endif
#ifdef KDTRACE_HOOKS
lda.spin_cnt++;
#endif
-#ifdef HWPMC_HOOKS
- PMC_SOFT_CALL( , , lock, failed);
-#endif
- lock_profile_obtain_lock_failed(&sx->lock_object, &contested,
- &waittime);
-
#ifdef ADAPTIVE_SX
+ if (__predict_false(!adaptive))
+ goto sleepq;
/*
* If the owner is running on another CPU, spin until
* the owner stops running or the state of the lock
* changes.
*/
- if ((sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) {
- owner = lv_sx_owner(x);
- if (TD_IS_RUNNING(owner)) {
- if (LOCK_LOG_TEST(&sx->lock_object, 0))
- CTR3(KTR_LOCK,
- "%s: spinning on %p held by %p",
- __func__, sx, owner);
- KTR_STATE1(KTR_SCHED, "thread",
- sched_tdname(curthread), "spinning",
- "lockname:\"%s\"", sx->lock_object.lo_name);
- GIANT_SAVE();
- do {
- lock_delay(&lda);
- x = SX_READ_VALUE(sx);
- owner = lv_sx_owner(x);
- } while (owner != NULL && TD_IS_RUNNING(owner));
- KTR_STATE0(KTR_SCHED, "thread",
- sched_tdname(curthread), "running");
- continue;
- }
+ owner = lv_sx_owner(x);
+ if (TD_IS_RUNNING(owner)) {
+ if (LOCK_LOG_TEST(&sx->lock_object, 0))
+ CTR3(KTR_LOCK,
+ "%s: spinning on %p held by %p",
+ __func__, sx, owner);
+ KTR_STATE1(KTR_SCHED, "thread",
+ sched_tdname(curthread), "spinning",
+ "lockname:\"%s\"", sx->lock_object.lo_name);
+ do {
+ lock_delay(&lda);
+ x = SX_READ_VALUE(sx);
+ owner = lv_sx_owner(x);
+ } while (owner != NULL && TD_IS_RUNNING(owner));
+ KTR_STATE0(KTR_SCHED, "thread",
+ sched_tdname(curthread), "running");
+ continue;
}
+sleepq:
#endif
/*
@@ -924,7 +1007,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
*/
sleepq_lock(&sx->lock_object);
x = SX_READ_VALUE(sx);
-
+retry_sleepq:
/*
* The lock could have been released while we spun.
* In this case loop back and retry.
@@ -940,8 +1023,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
* the owner stops running or the state of the lock
* changes.
*/
- if (!(x & SX_LOCK_SHARED) &&
- (sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) {
+ if (!(x & SX_LOCK_SHARED) && adaptive) {
owner = (struct thread *)SX_OWNER(x);
if (TD_IS_RUNNING(owner)) {
sleepq_release(&sx->lock_object);
@@ -957,12 +1039,9 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
* back.
*/
if (!(x & SX_LOCK_SHARED_WAITERS)) {
- if (!atomic_cmpset_ptr(&sx->sx_lock, x,
- x | SX_LOCK_SHARED_WAITERS)) {
- sleepq_release(&sx->lock_object);
- x = SX_READ_VALUE(sx);
- continue;
- }
+ if (!atomic_fcmpset_ptr(&sx->sx_lock, &x,
+ x | SX_LOCK_SHARED_WAITERS))
+ goto retry_sleepq;
if (LOCK_LOG_TEST(&sx->lock_object, 0))
CTR2(KTR_LOCK, "%s: %p set shared waiters flag",
__func__, sx);
@@ -979,7 +1058,6 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
#ifdef KDTRACE_HOOKS
sleep_time -= lockstat_nsecs(&sx->lock_object);
#endif
- GIANT_SAVE();
sleepq_add(&sx->lock_object, NULL, sx->lock_object.lo_name,
SLEEPQ_SX | ((opts & SX_INTERRUPTIBLE) ?
SLEEPQ_INTERRUPTIBLE : 0), SQ_SHARED_QUEUE);
@@ -1003,6 +1081,10 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
__func__, sx);
x = SX_READ_VALUE(sx);
}
+#if defined(KDTRACE_HOOKS) || defined(LOCK_PROFILING)
+ if (__predict_true(!extra_work))
+ return (error);
+#endif
#ifdef KDTRACE_HOOKS
all_time += lockstat_nsecs(&sx->lock_object);
if (sleep_time)
@@ -1023,7 +1105,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line, uintptr_t x)
}
int
-_sx_slock(struct sx *sx, int opts, const char *file, int line)
+_sx_slock_int(struct sx *sx, int opts LOCK_FILE_LINE_ARG_DEF)
{
uintptr_t x;
int error;
@@ -1039,8 +1121,8 @@ _sx_slock(struct sx *sx, int opts, const char *file, int line)
error = 0;
x = SX_READ_VALUE(sx);
if (__predict_false(LOCKSTAT_OOL_PROFILE_ENABLED(sx__acquire) ||
- !__sx_slock_try(sx, &x, file, line)))
- error = _sx_slock_hard(sx, opts, file, line, x);
+ !__sx_slock_try(sx, &x LOCK_FILE_LINE_ARG)))
+ error = _sx_slock_hard(sx, opts, x LOCK_FILE_LINE_ARG);
if (error == 0) {
LOCK_LOG_LOCK("SLOCK", &sx->lock_object, 0, 0, file, line);
WITNESS_LOCK(&sx->lock_object, 0, file, line);
@@ -1049,6 +1131,13 @@ _sx_slock(struct sx *sx, int opts, const char *file, int line)
return (error);
}
+int
+_sx_slock(struct sx *sx, int opts, const char *file, int line)
+{
+
+ return (_sx_slock_int(sx, opts LOCK_FILE_LINE_ARG));
+}
+
static bool __always_inline
_sx_sunlock_try(struct sx *sx, uintptr_t *xp)
{
@@ -1100,53 +1189,54 @@ _sx_sunlock_try(struct sx *sx, uintptr_t *xp)
}
static void __noinline
-_sx_sunlock_hard(struct sx *sx, uintptr_t x, const char *file, int line)
+_sx_sunlock_hard(struct sx *sx, uintptr_t x LOCK_FILE_LINE_ARG_DEF)
{
int wakeup_swapper;
+ uintptr_t setx;
if (SCHEDULER_STOPPED())
return;
- for (;;) {
- if (_sx_sunlock_try(sx, &x))
- break;
-
- /*
- * At this point, there should just be one sharer with
- * exclusive waiters.
- */
- MPASS(x == (SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS));
+ if (_sx_sunlock_try(sx, &x))
+ goto out_lockstat;
- sleepq_lock(&sx->lock_object);
+ /*
+ * At this point, there should just be one sharer with
+ * exclusive waiters.
+ */
+ MPASS(x == (SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS));
+ sleepq_lock(&sx->lock_object);
+ x = SX_READ_VALUE(sx);
+ for (;;) {
+ MPASS(x & SX_LOCK_EXCLUSIVE_WAITERS);
+ MPASS(!(x & SX_LOCK_SHARED_WAITERS));
/*
* Wake up semantic here is quite simple:
* Just wake up all the exclusive waiters.
* Note that the state of the lock could have changed,
* so if it fails loop back and retry.
*/
- if (!atomic_cmpset_rel_ptr(&sx->sx_lock,
- SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS,
- SX_LOCK_UNLOCKED)) {
- sleepq_release(&sx->lock_object);
- x = SX_READ_VALUE(sx);
+ setx = x - SX_ONE_SHARER;
+ setx &= ~SX_LOCK_EXCLUSIVE_WAITERS;
+ if (!atomic_fcmpset_rel_ptr(&sx->sx_lock, &x, setx))
continue;
- }
if (LOCK_LOG_TEST(&sx->lock_object, 0))
CTR2(KTR_LOCK, "%s: %p waking up all thread on"
"exclusive queue", __func__, sx);
wakeup_swapper = sleepq_broadcast(&sx->lock_object, SLEEPQ_SX,
0, SQ_EXCLUSIVE_QUEUE);
- sleepq_release(&sx->lock_object);
- if (wakeup_swapper)
- kick_proc0();
break;
}
+ sleepq_release(&sx->lock_object);
+ if (wakeup_swapper)
+ kick_proc0();
+out_lockstat:
LOCKSTAT_PROFILE_RELEASE_RWLOCK(sx__release, sx, LOCKSTAT_READER);
}
void
-_sx_sunlock(struct sx *sx, const char *file, int line)
+_sx_sunlock_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF)
{
uintptr_t x;
@@ -1159,11 +1249,18 @@ _sx_sunlock(struct sx *sx, const char *file, int line)
x = SX_READ_VALUE(sx);
if (__predict_false(LOCKSTAT_OOL_PROFILE_ENABLED(sx__release) ||
!_sx_sunlock_try(sx, &x)))
- _sx_sunlock_hard(sx, x, file, line);
+ _sx_sunlock_hard(sx, x LOCK_FILE_LINE_ARG);
TD_LOCKS_DEC(curthread);
}
+void
+_sx_sunlock(struct sx *sx, const char *file, int line)
+{
+
+ _sx_sunlock_int(sx LOCK_FILE_LINE_ARG);
+}
+
#ifdef INVARIANT_SUPPORT
#ifndef INVARIANTS
#undef _sx_assert
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 3bf23ec..411063f 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -88,7 +88,7 @@ static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
* sysctl requests larger than a single page via an exclusive lock.
*/
static struct rmlock sysctllock;
-static struct sx sysctlmemlock;
+static struct sx __exclusive_cache_line sysctlmemlock;
#define SYSCTL_WLOCK() rm_wlock(&sysctllock)
#define SYSCTL_WUNLOCK() rm_wunlock(&sysctllock)
@@ -1117,17 +1117,21 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
int error, oid[CTL_MAXNAME], len = 0;
struct sysctl_oid *op = NULL;
struct rm_priotracker tracker;
+ char buf[32];
if (!req->newlen)
return (ENOENT);
if (req->newlen >= MAXPATHLEN) /* XXX arbitrary, undocumented */
return (ENAMETOOLONG);
- p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK);
+ p = buf;
+ if (req->newlen >= sizeof(buf))
+ p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK);
error = SYSCTL_IN(req, p, req->newlen);
if (error) {
- free(p, M_SYSCTL);
+ if (p != buf)
+ free(p, M_SYSCTL);
return (error);
}
@@ -1137,7 +1141,8 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
error = name2oid(p, oid, &len, &op);
SYSCTL_RUNLOCK(&tracker);
- free(p, M_SYSCTL);
+ if (p != buf)
+ free(p, M_SYSCTL);
if (error)
return (error);
@@ -1977,16 +1982,9 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
}
}
req.validlen = req.oldlen;
-
- if (old) {
- if (!useracc(old, req.oldlen, VM_PROT_WRITE))
- return (EFAULT);
- req.oldptr= old;
- }
+ req.oldptr = old;
if (new != NULL) {
- if (!useracc(new, newlen, VM_PROT_READ))
- return (EFAULT);
req.newlen = newlen;
req.newptr = new;
}
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 333428e..4ed75f4 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -1603,10 +1603,10 @@ pps_fetch(struct pps_fetch_args *fapi, struct pps_state *pps)
tv.tv_usec = fapi->timeout.tv_nsec / 1000;
timo = tvtohz(&tv);
}
- aseq = pps->ppsinfo.assert_sequence;
- cseq = pps->ppsinfo.clear_sequence;
- while (aseq == pps->ppsinfo.assert_sequence &&
- cseq == pps->ppsinfo.clear_sequence) {
+ aseq = atomic_load_int(&pps->ppsinfo.assert_sequence);
+ cseq = atomic_load_int(&pps->ppsinfo.clear_sequence);
+ while (aseq == atomic_load_int(&pps->ppsinfo.assert_sequence) &&
+ cseq == atomic_load_int(&pps->ppsinfo.clear_sequence)) {
if (abi_aware(pps, 1) && pps->driver_mtx != NULL) {
if (pps->flags & PPSFLAG_MTX_SPIN) {
err = msleep_spin(pps, pps->driver_mtx,
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 66567ca..d31d825 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -2934,6 +2934,7 @@ device_attach(device_t dev)
else
dev->state = DS_ATTACHED;
dev->flags &= ~DF_DONENOMATCH;
+ EVENTHANDLER_INVOKE(device_attach, dev);
devadded(dev);
return (0);
}
@@ -2967,8 +2968,13 @@ device_detach(device_t dev)
if (dev->state != DS_ATTACHED)
return (0);
- if ((error = DEVICE_DETACH(dev)) != 0)
+ EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_BEGIN);
+ if ((error = DEVICE_DETACH(dev)) != 0) {
+ EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_FAILED);
return (error);
+ } else {
+ EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_COMPLETE);
+ }
devremoved(dev);
if (!device_is_quiet(dev))
device_printf(dev, "detached\n");
diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c
index 5894099..793210c 100644
--- a/sys/kern/subr_eventhandler.c
+++ b/sys/kern/subr_eventhandler.c
@@ -180,8 +180,9 @@ vimage_eventhandler_register(struct eventhandler_list *list, const char *name,
}
#endif
-void
-eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
+static void
+_eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag,
+ bool wait)
{
struct eventhandler_entry *ep = tag;
@@ -215,11 +216,26 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
ep->ee_priority = EHE_DEAD_PRIORITY;
}
}
- while (list->el_runcount > 0)
+ while (wait && list->el_runcount > 0)
mtx_sleep(list, &list->el_lock, 0, "evhrm", 0);
EHL_UNLOCK(list);
}
+void
+eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
+{
+
+ _eventhandler_deregister(list, tag, true);
+}
+
+void
+eventhandler_deregister_nowait(struct eventhandler_list *list,
+ eventhandler_tag tag)
+{
+
+ _eventhandler_deregister(list, tag, false);
+}
+
/*
* Internal version for use when eventhandler list is already locked.
*/
diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c
index 356ad37..249aab4 100644
--- a/sys/kern/subr_kdb.c
+++ b/sys/kern/subr_kdb.c
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
#include <machine/smp.h>
#endif
-int kdb_active = 0;
+u_char __read_frequently kdb_active = 0;
static void *kdb_jmpbufp = NULL;
struct kdb_dbbe *kdb_dbbe = NULL;
static struct pcb kdb_pcb;
diff --git a/sys/kern/subr_vmem.c b/sys/kern/subr_vmem.c
index 1de6378..4e3f04e 100644
--- a/sys/kern/subr_vmem.c
+++ b/sys/kern/subr_vmem.c
@@ -181,7 +181,7 @@ static struct callout vmem_periodic_ch;
static int vmem_periodic_interval;
static struct task vmem_periodic_wk;
-static struct mtx_padalign vmem_list_lock;
+static struct mtx_padalign __exclusive_cache_line vmem_list_lock;
static LIST_HEAD(, vmem) vmem_list = LIST_HEAD_INITIALIZER(vmem_list);
/* ---- misc */
@@ -580,7 +580,7 @@ qc_drain(vmem_t *vm)
#ifndef UMA_MD_SMALL_ALLOC
-static struct mtx_padalign vmem_bt_lock;
+static struct mtx_padalign __exclusive_cache_line vmem_bt_lock;
/*
* vmem_bt_alloc: Allocate a new page of boundary tags.
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index e8a72de..1c87c9c 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -253,23 +253,23 @@ SYSCTL_INT(_vfs, OID_AUTO, maxbcachebuf, CTLFLAG_RDTUN, &maxbcachebuf, 0,
/*
* This lock synchronizes access to bd_request.
*/
-static struct mtx_padalign bdlock;
+static struct mtx_padalign __exclusive_cache_line bdlock;
/*
* This lock protects the runningbufreq and synchronizes runningbufwakeup and
* waitrunningbufspace().
*/
-static struct mtx_padalign rbreqlock;
+static struct mtx_padalign __exclusive_cache_line rbreqlock;
/*
* Lock that protects needsbuffer and the sleeps/wakeups surrounding it.
*/
-static struct rwlock_padalign nblock;
+static struct rwlock_padalign __exclusive_cache_line nblock;
/*
* Lock that protects bdirtywait.
*/
-static struct mtx_padalign bdirtylock;
+static struct mtx_padalign __exclusive_cache_line bdirtylock;
/*
* Wakeup point for bufdaemon, as well as indicator of whether it is already
@@ -348,7 +348,7 @@ static int bq_len[BUFFER_QUEUES];
/*
* Lock for each bufqueue
*/
-static struct mtx_padalign bqlocks[BUFFER_QUEUES];
+static struct mtx_padalign __exclusive_cache_line bqlocks[BUFFER_QUEUES];
/*
* per-cpu empty buffer cache.
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 86adca1..586aaee 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -13,7 +13,7 @@
* 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
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -117,20 +117,10 @@ struct namecache {
* parent.
*/
struct namecache_ts {
- LIST_ENTRY(namecache) nc_hash; /* hash chain */
- LIST_ENTRY(namecache) nc_src; /* source vnode list */
- TAILQ_ENTRY(namecache) nc_dst; /* destination vnode list */
- struct vnode *nc_dvp; /* vnode of parent of name */
- union {
- struct vnode *nu_vp; /* vnode the name refers to */
- u_int nu_neghits; /* negative entry hits */
- } n_un;
- u_char nc_flag; /* flag bits */
- u_char nc_nlen; /* length of name */
struct timespec nc_time; /* timespec provided by fs */
struct timespec nc_dotdottime; /* dotdot timespec provided by fs */
int nc_ticks; /* ticks value when entry was added */
- char nc_name[0]; /* segment name + nul */
+ struct namecache nc_nc;
};
#define nc_vp n_un.nu_vp
@@ -204,7 +194,7 @@ static __read_mostly LIST_HEAD(nchashhead, namecache) *nchashtbl;/* Hash Table *
static u_long __read_mostly nchash; /* size of hash table */
SYSCTL_ULONG(_debug, OID_AUTO, nchash, CTLFLAG_RD, &nchash, 0,
"Size of namecache hash table");
-static u_long __read_mostly ncnegfactor = 16; /* ratio of negative entries */
+static u_long __read_mostly ncnegfactor = 12; /* ratio of negative entries */
SYSCTL_ULONG(_vfs, OID_AUTO, ncnegfactor, CTLFLAG_RW, &ncnegfactor, 0,
"Ratio of negative namecache entries");
static u_long __exclusive_cache_line numneg; /* number of negative entries allocated */
@@ -281,63 +271,64 @@ static uma_zone_t __read_mostly cache_zone_large_ts;
static struct namecache *
cache_alloc(int len, int ts)
{
+ struct namecache_ts *ncp_ts;
+ struct namecache *ncp;
- if (len > CACHE_PATH_CUTOFF) {
- if (ts)
- return (uma_zalloc(cache_zone_large_ts, M_WAITOK));
+ if (__predict_false(ts)) {
+ if (len <= CACHE_PATH_CUTOFF)
+ ncp_ts = uma_zalloc(cache_zone_small_ts, M_WAITOK);
else
- return (uma_zalloc(cache_zone_large, M_WAITOK));
+ ncp_ts = uma_zalloc(cache_zone_large_ts, M_WAITOK);
+ ncp = &ncp_ts->nc_nc;
+ } else {
+ if (len <= CACHE_PATH_CUTOFF)
+ ncp = uma_zalloc(cache_zone_small, M_WAITOK);
+ else
+ ncp = uma_zalloc(cache_zone_large, M_WAITOK);
}
- if (ts)
- return (uma_zalloc(cache_zone_small_ts, M_WAITOK));
- else
- return (uma_zalloc(cache_zone_small, M_WAITOK));
+ return (ncp);
}
static void
cache_free(struct namecache *ncp)
{
- int ts;
+ struct namecache_ts *ncp_ts;
if (ncp == NULL)
return;
- ts = ncp->nc_flag & NCF_TS;
if ((ncp->nc_flag & NCF_DVDROP) != 0)
vdrop(ncp->nc_dvp);
- if (ncp->nc_nlen <= CACHE_PATH_CUTOFF) {
- if (ts)
- uma_zfree(cache_zone_small_ts, ncp);
+ if (__predict_false(ncp->nc_flag & NCF_TS)) {
+ ncp_ts = __containerof(ncp, struct namecache_ts, nc_nc);
+ if (ncp->nc_nlen <= CACHE_PATH_CUTOFF)
+ uma_zfree(cache_zone_small_ts, ncp_ts);
else
+ uma_zfree(cache_zone_large_ts, ncp_ts);
+ } else {
+ if (ncp->nc_nlen <= CACHE_PATH_CUTOFF)
uma_zfree(cache_zone_small, ncp);
- } else if (ts)
- uma_zfree(cache_zone_large_ts, ncp);
- else
- uma_zfree(cache_zone_large, ncp);
-}
-
-static char *
-nc_get_name(struct namecache *ncp)
-{
- struct namecache_ts *ncp_ts;
-
- if ((ncp->nc_flag & NCF_TS) == 0)
- return (ncp->nc_name);
- ncp_ts = (struct namecache_ts *)ncp;
- return (ncp_ts->nc_name);
+ else
+ uma_zfree(cache_zone_large, ncp);
+ }
}
static void
cache_out_ts(struct namecache *ncp, struct timespec *tsp, int *ticksp)
{
+ struct namecache_ts *ncp_ts;
KASSERT((ncp->nc_flag & NCF_TS) != 0 ||
(tsp == NULL && ticksp == NULL),
("No NCF_TS"));
+ if (tsp == NULL && ticksp == NULL)
+ return;
+
+ ncp_ts = __containerof(ncp, struct namecache_ts, nc_nc);
if (tsp != NULL)
- *tsp = ((struct namecache_ts *)ncp)->nc_time;
+ *tsp = ncp_ts->nc_time;
if (ticksp != NULL)
- *ticksp = ((struct namecache_ts *)ncp)->nc_ticks;
+ *ticksp = ncp_ts->nc_ticks;
}
static int __read_mostly doingcache = 1; /* 1 => enable the cache */
@@ -437,7 +428,7 @@ NCP2BUCKETLOCK(struct namecache *ncp)
{
uint32_t hash;
- hash = cache_get_hash(nc_get_name(ncp), ncp->nc_nlen, ncp->nc_dvp);
+ hash = cache_get_hash(ncp->nc_name, ncp->nc_nlen, ncp->nc_dvp);
return (HASH2BUCKETLOCK(hash));
}
@@ -823,7 +814,7 @@ cache_negative_zap_one(void)
goto out_unlock_all;
}
SDT_PROBE3(vfs, namecache, shrink_negative, done, ncp->nc_dvp,
- nc_get_name(ncp), ncp->nc_neghits);
+ ncp->nc_name, ncp->nc_neghits);
cache_zap_locked(ncp, true);
out_unlock_all:
@@ -854,10 +845,10 @@ cache_zap_locked(struct namecache *ncp, bool neg_locked)
(ncp->nc_flag & NCF_NEGATIVE) ? NULL : ncp->nc_vp);
if (!(ncp->nc_flag & NCF_NEGATIVE)) {
SDT_PROBE3(vfs, namecache, zap, done, ncp->nc_dvp,
- nc_get_name(ncp), ncp->nc_vp);
+ ncp->nc_name, ncp->nc_vp);
} else {
SDT_PROBE3(vfs, namecache, zap_negative, done, ncp->nc_dvp,
- nc_get_name(ncp), ncp->nc_neghits);
+ ncp->nc_name, ncp->nc_neghits);
}
LIST_REMOVE(ncp, nc_hash);
if (!(ncp->nc_flag & NCF_NEGATIVE)) {
@@ -993,6 +984,28 @@ out:
}
static int
+cache_zap_wlocked_bucket(struct namecache *ncp, struct rwlock *blp)
+{
+ struct mtx *dvlp, *vlp;
+
+ cache_assert_bucket_locked(ncp, RA_WLOCKED);
+
+ dvlp = VP2VNODELOCK(ncp->nc_dvp);
+ vlp = NULL;
+ if (!(ncp->nc_flag & NCF_NEGATIVE))
+ vlp = VP2VNODELOCK(ncp->nc_vp);
+ if (cache_trylock_vnodes(dvlp, vlp) == 0) {
+ cache_zap_locked(ncp, false);
+ rw_wunlock(blp);
+ cache_unlock_vnodes(dvlp, vlp);
+ return (0);
+ }
+
+ rw_wunlock(blp);
+ return (EAGAIN);
+}
+
+static int
cache_zap_rlocked_bucket(struct namecache *ncp, struct rwlock *blp)
{
struct mtx *dvlp, *vlp;
@@ -1067,12 +1080,47 @@ cache_lookup_unlock(struct rwlock *blp, struct mtx *vlp)
if (blp != NULL) {
rw_runlock(blp);
- mtx_assert(vlp, MA_NOTOWNED);
} else {
mtx_unlock(vlp);
}
}
+static int __noinline
+cache_lookup_dot(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
+ struct timespec *tsp, int *ticksp)
+{
+ int ltype;
+
+ *vpp = dvp;
+ CTR2(KTR_VFS, "cache_lookup(%p, %s) found via .",
+ dvp, cnp->cn_nameptr);
+ counter_u64_add(dothits, 1);
+ SDT_PROBE3(vfs, namecache, lookup, hit, dvp, ".", *vpp);
+ if (tsp != NULL)
+ timespecclear(tsp);
+ if (ticksp != NULL)
+ *ticksp = ticks;
+ vrefact(*vpp);
+ /*
+ * When we lookup "." we still can be asked to lock it
+ * differently...
+ */
+ ltype = cnp->cn_lkflags & LK_TYPE_MASK;
+ if (ltype != VOP_ISLOCKED(*vpp)) {
+ if (ltype == LK_EXCLUSIVE) {
+ vn_lock(*vpp, LK_UPGRADE | LK_RETRY);
+ if ((*vpp)->v_iflag & VI_DOOMED) {
+ /* forced unmount */
+ vrele(*vpp);
+ *vpp = NULL;
+ return (ENOENT);
+ }
+ } else
+ vn_lock(*vpp, LK_DOWNGRADE | LK_RETRY);
+ }
+ return (-1);
+}
+
/*
* Lookup an entry in the cache
*
@@ -1090,10 +1138,94 @@ cache_lookup_unlock(struct rwlock *blp, struct mtx *vlp)
* not recursively acquired.
*/
+static __noinline int
+cache_lookup_nomakeentry(struct vnode *dvp, struct vnode **vpp,
+ struct componentname *cnp, struct timespec *tsp, int *ticksp)
+{
+ struct namecache *ncp;
+ struct rwlock *blp;
+ struct mtx *dvlp, *dvlp2;
+ uint32_t hash;
+ int error;
+
+ if (cnp->cn_namelen == 2 &&
+ cnp->cn_nameptr[0] == '.' && cnp->cn_nameptr[1] == '.') {
+ counter_u64_add(dotdothits, 1);
+ dvlp = VP2VNODELOCK(dvp);
+ dvlp2 = NULL;
+ mtx_lock(dvlp);
+retry_dotdot:
+ ncp = dvp->v_cache_dd;
+ if (ncp == NULL) {
+ SDT_PROBE3(vfs, namecache, lookup, miss, dvp,
+ "..", NULL);
+ mtx_unlock(dvlp);
+ if (dvlp2 != NULL)
+ mtx_unlock(dvlp2);
+ return (0);
+ }
+ if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) {
+ if (ncp->nc_dvp != dvp)
+ panic("dvp %p v_cache_dd %p\n", dvp, ncp);
+ if (!cache_zap_locked_vnode_kl2(ncp,
+ dvp, &dvlp2))
+ goto retry_dotdot;
+ MPASS(dvp->v_cache_dd == NULL);
+ mtx_unlock(dvlp);
+ if (dvlp2 != NULL)
+ mtx_unlock(dvlp2);
+ cache_free(ncp);
+ } else {
+ dvp->v_cache_dd = NULL;
+ mtx_unlock(dvlp);
+ if (dvlp2 != NULL)
+ mtx_unlock(dvlp2);
+ }
+ return (0);
+ }
+
+ hash = cache_get_hash(cnp->cn_nameptr, cnp->cn_namelen, dvp);
+ blp = HASH2BUCKETLOCK(hash);
+retry:
+ if (LIST_EMPTY(NCHHASH(hash)))
+ goto out_no_entry;
+
+ rw_wlock(blp);
+
+ LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) {
+ counter_u64_add(numchecks, 1);
+ if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen &&
+ !bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen))
+ break;
+ }
+
+ /* We failed to find an entry */
+ if (ncp == NULL) {
+ rw_wunlock(blp);
+ goto out_no_entry;
+ }
+
+ counter_u64_add(numposzaps, 1);
+
+ error = cache_zap_wlocked_bucket(ncp, blp);
+ if (error != 0) {
+ zap_and_exit_bucket_fail++;
+ cache_maybe_yield();
+ goto retry;
+ }
+ cache_free(ncp);
+ return (0);
+out_no_entry:
+ SDT_PROBE3(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, NULL);
+ counter_u64_add(nummisszap, 1);
+ return (0);
+}
+
int
cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
struct timespec *tsp, int *ticksp)
{
+ struct namecache_ts *ncp_ts;
struct namecache *ncp;
struct rwlock *blp;
struct mtx *dvlp, *dvlp2;
@@ -1104,96 +1236,52 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
cnp->cn_flags &= ~MAKEENTRY;
return (0);
}
+
+ counter_u64_add(numcalls, 1);
+
+ if (__predict_false(cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.'))
+ return (cache_lookup_dot(dvp, vpp, cnp, tsp, ticksp));
+
+ if ((cnp->cn_flags & MAKEENTRY) == 0)
+ return (cache_lookup_nomakeentry(dvp, vpp, cnp, tsp, ticksp));
+
retry:
blp = NULL;
- dvlp = VP2VNODELOCK(dvp);
error = 0;
- counter_u64_add(numcalls, 1);
-
- if (cnp->cn_nameptr[0] == '.') {
- if (cnp->cn_namelen == 1) {
- *vpp = dvp;
- CTR2(KTR_VFS, "cache_lookup(%p, %s) found via .",
- dvp, cnp->cn_nameptr);
- counter_u64_add(dothits, 1);
- SDT_PROBE3(vfs, namecache, lookup, hit, dvp, ".", *vpp);
- if (tsp != NULL)
- timespecclear(tsp);
- if (ticksp != NULL)
- *ticksp = ticks;
- vrefact(*vpp);
- /*
- * When we lookup "." we still can be asked to lock it
- * differently...
- */
- ltype = cnp->cn_lkflags & LK_TYPE_MASK;
- if (ltype != VOP_ISLOCKED(*vpp)) {
- if (ltype == LK_EXCLUSIVE) {
- vn_lock(*vpp, LK_UPGRADE | LK_RETRY);
- if ((*vpp)->v_iflag & VI_DOOMED) {
- /* forced unmount */
- vrele(*vpp);
- *vpp = NULL;
- return (ENOENT);
- }
- } else
- vn_lock(*vpp, LK_DOWNGRADE | LK_RETRY);
- }
- return (-1);
+ if (cnp->cn_namelen == 2 &&
+ cnp->cn_nameptr[0] == '.' && cnp->cn_nameptr[1] == '.') {
+ counter_u64_add(dotdothits, 1);
+ dvlp = VP2VNODELOCK(dvp);
+ dvlp2 = NULL;
+ mtx_lock(dvlp);
+ ncp = dvp->v_cache_dd;
+ if (ncp == NULL) {
+ SDT_PROBE3(vfs, namecache, lookup, miss, dvp,
+ "..", NULL);
+ mtx_unlock(dvlp);
+ return (0);
}
- if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') {
- counter_u64_add(dotdothits, 1);
- dvlp2 = NULL;
- mtx_lock(dvlp);
-retry_dotdot:
- ncp = dvp->v_cache_dd;
- if (ncp == NULL) {
- SDT_PROBE3(vfs, namecache, lookup, miss, dvp,
- "..", NULL);
- mtx_unlock(dvlp);
- return (0);
- }
- if ((cnp->cn_flags & MAKEENTRY) == 0) {
- if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) {
- if (ncp->nc_dvp != dvp)
- panic("dvp %p v_cache_dd %p\n", dvp, ncp);
- if (!cache_zap_locked_vnode_kl2(ncp,
- dvp, &dvlp2))
- goto retry_dotdot;
- MPASS(dvp->v_cache_dd == NULL);
- mtx_unlock(dvlp);
- if (dvlp2 != NULL)
- mtx_unlock(dvlp2);
- cache_free(ncp);
- } else {
- dvp->v_cache_dd = NULL;
- mtx_unlock(dvlp);
- if (dvlp2 != NULL)
- mtx_unlock(dvlp2);
- }
- return (0);
- }
- if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) {
- if (ncp->nc_flag & NCF_NEGATIVE)
- *vpp = NULL;
- else
- *vpp = ncp->nc_vp;
- } else
- *vpp = ncp->nc_dvp;
- /* Return failure if negative entry was found. */
- if (*vpp == NULL)
- goto negative_success;
- CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..",
- dvp, cnp->cn_nameptr, *vpp);
- SDT_PROBE3(vfs, namecache, lookup, hit, dvp, "..",
- *vpp);
- cache_out_ts(ncp, tsp, ticksp);
- if ((ncp->nc_flag & (NCF_ISDOTDOT | NCF_DTS)) ==
- NCF_DTS && tsp != NULL)
- *tsp = ((struct namecache_ts *)ncp)->
- nc_dotdottime;
- goto success;
+ if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) {
+ if (ncp->nc_flag & NCF_NEGATIVE)
+ *vpp = NULL;
+ else
+ *vpp = ncp->nc_vp;
+ } else
+ *vpp = ncp->nc_dvp;
+ /* Return failure if negative entry was found. */
+ if (*vpp == NULL)
+ goto negative_success;
+ CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..",
+ dvp, cnp->cn_nameptr, *vpp);
+ SDT_PROBE3(vfs, namecache, lookup, hit, dvp, "..",
+ *vpp);
+ cache_out_ts(ncp, tsp, ticksp);
+ if ((ncp->nc_flag & (NCF_ISDOTDOT | NCF_DTS)) ==
+ NCF_DTS && tsp != NULL) {
+ ncp_ts = __containerof(ncp, struct namecache_ts, nc_nc);
+ *tsp = ncp_ts->nc_dotdottime;
}
+ goto success;
}
hash = cache_get_hash(cnp->cn_nameptr, cnp->cn_namelen, dvp);
@@ -1203,26 +1291,17 @@ retry_dotdot:
LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) {
counter_u64_add(numchecks, 1);
if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen &&
- !bcmp(nc_get_name(ncp), cnp->cn_nameptr, ncp->nc_nlen))
+ !bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen))
break;
}
/* We failed to find an entry */
if (ncp == NULL) {
+ rw_runlock(blp);
SDT_PROBE3(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr,
NULL);
- if ((cnp->cn_flags & MAKEENTRY) == 0) {
- counter_u64_add(nummisszap, 1);
- } else {
- counter_u64_add(nummiss, 1);
- }
- goto unlock;
- }
-
- /* We don't want to have an entry, so dump it */
- if ((cnp->cn_flags & MAKEENTRY) == 0) {
- counter_u64_add(numposzaps, 1);
- goto zap_and_exit;
+ counter_u64_add(nummiss, 1);
+ return (0);
}
/* We found a "positive" match, return the vnode */
@@ -1231,7 +1310,7 @@ retry_dotdot:
*vpp = ncp->nc_vp;
CTR4(KTR_VFS, "cache_lookup(%p, %s) found %p via ncp %p",
dvp, cnp->cn_nameptr, *vpp, ncp);
- SDT_PROBE3(vfs, namecache, lookup, hit, dvp, nc_get_name(ncp),
+ SDT_PROBE3(vfs, namecache, lookup, hit, dvp, ncp->nc_name,
*vpp);
cache_out_ts(ncp, tsp, ticksp);
goto success;
@@ -1249,7 +1328,7 @@ negative_success:
if (ncp->nc_flag & NCF_WHITE)
cnp->cn_flags |= ISWHITEOUT;
SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp,
- nc_get_name(ncp));
+ ncp->nc_name);
cache_out_ts(ncp, tsp, ticksp);
cache_lookup_unlock(blp, dvlp);
return (ENOENT);
@@ -1287,10 +1366,6 @@ success:
}
return (-1);
-unlock:
- cache_lookup_unlock(blp, dvlp);
- return (0);
-
zap_and_exit:
if (blp != NULL)
error = cache_zap_rlocked_bucket(ncp, blp);
@@ -1526,13 +1601,14 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp,
{
struct celockstate cel;
struct namecache *ncp, *n2, *ndd;
- struct namecache_ts *n3;
+ struct namecache_ts *ncp_ts, *n2_ts;
struct nchashhead *ncpp;
struct neglist *neglist;
uint32_t hash;
int flag;
int len;
bool neg_locked;
+ int lnumcache;
CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr);
VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp,
@@ -1617,18 +1693,18 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp,
ncp->nc_flag |= NCF_NEGATIVE;
ncp->nc_dvp = dvp;
if (tsp != NULL) {
- n3 = (struct namecache_ts *)ncp;
- n3->nc_time = *tsp;
- n3->nc_ticks = ticks;
- n3->nc_flag |= NCF_TS;
+ ncp_ts = __containerof(ncp, struct namecache_ts, nc_nc);
+ ncp_ts->nc_time = *tsp;
+ ncp_ts->nc_ticks = ticks;
+ ncp_ts->nc_nc.nc_flag |= NCF_TS;
if (dtsp != NULL) {
- n3->nc_dotdottime = *dtsp;
- n3->nc_flag |= NCF_DTS;
+ ncp_ts->nc_dotdottime = *dtsp;
+ ncp_ts->nc_nc.nc_flag |= NCF_DTS;
}
}
len = ncp->nc_nlen = cnp->cn_namelen;
hash = cache_get_hash(cnp->cn_nameptr, len, dvp);
- strlcpy(nc_get_name(ncp), cnp->cn_nameptr, len + 1);
+ strlcpy(ncp->nc_name, cnp->cn_nameptr, len + 1);
cache_enter_lock(&cel, dvp, vp, hash);
/*
@@ -1640,22 +1716,18 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp,
LIST_FOREACH(n2, ncpp, nc_hash) {
if (n2->nc_dvp == dvp &&
n2->nc_nlen == cnp->cn_namelen &&
- !bcmp(nc_get_name(n2), cnp->cn_nameptr, n2->nc_nlen)) {
+ !bcmp(n2->nc_name, cnp->cn_nameptr, n2->nc_nlen)) {
if (tsp != NULL) {
KASSERT((n2->nc_flag & NCF_TS) != 0,
("no NCF_TS"));
- n3 = (struct namecache_ts *)n2;
- n3->nc_time =
- ((struct namecache_ts *)ncp)->nc_time;
- n3->nc_ticks =
- ((struct namecache_ts *)ncp)->nc_ticks;
+ n2_ts = __containerof(n2, struct namecache_ts, nc_nc);
+ n2_ts->nc_time = ncp_ts->nc_time;
+ n2_ts->nc_ticks = ncp_ts->nc_ticks;
if (dtsp != NULL) {
- n3->nc_dotdottime =
- ((struct namecache_ts *)ncp)->
- nc_dotdottime;
+ n2_ts->nc_dotdottime = ncp_ts->nc_dotdottime;
if (ncp->nc_flag & NCF_NEGATIVE)
mtx_lock(&ncneg_hot.nl_lock);
- n3->nc_flag |= NCF_DTS;
+ n2_ts->nc_nc.nc_flag |= NCF_DTS;
if (ncp->nc_flag & NCF_NEGATIVE)
mtx_unlock(&ncneg_hot.nl_lock);
}
@@ -1676,7 +1748,6 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp,
dvp->v_cache_dd = ncp;
}
- atomic_add_rel_long(&numcache, 1);
if (vp != NULL) {
if (vp->v_type == VDIR) {
if (flag != NCF_ISDOTDOT) {
@@ -1719,17 +1790,18 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp,
*/
if (vp != NULL) {
TAILQ_INSERT_HEAD(&vp->v_cache_dst, ncp, nc_dst);
- SDT_PROBE3(vfs, namecache, enter, done, dvp, nc_get_name(ncp),
+ SDT_PROBE3(vfs, namecache, enter, done, dvp, ncp->nc_name,
vp);
} else {
if (cnp->cn_flags & ISWHITEOUT)
ncp->nc_flag |= NCF_WHITE;
cache_negative_insert(ncp, false);
SDT_PROBE2(vfs, namecache, enter_negative, done, dvp,
- nc_get_name(ncp));
+ ncp->nc_name);
}
cache_enter_unlock(&cel);
- if (numneg * ncnegfactor > numcache)
+ lnumcache = atomic_fetchadd_long(&numcache, 1) + 1;
+ if (numneg * ncnegfactor > lnumcache)
cache_negative_zap_one();
cache_free(ndd);
return;
@@ -1852,7 +1924,7 @@ cache_changesize(int newmaxvnodes)
nchash = new_nchash;
for (i = 0; i <= old_nchash; i++) {
while ((ncp = LIST_FIRST(&old_nchashtbl[i])) != NULL) {
- hash = cache_get_hash(nc_get_name(ncp), ncp->nc_nlen,
+ hash = cache_get_hash(ncp->nc_name, ncp->nc_nlen,
ncp->nc_dvp);
LIST_REMOVE(ncp, nc_hash);
LIST_INSERT_HEAD(NCHHASH(hash), ncp, nc_hash);
@@ -1924,6 +1996,8 @@ cache_purge_negative(struct vnode *vp)
CTR1(KTR_VFS, "cache_purge_negative(%p)", vp);
SDT_PROBE1(vfs, namecache, purge_negative, done, vp);
+ if (LIST_EMPTY(&vp->v_cache_src))
+ return;
TAILQ_INIT(&ncps);
vlp = VP2VNODELOCK(vp);
mtx_lock(vlp);
@@ -2179,9 +2253,9 @@ vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, u_int *buflen)
return (error);
}
*buflen -= ncp->nc_nlen;
- memcpy(buf + *buflen, nc_get_name(ncp), ncp->nc_nlen);
+ memcpy(buf + *buflen, ncp->nc_name, ncp->nc_nlen);
SDT_PROBE3(vfs, namecache, fullpath, hit, ncp->nc_dvp,
- nc_get_name(ncp), vp);
+ ncp->nc_name, vp);
dvp = *vp;
*vp = ncp->nc_dvp;
vref(*vp);
@@ -2363,7 +2437,7 @@ vn_commname(struct vnode *vp, char *buf, u_int buflen)
return (ENOENT);
}
l = min(ncp->nc_nlen, buflen - 1);
- memcpy(buf, nc_get_name(ncp), l);
+ memcpy(buf, ncp->nc_name, l);
mtx_unlock(vlp);
buf[l] = '\0';
return (0);
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 0f82c2b..1e28cf8 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -165,6 +165,9 @@ extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
ssize_t cnt;
int error;
+ if (nbytes > IOSIZE_MAX)
+ return (EINVAL);
+
error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
if (error)
return (error);
@@ -175,10 +178,6 @@ extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
- if (nbytes > IOSIZE_MAX) {
- error = EINVAL;
- goto done;
- }
auio.uio_resid = nbytes;
auio.uio_rw = UIO_WRITE;
auio.uio_segflg = UIO_USERSPACE;
@@ -197,7 +196,9 @@ extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
cnt -= auio.uio_resid;
td->td_retval[0] = cnt;
+#ifdef MAC
done:
+#endif
VOP_UNLOCK(vp, 0);
vn_finished_write(mp);
return (error);
@@ -328,6 +329,9 @@ extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
size_t size, *sizep;
int error;
+ if (nbytes > IOSIZE_MAX)
+ return (EINVAL);
+
vn_lock(vp, LK_SHARED | LK_RETRY);
/*
@@ -344,10 +348,6 @@ extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
- if (nbytes > IOSIZE_MAX) {
- error = EINVAL;
- goto done;
- }
auio.uio_resid = nbytes;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_USERSPACE;
@@ -372,8 +372,9 @@ extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
td->td_retval[0] = cnt;
} else
td->td_retval[0] = size;
-
+#ifdef MAC
done:
+#endif
VOP_UNLOCK(vp, 0);
return (error);
}
@@ -636,6 +637,9 @@ extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
ssize_t cnt;
int error;
+ if (nbytes > IOSIZE_MAX)
+ return (EINVAL);
+
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
auiop = NULL;
@@ -647,10 +651,6 @@ extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
- if (nbytes > IOSIZE_MAX) {
- error = EINVAL;
- goto done;
- }
auio.uio_resid = nbytes;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_USERSPACE;
@@ -674,8 +674,9 @@ extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
td->td_retval[0] = cnt;
} else
td->td_retval[0] = size;
-
+#ifdef MAC
done:
+#endif
VOP_UNLOCK(vp, 0);
return (error);
}
diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h
index f29ad8c..79f6dfe 100644
--- a/sys/mips/include/atomic.h
+++ b/sys/mips/include/atomic.h
@@ -34,6 +34,8 @@
#error this file needs sys/cdefs.h as a prerequisite
#endif
+#include <sys/atomic_common.h>
+
/*
* Note: All the 64-bit atomic operations are only atomic when running
* in 64-bit mode. It is assumed that code compiled for n32 and n64
@@ -337,23 +339,6 @@ atomic_store_rel_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\
ATOMIC_STORE_LOAD(32)
ATOMIC_STORE_LOAD(64)
-#if !defined(__mips_n64) && !defined(__mips_n32)
-void atomic_store_64(__volatile uint64_t *, uint64_t *);
-void atomic_load_64(__volatile uint64_t *, uint64_t *);
-#else
-static __inline void
-atomic_store_64(__volatile uint64_t *p, uint64_t *v)
-{
- *p = *v;
-}
-
-static __inline void
-atomic_load_64(__volatile uint64_t *p, uint64_t *v)
-{
- *v = *p;
-}
-#endif
-
#undef ATOMIC_STORE_LOAD
/*
diff --git a/sys/mips/mips/db_interface.c b/sys/mips/mips/db_interface.c
index 6131095..b3da6f2 100644
--- a/sys/mips/mips/db_interface.c
+++ b/sys/mips/mips/db_interface.c
@@ -150,6 +150,7 @@ db_read_bytes(vm_offset_t addr, size_t size, char *data)
/*
* 'addr' could be a memory-mapped I/O address. Try to
* do atomic load/store in unit of size requested.
+ * size == 8 is only atomic on 64bit or n32 kernel.
*/
if ((size == 2 || size == 4 || size == 8) &&
((addr & (size -1)) == 0) &&
@@ -162,9 +163,8 @@ db_read_bytes(vm_offset_t addr, size_t size, char *data)
*(uint32_t *)data = *(uint32_t *)addr;
break;
case 8:
- atomic_load_64((volatile u_int64_t *)addr,
- (u_int64_t *)data);
- break;
+ *(uint64_t *)data = *(uint64_t *)addr;
+ break;
}
} else {
char *src;
@@ -193,6 +193,7 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data)
/*
* 'addr' could be a memory-mapped I/O address. Try to
* do atomic load/store in unit of size requested.
+ * size == 8 is only atomic on 64bit or n32 kernel.
*/
if ((size == 2 || size == 4 || size == 8) &&
((addr & (size -1)) == 0) &&
@@ -205,9 +206,8 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data)
*(uint32_t *)addr = *(uint32_t *)data;
break;
case 8:
- atomic_store_64((volatile u_int64_t *)addr,
- (u_int64_t *)data);
- break;
+ *(uint64_t *)addr = *(uint64_t *)data;
+ break;
}
} else {
char *dst;
diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S
index 44a5ccb..4df367d 100644
--- a/sys/mips/mips/support.S
+++ b/sys/mips/mips/support.S
@@ -839,75 +839,8 @@ LEAF(atomic_subtract_8)
nop
END(atomic_subtract_8)
-/*
- * atomic 64-bit register read/write assembly language support routines.
- */
-
.set noreorder # Noreorder is default style!
-#if !defined(__mips_n64) && !defined(__mips_n32)
- /*
- * I don't know if these routines have the right number of
- * NOPs in it for all processors. XXX
- *
- * Maybe it would be better to just leave this undefined in that case.
- *
- * XXX These routines are not safe in the case of a TLB miss on a1 or
- * a0 unless the trapframe is 64-bit, which it just isn't with O32.
- * If we take any exception, not just an interrupt, the upper
- * 32-bits will be clobbered. Use only N32 and N64 kernels if you
- * want to use 64-bit registers while interrupts are enabled or
- * with memory operations. Since this isn't even using load-linked
- * and store-conditional, perhaps it should just use two registers
- * instead, as is right and good with the O32 ABI.
- */
-LEAF(atomic_store_64)
- mfc0 t1, MIPS_COP_0_STATUS
- and t2, t1, ~MIPS_SR_INT_IE
- mtc0 t2, MIPS_COP_0_STATUS
- nop
- nop
- nop
- nop
- ld t0, (a1)
- nop
- nop
- sd t0, (a0)
- nop
- nop
- mtc0 t1,MIPS_COP_0_STATUS
- nop
- nop
- nop
- nop
- j ra
- nop
-END(atomic_store_64)
-
-LEAF(atomic_load_64)
- mfc0 t1, MIPS_COP_0_STATUS
- and t2, t1, ~MIPS_SR_INT_IE
- mtc0 t2, MIPS_COP_0_STATUS
- nop
- nop
- nop
- nop
- ld t0, (a0)
- nop
- nop
- sd t0, (a1)
- nop
- nop
- mtc0 t1,MIPS_COP_0_STATUS
- nop
- nop
- nop
- nop
- j ra
- nop
-END(atomic_load_64)
-#endif
-
#if defined(DDB) || defined(DEBUG)
LEAF(kdbpeek)
diff --git a/sys/modules/dtb/rpi/Makefile b/sys/modules/dtb/rpi/Makefile
index 767427c..2feb371 100644
--- a/sys/modules/dtb/rpi/Makefile
+++ b/sys/modules/dtb/rpi/Makefile
@@ -2,4 +2,11 @@
# DTS files for the Raspberry Pi-B
DTS=rpi.dts rpi2.dts
+LINKS= \
+ ${DTBDIR}/rpi.dtb ${DTBDIR}/bcm2835-rpi-b.dtb \
+ ${DTBDIR}/rpi.dtb ${DTBDIR}/bcm2835-rpi-b-rev2.dtb \
+ ${DTBDIR}/rpi.dtb ${DTBDIR}/bcm2835-rpi-b-plus.dtb \
+ ${DTBDIR}/rpi.dtb ${DTBDIR}/bcm2835-rpi-zero.dtb \
+ ${DTBDIR}/rpi2.dtb ${DTBDIR}/bcm2836-rpi-2-b.dtb
+
.include <bsd.dtb.mk>
diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c
index f830b06..5c1dd55 100644
--- a/sys/net/if_vxlan.c
+++ b/sys/net/if_vxlan.c
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <net/if_var.h>
#include <net/if_clone.h>
#include <net/if_dl.h>
+#include <net/if_media.h>
#include <net/if_types.h>
#include <net/if_vxlan.h>
#include <net/netisr.h>
@@ -177,6 +178,7 @@ struct vxlan_softc {
uint8_t vxl_hwaddr[ETHER_ADDR_LEN];
int vxl_mc_ifindex;
struct ifnet *vxl_mc_ifp;
+ struct ifmedia vxl_media;
char vxl_mc_ifname[IFNAMSIZ];
LIST_ENTRY(vxlan_softc) vxl_entry;
LIST_ENTRY(vxlan_softc) vxl_ifdetach_list;
@@ -342,6 +344,8 @@ static void vxlan_clone_destroy(struct ifnet *);
static uint32_t vxlan_mac_hash(struct vxlan_softc *, const uint8_t *);
static void vxlan_fakeaddr(struct vxlan_softc *);
+static int vxlan_media_change(struct ifnet *);
+static void vxlan_media_status(struct ifnet *, struct ifmediareq *);
static int vxlan_sockaddr_cmp(const union vxlan_sockaddr *,
const struct sockaddr *);
@@ -778,7 +782,7 @@ vxlan_ftable_entry_lookup(struct vxlan_softc *sc, const uint8_t *mac)
hash = VXLAN_SC_FTABLE_HASH(sc, mac);
LIST_FOREACH(fe, &sc->vxl_ftable[hash], vxlfe_hash) {
- dir = vxlan_ftable_addr_cmp(fe->vxlfe_mac, mac);
+ dir = vxlan_ftable_addr_cmp(mac, fe->vxlfe_mac);
if (dir == 0)
return (fe);
if (dir > 0)
@@ -1655,6 +1659,7 @@ vxlan_init(void *xsc)
vxlan_timer, sc);
VXLAN_WUNLOCK(sc);
+ if_link_state_change(ifp, LINK_STATE_UP);
out:
vxlan_init_complete(sc);
}
@@ -1710,6 +1715,7 @@ vxlan_teardown_locked(struct vxlan_softc *sc)
sc->vxl_sock = NULL;
VXLAN_WUNLOCK(sc);
+ if_link_state_change(ifp, LINK_STATE_DOWN);
if (vso != NULL) {
vxlan_socket_remove_softc(vso, sc);
@@ -2219,6 +2225,12 @@ vxlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCSIFFLAGS:
error = vxlan_ioctl_ifflags(sc);
break;
+
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &sc->vxl_media, cmd);
+ break;
+
default:
error = ether_ioctl(ifp, cmd, data);
break;
@@ -2685,6 +2697,10 @@ vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
ifp->if_transmit = vxlan_transmit;
ifp->if_qflush = vxlan_qflush;
+ ifmedia_init(&sc->vxl_media, 0, vxlan_media_change, vxlan_media_status);
+ ifmedia_add(&sc->vxl_media, IFM_ETHER | IFM_AUTO, 0, NULL);
+ ifmedia_set(&sc->vxl_media, IFM_ETHER | IFM_AUTO);
+
vxlan_fakeaddr(sc);
ether_ifattach(ifp, sc->vxl_hwaddr);
@@ -2711,6 +2727,7 @@ vxlan_clone_destroy(struct ifnet *ifp)
ether_ifdetach(ifp);
if_free(ifp);
+ ifmedia_removeall(&sc->vxl_media);
vxlan_ftable_fini(sc);
@@ -2771,6 +2788,22 @@ vxlan_fakeaddr(struct vxlan_softc *sc)
}
static int
+vxlan_media_change(struct ifnet *ifp)
+{
+
+ /* Ignore. */
+ return (0);
+}
+
+static void
+vxlan_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+
+ ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
+ ifmr->ifm_active = IFM_ETHER | IFM_FDX;
+}
+
+static int
vxlan_sockaddr_cmp(const union vxlan_sockaddr *vxladdr,
const struct sockaddr *sa)
{
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h
index af35c84..6d171f4 100644
--- a/sys/netinet/icmp6.h
+++ b/sys/netinet/icmp6.h
@@ -626,7 +626,7 @@ struct icmp6stat {
uint64_t icp6s_nd_badopt; /* bad ND options */
uint64_t icp6s_badns; /* bad neighbor solicitation */
uint64_t icp6s_badna; /* bad neighbor advertisement */
- uint64_t icp6s_badrs; /* bad router advertisement */
+ uint64_t icp6s_badrs; /* bad router solicitation */
uint64_t icp6s_badra; /* bad router advertisement */
uint64_t icp6s_badredirect; /* bad redirect message */
};
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 69fc6cb..9272ff3 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1686,25 +1686,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
to.to_tsecr = 0;
}
/*
- * If timestamps were negotiated during SYN/ACK they should
- * appear on every segment during this session and vice versa.
- */
- if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) {
- if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
- log(LOG_DEBUG, "%s; %s: Timestamp missing, "
- "no action\n", s, __func__);
- free(s, M_TCPLOG);
- }
- }
- if (!(tp->t_flags & TF_RCVD_TSTMP) && (to.to_flags & TOF_TS)) {
- if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
- log(LOG_DEBUG, "%s; %s: Timestamp not expected, "
- "no action\n", s, __func__);
- free(s, M_TCPLOG);
- }
- }
-
- /*
* Process options only when we get SYN/ACK back. The SYN case
* for incoming connections is handled in tcp_syncache.
* According to RFC1323 the window field in a SYN (i.e., a <SYN>
@@ -1735,6 +1716,25 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
}
/*
+ * If timestamps were negotiated during SYN/ACK they should
+ * appear on every segment during this session and vice versa.
+ */
+ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) {
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Timestamp missing, "
+ "no action\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
+ }
+ if (!(tp->t_flags & TF_RCVD_TSTMP) && (to.to_flags & TOF_TS)) {
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Timestamp not expected, "
+ "no action\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
+ }
+
+ /*
* Header prediction: check for the two common cases
* of a uni-directional data xfer. If the packet has
* no control flags, is in-sequence, the window didn't
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 3eff27c..f3d1e3e 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1275,12 +1275,13 @@ send:
* NOTE: since TCP options buffer doesn't point into
* mbuf's data, calculate offset and use it.
*/
- if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th,
- (u_char *)(th + 1) + (to.to_signature - opt)) != 0) {
+ if (!TCPMD5_ENABLED() || (error = TCPMD5_OUTPUT(m, th,
+ (u_char *)(th + 1) + (to.to_signature - opt))) != 0) {
/*
* Do not send segment if the calculation of MD5
* digest has failed.
*/
+ m_freem(m);
goto out;
}
}
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index df1f722..a8dd227 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -225,6 +225,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
IP6STAT_INC(ip6s_reassembled);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
*offp = offset;
+ m->m_flags |= M_FRAGMENTED;
return (ip6f->ip6f_nxt);
}
@@ -825,5 +826,6 @@ ip6_deletefraghdr(struct mbuf *m, int offset, int wait)
m_cat(m, t);
}
+ m->m_flags |= M_FRAGMENTED;
return (0);
}
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index a94ed8f..790c431 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2249,6 +2249,10 @@ icmp6_redirect_input(struct mbuf *m, int off)
if (!V_icmp6_rediraccept)
goto freeit;
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
#ifndef PULLDOWN_TEST
IP6_EXTHDR_CHECK(m, off, icmp6len,);
nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h
index e913c0a..140cd30 100644
--- a/sys/netinet6/in6.h
+++ b/sys/netinet6/in6.h
@@ -653,6 +653,7 @@ struct ip6_mtuinfo {
#define M_LOOP M_PROTO6
#define M_AUTHIPDGM M_PROTO7
#define M_RTALERT_MLD M_PROTO8
+#define M_FRAGMENTED M_PROTO9 /* contained fragment header */
#ifdef _KERNEL
struct cmsghdr;
diff --git a/sys/netinet6/ip6_id.c b/sys/netinet6/ip6_id.c
index 9a8086f..4c85278 100644
--- a/sys/netinet6/ip6_id.c
+++ b/sys/netinet6/ip6_id.c
@@ -63,7 +63,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $OpenBSD: ip_id.c,v 1.6 2002/03/15 18:19:52 millert Exp $
+ * $OpenBSD: ip6_id.c,v 1.2 2003/12/10 07:21:01 itojun Exp $
*/
#include <sys/cdefs.h>
@@ -230,15 +230,12 @@ static u_int32_t
randomid(struct randomtab *p)
{
int i, n;
- u_int32_t tmp;
if (p->ru_counter >= p->ru_max || time_uptime > p->ru_reseed)
initid(p);
- tmp = arc4random();
-
/* Skip a random number of ids */
- n = tmp & 0x3; tmp = tmp >> 2;
+ n = arc4random() & 0x3;
if (p->ru_counter + n >= p->ru_max)
initid(p);
@@ -249,7 +246,7 @@ randomid(struct randomtab *p)
p->ru_counter += i;
- return (p->ru_seed ^ pmod(p->ru_g, p->ru_seed2 ^ p->ru_x, p->ru_n)) |
+ return (p->ru_seed ^ pmod(p->ru_g, p->ru_seed2 + p->ru_x, p->ru_n)) |
p->ru_msb;
}
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 8bbdf85..31199a2 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -135,6 +135,10 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
struct sockaddr_dl proxydl;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
rflag = 0;
@@ -629,6 +633,10 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
int lladdr_off;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 193ce99..c5ce353 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -137,6 +137,10 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
if (!V_ip6_forwarding || ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV)
goto freeit;
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
/* Sanity checks */
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
@@ -227,6 +231,10 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV))
goto freeit;
+ /* RFC 6980: Nodes MUST silently ignore fragments */
+ if(m->m_flags & M_FRAGMENTED)
+ goto freeit;
+
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
diff --git a/sys/powerpc/include/atomic.h b/sys/powerpc/include/atomic.h
index cd9fa0d..eb992e0 100644
--- a/sys/powerpc/include/atomic.h
+++ b/sys/powerpc/include/atomic.h
@@ -36,6 +36,8 @@
#error this file needs sys/cdefs.h as a prerequisite
#endif
+#include <sys/atomic_common.h>
+
/*
* The __ATOMIC_REL/ACQ() macros provide memory barriers only in conjunction
* with the atomic lXarx/stXcx. sequences below. They are not exposed outside
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index 95fb554..dadcd7f 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -299,9 +299,7 @@ trap(struct trapframe *frame)
inst = fuword32((const void *)frame->srr0);
if (inst == 0x0FFFDDDD &&
dtrace_pid_probe_ptr != NULL) {
- struct reg regs;
- fill_regs(td, &regs);
- (*dtrace_pid_probe_ptr)(&regs);
+ (*dtrace_pid_probe_ptr)(frame);
break;
}
#endif
diff --git a/sys/riscv/include/atomic.h b/sys/riscv/include/atomic.h
index 33f3d5b..14b7524 100644
--- a/sys/riscv/include/atomic.h
+++ b/sys/riscv/include/atomic.h
@@ -37,6 +37,8 @@
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
+#include <sys/atomic_common.h>
+
#define fence() __asm __volatile("fence" ::: "memory");
#define mb() fence()
#define rmb() fence()
diff --git a/sys/security/audit/audit.c b/sys/security/audit/audit.c
index f2a01dd..399bec9 100644
--- a/sys/security/audit/audit.c
+++ b/sys/security/audit/audit.c
@@ -91,7 +91,7 @@ static SYSCTL_NODE(_security, OID_AUTO, audit, CTLFLAG_RW, 0,
*
* Define the audit control flags.
*/
-int audit_enabled;
+int __read_frequently audit_enabled;
int audit_suspended;
/*
diff --git a/sys/sparc64/include/atomic.h b/sys/sparc64/include/atomic.h
index b2fd8cc..3332edf 100644
--- a/sys/sparc64/include/atomic.h
+++ b/sys/sparc64/include/atomic.h
@@ -37,6 +37,8 @@
#define wmb() mb()
#define rmb() mb()
+#include <sys/atomic_common.h>
+
/* Userland needs different ASI's. */
#ifdef _KERNEL
#define __ASI_ATOMIC ASI_N
@@ -254,11 +256,6 @@ atomic_fcmpset_rel_ ## name(volatile ptype p, vtype *ep, vtype s) \
} \
\
static __inline vtype \
-atomic_load_ ## name(volatile ptype p) \
-{ \
- return ((vtype)atomic_cas((p), 0, 0, sz)); \
-} \
-static __inline vtype \
atomic_load_acq_ ## name(volatile ptype p) \
{ \
return ((vtype)atomic_cas_acq((p), 0, 0, sz)); \
diff --git a/sys/sys/atomic_common.h b/sys/sys/atomic_common.h
new file mode 100644
index 0000000..9aa30fa
--- /dev/null
+++ b/sys/sys/atomic_common.h
@@ -0,0 +1,73 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2017 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+#ifndef _SYS_ATOMIC_COMMON_H_
+#define _SYS_ATOMIC_COMMON_H_
+
+#ifndef _MACHINE_ATOMIC_H_
+#error do not include this header, use machine/atomic.h
+#endif
+
+#define atomic_load_char(p) (*(volatile u_char *)(p))
+#define atomic_load_short(p) (*(volatile u_short *)(p))
+#define atomic_load_int(p) (*(volatile u_int *)(p))
+#define atomic_load_long(p) (*(volatile u_long *)(p))
+#define atomic_load_ptr(p) (*(volatile uintptr_t*)(p))
+#define atomic_load_8(p) (*(volatile uint8_t *)(p))
+#define atomic_load_16(p) (*(volatile uint16_t *)(p))
+#define atomic_load_32(p) (*(volatile uint32_t *)(p))
+#ifdef _LP64
+#define atomic_load_64(p) (*(volatile uint64_t *)(p))
+#endif
+
+#define atomic_store_char(p, v) \
+ (*(volatile u_char *)(p) = (u_char)(v))
+#define atomic_store_short(p, v) \
+ (*(volatile u_short *)(p) = (u_short)(v))
+#define atomic_store_int(p, v) \
+ (*(volatile u_int *)(p) = (u_int)(v))
+#define atomic_store_long(p, v) \
+ (*(volatile u_long *)(p) = (u_long)(v))
+#define atomic_store_ptr(p, v) \
+ (*(uintptr_t *)(p) = (uintptr_t)(v))
+#define atomic_store_8(p, v) \
+ (*(volatile uint8_t *)(p) = (uint8_t)(v))
+#define atomic_store_16(p, v) \
+ (*(volatile uint16_t *)(p) = (uint16_t)(v))
+#define atomic_store_32(p, v) \
+ (*(volatile uint32_t *)(p) = (uint32_t)(v))
+#ifdef _LP64
+#define atomic_store_64(p, v) \
+ (*(volatile uint64_t *)(p) = (uint64_t)(v))
+#endif
+
+#endif
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 3ebb431..4a48cb4 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -491,6 +491,7 @@ struct resource_spec {
int rid;
int flags;
};
+#define RESOURCE_SPEC_END {-1, 0, 0}
int bus_alloc_resources(device_t dev, struct resource_spec *rs,
struct resource **res);
diff --git a/sys/sys/copyright.h b/sys/sys/copyright.h
index f0dc83f..9b35e47 100644
--- a/sys/sys/copyright.h
+++ b/sys/sys/copyright.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (C) 1992-2017 The FreeBSD Project. All rights reserved.
+ * Copyright (C) 1992-2018 The FreeBSD Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,7 +34,7 @@
/* FreeBSD */
#define COPYRIGHT_FreeBSD \
- "Copyright (c) 1992-2017 The FreeBSD Project.\n"
+ "Copyright (c) 1992-2018 The FreeBSD Project.\n"
/* Foundation */
#define TRADEMARK_Foundation \
diff --git a/sys/sys/dtrace_bsd.h b/sys/sys/dtrace_bsd.h
index f46b900..09f69e7 100644
--- a/sys/sys/dtrace_bsd.h
+++ b/sys/sys/dtrace_bsd.h
@@ -37,7 +37,6 @@ struct trapframe;
struct thread;
struct vattr;
struct vnode;
-struct reg;
int dtrace_trap(struct trapframe *, u_int);
@@ -58,9 +57,9 @@ typedef void (*dtrace_doubletrap_func_t)(void);
extern dtrace_doubletrap_func_t dtrace_doubletrap_func;
/* Pid provider hooks */
-typedef int (*dtrace_pid_probe_ptr_t)(struct reg *);
+typedef int (*dtrace_pid_probe_ptr_t)(struct trapframe *);
extern dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr;
-typedef int (*dtrace_return_probe_ptr_t)(struct reg *);
+typedef int (*dtrace_return_probe_ptr_t)(struct trapframe *);
extern dtrace_return_probe_ptr_t dtrace_return_probe_ptr;
/* Virtual time hook function type. */
diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h
index 164b0f0..2240a00 100644
--- a/sys/sys/eventhandler.h
+++ b/sys/sys/eventhandler.h
@@ -141,12 +141,21 @@ do { \
if ((_el = eventhandler_find_list(#name)) != NULL) \
eventhandler_deregister(_el, tag); \
} while(0)
-
+
+#define EVENTHANDLER_DEREGISTER_NOWAIT(name, tag) \
+do { \
+ struct eventhandler_list *_el; \
+ \
+ if ((_el = eventhandler_find_list(#name)) != NULL) \
+ eventhandler_deregister_nowait(_el, tag); \
+} while(0)
eventhandler_tag eventhandler_register(struct eventhandler_list *list,
const char *name, void *func, void *arg, int priority);
void eventhandler_deregister(struct eventhandler_list *list,
eventhandler_tag tag);
+void eventhandler_deregister_nowait(struct eventhandler_list *list,
+ eventhandler_tag tag);
struct eventhandler_list *eventhandler_find_list(const char *name);
void eventhandler_prune_list(struct eventhandler_list *list);
@@ -277,4 +286,15 @@ typedef void (*ada_probe_veto_fn)(void *, struct cam_path *,
struct ata_params *, int *);
EVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn);
+/* newbus device events */
+enum evhdev_detach {
+ EVHDEV_DETACH_BEGIN, /* Before detach() is called */
+ EVHDEV_DETACH_COMPLETE, /* After detach() returns 0 */
+ EVHDEV_DETACH_FAILED /* After detach() returns err */
+};
+typedef void (*device_attach_fn)(void *, device_t);
+typedef void (*device_detach_fn)(void *, device_t, enum evhdev_detach);
+EVENTHANDLER_DECLARE(device_attach, device_attach_fn);
+EVENTHANDLER_DECLARE(device_detach, device_detach_fn);
+
#endif /* _SYS_EVENTHANDLER_H_ */
diff --git a/sys/sys/kdb.h b/sys/sys/kdb.h
index 49c8c32..1e68c39 100644
--- a/sys/sys/kdb.h
+++ b/sys/sys/kdb.h
@@ -59,7 +59,7 @@ struct kdb_dbbe {
}; \
DATA_SET(kdb_dbbe_set, name##_dbbe)
-extern int kdb_active; /* Non-zero while in debugger. */
+extern u_char kdb_active; /* Non-zero while in debugger. */
extern int debugger_on_panic; /* enter the debugger on panic. */
extern struct kdb_dbbe *kdb_dbbe; /* Default debugger backend or NULL. */
extern struct trapframe *kdb_frame; /* Frame to kdb_trap(). */
diff --git a/sys/sys/lock.h b/sys/sys/lock.h
index cc34cb4..4c5d60b 100644
--- a/sys/sys/lock.h
+++ b/sys/sys/lock.h
@@ -137,9 +137,13 @@ struct lock_class {
* operations. Otherwise, use default values to avoid the unneeded bloat.
*/
#if LOCK_DEBUG > 0
+#define LOCK_FILE_LINE_ARG_DEF , const char *file, int line
+#define LOCK_FILE_LINE_ARG , file, line
#define LOCK_FILE __FILE__
#define LOCK_LINE __LINE__
#else
+#define LOCK_FILE_LINE_ARG_DEF
+#define LOCK_FILE_LINE_ARG
#define LOCK_FILE NULL
#define LOCK_LINE 0
#endif
@@ -226,6 +230,13 @@ lock_delay_arg_init(struct lock_delay_arg *la, struct lock_delay_config *lc)
la->spin_cnt = 0;
}
+#define lock_delay_spin(n) do { \
+ u_int _i; \
+ \
+ for (_i = (n); _i > 0; _i--) \
+ cpu_spinwait(); \
+} while (0)
+
#define LOCK_DELAY_SYSINIT(func) \
SYSINIT(func##_ld, SI_SUB_LOCK, SI_ORDER_ANY, func, NULL)
diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h
index 0097d08..5e19407 100644
--- a/sys/sys/mutex.h
+++ b/sys/sys/mutex.h
@@ -65,15 +65,11 @@
* State bits kept in mutex->mtx_lock, for the DEFAULT lock type. None of this,
* with the exception of MTX_UNOWNED, applies to spin locks.
*/
+#define MTX_UNOWNED 0x00000000 /* Cookie for free mutex */
#define MTX_RECURSED 0x00000001 /* lock recursed (for MTX_DEF only) */
#define MTX_CONTESTED 0x00000002 /* lock contested (for MTX_DEF only) */
-#define MTX_UNOWNED 0x00000004 /* Cookie for free mutex */
-#define MTX_FLAGMASK (MTX_RECURSED | MTX_CONTESTED | MTX_UNOWNED)
-
-/*
- * Value stored in mutex->mtx_lock to denote a destroyed mutex.
- */
-#define MTX_DESTROYED (MTX_CONTESTED | MTX_UNOWNED)
+#define MTX_DESTROYED 0x00000004 /* lock destroyed */
+#define MTX_FLAGMASK (MTX_RECURSED | MTX_CONTESTED | MTX_DESTROYED)
/*
* Prototypes
@@ -95,22 +91,27 @@ void _mtx_init(volatile uintptr_t *c, const char *name, const char *type,
int opts);
void _mtx_destroy(volatile uintptr_t *c);
void mtx_sysinit(void *arg);
+int _mtx_trylock_flags_int(struct mtx *m, int opts LOCK_FILE_LINE_ARG_DEF);
int _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file,
int line);
void mutex_init(void);
#if LOCK_DEBUG > 0
-void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
- int opts, const char *file, int line);
-void __mtx_unlock_sleep(volatile uintptr_t *c, int opts, const char *file,
- int line);
+void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, int opts,
+ const char *file, int line);
+void __mtx_unlock_sleep(volatile uintptr_t *c, uintptr_t v, int opts,
+ const char *file, int line);
#else
-void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid);
-void __mtx_unlock_sleep(volatile uintptr_t *c);
+void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v);
+void __mtx_unlock_sleep(volatile uintptr_t *c, uintptr_t v);
#endif
#ifdef SMP
-void _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
- int opts, const char *file, int line);
+#if LOCK_DEBUG > 0
+void _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, int opts,
+ const char *file, int line);
+#else
+void _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v);
+#endif
#endif
void __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file,
int line);
@@ -127,11 +128,31 @@ void __mtx_assert(const volatile uintptr_t *c, int what, const char *file,
int line);
#endif
void thread_lock_flags_(struct thread *, int, const char *, int);
+#if LOCK_DEBUG > 0
+void _thread_lock(struct thread *td, int opts, const char *file, int line);
+#else
+void _thread_lock(struct thread *);
+#endif
+#if defined(LOCK_PROFILING) || defined(KLD_MODULE)
#define thread_lock(tdp) \
thread_lock_flags_((tdp), 0, __FILE__, __LINE__)
+#elif LOCK_DEBUG > 0
+#define thread_lock(tdp) \
+ _thread_lock((tdp), 0, __FILE__, __LINE__)
+#else
+#define thread_lock(tdp) \
+ _thread_lock((tdp))
+#endif
+
+#if LOCK_DEBUG > 0
#define thread_lock_flags(tdp, opt) \
thread_lock_flags_((tdp), (opt), __FILE__, __LINE__)
+#else
+#define thread_lock_flags(tdp, opt) \
+ _thread_lock(tdp)
+#endif
+
#define thread_unlock(tdp) \
mtx_unlock_spin((tdp)->td_lock)
@@ -147,19 +168,24 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
#define mtx_trylock_flags_(m, o, f, l) \
_mtx_trylock_flags_(&(m)->mtx_lock, o, f, l)
#if LOCK_DEBUG > 0
-#define _mtx_lock_sleep(m, v, t, o, f, l) \
- __mtx_lock_sleep(&(m)->mtx_lock, v, t, o, f, l)
-#define _mtx_unlock_sleep(m, o, f, l) \
- __mtx_unlock_sleep(&(m)->mtx_lock, o, f, l)
+#define _mtx_lock_sleep(m, v, o, f, l) \
+ __mtx_lock_sleep(&(m)->mtx_lock, v, o, f, l)
+#define _mtx_unlock_sleep(m, v, o, f, l) \
+ __mtx_unlock_sleep(&(m)->mtx_lock, v, o, f, l)
#else
-#define _mtx_lock_sleep(m, v, t, o, f, l) \
- __mtx_lock_sleep(&(m)->mtx_lock, v, t)
-#define _mtx_unlock_sleep(m, o, f, l) \
- __mtx_unlock_sleep(&(m)->mtx_lock)
+#define _mtx_lock_sleep(m, v, o, f, l) \
+ __mtx_lock_sleep(&(m)->mtx_lock, v)
+#define _mtx_unlock_sleep(m, v, o, f, l) \
+ __mtx_unlock_sleep(&(m)->mtx_lock, v)
#endif
#ifdef SMP
-#define _mtx_lock_spin(m, v, t, o, f, l) \
- _mtx_lock_spin_cookie(&(m)->mtx_lock, v, t, o, f, l)
+#if LOCK_DEBUG > 0
+#define _mtx_lock_spin(m, v, o, f, l) \
+ _mtx_lock_spin_cookie(&(m)->mtx_lock, v, o, f, l)
+#else
+#define _mtx_lock_spin(m, v, o, f, l) \
+ _mtx_lock_spin_cookie(&(m)->mtx_lock, v)
+#endif
#endif
#define _mtx_lock_flags(m, o, f, l) \
__mtx_lock_flags(&(m)->mtx_lock, o, f, l)
@@ -195,6 +221,9 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
#define _mtx_release_lock_quick(mp) \
atomic_store_rel_ptr(&(mp)->mtx_lock, MTX_UNOWNED)
+#define _mtx_release_lock_fetch(mp, vp) \
+ atomic_fcmpset_rel_ptr(&(mp)->mtx_lock, (vp), MTX_UNOWNED)
+
/*
* Full lock operations that are suitable to be inlined in non-debug
* kernels. If the lock cannot be acquired or released trivially then
@@ -208,7 +237,7 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
\
if (__predict_false(LOCKSTAT_PROFILE_ENABLED(adaptive__acquire) ||\
!_mtx_obtain_lock_fetch((mp), &_v, _tid))) \
- _mtx_lock_sleep((mp), _v, _tid, (opts), (file), (line));\
+ _mtx_lock_sleep((mp), _v, (opts), (file), (line)); \
} while (0)
/*
@@ -223,11 +252,9 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
uintptr_t _v = MTX_UNOWNED; \
\
spinlock_enter(); \
- if (!_mtx_obtain_lock_fetch((mp), &_v, _tid)) \
- _mtx_lock_spin((mp), _v, _tid, (opts), (file), (line)); \
- else \
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(spin__acquire, \
- mp, 0, 0, file, line); \
+ if (__predict_false(LOCKSTAT_PROFILE_ENABLED(spin__acquire) || \
+ !_mtx_obtain_lock_fetch((mp), &_v, _tid))) \
+ _mtx_lock_spin((mp), _v, (opts), (file), (line)); \
} while (0)
#define __mtx_trylock_spin(mp, tid, opts, file, line) __extension__ ({ \
uintptr_t _tid = (uintptr_t)(tid); \
@@ -274,11 +301,11 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
/* Unlock a normal mutex. */
#define __mtx_unlock(mp, tid, opts, file, line) do { \
- uintptr_t _tid = (uintptr_t)(tid); \
+ uintptr_t _v = (uintptr_t)(tid); \
\
if (__predict_false(LOCKSTAT_PROFILE_ENABLED(adaptive__release) ||\
- !_mtx_release_lock((mp), _tid))) \
- _mtx_unlock_sleep((mp), (opts), (file), (line)); \
+ !_mtx_release_lock_fetch((mp), &_v))) \
+ _mtx_unlock_sleep((mp), _v, (opts), (file), (line)); \
} while (0)
/*
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index a27e5d1..cce2d28 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -182,6 +182,8 @@ struct td_sched;
struct thread;
struct trapframe;
struct turnstile;
+struct vm_map;
+struct vm_map_entry;
/*
* XXX: Does this belong in resource.h or resourcevar.h instead?
@@ -1002,6 +1004,8 @@ void fork_exit(void (*)(void *, struct trapframe *), void *,
struct trapframe *);
void fork_return(struct thread *, struct trapframe *);
int inferior(struct proc *p);
+void kern_proc_vmmap_resident(struct vm_map *map, struct vm_map_entry *entry,
+ int *resident_count, bool *super);
void kern_yield(int);
void kick_proc0(void);
void killjobc(void);
diff --git a/sys/sys/rwlock.h b/sys/sys/rwlock.h
index cd88825..2bf31ec 100644
--- a/sys/sys/rwlock.h
+++ b/sys/sys/rwlock.h
@@ -92,6 +92,9 @@
#define _rw_write_unlock(rw, tid) \
atomic_cmpset_rel_ptr(&(rw)->rw_lock, (tid), RW_UNLOCKED)
+#define _rw_write_unlock_fetch(rw, tid) \
+ atomic_fcmpset_rel_ptr(&(rw)->rw_lock, (tid), RW_UNLOCKED)
+
/*
* Full lock operations that are suitable to be inlined in non-debug
* kernels. If the lock cannot be acquired or released trivially then
@@ -105,16 +108,16 @@
\
if (__predict_false(LOCKSTAT_PROFILE_ENABLED(rw__acquire) || \
!_rw_write_lock_fetch((rw), &_v, _tid))) \
- _rw_wlock_hard((rw), _v, _tid, (file), (line)); \
+ _rw_wlock_hard((rw), _v, (file), (line)); \
} while (0)
/* Release a write lock. */
#define __rw_wunlock(rw, tid, file, line) do { \
- uintptr_t _tid = (uintptr_t)(tid); \
+ uintptr_t _v = (uintptr_t)(tid); \
\
if (__predict_false(LOCKSTAT_PROFILE_ENABLED(rw__release) || \
- !_rw_write_unlock((rw), _tid))) \
- _rw_wunlock_hard((rw), _tid, (file), (line)); \
+ !_rw_write_unlock_fetch((rw), &_v))) \
+ _rw_wunlock_hard((rw), _v, (file), (line)); \
} while (0)
/*
@@ -128,16 +131,22 @@ void rw_sysinit(void *arg);
void rw_sysinit_flags(void *arg);
int _rw_wowned(const volatile uintptr_t *c);
void _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line);
+int __rw_try_wlock_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF);
int __rw_try_wlock(volatile uintptr_t *c, const char *file, int line);
void _rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line);
+void __rw_rlock_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF);
void __rw_rlock(volatile uintptr_t *c, const char *file, int line);
+int __rw_try_rlock_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF);
int __rw_try_rlock(volatile uintptr_t *c, const char *file, int line);
+void _rw_runlock_cookie_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF);
void _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line);
-void __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v, uintptr_t tid,
- const char *file, int line);
-void __rw_wunlock_hard(volatile uintptr_t *c, uintptr_t tid,
- const char *file, int line);
+void __rw_wlock_hard(volatile uintptr_t *c, uintptr_t v
+ LOCK_FILE_LINE_ARG_DEF);
+void __rw_wunlock_hard(volatile uintptr_t *c, uintptr_t v
+ LOCK_FILE_LINE_ARG_DEF);
+int __rw_try_upgrade_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF);
int __rw_try_upgrade(volatile uintptr_t *c, const char *file, int line);
+void __rw_downgrade_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF);
void __rw_downgrade(volatile uintptr_t *c, const char *file, int line);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
void __rw_assert(const volatile uintptr_t *c, int what, const char *file,
@@ -163,20 +172,38 @@ void __rw_assert(const volatile uintptr_t *c, int what, const char *file,
__rw_try_wlock(&(rw)->rw_lock, f, l)
#define _rw_wunlock(rw, f, l) \
_rw_wunlock_cookie(&(rw)->rw_lock, f, l)
-#define _rw_rlock(rw, f, l) \
- __rw_rlock(&(rw)->rw_lock, f, l)
#define _rw_try_rlock(rw, f, l) \
__rw_try_rlock(&(rw)->rw_lock, f, l)
+#if LOCK_DEBUG > 0
+#define _rw_rlock(rw, f, l) \
+ __rw_rlock(&(rw)->rw_lock, f, l)
#define _rw_runlock(rw, f, l) \
_rw_runlock_cookie(&(rw)->rw_lock, f, l)
-#define _rw_wlock_hard(rw, v, t, f, l) \
- __rw_wlock_hard(&(rw)->rw_lock, v, t, f, l)
-#define _rw_wunlock_hard(rw, t, f, l) \
- __rw_wunlock_hard(&(rw)->rw_lock, t, f, l)
+#else
+#define _rw_rlock(rw, f, l) \
+ __rw_rlock_int((struct rwlock *)rw)
+#define _rw_runlock(rw, f, l) \
+ _rw_runlock_cookie_int((struct rwlock *)rw)
+#endif
+#if LOCK_DEBUG > 0
+#define _rw_wlock_hard(rw, v, f, l) \
+ __rw_wlock_hard(&(rw)->rw_lock, v, f, l)
+#define _rw_wunlock_hard(rw, v, f, l) \
+ __rw_wunlock_hard(&(rw)->rw_lock, v, f, l)
#define _rw_try_upgrade(rw, f, l) \
__rw_try_upgrade(&(rw)->rw_lock, f, l)
#define _rw_downgrade(rw, f, l) \
__rw_downgrade(&(rw)->rw_lock, f, l)
+#else
+#define _rw_wlock_hard(rw, v, f, l) \
+ __rw_wlock_hard(&(rw)->rw_lock, v)
+#define _rw_wunlock_hard(rw, v, f, l) \
+ __rw_wunlock_hard(&(rw)->rw_lock, v)
+#define _rw_try_upgrade(rw, f, l) \
+ __rw_try_upgrade_int(rw)
+#define _rw_downgrade(rw, f, l) \
+ __rw_downgrade_int(rw)
+#endif
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
#define _rw_assert(rw, w, f, l) \
__rw_assert(&(rw)->rw_lock, w, f, l)
diff --git a/sys/sys/sdt.h b/sys/sys/sdt.h
index c680ea8..6771bf9 100644
--- a/sys/sys/sdt.h
+++ b/sys/sys/sdt.h
@@ -80,13 +80,14 @@
#include <sys/cdefs.h>
#include <sys/linker_set.h>
+extern volatile bool sdt_probes_enabled;
+
#ifndef KDTRACE_HOOKS
#define SDT_PROVIDER_DEFINE(prov)
#define SDT_PROVIDER_DECLARE(prov)
#define SDT_PROBE_DEFINE(prov, mod, func, name)
#define SDT_PROBE_DECLARE(prov, mod, func, name)
-#define SDT_PROBE_ENABLED(prov, mod, func, name) 0
#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4)
#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype)
@@ -161,14 +162,13 @@ SET_DECLARE(sdt_argtypes_set, struct sdt_argtype);
#define SDT_PROBE_DECLARE(prov, mod, func, name) \
extern struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1]
-#define SDT_PROBE_ENABLED(prov, mod, func, name) \
- __predict_false((sdt_##prov##_##mod##_##func##_##name->id))
-
#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) do { \
- if (__predict_false(sdt_##prov##_##mod##_##func##_##name->id)) \
+ if (__predict_false(sdt_probes_enabled)) { \
+ if (__predict_false(sdt_##prov##_##mod##_##func##_##name->id)) \
(*sdt_probe_func)(sdt_##prov##_##mod##_##func##_##name->id, \
(uintptr_t) arg0, (uintptr_t) arg1, (uintptr_t) arg2, \
(uintptr_t) arg3, (uintptr_t) arg4); \
+ } \
} while (0)
#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype) \
diff --git a/sys/sys/sx.h b/sys/sys/sx.h
index a31c328..3550ce6 100644
--- a/sys/sys/sx.h
+++ b/sys/sys/sx.h
@@ -101,18 +101,22 @@ void sx_sysinit(void *arg);
#define sx_init(sx, desc) sx_init_flags((sx), (desc), 0)
void sx_init_flags(struct sx *sx, const char *description, int opts);
void sx_destroy(struct sx *sx);
+int sx_try_slock_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF);
int sx_try_slock_(struct sx *sx, const char *file, int line);
+int sx_try_xlock_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF);
int sx_try_xlock_(struct sx *sx, const char *file, int line);
+int sx_try_upgrade_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF);
int sx_try_upgrade_(struct sx *sx, const char *file, int line);
+void sx_downgrade_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF);
void sx_downgrade_(struct sx *sx, const char *file, int line);
+int _sx_slock_int(struct sx *sx, int opts LOCK_FILE_LINE_ARG_DEF);
int _sx_slock(struct sx *sx, int opts, const char *file, int line);
int _sx_xlock(struct sx *sx, int opts, const char *file, int line);
+void _sx_sunlock_int(struct sx *sx LOCK_FILE_LINE_ARG_DEF);
void _sx_sunlock(struct sx *sx, const char *file, int line);
void _sx_xunlock(struct sx *sx, const char *file, int line);
-int _sx_xlock_hard(struct sx *sx, uintptr_t v, uintptr_t tid, int opts,
- const char *file, int line);
-void _sx_xunlock_hard(struct sx *sx, uintptr_t tid, const char *file, int
- line);
+int _sx_xlock_hard(struct sx *sx, uintptr_t x, int opts LOCK_FILE_LINE_ARG_DEF);
+void _sx_xunlock_hard(struct sx *sx, uintptr_t x LOCK_FILE_LINE_ARG_DEF);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
void _sx_assert(const struct sx *sx, int what, const char *file, int line);
#endif
@@ -157,7 +161,7 @@ __sx_xlock(struct sx *sx, struct thread *td, int opts, const char *file,
if (__predict_false(LOCKSTAT_PROFILE_ENABLED(sx__acquire) ||
!atomic_fcmpset_acq_ptr(&sx->sx_lock, &v, tid)))
- error = _sx_xlock_hard(sx, v, tid, opts, file, line);
+ error = _sx_xlock_hard(sx, v, opts);
return (error);
}
@@ -166,11 +170,11 @@ __sx_xlock(struct sx *sx, struct thread *td, int opts, const char *file,
static __inline void
__sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line)
{
- uintptr_t tid = (uintptr_t)td;
+ uintptr_t x = (uintptr_t)td;
if (__predict_false(LOCKSTAT_PROFILE_ENABLED(sx__release) ||
- !atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED)))
- _sx_xunlock_hard(sx, tid, file, line);
+ !atomic_fcmpset_rel_ptr(&sx->sx_lock, &x, SX_LOCK_UNLOCKED)))
+ _sx_xunlock_hard(sx, x);
}
#endif
@@ -195,6 +199,7 @@ __sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line)
#define sx_xunlock_(sx, file, line) \
__sx_xunlock((sx), curthread, (file), (line))
#endif /* LOCK_DEBUG > 0 || SX_NOINLINE */
+#if (LOCK_DEBUG > 0)
#define sx_slock_(sx, file, line) \
(void)_sx_slock((sx), 0, (file), (line))
#define sx_slock_sig_(sx, file, line) \
@@ -205,6 +210,18 @@ __sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line)
#define sx_try_xlock(sx) sx_try_xlock_((sx), LOCK_FILE, LOCK_LINE)
#define sx_try_upgrade(sx) sx_try_upgrade_((sx), LOCK_FILE, LOCK_LINE)
#define sx_downgrade(sx) sx_downgrade_((sx), LOCK_FILE, LOCK_LINE)
+#else
+#define sx_slock_(sx, file, line) \
+ (void)_sx_slock_int((sx), 0)
+#define sx_slock_sig_(sx, file, line) \
+ _sx_slock_int((sx), SX_INTERRUPTIBLE)
+#define sx_sunlock_(sx, file, line) \
+ _sx_sunlock_int((sx))
+#define sx_try_slock(sx) sx_try_slock_int((sx))
+#define sx_try_xlock(sx) sx_try_xlock_int((sx))
+#define sx_try_upgrade(sx) sx_try_upgrade_int((sx))
+#define sx_downgrade(sx) sx_downgrade_int((sx))
+#endif
#ifdef INVARIANTS
#define sx_assert_(sx, what, file, line) \
_sx_assert((sx), (what), (file), (line))
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 651cd50..fa5bc3f 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -138,6 +138,7 @@ void kassert_panic(const char *fmt, ...) __printflike(1, 2);
* Align variables.
*/
#define __read_mostly __section(".data.read_mostly")
+#define __read_frequently __section(".data.read_frequently")
#define __exclusive_cache_line __aligned(CACHE_LINE_SIZE) \
__section(".data.exclusive_cache_line")
/*
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index fb719cfb..3fa4ab0 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -1974,6 +1974,16 @@ getinobuf(struct inode *ip, u_int cg, u_int32_t cginoblk, int gbflags)
}
/*
+ * Synchronous inode initialization is needed only when barrier writes do not
+ * work as advertised, and will impose a heavy cost on file creation in a newly
+ * created filesystem.
+ */
+static int doasyncinodeinit = 1;
+SYSCTL_INT(_vfs_ffs, OID_AUTO, doasyncinodeinit, CTLFLAG_RWTUN,
+ &doasyncinodeinit, 0,
+ "Perform inode block initialization using asynchronous writes");
+
+/*
* Determine whether an inode can be allocated.
*
* Check to see if an inode is available, and if it is,
@@ -2086,6 +2096,7 @@ gotit:
dp2->di_gen = arc4random();
dp2++;
}
+
/*
* Rather than adding a soft updates dependency to ensure
* that the new inode block is written before it is claimed
@@ -2095,7 +2106,10 @@ gotit:
* written. The barrier write should only slow down bulk
* loading of newly created filesystems.
*/
- babarrierwrite(ibp);
+ if (doasyncinodeinit)
+ babarrierwrite(ibp);
+ else
+ bwrite(ibp);
/*
* After the inode block is written, try to update the
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 8504a72..bdb6fae 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -138,7 +138,7 @@ static LIST_HEAD(,uma_zone) uma_cachezones =
LIST_HEAD_INITIALIZER(uma_cachezones);
/* This RW lock protects the keg list */
-static struct rwlock_padalign uma_rwlock;
+static struct rwlock_padalign __exclusive_cache_line uma_rwlock;
/* Linked list of boot time pages */
static LIST_HEAD(,uma_slab) uma_boot_pages =
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 3778f76..dc0ae36 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
+#include <vm/vm_radix.h>
#include <vm/vm_extern.h>
#include <vm/uma.h>
@@ -329,7 +330,7 @@ int
kmem_back(vm_object_t object, vm_offset_t addr, vm_size_t size, int flags)
{
vm_offset_t offset, i;
- vm_page_t m;
+ vm_page_t m, mpred;
int pflags;
KASSERT(object == kmem_object || object == kernel_object,
@@ -338,10 +339,13 @@ kmem_back(vm_object_t object, vm_offset_t addr, vm_size_t size, int flags)
offset = addr - VM_MIN_KERNEL_ADDRESS;
pflags = malloc2vm_flags(flags) | VM_ALLOC_NOBUSY | VM_ALLOC_WIRED;
- VM_OBJECT_WLOCK(object);
- for (i = 0; i < size; i += PAGE_SIZE) {
+ i = 0;
retry:
- m = vm_page_alloc(object, atop(offset + i), pflags);
+ VM_OBJECT_WLOCK(object);
+ mpred = vm_radix_lookup_le(&object->rtree, atop(offset + i));
+ for (; i < size; i += PAGE_SIZE, mpred = m) {
+ m = vm_page_alloc_after(object, atop(offset + i), pflags,
+ mpred);
/*
* Ran out of space, free everything up and return. Don't need
@@ -352,7 +356,6 @@ retry:
VM_OBJECT_WUNLOCK(object);
if ((flags & M_NOWAIT) == 0) {
VM_WAIT;
- VM_OBJECT_WLOCK(object);
goto retry;
}
kmem_unback(object, addr, i);
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 16dc868..888af45 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -127,9 +127,9 @@ __FBSDID("$FreeBSD$");
*/
struct vm_domain vm_dom[MAXMEMDOM];
-struct mtx_padalign vm_page_queue_free_mtx;
+struct mtx_padalign __exclusive_cache_line vm_page_queue_free_mtx;
-struct mtx_padalign pa_lock[PA_LOCK_COUNT];
+struct mtx_padalign __exclusive_cache_line pa_lock[PA_LOCK_COUNT];
vm_page_t vm_page_array;
long vm_page_array_size;
@@ -1583,15 +1583,32 @@ vm_page_rename(vm_page_t m, vm_object_t new_object, vm_pindex_t new_pindex)
vm_page_t
vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
{
- vm_page_t m, mpred;
+
+ return (vm_page_alloc_after(object, pindex, req, object != NULL ?
+ vm_radix_lookup_le(&object->rtree, pindex) : NULL));
+}
+
+/*
+ * Allocate a page in the specified object with the given page index. To
+ * optimize insertion of the page into the object, the caller must also specifiy
+ * the resident page in the object with largest index smaller than the given
+ * page index, or NULL if no such page exists.
+ */
+vm_page_t
+vm_page_alloc_after(vm_object_t object, vm_pindex_t pindex, int req,
+ vm_page_t mpred)
+{
+ vm_page_t m;
int flags, req_class;
- mpred = NULL; /* XXX: pacify gcc */
KASSERT((object != NULL) == ((req & VM_ALLOC_NOOBJ) == 0) &&
(object != NULL || (req & VM_ALLOC_SBUSY) == 0) &&
((req & (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)) !=
(VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)),
- ("vm_page_alloc: inconsistent object(%p)/req(%x)", object, req));
+ ("inconsistent object(%p)/req(%x)", object, req));
+ KASSERT(mpred == NULL || mpred->pindex < pindex,
+ ("mpred %p doesn't precede pindex 0x%jx", mpred,
+ (uintmax_t)pindex));
if (object != NULL)
VM_OBJECT_ASSERT_WLOCKED(object);
@@ -1606,12 +1623,6 @@ vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
if (curproc == pageproc && req_class != VM_ALLOC_INTERRUPT)
req_class = VM_ALLOC_SYSTEM;
- if (object != NULL) {
- mpred = vm_radix_lookup_le(&object->rtree, pindex);
- KASSERT(mpred == NULL || mpred->pindex != pindex,
- ("vm_page_alloc: pindex already allocated"));
- }
-
/*
* Allocate a page if the number of free pages exceeds the minimum
* for the request class.
@@ -1658,7 +1669,7 @@ vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
/*
* At this point we had better have found a good page.
*/
- KASSERT(m != NULL, ("vm_page_alloc: missing page"));
+ KASSERT(m != NULL, ("missing page"));
vm_phys_freecnt_adj(m, -1);
if ((m->flags & PG_ZERO) != 0)
vm_page_zero_count--;
@@ -3261,7 +3272,7 @@ int
vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags,
vm_page_t *ma, int count)
{
- vm_page_t m;
+ vm_page_t m, mpred;
int i;
bool sleep;
@@ -3278,7 +3289,12 @@ vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags,
return (0);
i = 0;
retrylookup:
- m = vm_page_lookup(object, pindex + i);
+ m = vm_radix_lookup_le(&object->rtree, pindex + i);
+ if (m == NULL || m->pindex != pindex + i) {
+ mpred = m;
+ m = NULL;
+ } else
+ mpred = TAILQ_PREV(m, pglist, listq);
for (; i < count; i++) {
if (m != NULL) {
sleep = (allocflags & VM_ALLOC_IGN_SBUSY) != 0 ?
@@ -3310,8 +3326,9 @@ retrylookup:
if ((allocflags & VM_ALLOC_SBUSY) != 0)
vm_page_sbusy(m);
} else {
- m = vm_page_alloc(object, pindex + i, (allocflags &
- ~VM_ALLOC_IGN_SBUSY) | VM_ALLOC_COUNT(count - i));
+ m = vm_page_alloc_after(object, pindex + i,
+ (allocflags & ~VM_ALLOC_IGN_SBUSY) |
+ VM_ALLOC_COUNT(count - i), mpred);
if (m == NULL) {
if ((allocflags & VM_ALLOC_NOWAIT) != 0)
break;
@@ -3326,7 +3343,7 @@ retrylookup:
pmap_zero_page(m);
m->valid = VM_PAGE_BITS_ALL;
}
- ma[i] = m;
+ ma[i] = mpred = m;
m = vm_page_next(m);
}
return (i);
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index d27fe10..7922d2e 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -462,7 +462,8 @@ void vm_page_free_zero(vm_page_t m);
void vm_page_activate (vm_page_t);
void vm_page_advise(vm_page_t m, int advice);
-vm_page_t vm_page_alloc (vm_object_t, vm_pindex_t, int);
+vm_page_t vm_page_alloc(vm_object_t, vm_pindex_t, int);
+vm_page_t vm_page_alloc_after(vm_object_t, vm_pindex_t, int, vm_page_t);
vm_page_t vm_page_alloc_contig(vm_object_t object, vm_pindex_t pindex, int req,
u_long npages, vm_paddr_t low, vm_paddr_t high, u_long alignment,
vm_paddr_t boundary, vm_memattr_t memattr);
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 793e2e9..a8c1fa7 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1339,7 +1339,7 @@ drop_page:
inactq_shortage = vm_cnt.v_inactive_target - (vm_cnt.v_inactive_count +
vm_cnt.v_laundry_count / act_scan_laundry_weight) +
vm_paging_target() + deficit + addl_page_shortage;
- page_shortage *= act_scan_laundry_weight;
+ inactq_shortage *= act_scan_laundry_weight;
pq = &vmd->vmd_pagequeues[PQ_ACTIVE];
vm_pagequeue_lock(pq);
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index 45d0c27..3625b41 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -165,7 +165,7 @@ struct pagerops *pagertab[] = {
* cleaning requests (NPENDINGIO == 64) * the maximum swap cluster size
* (MAXPHYS == 64k) if you want to get the most efficiency.
*/
-struct mtx_padalign pbuf_mtx;
+struct mtx_padalign __exclusive_cache_line pbuf_mtx;
static TAILQ_HEAD(swqueue, buf) bswlist;
static int bswneeded;
vm_offset_t swapbkva; /* swap buffers kva */
diff --git a/sys/vm/vm_swapout.c b/sys/vm/vm_swapout.c
index 91b6422..fcef000 100644
--- a/sys/vm/vm_swapout.c
+++ b/sys/vm/vm_swapout.c
@@ -201,6 +201,8 @@ vm_swapout_object_deactivate_pages(pmap_t pmap, vm_object_t first_object,
TAILQ_FOREACH(p, &object->memq, listq) {
if (pmap_resident_count(pmap) <= desired)
goto unlock_return;
+ if (should_yield())
+ goto unlock_return;
if (vm_page_busied(p))
continue;
PCPU_INC(cnt.v_pdpages);
@@ -261,7 +263,7 @@ vm_swapout_map_deactivate_pages(vm_map_t map, long desired)
vm_object_t obj, bigobj;
int nothingwired;
- if (!vm_map_trylock(map))
+ if (!vm_map_trylock_read(map))
return;
bigobj = NULL;
@@ -325,7 +327,7 @@ vm_swapout_map_deactivate_pages(vm_map_t map, long desired)
vm_map_max(map));
}
- vm_map_unlock(map);
+ vm_map_unlock_read(map);
}
/*
@@ -514,8 +516,10 @@ again:
PRELE(p);
}
sx_sunlock(&allproc_lock);
- if (tryagain != 0 && attempts <= 10)
+ if (tryagain != 0 && attempts <= 10) {
+ maybe_yield();
goto again;
+ }
}
}
@@ -554,16 +558,14 @@ vm_thread_swapin(struct thread *td)
{
vm_object_t ksobj;
vm_page_t ma[KSTACK_MAX_PAGES];
- int pages;
+ int a, count, i, j, pages, rv;
pages = td->td_kstack_pages;
ksobj = td->td_kstack_obj;
VM_OBJECT_WLOCK(ksobj);
(void)vm_page_grab_pages(ksobj, 0, VM_ALLOC_NORMAL | VM_ALLOC_WIRED, ma,
pages);
- for (int i = 0; i < pages;) {
- int j, a, count, rv;
-
+ for (i = 0; i < pages;) {
vm_page_assert_xbusied(ma[i]);
if (ma[i]->valid == VM_PAGE_BITS_ALL) {
vm_page_xunbusy(ma[i]);
@@ -640,13 +642,9 @@ faultin(struct proc *p)
void
swapper(void)
{
- struct proc *p;
+ struct proc *p, *pp;
struct thread *td;
- struct proc *pp;
- int slptime;
- int swtime;
- int ppri;
- int pri;
+ int ppri, pri, slptime, swtime;
loop:
if (vm_page_count_min()) {
@@ -713,8 +711,7 @@ loop:
}
/*
- * We would like to bring someone in. (only if there is space).
- * [What checks the space? ]
+ * We would like to bring someone in.
*/
faultin(p);
PROC_UNLOCK(p);
@@ -734,15 +731,14 @@ swapout_procs(int action)
{
struct proc *p;
struct thread *td;
- int didswap = 0;
+ int minslptime, slptime;
+ bool didswap;
+ minslptime = 100000;
+ didswap = false;
retry:
sx_slock(&allproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
- struct vmspace *vm;
- int minslptime = 100000;
- int slptime;
-
PROC_LOCK(p);
/*
* Watch out for a process in
@@ -768,41 +764,26 @@ retry:
PROC_UNLOCK(p);
sx_sunlock(&allproc_lock);
- /*
- * Do not swapout a process that
- * is waiting for VM data
- * structures as there is a possible
- * deadlock. Test this first as
- * this may block.
- *
- * Lock the map until swapout
- * finishes, or a thread of this
- * process may attempt to alter
- * the map.
- */
- vm = vmspace_acquire_ref(p);
- if (vm == NULL)
- goto nextproc2;
- if (!vm_map_trylock(&vm->vm_map))
- goto nextproc1;
-
PROC_LOCK(p);
if (p->p_lock != 1 || (p->p_flag & (P_STOPPED_SINGLE |
P_TRACED | P_SYSTEM)) != 0)
goto nextproc;
/*
- * only aiod changes vmspace, however it will be
+ * Only aiod changes vmspace. However, it will be
* skipped because of the if statement above checking
- * for P_SYSTEM
+ * for P_SYSTEM.
*/
- if ((p->p_flag & (P_INMEM|P_SWAPPINGOUT|P_SWAPPINGIN)) != P_INMEM)
+ if ((p->p_flag & (P_INMEM | P_SWAPPINGOUT | P_SWAPPINGIN)) !=
+ P_INMEM)
goto nextproc;
switch (p->p_state) {
default:
- /* Don't swap out processes in any sort
- * of 'special' state. */
+ /*
+ * Don't swap out processes in any sort
+ * of 'special' state.
+ */
break;
case PRS_NORMAL:
@@ -845,9 +826,9 @@ retry:
* idle processes >= swap_idle_threshold2,
* then swap the process out.
*/
- if (((action & VM_SWAP_NORMAL) == 0) &&
- (((action & VM_SWAP_IDLE) == 0) ||
- (slptime < swap_idle_threshold2))) {
+ if ((action & VM_SWAP_NORMAL) == 0 &&
+ ((action & VM_SWAP_IDLE) == 0 ||
+ slptime < swap_idle_threshold2)) {
thread_unlock(td);
goto nextproc;
}
@@ -862,24 +843,18 @@ retry:
* or if this process is idle and the system is
* configured to swap proactively, swap it out.
*/
- if ((action & VM_SWAP_NORMAL) ||
- ((action & VM_SWAP_IDLE) &&
- (minslptime > swap_idle_threshold2))) {
+ if ((action & VM_SWAP_NORMAL) != 0 ||
+ ((action & VM_SWAP_IDLE) != 0 &&
+ minslptime > swap_idle_threshold2)) {
_PRELE(p);
if (swapout(p) == 0)
- didswap++;
+ didswap = true;
PROC_UNLOCK(p);
- vm_map_unlock(&vm->vm_map);
- vmspace_free(vm);
goto retry;
}
}
nextproc:
PROC_UNLOCK(p);
- vm_map_unlock(&vm->vm_map);
-nextproc1:
- vmspace_free(vm);
-nextproc2:
sx_slock(&allproc_lock);
PRELE(p);
}
@@ -937,9 +912,10 @@ swapout(struct proc *p)
P_INMEM, ("swapout: lost a swapout race?"));
/*
- * remember the process resident count
+ * Remember the resident count.
*/
p->p_vmspace->vm_swrss = vmspace_resident_count(p->p_vmspace);
+
/*
* Check and mark all threads before we proceed.
*/
diff --git a/sys/x86/include/specialreg.h b/sys/x86/include/specialreg.h
index 10bc4e7b..94cadd3 100644
--- a/sys/x86/include/specialreg.h
+++ b/sys/x86/include/specialreg.h
@@ -74,6 +74,7 @@
#define CR4_PCIDE 0x00020000 /* Enable Context ID */
#define CR4_XSAVE 0x00040000 /* XSETBV/XGETBV */
#define CR4_SMEP 0x00100000 /* Supervisor-Mode Execution Prevention */
+#define CR4_SMAP 0x00200000 /* Supervisor-Mode Access Prevention */
/*
* Bits in AMD64 special registers. EFER is 64 bits wide.
@@ -362,6 +363,7 @@
#define CPUID_STDEXT_AVX512CD 0x10000000
#define CPUID_STDEXT_SHA 0x20000000
#define CPUID_STDEXT_AVX512BW 0x40000000
+#define CPUID_STDEXT_AVX512VL 0x80000000
/*
* CPUID instruction 7 Structured Extended Features, leaf 0 ecx info
diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c
index d17a37a..7c20254 100644
--- a/sys/x86/x86/identcpu.c
+++ b/sys/x86/x86/identcpu.c
@@ -961,6 +961,7 @@ printcpuinfo(void)
"\035AVX512CD"
"\036SHA"
"\037AVX512BW"
+ "\040AVX512VL"
);
}
diff --git a/tests/sys/geom/class/geom_subr.sh b/tests/sys/geom/class/geom_subr.sh
index b03ee43..3283d1b 100644
--- a/tests/sys/geom/class/geom_subr.sh
+++ b/tests/sys/geom/class/geom_subr.sh
@@ -20,6 +20,16 @@ attach_md()
echo $test_md
}
+detach_md()
+{
+ local test_md unit
+
+ test_md=$1
+ unit=${test_md#md}
+ mdconfig -d -u $unit || exit
+ sed -i '' "/^${test_md}$/d" $TEST_MDS_FILE || exit
+}
+
geom_test_cleanup()
{
local test_md
@@ -38,6 +48,7 @@ if [ $(id -u) -ne 0 ]; then
echo '1..0 # SKIP tests must be run as root'
exit 0
fi
+
# If the geom class isn't already loaded, try loading it.
if ! kldstat -q -m g_${class}; then
if ! geom ${class} load; then
diff --git a/tests/sys/geom/class/mirror/10_test.sh b/tests/sys/geom/class/mirror/10_test.sh
new file mode 100755
index 0000000..c818718
--- /dev/null
+++ b/tests/sys/geom/class/mirror/10_test.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+# $FreeBSD$
+
+# Test handling of read errors.
+
+. $(dirname $0)/conf.sh
+
+echo 1..3
+
+set -e
+
+ddbs=2048
+regreadfp="debug.fail_point.g_mirror_regular_request_read"
+m1=$(mktemp $base.XXXXXX)
+m2=$(mktemp $base.XXXXXX)
+
+dd if=/dev/random of=$m1 bs=$ddbs count=1024 >/dev/null 2>&1
+dd if=/dev/zero of=$m2 bs=$ddbs count=1024 >/dev/null 2>&1
+
+us0=$(attach_md -t vnode -f $m1)
+us1=$(attach_md -t vnode -f $m2)
+
+gmirror label $name /dev/$us0
+gmirror insert $name /dev/$us1
+devwait
+syncwait
+
+tmp1=$(mktemp $base.XXXXXX)
+tmp2=$(mktemp $base.XXXXXX)
+
+EIO=5
+# gmirror should retry a failed read from the other mirror.
+sysctl ${regreadfp}="1*return(${EIO})"
+dd if=/dev/mirror/$name of=$tmp1 iseek=256 bs=$ddbs count=1 >/dev/null 2>&1
+dd if=/dev/$us1 of=$tmp2 iseek=256 bs=$ddbs count=1 >/dev/null 2>&1
+sysctl ${regreadfp}='off'
+
+if cmp -s $tmp1 $tmp2; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+
+# Make sure that one of the mirrors was marked broken.
+genid1=$(gmirror dump /dev/$us0 | awk '/^[[:space:]]*genid: /{print $2}')
+genid2=$(gmirror dump /dev/$us1 | awk '/^[[:space:]]*genid: /{print $2}')
+if [ $genid1 -eq $(($genid2 + 1)) -o $genid2 -eq $(($genid1 + 1)) ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+# Force a retaste of the disconnected component.
+if [ $(gmirror status -s $name | awk '{print $3}') = $us0 ]; then
+ detach_md $us1
+ us1=$(attach_md -t vnode -f $m2)
+else
+ detach_md $us0
+ us0=$(attach_md -t vnode -f $m1)
+fi
+
+# Make sure that the component wasn't re-added to the gmirror.
+if [ $(gmirror status -s $name | wc -l) -eq 1 ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+rm -f $m1 $m2 $tmp1 $tmp2
diff --git a/tests/sys/geom/class/mirror/11_test.sh b/tests/sys/geom/class/mirror/11_test.sh
new file mode 100755
index 0000000..284aa19
--- /dev/null
+++ b/tests/sys/geom/class/mirror/11_test.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+# $FreeBSD$
+
+# Test handling of read errors.
+
+. $(dirname $0)/conf.sh
+
+echo 1..4
+
+set -e
+
+ddbs=2048
+regreadfp="debug.fail_point.g_mirror_regular_request_read"
+m1=$(mktemp $base.XXXXXX)
+m2=$(mktemp $base.XXXXXX)
+
+dd if=/dev/random of=$m1 bs=$ddbs count=1024 >/dev/null 2>&1
+dd if=/dev/zero of=$m2 bs=$ddbs count=1024 >/dev/null 2>&1
+
+us0=$(attach_md -t vnode -f $m1)
+us1=$(attach_md -t vnode -f $m2)
+
+gmirror label $name /dev/$us0
+gmirror insert $name /dev/$us1
+devwait
+syncwait
+
+tmp1=$(mktemp $base.XXXXXX)
+tmp2=$(mktemp $base.XXXXXX)
+
+ENXIO=6
+# gmirror has special handling for ENXIO. It does not mark the failed component
+# as broken, allowing it to rejoin the mirror automatically when it appears.
+sysctl ${regreadfp}="1*return(${ENXIO})"
+dd if=/dev/mirror/$name of=$tmp1 iseek=512 bs=$ddbs count=1 >/dev/null 2>&1
+dd if=/dev/$us1 of=$tmp2 iseek=512 bs=$ddbs count=1 >/dev/null 2>&1
+sysctl ${regreadfp}='off'
+
+if cmp -s $tmp1 $tmp2; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+
+# Verify that the genids still match after ENXIO.
+genid1=$(gmirror dump /dev/$us0 | awk '/^[[:space:]]*genid: /{print $2}')
+genid2=$(gmirror dump /dev/$us1 | awk '/^[[:space:]]*genid: /{print $2}')
+if [ $genid1 -eq $genid2 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+# Trigger a syncid bump.
+dd if=/dev/zero of=/dev/mirror/$name bs=$ddbs count=1 >/dev/null 2>&1
+
+# The ENXIO+write should have caused a syncid bump.
+syncid1=$(gmirror dump /dev/$us0 | awk '/^[[:space:]]*syncid: /{print $2}')
+syncid2=$(gmirror dump /dev/$us1 | awk '/^[[:space:]]*syncid: /{print $2}')
+if [ $syncid1 -eq $(($syncid2 + 1)) -o $syncid2 -eq $(($syncid1 + 1)) ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+# Force a retaste of the disconnected component.
+if [ $(gmirror status -s $name | awk '{print $3}') = $us0 ]; then
+ detach_md $us1
+ us1=$(attach_md -t vnode -f $m2)
+else
+ detach_md $us0
+ us0=$(attach_md -t vnode -f $m1)
+fi
+
+# Make sure that the retaste caused the mirror to automatically be re-added.
+if [ $(gmirror status -s $name | wc -l) -eq 2 ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+
+syncwait
+
+rm -f $m1 $m2 $tmp1 $tmp2
diff --git a/tests/sys/geom/class/mirror/12_test.sh b/tests/sys/geom/class/mirror/12_test.sh
new file mode 100755
index 0000000..07d69b6
--- /dev/null
+++ b/tests/sys/geom/class/mirror/12_test.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+# $FreeBSD$
+
+# Test handling of write errors.
+
+. $(dirname $0)/conf.sh
+
+echo 1..3
+
+set -e
+
+ddbs=2048
+regwritefp="debug.fail_point.g_mirror_regular_request_write"
+m1=$(mktemp $base.XXXXXX)
+m2=$(mktemp $base.XXXXXX)
+
+dd if=/dev/zero of=$m1 bs=$ddbs count=1024 >/dev/null 2>&1
+dd if=/dev/zero of=$m2 bs=$ddbs count=1024 >/dev/null 2>&1
+
+us0=$(attach_md -t vnode -f $m1)
+us1=$(attach_md -t vnode -f $m2)
+
+gmirror label $name /dev/$us0 /dev/$us1
+devwait
+
+tmp1=$(mktemp $base.XXXXXX)
+tmp2=$(mktemp $base.XXXXXX)
+dd if=/dev/random of=$tmp1 bs=$ddbs count=1 >/dev/null 2>&1
+
+EIO=5
+# gmirror should kick one of the mirrors out after hitting EIO.
+sysctl ${regwritefp}="1*return(${EIO})"
+dd if=$tmp1 of=/dev/mirror/$name bs=$ddbs count=1 >/dev/null 2>&1
+dd if=/dev/mirror/$name of=$tmp2 bs=$ddbs count=1 >/dev/null 2>&1
+sysctl ${regwritefp}='off'
+
+if cmp -s $tmp1 $tmp2; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+
+# Make sure that one of the mirrors was marked broken.
+genid1=$(gmirror dump /dev/$us0 | awk '/^[[:space:]]*genid: /{print $2}')
+genid2=$(gmirror dump /dev/$us1 | awk '/^[[:space:]]*genid: /{print $2}')
+if [ $genid1 -eq $(($genid2 + 1)) -o $genid2 -eq $(($genid1 + 1)) ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+# Force a retaste of the disconnected component.
+if [ $(gmirror status -s $name | awk '{print $3}') = $us0 ]; then
+ detach_md $us1
+ us1=$(attach_md -t vnode -f $m2)
+else
+ detach_md $us0
+ us0=$(attach_md -t vnode -f $m1)
+fi
+
+# Make sure that the component wasn't re-added to the gmirror.
+if [ $(gmirror status -s $name | wc -l) -eq 1 ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+rm -f $m1 $m2 $tmp1 $tmp2
diff --git a/tests/sys/geom/class/mirror/13_test.sh b/tests/sys/geom/class/mirror/13_test.sh
new file mode 100755
index 0000000..4a66d65
--- /dev/null
+++ b/tests/sys/geom/class/mirror/13_test.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+# $FreeBSD$
+
+# Test handling of write errors.
+
+. $(dirname $0)/conf.sh
+
+echo 1..4
+
+set -e
+
+ddbs=2048
+regwritefp="debug.fail_point.g_mirror_regular_request_write"
+m1=$(mktemp $base.XXXXXX)
+m2=$(mktemp $base.XXXXXX)
+
+dd if=/dev/random of=$m1 bs=$ddbs count=1024 >/dev/null 2>&1
+dd if=/dev/zero of=$m2 bs=$ddbs count=1024 >/dev/null 2>&1
+
+us0=$(attach_md -t vnode -f $m1)
+us1=$(attach_md -t vnode -f $m2)
+
+gmirror label $name /dev/$us0 /dev/$us1
+devwait
+
+tmp1=$(mktemp $base.XXXXXX)
+tmp2=$(mktemp $base.XXXXXX)
+
+dd if=/dev/random of=$tmp1 bs=$ddbs count=1 >/dev/null 2>&1
+
+ENXIO=6
+# gmirror has special handling for ENXIO. It does not mark the failed component
+# as broken, allowing it to rejoin the mirror automatically when it appears.
+sysctl ${regwritefp}="1*return(${ENXIO})"
+dd if=$tmp1 of=/dev/mirror/$name bs=$ddbs count=1 >/dev/null 2>&1
+dd if=/dev/mirror/$name of=$tmp2 bs=$ddbs count=1 >/dev/null 2>&1
+sysctl ${regwritefp}='off'
+
+if cmp -s $tmp1 $tmp2; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+
+# Verify that the genids still match after ENXIO.
+genid1=$(gmirror dump /dev/$us0 | awk '/^[[:space:]]*genid: /{print $2}')
+genid2=$(gmirror dump /dev/$us1 | awk '/^[[:space:]]*genid: /{print $2}')
+if [ $genid1 -eq $genid2 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+# The ENXIO should have caused a syncid bump.
+syncid1=$(gmirror dump /dev/$us0 | awk '/^[[:space:]]*syncid: /{print $2}')
+syncid2=$(gmirror dump /dev/$us1 | awk '/^[[:space:]]*syncid: /{print $2}')
+if [ $syncid1 -eq $(($syncid2 + 1)) -o $syncid2 -eq $(($syncid1 + 1)) ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+# Force a retaste of the disconnected component.
+if [ $(gmirror status -s $name | awk '{print $3}') = $us0 ]; then
+ detach_md $us1
+ us1=$(attach_md -t vnode -f $m2)
+else
+ detach_md $us0
+ us0=$(attach_md -t vnode -f $m1)
+fi
+
+# Make sure that the retaste caused the mirror to automatically be re-added.
+if [ $(gmirror status -s $name | wc -l) -eq 2 ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+
+syncwait
+
+rm -f $m1 $m2 $tmp1 $tmp2
diff --git a/tests/sys/geom/class/mirror/8_test.sh b/tests/sys/geom/class/mirror/8_test.sh
index 9eefc9d..d288190 100644
--- a/tests/sys/geom/class/mirror/8_test.sh
+++ b/tests/sys/geom/class/mirror/8_test.sh
@@ -35,9 +35,7 @@ devwait # This will take kern.geom.mirror.timeout seconds.
# Re-attach the second mirror and wait for it to synchronize.
us1=$(attach_md -t vnode -f $m2) || exit 1
-while [ $(gmirror status $name | grep ACTIVE | wc -l) -ne 2 ]; do
- sleep 1
-done
+syncwait
# Verify the two mirrors are identical. Destroy the gmirror first so that
# the mirror metadata is wiped; otherwise the metadata blocks will fail
@@ -45,9 +43,9 @@ done
# command instead.
gmirror destroy $name
if cmp -s ${m1} ${m2}; then
- echo "ok 1"
+ echo "ok 1"
else
- echo "not ok 1"
+ echo "not ok 1"
fi
rm -f $m1 $m2
diff --git a/tests/sys/geom/class/mirror/9_test.sh b/tests/sys/geom/class/mirror/9_test.sh
index 072499f..c7af15b 100644
--- a/tests/sys/geom/class/mirror/9_test.sh
+++ b/tests/sys/geom/class/mirror/9_test.sh
@@ -33,9 +33,7 @@ sysctl debug.fail_point.g_mirror_metadata_write='off' || exit 1
# Replace the broken mirror, and then stop the gmirror.
gmirror forget $name || exit 1
gmirror insert $name /dev/$us2 || exit 1
-while [ $(gmirror status $name | grep ACTIVE | wc -l) -ne 2 ]; do
- sleep 1
-done
+syncwait
gmirror stop $name || exit 1
# Restart the gmirror on the original two mirrors. One of them is broken,
@@ -49,14 +47,12 @@ dd if=/dev/random of=/dev/mirror/$name bs=$ddbs count=1 >/dev/null 2>&1
# the metadata blocks will fail the comparison. It would be nice to do this
# with a "gmirror verify" command instead.
gmirror activate $name /dev/$us2 || exit 1
-while [ $(gmirror status $name | grep ACTIVE | wc -l) -ne 2 ]; do
- sleep 1
-done
+syncwait
gmirror destroy $name || exit 1
if cmp -s $m1 $m3; then
- echo "ok 1"
+ echo "ok 1"
else
- echo "not ok 1"
+ echo "not ok 1"
fi
rm -f $m1 $m2 $m3
diff --git a/tests/sys/geom/class/mirror/Makefile b/tests/sys/geom/class/mirror/Makefile
index 66f9249..095fb90 100644
--- a/tests/sys/geom/class/mirror/Makefile
+++ b/tests/sys/geom/class/mirror/Makefile
@@ -13,6 +13,10 @@ TAP_TESTS_SH+= 6_test
TAP_TESTS_SH+= 7_test
TAP_TESTS_SH+= 8_test
TAP_TESTS_SH+= 9_test
+TAP_TESTS_SH+= 10_test
+TAP_TESTS_SH+= 11_test
+TAP_TESTS_SH+= 12_test
+TAP_TESTS_SH+= 13_test
${PACKAGE}FILES+= conf.sh
diff --git a/tests/sys/geom/class/mirror/conf.sh b/tests/sys/geom/class/mirror/conf.sh
index d8595f1..1cb785e 100644
--- a/tests/sys/geom/class/mirror/conf.sh
+++ b/tests/sys/geom/class/mirror/conf.sh
@@ -12,4 +12,11 @@ gmirror_test_cleanup()
}
trap gmirror_test_cleanup ABRT EXIT INT TERM
+syncwait()
+{
+ while $(gmirror status -s $name | grep -q SYNCHRONIZING); do
+ sleep 0.1;
+ done
+}
+
. `dirname $0`/../geom_subr.sh
diff --git a/tests/sys/geom/class/nop/nop_test.sh b/tests/sys/geom/class/nop/nop_test.sh
index 35cc191..edf5ac7 100644
--- a/tests/sys/geom/class/nop/nop_test.sh
+++ b/tests/sys/geom/class/nop/nop_test.sh
@@ -36,6 +36,7 @@ diskinfo_head()
}
diskinfo_body()
{
+ load_gnop
us=$(alloc_md)
atf_check gnop create /dev/${us}
md_secsize=$(diskinfo ${us} | cut -wf 2)
@@ -62,6 +63,7 @@ io_head()
}
io_body()
{
+ load_gnop
us=$(alloc_md)
atf_check gnop create /dev/${us}
@@ -87,6 +89,7 @@ size_head()
}
size_body()
{
+ load_gnop
us=$(alloc_md)
for mediasize in 65536 524288 1048576; do
atf_check gnop create -s ${mediasize} /dev/${us}
@@ -111,6 +114,7 @@ stripesize_head()
}
stripesize_body()
{
+ load_gnop
us=$(alloc_md)
for ss in 512 1024 2048 4096 8192; do
for sofs in `seq 0 512 ${ss}`; do
@@ -164,3 +168,10 @@ common_cleanup()
fi
true
}
+
+load_gnop()
+{
+ if ! kldstat -q -m g_nop; then
+ geom nop load || atf_skip "could not load module for geom nop"
+ fi
+}
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index cd30070..380aff6 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -1356,119 +1356,122 @@ OLD_FILES+=usr/bin/clang-cpp
OLD_FILES+=usr/bin/clang-tblgen
OLD_FILES+=usr/bin/llvm-objdump
OLD_FILES+=usr/bin/llvm-tblgen
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/allocator_interface.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/asan_interface.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/common_interface_defs.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/coverage_interface.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/dfsan_interface.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/esan_interface.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/linux_syscall_hooks.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/lsan_interface.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/msan_interface.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/tsan_interface_atomic.h
-OLD_DIRS+=usr/lib/clang/5.0.0/include/sanitizer
-OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_builtin_vars.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_cmath.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_complex_builtins.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_intrinsics.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_math_forward_declares.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_runtime_wrapper.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/__stddef_max_align_t.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/__wmmintrin_aes.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/__wmmintrin_pclmul.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/adxintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/altivec.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/ammintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/arm_acle.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/arm_neon.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/armintr.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx2intrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512bwintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512cdintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512dqintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512erintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512fintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512ifmaintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512ifmavlintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512pfintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vbmiintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vbmivlintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlbwintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlcdintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vldqintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/avxintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/bmi2intrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/bmiintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/clflushoptintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/clzerointrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/cpuid.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/emmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/f16cintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/fma4intrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/fmaintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/fxsrintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/htmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/htmxlintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/ia32intrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/immintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/lwpintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/lzcntintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/mm3dnow.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/mm_malloc.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/mmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/module.modulemap
-OLD_FILES+=usr/lib/clang/5.0.0/include/msa.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/mwaitxintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/nmmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/opencl-c.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/pkuintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/pmmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/popcntintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/prfchwintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/rdseedintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/rtmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/s390intrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/shaintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/smmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/tbmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/tmmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/vadefs.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/vecintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/wmmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/x86intrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/xmmintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/xopintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/xsavecintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/xsaveintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/xsaveoptintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/xsavesintrin.h
-OLD_FILES+=usr/lib/clang/5.0.0/include/xtestintrin.h
-OLD_DIRS+=usr/lib/clang/5.0.0/include
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-i386.so
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-x86_64.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-x86_64.so
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-arm.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-x86_64.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.safestack-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats-x86_64.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats_client-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a
-OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a
-OLD_DIRS+=usr/lib/clang/5.0.0/lib/freebsd
-OLD_DIRS+=usr/lib/clang/5.0.0/lib
-OLD_DIRS+=usr/lib/clang/5.0.0
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/allocator_interface.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/asan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/common_interface_defs.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/coverage_interface.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/dfsan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/esan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/linux_syscall_hooks.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/lsan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/msan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/tsan_interface.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/tsan_interface_atomic.h
+OLD_DIRS+=usr/lib/clang/5.0.1/include/sanitizer
+OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_builtin_vars.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_cmath.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_complex_builtins.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_intrinsics.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_math_forward_declares.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_runtime_wrapper.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/__stddef_max_align_t.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/__wmmintrin_aes.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/__wmmintrin_pclmul.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/adxintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/altivec.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/ammintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/arm_acle.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/arm_neon.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/armintr.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx2intrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512bwintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512cdintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512dqintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512erintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512fintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512ifmaintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512ifmavlintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512pfintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vbmiintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vbmivlintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vlbwintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vlcdintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vldqintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vlintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vpopcntdqintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/avxintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/bmi2intrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/bmiintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/clflushoptintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/clzerointrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/cpuid.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/emmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/f16cintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/fma4intrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/fmaintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/fxsrintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/htmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/htmxlintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/ia32intrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/immintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/lwpintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/lzcntintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/mm3dnow.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/mm_malloc.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/mmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/module.modulemap
+OLD_FILES+=usr/lib/clang/5.0.1/include/msa.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/mwaitxintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/nmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/opencl-c.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/pkuintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/pmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/popcntintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/prfchwintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/rdseedintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/rtmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/s390intrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/shaintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/smmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/tbmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/tmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/vadefs.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/vecintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/wmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/x86intrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/xmmintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/xopintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/xsavecintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/xsaveintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/xsaveoptintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/xsavesintrin.h
+OLD_FILES+=usr/lib/clang/5.0.1/include/xtestintrin.h
+OLD_DIRS+=usr/lib/clang/5.0.1/include
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-i386.so
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-x86_64.so
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.profile-arm.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.profile-armhf.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.profile-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.profile-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.safestack-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.stats-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.stats-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.stats_client-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a
+OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a
+OLD_DIRS+=usr/lib/clang/5.0.1/lib/freebsd
+OLD_DIRS+=usr/lib/clang/5.0.1/lib
+OLD_DIRS+=usr/lib/clang/5.0.1
OLD_DIRS+=usr/lib/clang
OLD_FILES+=usr/share/doc/llvm/clang/LICENSE.TXT
OLD_DIRS+=usr/share/doc/llvm/clang
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index f0ab210..65a70ba 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -148,6 +148,7 @@ SUBDIR= alias \
split \
stat \
stdbuf \
+ strings \
su \
systat \
tabs \
@@ -285,7 +286,6 @@ SUBDIR.${MK_TOOLCHAIN}+= readelf
SUBDIR.${MK_TOOLCHAIN}+= rpcgen
SUBDIR.${MK_TOOLCHAIN}+= unifdef
SUBDIR.${MK_TOOLCHAIN}+= size
-SUBDIR.${MK_TOOLCHAIN}+= strings
.if ${MACHINE_ARCH} != "aarch64" # ARM64TODO xlint does not build
SUBDIR.${MK_TOOLCHAIN}+= xlint
.endif
diff --git a/usr.bin/ctlstat/ctlstat.c b/usr.bin/ctlstat/ctlstat.c
index d90c071..70c1f7a 100644
--- a/usr.bin/ctlstat/ctlstat.c
+++ b/usr.bin/ctlstat/ctlstat.c
@@ -72,12 +72,7 @@ __FBSDID("$FreeBSD$");
*/
#define CTL_STAT_NUM_ITEMS 256
-/*
- * The default number of LUN selection bits we allocate. This is large
- * because we don't currently increase it if the user specifies a LUN
- * number of 1024 or larger.
- */
-#define CTL_STAT_BITS 1024L
+static int ctl_stat_bits;
static const char *ctlstat_opts = "Cc:Ddhjl:n:p:tw:";
static const char *ctlstat_usage = "Usage: ctlstat [-CDdjht] [-l lunnum]"
@@ -125,7 +120,7 @@ struct ctlstat_context {
struct ctl_cpu_stats cur_cpu, prev_cpu;
uint64_t cur_total_jiffies, prev_total_jiffies;
uint64_t cur_idle, prev_idle;
- bitstr_t bit_decl(item_mask, CTL_STAT_BITS);
+ bitstr_t *item_mask;
int cur_items, prev_items;
int cur_alloc, prev_alloc;
int numdevs;
@@ -429,7 +424,7 @@ ctlstat_standard(struct ctlstat_context *ctx) {
(F_TIMEVAL(ctx) != 0) ? " " : "");
n = 3;
} else {
- for (i = n = 0; i < min(CTL_STAT_BITS,
+ for (i = n = 0; i < min(ctl_stat_bits,
ctx->cur_items); i++) {
int item;
@@ -537,7 +532,7 @@ ctlstat_standard(struct ctlstat_context *ctx) {
dmas_per_sec[i], mbsec[i]);
}
} else {
- for (i = n = 0; i < min(CTL_STAT_BITS, ctx->cur_items); i++) {
+ for (i = n = 0; i < min(ctl_stat_bits, ctx->cur_items); i++) {
long double mbsec, kb_per_transfer;
long double transfers_per_sec;
long double ms_per_transfer;
@@ -580,6 +575,7 @@ main(int argc, char **argv)
int c;
int count, waittime;
int fd, retval;
+ size_t size;
struct ctlstat_context ctx;
struct ctl_io_stats *tmp_stats;
@@ -594,6 +590,16 @@ main(int argc, char **argv)
ctx.flags |= CTLSTAT_FLAG_FIRST_RUN;
ctx.flags |= CTLSTAT_FLAG_HEADER;
+ size = sizeof(ctl_stat_bits);
+ if (sysctlbyname("kern.cam.ctl.max_luns", &ctl_stat_bits, &size, NULL,
+ 0) == -1) {
+ /* Backward compatibility for where the sysctl wasn't exposed */
+ ctl_stat_bits = 1024;
+ }
+ ctx.item_mask = bit_alloc(ctl_stat_bits);
+ if (ctx.item_mask == NULL)
+ err(1, "bit_alloc() failed");
+
while ((c = getopt(argc, argv, ctlstat_opts)) != -1) {
switch (c) {
case 'C':
@@ -620,7 +626,7 @@ main(int argc, char **argv)
int cur_lun;
cur_lun = atoi(optarg);
- if (cur_lun > CTL_STAT_BITS)
+ if (cur_lun > ctl_stat_bits)
errx(1, "Invalid LUN number %d", cur_lun);
if (!F_MASK(&ctx))
@@ -639,7 +645,7 @@ main(int argc, char **argv)
int cur_port;
cur_port = atoi(optarg);
- if (cur_port > CTL_STAT_BITS)
+ if (cur_port > ctl_stat_bits)
errx(1, "Invalid port number %d", cur_port);
if (!F_MASK(&ctx))
diff --git a/usr.bin/fold/Makefile b/usr.bin/fold/Makefile
index d73d0a7..8583352 100644
--- a/usr.bin/fold/Makefile
+++ b/usr.bin/fold/Makefile
@@ -1,6 +1,11 @@
# From: @(#)Makefile 8.1 (Berkeley) 6/6/93
# $FreeBSD$
+.include <src.opts.mk>
+
PROG= fold
+HAS_TESTS=
+SUBDIR.${MK_TESTS}+= tests
+
.include <bsd.prog.mk>
diff --git a/usr.bin/fold/tests/Makefile b/usr.bin/fold/tests/Makefile
new file mode 100644
index 0000000..494b7e5
--- /dev/null
+++ b/usr.bin/fold/tests/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+ATF_TESTS_SH+= fold_test
+
+.include <bsd.test.mk>
diff --git a/usr.bin/fold/tests/fold_test.sh b/usr.bin/fold/tests/fold_test.sh
new file mode 100644
index 0000000..17ef287
--- /dev/null
+++ b/usr.bin/fold/tests/fold_test.sh
@@ -0,0 +1,81 @@
+#
+# Copyright 2017 Shivansh
+# 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$
+#
+
+atf_test_case b_flag
+b_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'b'"
+}
+
+b_flag_body()
+{
+ atf_check -s exit:0 -o empty fold -b < /dev/null
+}
+
+atf_test_case s_flag
+s_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 's'"
+}
+
+s_flag_body()
+{
+ atf_check -s exit:0 -o empty fold -s < /dev/null
+}
+
+atf_test_case invalid_usage
+invalid_usage_head()
+{
+ atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
+}
+
+invalid_usage_body()
+{
+ atf_check -s not-exit:0 -e inline:"fold: option requires an argument -- w
+usage: fold [-bs] [-w width] [file ...]
+" fold -w
+}
+
+atf_test_case no_arguments
+no_arguments_head()
+{
+ atf_set "descr" "Verify that fold(1) executes successfully and silently when invoked without any arguments"
+}
+
+no_arguments_body()
+{
+ atf_check -s exit:0 -o empty fold < /dev/null
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case b_flag
+ atf_add_test_case s_flag
+ atf_add_test_case invalid_usage
+ atf_add_test_case no_arguments
+}
diff --git a/usr.bin/gzip/Makefile b/usr.bin/gzip/Makefile
index 1266277..d4cb106 100644
--- a/usr.bin/gzip/Makefile
+++ b/usr.bin/gzip/Makefile
@@ -20,11 +20,13 @@ MLINKS+= gzip.1 gunzip.1 \
gzip.1 gzcat.1 \
gzip.1 zcat.1 \
zdiff.1 zcmp.1 \
+ zdiff.1 xzdiff.1 \
zmore.1 zless.1
LINKS+= ${BINDIR}/gzip ${BINDIR}/gunzip \
${BINDIR}/gzip ${BINDIR}/gzcat \
${BINDIR}/gzip ${BINDIR}/zcat \
+ ${BINDIR}/zdiff ${BINDIR}/xzdiff \
${BINDIR}/zdiff ${BINDIR}/zcmp
.if ${MK_TESTS} != "no"
diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c
index a72b775..68f83fe 100644
--- a/usr.bin/gzip/gzip.c
+++ b/usr.bin/gzip/gzip.c
@@ -1717,7 +1717,7 @@ file_uncompress(char *file, char *outfile, size_t outsize)
if (fd != -1)
close(fd);
if (zfd != -1 && zfd != STDOUT_FILENO)
- close(fd);
+ close(zfd);
return -1;
}
diff --git a/usr.bin/gzip/zuncompress.c b/usr.bin/gzip/zuncompress.c
index 6069cae..d99e70f 100644
--- a/usr.bin/gzip/zuncompress.c
+++ b/usr.bin/gzip/zuncompress.c
@@ -279,7 +279,7 @@ zread(void *cookie, char *rbp, int num)
if (zs->u.r.zs_code > zs->zs_free_ent ||
zs->u.r.zs_oldcode == -1) {
/* Bad stream. */
- errno = EINVAL;
+ errno = EFTYPE;
return (-1);
}
*zs->u.r.zs_stackp++ = zs->u.r.zs_finchar;
diff --git a/usr.bin/man/man.1 b/usr.bin/man/man.1
index 6705677..26e3fc0 100644
--- a/usr.bin/man/man.1
+++ b/usr.bin/man/man.1
@@ -355,6 +355,8 @@ System configuration file.
.It Pa /usr/local/etc/man.d/*.conf
Local configuration files.
.El
+.Sh EXIT STATUS
+.Ex -std
.Sh SEE ALSO
.Xr apropos 1 ,
.Xr intro 1 ,
diff --git a/usr.bin/pathchk/pathchk.c b/usr.bin/pathchk/pathchk.c
index 3dc901b..be80ec9 100644
--- a/usr.bin/pathchk/pathchk.c
+++ b/usr.bin/pathchk/pathchk.c
@@ -89,7 +89,7 @@ static void
usage(void)
{
- fprintf(stderr, "usage: pathchk [-p] pathname ...\n");
+ fprintf(stderr, "usage: pathchk [-Pp] pathname ...\n");
exit(1);
}
diff --git a/usr.bin/rs/Makefile b/usr.bin/rs/Makefile
index 21da34d..20da0d9 100644
--- a/usr.bin/rs/Makefile
+++ b/usr.bin/rs/Makefile
@@ -1,5 +1,11 @@
# @(#)Makefile 8.1 (Berkeley) 6/6/93
+# $FreeBSD$
+
+.include <src.opts.mk>
PROG= rs
+HAS_TESTS=
+SUBDIR.${MK_TESTS}+= tests
+
.include <bsd.prog.mk>
diff --git a/usr.bin/rs/tests/Makefile b/usr.bin/rs/tests/Makefile
new file mode 100644
index 0000000..5aae84c
--- /dev/null
+++ b/usr.bin/rs/tests/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+ATF_TESTS_SH+= rs_test
+
+.include <bsd.test.mk>
diff --git a/usr.bin/rs/tests/rs_test.sh b/usr.bin/rs/tests/rs_test.sh
new file mode 100644
index 0000000..1960f9bb
--- /dev/null
+++ b/usr.bin/rs/tests/rs_test.sh
@@ -0,0 +1,278 @@
+#
+# Copyright 2017 Shivansh
+# 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$
+#
+
+atf_test_case c_flag
+c_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'c'"
+}
+
+c_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -c < /dev/null
+}
+
+atf_test_case s_flag
+s_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 's'"
+}
+
+s_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -s < /dev/null
+}
+
+atf_test_case C_flag
+C_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'C'"
+}
+
+C_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -C < /dev/null
+}
+
+atf_test_case S_flag
+S_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'S'"
+}
+
+S_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -S < /dev/null
+}
+
+atf_test_case t_flag
+t_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 't'"
+}
+
+t_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -t < /dev/null
+}
+
+atf_test_case T_flag
+T_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'T'"
+}
+
+T_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -T < /dev/null
+}
+
+atf_test_case k_flag
+k_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'k'"
+}
+
+k_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -k < /dev/null
+}
+
+atf_test_case K_flag
+K_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'K'"
+}
+
+K_flag_body()
+{
+ atf_check -s exit:0 -o inline:"
+" rs -K < /dev/null
+}
+
+atf_test_case g_flag
+g_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'g'"
+}
+
+g_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -g < /dev/null
+}
+
+atf_test_case G_flag
+G_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'G'"
+}
+
+G_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -G < /dev/null
+}
+
+atf_test_case e_flag
+e_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'e'"
+}
+
+e_flag_body()
+{
+ atf_check -s exit:0 -o inline:"
+" rs -e < /dev/null
+}
+
+atf_test_case n_flag
+n_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'n'"
+}
+
+n_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -n < /dev/null
+}
+
+atf_test_case y_flag
+y_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'y'"
+}
+
+y_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -y < /dev/null
+}
+
+atf_test_case h_flag
+h_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'h'"
+}
+
+h_flag_body()
+{
+ atf_check -s exit:0 -o inline:"1 0
+" rs -h < /dev/null
+}
+
+atf_test_case H_flag
+H_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'H'"
+}
+
+H_flag_body()
+{
+ atf_check -s exit:0 -o inline:" 0 line 1
+1 0
+" rs -H < /dev/null
+}
+
+atf_test_case j_flag
+j_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'j'"
+}
+
+j_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -j < /dev/null
+}
+
+atf_test_case m_flag
+m_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'm'"
+}
+
+m_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -m < /dev/null
+}
+
+atf_test_case z_flag
+z_flag_head()
+{
+ atf_set "descr" "Verify the usage of option 'z'"
+}
+
+z_flag_body()
+{
+ atf_check -s exit:0 -o empty rs -z < /dev/null
+}
+
+atf_test_case invalid_usage
+invalid_usage_head()
+{
+ atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
+}
+
+invalid_usage_body()
+{
+ atf_check -s not-exit:0 -e inline:"rs: width must be a positive integer
+" rs -w
+}
+
+atf_test_case no_arguments
+no_arguments_head()
+{
+ atf_set "descr" "Verify that rs(1) executes successfully and produces a valid output when invoked without any arguments"
+}
+
+no_arguments_body()
+{
+ atf_check -s exit:0 -o inline:"
+" rs < /dev/null
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case c_flag
+ atf_add_test_case s_flag
+ atf_add_test_case C_flag
+ atf_add_test_case S_flag
+ atf_add_test_case t_flag
+ atf_add_test_case T_flag
+ atf_add_test_case k_flag
+ atf_add_test_case K_flag
+ atf_add_test_case g_flag
+ atf_add_test_case G_flag
+ atf_add_test_case e_flag
+ atf_add_test_case n_flag
+ atf_add_test_case y_flag
+ atf_add_test_case h_flag
+ atf_add_test_case H_flag
+ atf_add_test_case j_flag
+ atf_add_test_case m_flag
+ atf_add_test_case z_flag
+ atf_add_test_case invalid_usage
+ atf_add_test_case no_arguments
+}
diff --git a/usr.bin/su/su.c b/usr.bin/su/su.c
index 9a08ddf..e27a4aa 100644
--- a/usr.bin/su/su.c
+++ b/usr.bin/su/su.c
@@ -275,9 +275,9 @@ main(int argc, char *argv[])
if (asme) {
if (pwd->pw_shell != NULL && *pwd->pw_shell != '\0') {
/* must copy - pwd memory is recycled */
- shell = strncpy(shellbuf, pwd->pw_shell,
+ strlcpy(shellbuf, pwd->pw_shell,
sizeof(shellbuf));
- shellbuf[sizeof(shellbuf) - 1] = '\0';
+ shell = shellbuf;
}
else {
shell = _PATH_BSHELL;
diff --git a/usr.bin/units/units.c b/usr.bin/units/units.c
index b40b653..d5dd843 100644
--- a/usr.bin/units/units.c
+++ b/usr.bin/units/units.c
@@ -761,7 +761,7 @@ main(int argc, char **argv)
history_file = NULL;
outputformat = numfmt;
quit = false;
- while ((optchar = getopt_long(argc, argv, "+ehf:oqtvHUV", longopts, NULL)) != -1) {
+ while ((optchar = getopt_long(argc, argv, "+ehf:o:qtvH:UV", longopts, NULL)) != -1) {
switch (optchar) {
case 'e':
outputformat = "%6e";
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c
index 44ab194..16eba77 100644
--- a/usr.bin/xinstall/xinstall.c
+++ b/usr.bin/xinstall/xinstall.c
@@ -1292,17 +1292,19 @@ install_dir(char *path)
{
char *p;
struct stat sb;
- int ch;
+ int ch, tried_mkdir;
for (p = path;; ++p)
if (!*p || (p != path && *p == '/')) {
+ tried_mkdir = 0;
ch = *p;
*p = '\0';
again:
if (stat(path, &sb) < 0) {
- if (errno != ENOENT)
+ if (errno != ENOENT || tried_mkdir)
err(EX_OSERR, "stat %s", path);
if (mkdir(path, 0755) < 0) {
+ tried_mkdir = 1;
if (errno == EEXIST)
goto again;
err(EX_OSERR, "mkdir %s", path);
diff --git a/usr.sbin/acpi/acpidb/Makefile b/usr.sbin/acpi/acpidb/Makefile
index 2f24d80..a425d40 100644
--- a/usr.sbin/acpi/acpidb/Makefile
+++ b/usr.sbin/acpi/acpidb/Makefile
@@ -66,8 +66,9 @@ SRCS+= utaddress.c utalloc.c utascii.c utbuffer.c utcache.c \
uteval.c utexcep.c utglobal.c uthex.c utids.c utinit.c \
utlock.c utmath.c utmisc.c utmutex.c utnonansi.c \
utobject.c utosi.c utownerid.c utpredef.c utresdecode.c \
- utresrc.c utstate.c utstring.c utstrtoul64.c uttrack.c \
- utuuid.c utxface.c utxferror.c utxfinit.c
+ utresrc.c utstate.c utstring.c utstrsuppt.c \
+ utstrtoul64.c uttrack.c utuuid.c utxface.c utxferror.c \
+ utxfinit.c
# os_specific/service_layers
SRCS+= osgendbg.c osunixxf.c
diff --git a/usr.sbin/acpi/iasl/Makefile b/usr.sbin/acpi/iasl/Makefile
index 77a13ec..8171d5a 100644
--- a/usr.sbin/acpi/iasl/Makefile
+++ b/usr.sbin/acpi/iasl/Makefile
@@ -9,27 +9,27 @@ SRCS= acfileio.c adfile.c adisasm.c adwalk.c ahids.c \
dmtbinfo.c getopt.c
# compiler
-SRCS+= aslanalyze.c aslascii.c aslbtypes.c aslcodegen.c \
- aslcompile.c aslcompiler.y.h aslcompilerlex.c \
- aslcompilerparse.c asldebug.c aslerror.c aslexternal.c \
- aslfileio.c aslfiles.c aslfold.c aslhelp.c aslhex.c \
- asllength.c asllisting.c asllistsup.c aslload.c \
- asllookup.c aslmain.c aslmap.c aslmapenter.c \
- aslmapoutput.c aslmaputils.c aslmessages.c aslmethod.c \
- aslnamesp.c asloffset.c aslopcodes.c asloperands.c \
- aslopt.c asloptions.c aslparseop.c aslpld.c aslpredef.c \
- aslprepkg.c aslprintf.c aslprune.c aslresource.c \
- aslrestype1.c aslrestype1i.c aslrestype2.c \
- aslrestype2d.c aslrestype2e.c aslrestype2q.c \
- aslrestype2s.c aslrestype2w.c aslstartup.c aslstubs.c \
- asltransform.c asltree.c aslutils.c asluuid.c \
- aslwalks.c aslxref.c aslxrefout.c cvcompiler.c \
- cvdisasm.c cvparser.c dtcompile.c dtexpress.c dtfield.c \
- dtio.c dtparser.y.h dtparserlex.c dtparserparse.c \
- dtsubtable.c dttable.c dttable1.c dttable2.c \
- dttemplate.c dtutils.c prexpress.c prmacros.c \
- prparser.y.h prparserlex.c prparserparse.c prscan.c \
- prutils.c
+SRCS+= aslallocate.c aslanalyze.c aslascii.c aslbtypes.c \
+ aslcache.c aslcodegen.c aslcompile.c aslcompiler.y.h \
+ aslcompilerlex.c aslcompilerparse.c asldebug.c \
+ aslerror.c aslexternal.c aslfileio.c aslfiles.c \
+ aslfold.c aslhelp.c aslhex.c asllength.c asllisting.c \
+ asllistsup.c aslload.c asllookup.c aslmain.c aslmap.c \
+ aslmapenter.c aslmapoutput.c aslmaputils.c \
+ aslmessages.c aslmethod.c aslnamesp.c asloffset.c \
+ aslopcodes.c asloperands.c aslopt.c asloptions.c \
+ aslparseop.c aslpld.c aslpredef.c aslprepkg.c \
+ aslprintf.c aslprune.c aslresource.c aslrestype1.c \
+ aslrestype1i.c aslrestype2.c aslrestype2d.c \
+ aslrestype2e.c aslrestype2q.c aslrestype2s.c \
+ aslrestype2w.c aslstartup.c aslstubs.c asltransform.c \
+ asltree.c aslutils.c asluuid.c aslwalks.c aslxref.c \
+ aslxrefout.c cvcompiler.c cvdisasm.c cvparser.c \
+ dtcompile.c dtexpress.c dtfield.c dtio.c dtparser.y.h \
+ dtparserlex.c dtparserparse.c dtsubtable.c dttable.c \
+ dttable1.c dttable2.c dttemplate.c dtutils.c \
+ prexpress.c prmacros.c prparser.y.h prparserlex.c \
+ prparserparse.c prscan.c prutils.c
# components/debugger
SRCS+= dbfileio.c
@@ -68,7 +68,8 @@ SRCS+= utaddress.c utalloc.c utascii.c utbuffer.c utcache.c \
utexcep.c utglobal.c uthex.c utinit.c utlock.c utmath.c \
utmisc.c utmutex.c utnonansi.c utobject.c utownerid.c \
utpredef.c utresdecode.c utresrc.c utstate.c utstring.c \
- utstrtoul64.c utuuid.c utxface.c utxferror.c
+ utstrsuppt.c utstrtoul64.c utuuid.c utxface.c \
+ utxferror.c
# os_specific/service_layers
SRCS+= osunixxf.c
diff --git a/usr.sbin/cpucontrol/intel.c b/usr.sbin/cpucontrol/intel.c
index 96ab704..557cbac 100644
--- a/usr.sbin/cpucontrol/intel.c
+++ b/usr.sbin/cpucontrol/intel.c
@@ -86,7 +86,7 @@ intel_update(const char *dev, const char *path)
intel_fw_header_t *fw_header;
intel_cpu_signature_t *ext_table;
intel_ext_header_t *ext_header;
- uint32_t signature, flags;
+ uint32_t sig, signature, flags;
int32_t revision;
ssize_t ext_size;
size_t ext_table_size;
@@ -145,7 +145,7 @@ intel_update(const char *dev, const char *path)
fd = open(path, O_RDONLY, 0);
if (fd < 0) {
WARN(0, "open(%s)", path);
- return;
+ goto fail;
}
error = fstat(fd, &st);
if (error != 0) {
@@ -229,7 +229,8 @@ intel_update(const char *dev, const char *path)
for (i = 0; i < (ext_table_size / sizeof(uint32_t)); i++)
sum += *((uint32_t *)ext_header + i);
if (sum != 0) {
- WARNX(2, "%s: extended signature table checksum invalid",
+ WARNX(2,
+ "%s: extended signature table checksum invalid",
path);
goto no_table;
}
@@ -244,10 +245,10 @@ no_table:
*/
if (signature == fw_header->cpu_signature &&
(flags & fw_header->cpu_flags) != 0)
- goto matched;
+ goto matched;
else if (have_ext_table != 0) {
for (i = 0; i < ext_header->sig_count; i++) {
- uint32_t sig = ext_table[i].cpu_signature;
+ sig = ext_table[i].cpu_signature;
if (signature == sig &&
(flags & ext_table[i].cpu_flags) != 0)
goto matched;
@@ -259,17 +260,17 @@ matched:
if (revision >= fw_header->revision) {
WARNX(1, "skipping %s of rev %#x: up to date",
path, fw_header->revision);
- return;
+ goto fail;
}
fprintf(stderr, "%s: updating cpu %s from rev %#x to rev %#x... ",
- path, dev, revision, fw_header->revision);
+ path, dev, revision, fw_header->revision);
args.data = fw_data;
args.size = data_size;
error = ioctl(devfd, CPUCTL_UPDATE, &args);
if (error < 0) {
- error = errno;
+ error = errno;
fprintf(stderr, "failed.\n");
- errno = error;
+ errno = error;
WARN(0, "ioctl()");
goto fail;
}
@@ -283,5 +284,4 @@ fail:
close(devfd);
if (fd >= 0)
close(fd);
- return;
}
diff --git a/usr.sbin/cpucontrol/via.c b/usr.sbin/cpucontrol/via.c
index d17e31f..8985ae6 100644
--- a/usr.sbin/cpucontrol/via.c
+++ b/usr.sbin/cpucontrol/via.c
@@ -138,7 +138,7 @@ via_update(const char *dev, const char *path)
fd = open(path, O_RDONLY, 0);
if (fd < 0) {
WARN(0, "open(%s)", path);
- return;
+ goto fail;
}
error = fstat(fd, &st);
if (error != 0) {
diff --git a/usr.sbin/diskinfo/diskinfo.c b/usr.sbin/diskinfo/diskinfo.c
index 7ce620a..e3378a3 100644
--- a/usr.sbin/diskinfo/diskinfo.c
+++ b/usr.sbin/diskinfo/diskinfo.c
@@ -644,22 +644,22 @@ parwrite(int fd, size_t size, off_t off)
{
struct aiocb aios[MAXIOS];
off_t o;
- size_t s;
int n, error;
struct aiocb *aiop;
- for (n = 0, o = 0; size > MAXIO; n++, size -= s, o += s) {
- s = (size >= MAXIO) ? MAXIO : size;
+ // if size > MAXIO, use AIO to write n - 1 pieces in parallel
+ for (n = 0, o = 0; size > MAXIO; n++, size -= MAXIO, o += MAXIO) {
aiop = &aios[n];
bzero(aiop, sizeof(*aiop));
aiop->aio_buf = &buf[o];
aiop->aio_fildes = fd;
aiop->aio_offset = off + o;
- aiop->aio_nbytes = s;
+ aiop->aio_nbytes = MAXIO;
error = aio_write(aiop);
if (error != 0)
err(EX_IOERR, "AIO write submit error");
}
+ // Use synchronous writes for the runt of size <= MAXIO
error = pwrite(fd, &buf[o], size, off + o);
if (error < 0)
err(EX_IOERR, "Sync write error");
diff --git a/usr.sbin/fdformat/Makefile b/usr.sbin/fdformat/Makefile
index e7b5f23..1b86410 100644
--- a/usr.sbin/fdformat/Makefile
+++ b/usr.sbin/fdformat/Makefile
@@ -3,6 +3,7 @@
.PATH: ${.CURDIR:H}/fdread
PROG= fdformat
+MAN= fdformat.8
SRCS= fdformat.c fdutil.c
CFLAGS+= -I${.CURDIR:H}/fdread
diff --git a/usr.sbin/fdformat/fdformat.1 b/usr.sbin/fdformat/fdformat.8
index 596b09b..17da29e 100644
--- a/usr.sbin/fdformat/fdformat.1
+++ b/usr.sbin/fdformat/fdformat.8
@@ -24,8 +24,8 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 25, 2001
-.Dt FDFORMAT 1
+.Dd December 4, 2017
+.Dt FDFORMAT 8
.Os
.Sh NAME
.Nm fdformat
diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c
index 6a89442..209588a 100644
--- a/usr.sbin/makefs/ffs.c
+++ b/usr.sbin/makefs/ffs.c
@@ -1134,7 +1134,7 @@ ffs_write_inode(union dinode *dp, uint32_t ino, const fsinfo_t *fsopts)
* Initialize inode blocks on the fly for UFS2.
*/
initediblk = ufs_rw32(cgp->cg_initediblk, fsopts->needswap);
- if (ffs_opts->version == 2 && cgino + INOPB(fs) > initediblk &&
+ while (ffs_opts->version == 2 && cgino + INOPB(fs) > initediblk &&
initediblk < ufs_rw32(cgp->cg_niblk, fsopts->needswap)) {
memset(buf, 0, fs->fs_bsize);
dip = (struct ufs2_dinode *)buf;
diff --git a/usr.sbin/nandtool/nand_read.c b/usr.sbin/nandtool/nand_read.c
index 5267b7d..58a41ba 100644
--- a/usr.sbin/nandtool/nand_read.c
+++ b/usr.sbin/nandtool/nand_read.c
@@ -50,7 +50,7 @@ int nand_read(struct cmd_param *params)
}
if ((out = param_get_string(params, "out"))) {
- out_fd = open(out, O_WRONLY|O_CREAT);
+ out_fd = open(out, O_WRONLY|O_CREAT, 0666);
if (out_fd == -1) {
perrorf("Cannot open %s for writing", out);
return (1);
diff --git a/usr.sbin/nandtool/nand_readoob.c b/usr.sbin/nandtool/nand_readoob.c
index 37fd14b..cc66ad3 100644
--- a/usr.sbin/nandtool/nand_readoob.c
+++ b/usr.sbin/nandtool/nand_readoob.c
@@ -57,7 +57,7 @@ int nand_read_oob(struct cmd_param *params)
}
if ((out = param_get_string(params, "out"))) {
- if ((fd_out = open(out, O_WRONLY | O_CREAT)) == -1) {
+ if ((fd_out = open(out, O_WRONLY | O_CREAT, 0666)) == -1) {
perrorf("Cannot open %s", out);
ret = 1;
goto out;
diff --git a/usr.sbin/pw/psdate.c b/usr.sbin/pw/psdate.c
index b63d882..1ce628f 100644
--- a/usr.sbin/pw/psdate.c
+++ b/usr.sbin/pw/psdate.c
@@ -38,7 +38,7 @@ static const char rcsid[] =
#include "psdate.h"
-static int
+int
numerics(char const * str)
{
diff --git a/usr.sbin/pw/psdate.h b/usr.sbin/pw/psdate.h
index a1e99d4..6ae1db2 100644
--- a/usr.sbin/pw/psdate.h
+++ b/usr.sbin/pw/psdate.h
@@ -33,6 +33,7 @@
#include <sys/cdefs.h>
__BEGIN_DECLS
+int numerics(char const * str);
time_t parse_date(time_t dt, char const * str);
void print_date(char *buf, time_t t, int dotime);
__END_DECLS
diff --git a/usr.sbin/pw/pw.8 b/usr.sbin/pw/pw.8
index 4cf52b6..a8304d4 100644
--- a/usr.sbin/pw/pw.8
+++ b/usr.sbin/pw/pw.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 23, 2016
+.Dd December 10, 2017
.Dt PW 8
.Os
.Sh NAME
@@ -611,6 +611,14 @@ that the account expires.
A value of 0 suppresses automatic calculation of the expiry date.
.It Fl p Ar days
Set the default password expiration period in days.
+When
+.Fl D
+is used, the
+.Ar days
+argument is interpreted differently.
+It must be numeric and represents the number of days after creation
+that the account expires.
+A value of 0 suppresses automatic calculation of the expiry date.
.It Fl g Ar group
Set the default group for new users.
If a blank group is specified using
diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h
index 05a51c2..16cf793 100644
--- a/usr.sbin/pw/pw.h
+++ b/usr.sbin/pw/pw.h
@@ -47,6 +47,14 @@ enum _mode
M_NUM
};
+enum _passmode
+{
+ P_NO,
+ P_NONE,
+ P_RANDOM,
+ P_YES
+};
+
enum _which
{
W_USER,
diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c
index a3bd0bd..d4fa99a 100644
--- a/usr.sbin/pw/pw_conf.c
+++ b/usr.sbin/pw/pw_conf.c
@@ -198,18 +198,18 @@ passwd_val(char const * str, int dflt)
for (i = 0; booltrue[i]; i++)
if (strcmp(str, booltrue[i]) == 0)
- return 1;
+ return P_YES;
for (i = 0; boolfalse[i]; i++)
if (strcmp(str, boolfalse[i]) == 0)
- return 0;
+ return P_NO;
/*
* Special cases for defaultpassword
*/
if (strcmp(str, "random") == 0)
- return -1;
+ return P_RANDOM;
if (strcmp(str, "none") == 0)
- return -2;
+ return P_NONE;
errx(1, "Invalid value for default password");
}
diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c
index 92d5c6c..61931c1 100644
--- a/usr.sbin/pw/pw_user.c
+++ b/usr.sbin/pw/pw_user.c
@@ -515,7 +515,9 @@ pw_password(struct userconf * cnf, char const * user, bool dryrun)
char pwbuf[32];
switch (cnf->default_password) {
- case -1: /* Random password */
+ case P_NONE: /* No password at all! */
+ return "";
+ case P_RANDOM: /* Random password */
l = (arc4random() % 8 + 8); /* 8 - 16 chars */
for (i = 0; i < l; i++)
pwbuf[i] = chars[arc4random_uniform(sizeof(chars)-1)];
@@ -531,17 +533,13 @@ pw_password(struct userconf * cnf, char const * user, bool dryrun)
fflush(stdout);
}
break;
-
- case -2: /* No password at all! */
- return "";
-
- case 0: /* No login - default */
- default:
- return "*";
-
- case 1: /* user's name */
+ case P_YES: /* user's name */
strlcpy(pwbuf, user, sizeof(pwbuf));
break;
+ case P_NO: /* No login - default */
+ /* FALLTHROUGH */
+ default:
+ return "*";
}
return pw_pwcrypt(pwbuf);
}
@@ -1122,11 +1120,20 @@ validate_mode(char *mode)
return (m);
}
+static long
+validate_expire(char *str, int opt)
+{
+ if (!numerics(str))
+ errx(EX_DATAERR, "-%c argument must be numeric "
+ "when setting defaults: %s", (char)opt, str);
+ return strtol(str, NULL, 0);
+}
+
static void
mix_config(struct userconf *cmdcnf, struct userconf *cfg)
{
- if (cmdcnf->default_password == 0)
+ if (cmdcnf->default_password < 0)
cmdcnf->default_password = cfg->default_password;
if (cmdcnf->reuse_uids == 0)
cmdcnf->reuse_uids = cfg->reuse_uids;
@@ -1164,9 +1171,9 @@ mix_config(struct userconf *cmdcnf, struct userconf *cfg)
cmdcnf->min_gid = cfg->min_gid;
if (cmdcnf->max_gid == 0)
cmdcnf->max_gid = cfg->max_gid;
- if (cmdcnf->expire_days == 0)
+ if (cmdcnf->expire_days < 0)
cmdcnf->expire_days = cfg->expire_days;
- if (cmdcnf->password_days == 0)
+ if (cmdcnf->password_days < 0)
cmdcnf->password_days = cfg->password_days;
}
@@ -1198,6 +1205,9 @@ pw_user_add(int argc, char **argv, char *arg1)
if ((cmdcnf = calloc(1, sizeof(struct userconf))) == NULL)
err(EXIT_FAILURE, "calloc()");
+ cmdcnf->default_password = cmdcnf->expire_days = cmdcnf->password_days = -1;
+ now = time(NULL);
+
if (arg1 != NULL) {
if (arg1[strspn(arg1, "0123456789")] == '\0')
id = pw_checkid(arg1, UID_MAX);
@@ -1226,12 +1236,16 @@ pw_user_add(int argc, char **argv, char *arg1)
homedir = optarg;
break;
case 'e':
- now = time(NULL);
- cmdcnf->expire_days = parse_date(now, optarg);
+ if (genconf)
+ cmdcnf->expire_days = validate_expire(optarg, ch);
+ else
+ cmdcnf->expire_days = parse_date(now, optarg);
break;
case 'p':
- now = time(NULL);
- cmdcnf->password_days = parse_date(now, optarg);
+ if (genconf)
+ cmdcnf->password_days = validate_expire(optarg, ch);
+ else
+ cmdcnf->password_days = parse_date(now, optarg);
break;
case 'g':
validate_grname(cmdcnf, optarg);
@@ -1369,8 +1383,13 @@ pw_user_add(int argc, char **argv, char *arg1)
pwd->pw_uid = pw_uidpolicy(cmdcnf, id);
pwd->pw_gid = pw_gidpolicy(cnf, grname, pwd->pw_name,
(gid_t) pwd->pw_uid, dryrun);
- pwd->pw_change = cmdcnf->password_days;
- pwd->pw_expire = cmdcnf->expire_days;
+
+ /* cmdcnf->password_days and cmdcnf->expire_days hold unixtime here */
+ if (cmdcnf->password_days > 0)
+ pwd->pw_change = cmdcnf->password_days;
+ if (cmdcnf->expire_days > 0)
+ pwd->pw_expire = cmdcnf->expire_days;
+
pwd->pw_dir = pw_homepolicy(cmdcnf, homedir, pwd->pw_name);
pwd->pw_shell = pw_shellpolicy(cmdcnf);
lc = login_getpwclass(pwd);
@@ -1503,14 +1522,15 @@ pw_user_mod(int argc, char **argv, char *arg1)
bool quiet, createhome, pretty, dryrun, nis, edited;
bool precrypted;
mode_t homemode = 0;
- time_t expire_days, password_days, now;
+ time_t expire_time, password_time, now;
- expire_days = password_days = -1;
+ expire_time = password_time = -1;
gecos = homedir = grname = name = newname = skel = shell =NULL;
passwd = NULL;
class = nispasswd = NULL;
quiet = createhome = pretty = dryrun = nis = precrypted = false;
edited = false;
+ now = time(NULL);
if (arg1 != NULL) {
if (arg1[strspn(arg1, "0123456789")] == '\0')
@@ -1540,12 +1560,10 @@ pw_user_mod(int argc, char **argv, char *arg1)
homedir = optarg;
break;
case 'e':
- now = time(NULL);
- expire_days = parse_date(now, optarg);
+ expire_time = parse_date(now, optarg);
break;
case 'p':
- now = time(NULL);
- password_days = parse_date(now, optarg);
+ password_time = parse_date(now, optarg);
break;
case 'g':
group_from_name_or_id(optarg);
@@ -1679,13 +1697,14 @@ pw_user_mod(int argc, char **argv, char *arg1)
}
}
- if (password_days >= 0 && pwd->pw_change != password_days) {
- pwd->pw_change = password_days;
+
+ if (password_time >= 0 && pwd->pw_change != password_time) {
+ pwd->pw_change = password_time;
edited = true;
}
- if (expire_days >= 0 && pwd->pw_expire != expire_days) {
- pwd->pw_expire = expire_days;
+ if (expire_time >= 0 && pwd->pw_expire != expire_time) {
+ pwd->pw_expire = expire_time;
edited = true;
}
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
index 71f03e1..33efb0f 100644
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -1658,7 +1658,7 @@ configfiles(const struct dirent *dp)
return (1);
}
-static void
+static struct filed **
readconfigfile(FILE *cf, struct filed **nextp, int allow_includes)
{
FILE *cf2;
@@ -1719,7 +1719,7 @@ readconfigfile(FILE *cf, struct filed **nextp, int allow_includes)
if (cf2 == NULL)
continue;
dprintf("reading %s\n", file);
- readconfigfile(cf2, nextp, 0);
+ nextp = readconfigfile(cf2, nextp, 0);
fclose(cf2);
}
free(ent);
@@ -1786,6 +1786,7 @@ readconfigfile(FILE *cf, struct filed **nextp, int allow_includes)
nextp = &f->f_next;
cfline(cline, f, prog, host);
}
+ return nextp;
}
/*
OpenPOWER on IntegriCloud