├── .gitignore ├── LICENSE ├── Makefile.in ├── README.md ├── config.guess ├── config.sub ├── configure ├── configure.ac ├── include ├── binsearch.h ├── config.h.in └── xen-interface.h ├── install.sh ├── symbolize.cc ├── uniprof.c ├── xen-interface-arm.c ├── xen-interface-common.c └── xen-interface-x86.c /.gitignore: -------------------------------------------------------------------------------- 1 | ignore/ 2 | autom4te.cache/ 3 | autoscan.log 4 | config.cache 5 | config.log 6 | config.status 7 | include/config.h 8 | include/config.h.in~ 9 | Makefile 10 | *.o 11 | .*.d 12 | uniprof 13 | symbolize 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, NEC Europe Ltd., NEC Corporation All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 3. Neither the name of the copyright holder nor the names of its contributors 12 | may be used to endorse or promote products derived from this software without 13 | specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | ARCH = @target_arch@ 2 | CC = @CC@ 3 | CXX = @CXX@ 4 | prefix = @prefix@ 5 | exec_prefix = @exec_prefix@ 6 | 7 | # we have two options: build against installed system libraries and headers, 8 | # or build against a xen source tree. We have to set flags accordingly 9 | 10 | ifeq (@use_syslibs@,y) 11 | # OPTION 1: build against system libraries and headers 12 | ARCH = @target_arch@ 13 | CPPFLAGS += -D__XEN_TOOLS__ -Iinclude 14 | CFLAGS += @oflags@ -Wall -Wextra -MMD -MF .$(if $(filter-out .,$(@D)),$(subst /,@,$(@D))@)$(@F).d 15 | CXXFLAGS += @oflags@ -Wall -Wextra -MMD -MF .$(if $(filter-out .,$(@D)),$(subst /,@,$(@D))@)$(@F).d 16 | ifeq (@hypercall_lib@,libxc) 17 | LDLIBS += -lxenctrl 18 | else 19 | LDLIBS += -lxencall -lxenforeignmemory 20 | endif 21 | 22 | else 23 | # OPTION 2: build against Xen source tree 24 | XEN_ROOT ?= $(realpath @xenroot@) 25 | include $(XEN_ROOT)/tools/Rules.mk 26 | CPPFLAGS += -D__XEN_TOOLS__ -Iinclude 27 | CFLAGS += $(CFLAGS_libxenctrl) @oflags@ -Wall -Wextra 28 | CXXFLAGS += @oflags@ -Wall -Wextra -MMD -MF .$(if $(filter-out .,$(@D)),$(subst /,@,$(@D))@)$(@F).d 29 | ifeq (@hypercall_lib@,libxc) 30 | LDLIBS += $(LDLIBS_libxenctrl) 31 | else 32 | LDLIBS += $(LDLIBS_libxencall) $(LDLIBS_libxenforeignmemory) 33 | endif 34 | endif 35 | 36 | LDLIBS += @libunwind@ 37 | 38 | BIN = uniprof symbolize 39 | OBJ = $(addsuffix .o,$(BIN)) xen-interface-common.o xen-interface-$(ARCH).o 40 | DEP = $(addprefix .,$(addsuffix .d,$(OBJ))) 41 | 42 | .PHONY: all 43 | all: $(BIN) 44 | 45 | .PHONY: clean distclean 46 | clean: 47 | $(RM) *.a *.so *.o $(BIN) $(DEP) $(OBJ) 48 | 49 | distclean: clean 50 | -rm -rf autom4te.cache/ 51 | $(RM) config.log autoscan.log config.cache config.log config.status include/config.h Makefile 52 | 53 | install: $(BIN) 54 | /bin/cp -v $(BIN) @bindir@/ 55 | 56 | .PHONY: uninstall 57 | uninstall: 58 | rm -vf $(addprefix @bindir@/, $(BIN)) 59 | 60 | uniprof: uniprof.o xen-interface-common.o xen-interface-$(ARCH).o 61 | $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(APPEND_LDFLAGS) 62 | 63 | symbolize: symbolize.o 64 | $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $< $(APPEND_LDFLAGS) 65 | 66 | -include $(DEP) 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | uniprof: Xen Domain Stack Profiler 2 | ======================== 3 | 4 | uniprof is a stack tracer/profiler for Xen domains, primarily, but not 5 | exclusively, for unikernels. It allows producing stack traces of a running 6 | domU, at specified sampling rates, from outside (typically dom0). 7 | These traces can then be aggregated to produce profiling information and 8 | visualization, for example, via [flame 9 | graphs](https://github.com/brendangregg/FlameGraph). 10 | 11 | Building and using the stack tracer 12 | ---------------------------------- 13 | 14 | ### Quick start 15 | If you already have Xen and its tools installed (and why wouldn't you if you 16 | want to use this tool), then you can simply do the following: 17 | 18 | ./configure 19 | make 20 | 21 | Afterwards, run ./uniprof --help for an overview of the command line. 22 | 23 | ### Supported CPU architectures 24 | uniprof supports both x86 and ARM. 25 | 26 | ### Build options 27 | The configure script has several options that you can set to influence the 28 | build. 29 | 30 | ###### --with-libxc / --with-libxencall 31 | These two options control which library uniprof is built against. There are 32 | two options: either libxc, the classic, but less performant approach, and 33 | libxencall/libxenforeignmemory, introduced with Xen 4.7, that are faster, 34 | lower-level libraries to issue hypercalls and map memory between domains. By 35 | default, libxencall/libxenforeignmemory are used if they are available. You can 36 | enforce using libxc by giving the --with-libxc option to configure. Note that 37 | this will not work when building on ARM, because libxc does not provide the 38 | necessary memory address translation functionality for ARM. (This also means 39 | that you have to use Xen 4.7 or newer on ARM.) 40 | 41 | ###### --with-xen=\ 42 | Instead of using the system headers and libraries installed by Xen, you can 43 | also build against a Xen source tree. Make sure you at the very least ran a 44 | "make tools" inside that source tree, so that the required libraries are 45 | available. 46 | 47 | ###### --without-libunwind 48 | If the configure script finds the libunwind-xen library, it will by default 49 | add support for it to uniprof. If, for some reason, you do not want this 50 | behavior, you can disable building against libunwind. 51 | 52 | ### Profiling a domain using the frame pointer register 53 | As a first test, start a unikernel domain, note its domid, and run 54 | 55 | ./uniprof -F 1 -T 1 - [domid] 56 | 57 | You should see an output of a stack trace. If you don't, then you probably 58 | compiled your unikernel with -fomit-frame-pointer. Either recompile your 59 | unikernel with -fno-omit-frame-pointer, or see below on how to use a specially 60 | patched libunwind to unwind the stack. 61 | 62 | However, even then, you will notice that you only get a bunch of memory 63 | addresses as output, similar to this: 64 | 65 | 0x422c3c 66 | 0x413930 67 | 0x41953c 68 | 69 | This isn't exactly helpful. Indeed, you need a symbol table to translate 70 | addresses into function names. To create that, locate your unikernel binary 71 | and run `nm -n [image] > [image].syms` on it. For this, your binary must NOT 72 | be stripped! You are, however, welcome to strip it after running `nm`, if 73 | you prefer. 74 | 75 | You now have two options: online resolution or offline resolution. Online 76 | resolution means to do the symbol resolution during the stack trace. This is 77 | helpful for rapid checking of functionality and the occasional single stack 78 | trace. To do so, add the `-s [symbolfile]` command line option to 79 | uniprof. You will now see more helpful output: 80 | 81 | block_domain+0x88 82 | schedule+0x230 83 | xenbus_thread_func+0x128 84 | 85 | However, this incurs a slight performance overhead, since each 86 | address must be resolved to a symbol during the stack walk. For performance 87 | profiling, you might therefore prefer to only record the addresses and resolve 88 | them offline after finishing the profiling run. To do so, use the 89 | `symbolize` tool provided. 90 | 91 | ### Profiling a domain using libunwind-xen 92 | If you cannot or do not want to use the frame pointer register to unwind the 93 | stack, you can use a specially patched version of libunwind (available at 94 | https://github.com/sysml/libunwind) to do the unwinding. This requires 95 | you to have the ELF binary available, and that binary to contain an `.eh_frame` 96 | section (which generally is there by default). uniprof then compares the 97 | current IP register to information in the `.eh_frame` to assess the size of the 98 | currently running function's stack frame. It then restores the return address 99 | and iterates the lookup process until the end of the stack is reached. 100 | 101 | Note that this is currently significantly slower than the frame pointer 102 | method, due to overhead introduced by the libunwind core functions. However, 103 | it allows you to create stack traces for VMs that don't use the frame 104 | pointer. 105 | 106 | To use this feature, use the `-e` or `-E` option when starting uniprof, 107 | providing the ELF binary of the kernel as parameter. If the binary is 108 | unstripped, the `-E` option will also give you symbol resolution. 109 | 110 | ### Using uniprof for standard Operating Systems 111 | If your Xen domain is not a unikernel, but rather a standard kernel with 112 | user-space tools running concurrently, you can still use uniprof, albeit with 113 | some limitations. First of all, you will need to acquire a symbol table, which 114 | you will need to resolve the stack addresses to function names. Especially in 115 | case of dynamically-loaded parts of the kernel (e.g., Linux kernel modules), 116 | you cannot simply rely on a statically-created symbol table via the `nm` 117 | method. For Linux, you will instead need the dynamic symbol table, which you 118 | can retrieve from /proc/kallsyms if the kernel was compiled with 119 | CONFIG\_KALLSYMS. Note that this only allows you to resolve kernel symbols; 120 | userspace symbols are still non-resolved, so you will need to filter those out 121 | from your traces to create useful profiling. When using the Linux kernel, you 122 | will probably have more success and more meaningful results if you set up 123 | `perf` profiling inside your domain, but uniprof can still help traving from 124 | the outside in case tracing from the inside is impossible (e.g., tracking down 125 | insidious kernel bugs) or when using operating systems with less-developed 126 | profiling tools. 127 | 128 | Further documentation 129 | --------------------- 130 | 131 | I presented uniprof at the Xen Developer and Design Summit 2017. Here's a 132 | [video of the talk](https://www.youtube.com/watch?v=aUzrm8hBMzc), and 133 | [the slide set](http://flosch.eu/papers/2017-xensummit-uniprof-slides.pdf). 134 | 135 | You can also get a more general overview and problem statement from the 136 | [two-page summary of uniprof](http://flosch.eu/papers/2017-sigcomm-uniprof.pdf) 137 | written as a poster abstract for SIGCOMM 2017. 138 | -------------------------------------------------------------------------------- /config.guess: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Attempt to guess a canonical system name. 3 | # Copyright 1992-2016 Free Software Foundation, Inc. 4 | 5 | timestamp='2016-05-15' 6 | 7 | # This file is free software; you can redistribute it and/or modify it 8 | # under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, see . 19 | # 20 | # As a special exception to the GNU General Public License, if you 21 | # distribute this file as part of a program that contains a 22 | # configuration script generated by Autoconf, you may include it under 23 | # the same distribution terms that you use for the rest of that 24 | # program. This Exception is an additional permission under section 7 25 | # of the GNU General Public License, version 3 ("GPLv3"). 26 | # 27 | # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. 28 | # 29 | # You can get the latest version of this script from: 30 | # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess 31 | # 32 | # Please send patches to . 33 | 34 | 35 | me=`echo "$0" | sed -e 's,.*/,,'` 36 | 37 | usage="\ 38 | Usage: $0 [OPTION] 39 | 40 | Output the configuration name of the system \`$me' is run on. 41 | 42 | Operation modes: 43 | -h, --help print this help, then exit 44 | -t, --time-stamp print date of last modification, then exit 45 | -v, --version print version number, then exit 46 | 47 | Report bugs and patches to ." 48 | 49 | version="\ 50 | GNU config.guess ($timestamp) 51 | 52 | Originally written by Per Bothner. 53 | Copyright 1992-2016 Free Software Foundation, Inc. 54 | 55 | This is free software; see the source for copying conditions. There is NO 56 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." 57 | 58 | help=" 59 | Try \`$me --help' for more information." 60 | 61 | # Parse command line 62 | while test $# -gt 0 ; do 63 | case $1 in 64 | --time-stamp | --time* | -t ) 65 | echo "$timestamp" ; exit ;; 66 | --version | -v ) 67 | echo "$version" ; exit ;; 68 | --help | --h* | -h ) 69 | echo "$usage"; exit ;; 70 | -- ) # Stop option processing 71 | shift; break ;; 72 | - ) # Use stdin as input. 73 | break ;; 74 | -* ) 75 | echo "$me: invalid option $1$help" >&2 76 | exit 1 ;; 77 | * ) 78 | break ;; 79 | esac 80 | done 81 | 82 | if test $# != 0; then 83 | echo "$me: too many arguments$help" >&2 84 | exit 1 85 | fi 86 | 87 | trap 'exit 1' 1 2 15 88 | 89 | # CC_FOR_BUILD -- compiler used by this script. Note that the use of a 90 | # compiler to aid in system detection is discouraged as it requires 91 | # temporary files to be created and, as you can see below, it is a 92 | # headache to deal with in a portable fashion. 93 | 94 | # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still 95 | # use `HOST_CC' if defined, but it is deprecated. 96 | 97 | # Portable tmp directory creation inspired by the Autoconf team. 98 | 99 | set_cc_for_build=' 100 | trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; 101 | trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; 102 | : ${TMPDIR=/tmp} ; 103 | { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || 104 | { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || 105 | { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || 106 | { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; 107 | dummy=$tmp/dummy ; 108 | tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; 109 | case $CC_FOR_BUILD,$HOST_CC,$CC in 110 | ,,) echo "int x;" > $dummy.c ; 111 | for c in cc gcc c89 c99 ; do 112 | if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then 113 | CC_FOR_BUILD="$c"; break ; 114 | fi ; 115 | done ; 116 | if test x"$CC_FOR_BUILD" = x ; then 117 | CC_FOR_BUILD=no_compiler_found ; 118 | fi 119 | ;; 120 | ,,*) CC_FOR_BUILD=$CC ;; 121 | ,*,*) CC_FOR_BUILD=$HOST_CC ;; 122 | esac ; set_cc_for_build= ;' 123 | 124 | # This is needed to find uname on a Pyramid OSx when run in the BSD universe. 125 | # (ghazi@noc.rutgers.edu 1994-08-24) 126 | if (test -f /.attbin/uname) >/dev/null 2>&1 ; then 127 | PATH=$PATH:/.attbin ; export PATH 128 | fi 129 | 130 | UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown 131 | UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown 132 | UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown 133 | UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown 134 | 135 | case "${UNAME_SYSTEM}" in 136 | Linux|GNU|GNU/*) 137 | # If the system lacks a compiler, then just pick glibc. 138 | # We could probably try harder. 139 | LIBC=gnu 140 | 141 | eval $set_cc_for_build 142 | cat <<-EOF > $dummy.c 143 | #include 144 | #if defined(__UCLIBC__) 145 | LIBC=uclibc 146 | #elif defined(__dietlibc__) 147 | LIBC=dietlibc 148 | #else 149 | LIBC=gnu 150 | #endif 151 | EOF 152 | eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` 153 | ;; 154 | esac 155 | 156 | # Note: order is significant - the case branches are not exclusive. 157 | 158 | case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in 159 | *:NetBSD:*:*) 160 | # NetBSD (nbsd) targets should (where applicable) match one or 161 | # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, 162 | # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently 163 | # switched to ELF, *-*-netbsd* would select the old 164 | # object file format. This provides both forward 165 | # compatibility and a consistent mechanism for selecting the 166 | # object file format. 167 | # 168 | # Note: NetBSD doesn't particularly care about the vendor 169 | # portion of the name. We always set it to "unknown". 170 | sysctl="sysctl -n hw.machine_arch" 171 | UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ 172 | /sbin/$sysctl 2>/dev/null || \ 173 | /usr/sbin/$sysctl 2>/dev/null || \ 174 | echo unknown)` 175 | case "${UNAME_MACHINE_ARCH}" in 176 | armeb) machine=armeb-unknown ;; 177 | arm*) machine=arm-unknown ;; 178 | sh3el) machine=shl-unknown ;; 179 | sh3eb) machine=sh-unknown ;; 180 | sh5el) machine=sh5le-unknown ;; 181 | earmv*) 182 | arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` 183 | endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` 184 | machine=${arch}${endian}-unknown 185 | ;; 186 | *) machine=${UNAME_MACHINE_ARCH}-unknown ;; 187 | esac 188 | # The Operating System including object format, if it has switched 189 | # to ELF recently (or will in the future) and ABI. 190 | case "${UNAME_MACHINE_ARCH}" in 191 | earm*) 192 | os=netbsdelf 193 | ;; 194 | arm*|i386|m68k|ns32k|sh3*|sparc|vax) 195 | eval $set_cc_for_build 196 | if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ 197 | | grep -q __ELF__ 198 | then 199 | # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). 200 | # Return netbsd for either. FIX? 201 | os=netbsd 202 | else 203 | os=netbsdelf 204 | fi 205 | ;; 206 | *) 207 | os=netbsd 208 | ;; 209 | esac 210 | # Determine ABI tags. 211 | case "${UNAME_MACHINE_ARCH}" in 212 | earm*) 213 | expr='s/^earmv[0-9]/-eabi/;s/eb$//' 214 | abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` 215 | ;; 216 | esac 217 | # The OS release 218 | # Debian GNU/NetBSD machines have a different userland, and 219 | # thus, need a distinct triplet. However, they do not need 220 | # kernel version information, so it can be replaced with a 221 | # suitable tag, in the style of linux-gnu. 222 | case "${UNAME_VERSION}" in 223 | Debian*) 224 | release='-gnu' 225 | ;; 226 | *) 227 | release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` 228 | ;; 229 | esac 230 | # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: 231 | # contains redundant information, the shorter form: 232 | # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. 233 | echo "${machine}-${os}${release}${abi}" 234 | exit ;; 235 | *:Bitrig:*:*) 236 | UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` 237 | echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} 238 | exit ;; 239 | *:OpenBSD:*:*) 240 | UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` 241 | echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} 242 | exit ;; 243 | *:LibertyBSD:*:*) 244 | UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` 245 | echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} 246 | exit ;; 247 | *:ekkoBSD:*:*) 248 | echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} 249 | exit ;; 250 | *:SolidBSD:*:*) 251 | echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} 252 | exit ;; 253 | macppc:MirBSD:*:*) 254 | echo powerpc-unknown-mirbsd${UNAME_RELEASE} 255 | exit ;; 256 | *:MirBSD:*:*) 257 | echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} 258 | exit ;; 259 | *:Sortix:*:*) 260 | echo ${UNAME_MACHINE}-unknown-sortix 261 | exit ;; 262 | alpha:OSF1:*:*) 263 | case $UNAME_RELEASE in 264 | *4.0) 265 | UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` 266 | ;; 267 | *5.*) 268 | UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` 269 | ;; 270 | esac 271 | # According to Compaq, /usr/sbin/psrinfo has been available on 272 | # OSF/1 and Tru64 systems produced since 1995. I hope that 273 | # covers most systems running today. This code pipes the CPU 274 | # types through head -n 1, so we only detect the type of CPU 0. 275 | ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` 276 | case "$ALPHA_CPU_TYPE" in 277 | "EV4 (21064)") 278 | UNAME_MACHINE=alpha ;; 279 | "EV4.5 (21064)") 280 | UNAME_MACHINE=alpha ;; 281 | "LCA4 (21066/21068)") 282 | UNAME_MACHINE=alpha ;; 283 | "EV5 (21164)") 284 | UNAME_MACHINE=alphaev5 ;; 285 | "EV5.6 (21164A)") 286 | UNAME_MACHINE=alphaev56 ;; 287 | "EV5.6 (21164PC)") 288 | UNAME_MACHINE=alphapca56 ;; 289 | "EV5.7 (21164PC)") 290 | UNAME_MACHINE=alphapca57 ;; 291 | "EV6 (21264)") 292 | UNAME_MACHINE=alphaev6 ;; 293 | "EV6.7 (21264A)") 294 | UNAME_MACHINE=alphaev67 ;; 295 | "EV6.8CB (21264C)") 296 | UNAME_MACHINE=alphaev68 ;; 297 | "EV6.8AL (21264B)") 298 | UNAME_MACHINE=alphaev68 ;; 299 | "EV6.8CX (21264D)") 300 | UNAME_MACHINE=alphaev68 ;; 301 | "EV6.9A (21264/EV69A)") 302 | UNAME_MACHINE=alphaev69 ;; 303 | "EV7 (21364)") 304 | UNAME_MACHINE=alphaev7 ;; 305 | "EV7.9 (21364A)") 306 | UNAME_MACHINE=alphaev79 ;; 307 | esac 308 | # A Pn.n version is a patched version. 309 | # A Vn.n version is a released version. 310 | # A Tn.n version is a released field test version. 311 | # A Xn.n version is an unreleased experimental baselevel. 312 | # 1.2 uses "1.2" for uname -r. 313 | echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` 314 | # Reset EXIT trap before exiting to avoid spurious non-zero exit code. 315 | exitcode=$? 316 | trap '' 0 317 | exit $exitcode ;; 318 | Alpha\ *:Windows_NT*:*) 319 | # How do we know it's Interix rather than the generic POSIX subsystem? 320 | # Should we change UNAME_MACHINE based on the output of uname instead 321 | # of the specific Alpha model? 322 | echo alpha-pc-interix 323 | exit ;; 324 | 21064:Windows_NT:50:3) 325 | echo alpha-dec-winnt3.5 326 | exit ;; 327 | Amiga*:UNIX_System_V:4.0:*) 328 | echo m68k-unknown-sysv4 329 | exit ;; 330 | *:[Aa]miga[Oo][Ss]:*:*) 331 | echo ${UNAME_MACHINE}-unknown-amigaos 332 | exit ;; 333 | *:[Mm]orph[Oo][Ss]:*:*) 334 | echo ${UNAME_MACHINE}-unknown-morphos 335 | exit ;; 336 | *:OS/390:*:*) 337 | echo i370-ibm-openedition 338 | exit ;; 339 | *:z/VM:*:*) 340 | echo s390-ibm-zvmoe 341 | exit ;; 342 | *:OS400:*:*) 343 | echo powerpc-ibm-os400 344 | exit ;; 345 | arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) 346 | echo arm-acorn-riscix${UNAME_RELEASE} 347 | exit ;; 348 | arm*:riscos:*:*|arm*:RISCOS:*:*) 349 | echo arm-unknown-riscos 350 | exit ;; 351 | SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) 352 | echo hppa1.1-hitachi-hiuxmpp 353 | exit ;; 354 | Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) 355 | # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. 356 | if test "`(/bin/universe) 2>/dev/null`" = att ; then 357 | echo pyramid-pyramid-sysv3 358 | else 359 | echo pyramid-pyramid-bsd 360 | fi 361 | exit ;; 362 | NILE*:*:*:dcosx) 363 | echo pyramid-pyramid-svr4 364 | exit ;; 365 | DRS?6000:unix:4.0:6*) 366 | echo sparc-icl-nx6 367 | exit ;; 368 | DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) 369 | case `/usr/bin/uname -p` in 370 | sparc) echo sparc-icl-nx7; exit ;; 371 | esac ;; 372 | s390x:SunOS:*:*) 373 | echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 374 | exit ;; 375 | sun4H:SunOS:5.*:*) 376 | echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 377 | exit ;; 378 | sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) 379 | echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 380 | exit ;; 381 | i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) 382 | echo i386-pc-auroraux${UNAME_RELEASE} 383 | exit ;; 384 | i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) 385 | eval $set_cc_for_build 386 | SUN_ARCH=i386 387 | # If there is a compiler, see if it is configured for 64-bit objects. 388 | # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. 389 | # This test works for both compilers. 390 | if [ "$CC_FOR_BUILD" != no_compiler_found ]; then 391 | if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ 392 | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ 393 | grep IS_64BIT_ARCH >/dev/null 394 | then 395 | SUN_ARCH=x86_64 396 | fi 397 | fi 398 | echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 399 | exit ;; 400 | sun4*:SunOS:6*:*) 401 | # According to config.sub, this is the proper way to canonicalize 402 | # SunOS6. Hard to guess exactly what SunOS6 will be like, but 403 | # it's likely to be more like Solaris than SunOS4. 404 | echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 405 | exit ;; 406 | sun4*:SunOS:*:*) 407 | case "`/usr/bin/arch -k`" in 408 | Series*|S4*) 409 | UNAME_RELEASE=`uname -v` 410 | ;; 411 | esac 412 | # Japanese Language versions have a version number like `4.1.3-JL'. 413 | echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` 414 | exit ;; 415 | sun3*:SunOS:*:*) 416 | echo m68k-sun-sunos${UNAME_RELEASE} 417 | exit ;; 418 | sun*:*:4.2BSD:*) 419 | UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` 420 | test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 421 | case "`/bin/arch`" in 422 | sun3) 423 | echo m68k-sun-sunos${UNAME_RELEASE} 424 | ;; 425 | sun4) 426 | echo sparc-sun-sunos${UNAME_RELEASE} 427 | ;; 428 | esac 429 | exit ;; 430 | aushp:SunOS:*:*) 431 | echo sparc-auspex-sunos${UNAME_RELEASE} 432 | exit ;; 433 | # The situation for MiNT is a little confusing. The machine name 434 | # can be virtually everything (everything which is not 435 | # "atarist" or "atariste" at least should have a processor 436 | # > m68000). The system name ranges from "MiNT" over "FreeMiNT" 437 | # to the lowercase version "mint" (or "freemint"). Finally 438 | # the system name "TOS" denotes a system which is actually not 439 | # MiNT. But MiNT is downward compatible to TOS, so this should 440 | # be no problem. 441 | atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) 442 | echo m68k-atari-mint${UNAME_RELEASE} 443 | exit ;; 444 | atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) 445 | echo m68k-atari-mint${UNAME_RELEASE} 446 | exit ;; 447 | *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) 448 | echo m68k-atari-mint${UNAME_RELEASE} 449 | exit ;; 450 | milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) 451 | echo m68k-milan-mint${UNAME_RELEASE} 452 | exit ;; 453 | hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) 454 | echo m68k-hades-mint${UNAME_RELEASE} 455 | exit ;; 456 | *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) 457 | echo m68k-unknown-mint${UNAME_RELEASE} 458 | exit ;; 459 | m68k:machten:*:*) 460 | echo m68k-apple-machten${UNAME_RELEASE} 461 | exit ;; 462 | powerpc:machten:*:*) 463 | echo powerpc-apple-machten${UNAME_RELEASE} 464 | exit ;; 465 | RISC*:Mach:*:*) 466 | echo mips-dec-mach_bsd4.3 467 | exit ;; 468 | RISC*:ULTRIX:*:*) 469 | echo mips-dec-ultrix${UNAME_RELEASE} 470 | exit ;; 471 | VAX*:ULTRIX*:*:*) 472 | echo vax-dec-ultrix${UNAME_RELEASE} 473 | exit ;; 474 | 2020:CLIX:*:* | 2430:CLIX:*:*) 475 | echo clipper-intergraph-clix${UNAME_RELEASE} 476 | exit ;; 477 | mips:*:*:UMIPS | mips:*:*:RISCos) 478 | eval $set_cc_for_build 479 | sed 's/^ //' << EOF >$dummy.c 480 | #ifdef __cplusplus 481 | #include /* for printf() prototype */ 482 | int main (int argc, char *argv[]) { 483 | #else 484 | int main (argc, argv) int argc; char *argv[]; { 485 | #endif 486 | #if defined (host_mips) && defined (MIPSEB) 487 | #if defined (SYSTYPE_SYSV) 488 | printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); 489 | #endif 490 | #if defined (SYSTYPE_SVR4) 491 | printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); 492 | #endif 493 | #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) 494 | printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); 495 | #endif 496 | #endif 497 | exit (-1); 498 | } 499 | EOF 500 | $CC_FOR_BUILD -o $dummy $dummy.c && 501 | dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && 502 | SYSTEM_NAME=`$dummy $dummyarg` && 503 | { echo "$SYSTEM_NAME"; exit; } 504 | echo mips-mips-riscos${UNAME_RELEASE} 505 | exit ;; 506 | Motorola:PowerMAX_OS:*:*) 507 | echo powerpc-motorola-powermax 508 | exit ;; 509 | Motorola:*:4.3:PL8-*) 510 | echo powerpc-harris-powermax 511 | exit ;; 512 | Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) 513 | echo powerpc-harris-powermax 514 | exit ;; 515 | Night_Hawk:Power_UNIX:*:*) 516 | echo powerpc-harris-powerunix 517 | exit ;; 518 | m88k:CX/UX:7*:*) 519 | echo m88k-harris-cxux7 520 | exit ;; 521 | m88k:*:4*:R4*) 522 | echo m88k-motorola-sysv4 523 | exit ;; 524 | m88k:*:3*:R3*) 525 | echo m88k-motorola-sysv3 526 | exit ;; 527 | AViiON:dgux:*:*) 528 | # DG/UX returns AViiON for all architectures 529 | UNAME_PROCESSOR=`/usr/bin/uname -p` 530 | if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] 531 | then 532 | if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ 533 | [ ${TARGET_BINARY_INTERFACE}x = x ] 534 | then 535 | echo m88k-dg-dgux${UNAME_RELEASE} 536 | else 537 | echo m88k-dg-dguxbcs${UNAME_RELEASE} 538 | fi 539 | else 540 | echo i586-dg-dgux${UNAME_RELEASE} 541 | fi 542 | exit ;; 543 | M88*:DolphinOS:*:*) # DolphinOS (SVR3) 544 | echo m88k-dolphin-sysv3 545 | exit ;; 546 | M88*:*:R3*:*) 547 | # Delta 88k system running SVR3 548 | echo m88k-motorola-sysv3 549 | exit ;; 550 | XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) 551 | echo m88k-tektronix-sysv3 552 | exit ;; 553 | Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) 554 | echo m68k-tektronix-bsd 555 | exit ;; 556 | *:IRIX*:*:*) 557 | echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` 558 | exit ;; 559 | ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. 560 | echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id 561 | exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' 562 | i*86:AIX:*:*) 563 | echo i386-ibm-aix 564 | exit ;; 565 | ia64:AIX:*:*) 566 | if [ -x /usr/bin/oslevel ] ; then 567 | IBM_REV=`/usr/bin/oslevel` 568 | else 569 | IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} 570 | fi 571 | echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} 572 | exit ;; 573 | *:AIX:2:3) 574 | if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then 575 | eval $set_cc_for_build 576 | sed 's/^ //' << EOF >$dummy.c 577 | #include 578 | 579 | main() 580 | { 581 | if (!__power_pc()) 582 | exit(1); 583 | puts("powerpc-ibm-aix3.2.5"); 584 | exit(0); 585 | } 586 | EOF 587 | if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` 588 | then 589 | echo "$SYSTEM_NAME" 590 | else 591 | echo rs6000-ibm-aix3.2.5 592 | fi 593 | elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then 594 | echo rs6000-ibm-aix3.2.4 595 | else 596 | echo rs6000-ibm-aix3.2 597 | fi 598 | exit ;; 599 | *:AIX:*:[4567]) 600 | IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` 601 | if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then 602 | IBM_ARCH=rs6000 603 | else 604 | IBM_ARCH=powerpc 605 | fi 606 | if [ -x /usr/bin/lslpp ] ; then 607 | IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | 608 | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` 609 | else 610 | IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} 611 | fi 612 | echo ${IBM_ARCH}-ibm-aix${IBM_REV} 613 | exit ;; 614 | *:AIX:*:*) 615 | echo rs6000-ibm-aix 616 | exit ;; 617 | ibmrt:4.4BSD:*|romp-ibm:BSD:*) 618 | echo romp-ibm-bsd4.4 619 | exit ;; 620 | ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and 621 | echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to 622 | exit ;; # report: romp-ibm BSD 4.3 623 | *:BOSX:*:*) 624 | echo rs6000-bull-bosx 625 | exit ;; 626 | DPX/2?00:B.O.S.:*:*) 627 | echo m68k-bull-sysv3 628 | exit ;; 629 | 9000/[34]??:4.3bsd:1.*:*) 630 | echo m68k-hp-bsd 631 | exit ;; 632 | hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) 633 | echo m68k-hp-bsd4.4 634 | exit ;; 635 | 9000/[34678]??:HP-UX:*:*) 636 | HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` 637 | case "${UNAME_MACHINE}" in 638 | 9000/31? ) HP_ARCH=m68000 ;; 639 | 9000/[34]?? ) HP_ARCH=m68k ;; 640 | 9000/[678][0-9][0-9]) 641 | if [ -x /usr/bin/getconf ]; then 642 | sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` 643 | sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` 644 | case "${sc_cpu_version}" in 645 | 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 646 | 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 647 | 532) # CPU_PA_RISC2_0 648 | case "${sc_kernel_bits}" in 649 | 32) HP_ARCH=hppa2.0n ;; 650 | 64) HP_ARCH=hppa2.0w ;; 651 | '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 652 | esac ;; 653 | esac 654 | fi 655 | if [ "${HP_ARCH}" = "" ]; then 656 | eval $set_cc_for_build 657 | sed 's/^ //' << EOF >$dummy.c 658 | 659 | #define _HPUX_SOURCE 660 | #include 661 | #include 662 | 663 | int main () 664 | { 665 | #if defined(_SC_KERNEL_BITS) 666 | long bits = sysconf(_SC_KERNEL_BITS); 667 | #endif 668 | long cpu = sysconf (_SC_CPU_VERSION); 669 | 670 | switch (cpu) 671 | { 672 | case CPU_PA_RISC1_0: puts ("hppa1.0"); break; 673 | case CPU_PA_RISC1_1: puts ("hppa1.1"); break; 674 | case CPU_PA_RISC2_0: 675 | #if defined(_SC_KERNEL_BITS) 676 | switch (bits) 677 | { 678 | case 64: puts ("hppa2.0w"); break; 679 | case 32: puts ("hppa2.0n"); break; 680 | default: puts ("hppa2.0"); break; 681 | } break; 682 | #else /* !defined(_SC_KERNEL_BITS) */ 683 | puts ("hppa2.0"); break; 684 | #endif 685 | default: puts ("hppa1.0"); break; 686 | } 687 | exit (0); 688 | } 689 | EOF 690 | (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` 691 | test -z "$HP_ARCH" && HP_ARCH=hppa 692 | fi ;; 693 | esac 694 | if [ ${HP_ARCH} = hppa2.0w ] 695 | then 696 | eval $set_cc_for_build 697 | 698 | # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating 699 | # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler 700 | # generating 64-bit code. GNU and HP use different nomenclature: 701 | # 702 | # $ CC_FOR_BUILD=cc ./config.guess 703 | # => hppa2.0w-hp-hpux11.23 704 | # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess 705 | # => hppa64-hp-hpux11.23 706 | 707 | if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | 708 | grep -q __LP64__ 709 | then 710 | HP_ARCH=hppa2.0w 711 | else 712 | HP_ARCH=hppa64 713 | fi 714 | fi 715 | echo ${HP_ARCH}-hp-hpux${HPUX_REV} 716 | exit ;; 717 | ia64:HP-UX:*:*) 718 | HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` 719 | echo ia64-hp-hpux${HPUX_REV} 720 | exit ;; 721 | 3050*:HI-UX:*:*) 722 | eval $set_cc_for_build 723 | sed 's/^ //' << EOF >$dummy.c 724 | #include 725 | int 726 | main () 727 | { 728 | long cpu = sysconf (_SC_CPU_VERSION); 729 | /* The order matters, because CPU_IS_HP_MC68K erroneously returns 730 | true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct 731 | results, however. */ 732 | if (CPU_IS_PA_RISC (cpu)) 733 | { 734 | switch (cpu) 735 | { 736 | case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; 737 | case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; 738 | case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; 739 | default: puts ("hppa-hitachi-hiuxwe2"); break; 740 | } 741 | } 742 | else if (CPU_IS_HP_MC68K (cpu)) 743 | puts ("m68k-hitachi-hiuxwe2"); 744 | else puts ("unknown-hitachi-hiuxwe2"); 745 | exit (0); 746 | } 747 | EOF 748 | $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && 749 | { echo "$SYSTEM_NAME"; exit; } 750 | echo unknown-hitachi-hiuxwe2 751 | exit ;; 752 | 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) 753 | echo hppa1.1-hp-bsd 754 | exit ;; 755 | 9000/8??:4.3bsd:*:*) 756 | echo hppa1.0-hp-bsd 757 | exit ;; 758 | *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) 759 | echo hppa1.0-hp-mpeix 760 | exit ;; 761 | hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) 762 | echo hppa1.1-hp-osf 763 | exit ;; 764 | hp8??:OSF1:*:*) 765 | echo hppa1.0-hp-osf 766 | exit ;; 767 | i*86:OSF1:*:*) 768 | if [ -x /usr/sbin/sysversion ] ; then 769 | echo ${UNAME_MACHINE}-unknown-osf1mk 770 | else 771 | echo ${UNAME_MACHINE}-unknown-osf1 772 | fi 773 | exit ;; 774 | parisc*:Lites*:*:*) 775 | echo hppa1.1-hp-lites 776 | exit ;; 777 | C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) 778 | echo c1-convex-bsd 779 | exit ;; 780 | C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) 781 | if getsysinfo -f scalar_acc 782 | then echo c32-convex-bsd 783 | else echo c2-convex-bsd 784 | fi 785 | exit ;; 786 | C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) 787 | echo c34-convex-bsd 788 | exit ;; 789 | C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) 790 | echo c38-convex-bsd 791 | exit ;; 792 | C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) 793 | echo c4-convex-bsd 794 | exit ;; 795 | CRAY*Y-MP:*:*:*) 796 | echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 797 | exit ;; 798 | CRAY*[A-Z]90:*:*:*) 799 | echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ 800 | | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ 801 | -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ 802 | -e 's/\.[^.]*$/.X/' 803 | exit ;; 804 | CRAY*TS:*:*:*) 805 | echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 806 | exit ;; 807 | CRAY*T3E:*:*:*) 808 | echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 809 | exit ;; 810 | CRAY*SV1:*:*:*) 811 | echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 812 | exit ;; 813 | *:UNICOS/mp:*:*) 814 | echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 815 | exit ;; 816 | F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) 817 | FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` 818 | FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` 819 | FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` 820 | echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" 821 | exit ;; 822 | 5000:UNIX_System_V:4.*:*) 823 | FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` 824 | FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` 825 | echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" 826 | exit ;; 827 | i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) 828 | echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} 829 | exit ;; 830 | sparc*:BSD/OS:*:*) 831 | echo sparc-unknown-bsdi${UNAME_RELEASE} 832 | exit ;; 833 | *:BSD/OS:*:*) 834 | echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} 835 | exit ;; 836 | *:FreeBSD:*:*) 837 | UNAME_PROCESSOR=`/usr/bin/uname -p` 838 | case ${UNAME_PROCESSOR} in 839 | amd64) 840 | echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; 841 | *) 842 | echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; 843 | esac 844 | exit ;; 845 | i*:CYGWIN*:*) 846 | echo ${UNAME_MACHINE}-pc-cygwin 847 | exit ;; 848 | *:MINGW64*:*) 849 | echo ${UNAME_MACHINE}-pc-mingw64 850 | exit ;; 851 | *:MINGW*:*) 852 | echo ${UNAME_MACHINE}-pc-mingw32 853 | exit ;; 854 | *:MSYS*:*) 855 | echo ${UNAME_MACHINE}-pc-msys 856 | exit ;; 857 | i*:windows32*:*) 858 | # uname -m includes "-pc" on this system. 859 | echo ${UNAME_MACHINE}-mingw32 860 | exit ;; 861 | i*:PW*:*) 862 | echo ${UNAME_MACHINE}-pc-pw32 863 | exit ;; 864 | *:Interix*:*) 865 | case ${UNAME_MACHINE} in 866 | x86) 867 | echo i586-pc-interix${UNAME_RELEASE} 868 | exit ;; 869 | authenticamd | genuineintel | EM64T) 870 | echo x86_64-unknown-interix${UNAME_RELEASE} 871 | exit ;; 872 | IA64) 873 | echo ia64-unknown-interix${UNAME_RELEASE} 874 | exit ;; 875 | esac ;; 876 | [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) 877 | echo i${UNAME_MACHINE}-pc-mks 878 | exit ;; 879 | 8664:Windows_NT:*) 880 | echo x86_64-pc-mks 881 | exit ;; 882 | i*:Windows_NT*:* | Pentium*:Windows_NT*:*) 883 | # How do we know it's Interix rather than the generic POSIX subsystem? 884 | # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we 885 | # UNAME_MACHINE based on the output of uname instead of i386? 886 | echo i586-pc-interix 887 | exit ;; 888 | i*:UWIN*:*) 889 | echo ${UNAME_MACHINE}-pc-uwin 890 | exit ;; 891 | amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) 892 | echo x86_64-unknown-cygwin 893 | exit ;; 894 | p*:CYGWIN*:*) 895 | echo powerpcle-unknown-cygwin 896 | exit ;; 897 | prep*:SunOS:5.*:*) 898 | echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` 899 | exit ;; 900 | *:GNU:*:*) 901 | # the GNU system 902 | echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` 903 | exit ;; 904 | *:GNU/*:*:*) 905 | # other systems with GNU libc and userland 906 | echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} 907 | exit ;; 908 | i*86:Minix:*:*) 909 | echo ${UNAME_MACHINE}-pc-minix 910 | exit ;; 911 | aarch64:Linux:*:*) 912 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 913 | exit ;; 914 | aarch64_be:Linux:*:*) 915 | UNAME_MACHINE=aarch64_be 916 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 917 | exit ;; 918 | alpha:Linux:*:*) 919 | case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in 920 | EV5) UNAME_MACHINE=alphaev5 ;; 921 | EV56) UNAME_MACHINE=alphaev56 ;; 922 | PCA56) UNAME_MACHINE=alphapca56 ;; 923 | PCA57) UNAME_MACHINE=alphapca56 ;; 924 | EV6) UNAME_MACHINE=alphaev6 ;; 925 | EV67) UNAME_MACHINE=alphaev67 ;; 926 | EV68*) UNAME_MACHINE=alphaev68 ;; 927 | esac 928 | objdump --private-headers /bin/sh | grep -q ld.so.1 929 | if test "$?" = 0 ; then LIBC=gnulibc1 ; fi 930 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 931 | exit ;; 932 | arc:Linux:*:* | arceb:Linux:*:*) 933 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 934 | exit ;; 935 | arm*:Linux:*:*) 936 | eval $set_cc_for_build 937 | if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ 938 | | grep -q __ARM_EABI__ 939 | then 940 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 941 | else 942 | if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ 943 | | grep -q __ARM_PCS_VFP 944 | then 945 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi 946 | else 947 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf 948 | fi 949 | fi 950 | exit ;; 951 | avr32*:Linux:*:*) 952 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 953 | exit ;; 954 | cris:Linux:*:*) 955 | echo ${UNAME_MACHINE}-axis-linux-${LIBC} 956 | exit ;; 957 | crisv32:Linux:*:*) 958 | echo ${UNAME_MACHINE}-axis-linux-${LIBC} 959 | exit ;; 960 | e2k:Linux:*:*) 961 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 962 | exit ;; 963 | frv:Linux:*:*) 964 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 965 | exit ;; 966 | hexagon:Linux:*:*) 967 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 968 | exit ;; 969 | i*86:Linux:*:*) 970 | echo ${UNAME_MACHINE}-pc-linux-${LIBC} 971 | exit ;; 972 | ia64:Linux:*:*) 973 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 974 | exit ;; 975 | k1om:Linux:*:*) 976 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 977 | exit ;; 978 | m32r*:Linux:*:*) 979 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 980 | exit ;; 981 | m68*:Linux:*:*) 982 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 983 | exit ;; 984 | mips:Linux:*:* | mips64:Linux:*:*) 985 | eval $set_cc_for_build 986 | sed 's/^ //' << EOF >$dummy.c 987 | #undef CPU 988 | #undef ${UNAME_MACHINE} 989 | #undef ${UNAME_MACHINE}el 990 | #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) 991 | CPU=${UNAME_MACHINE}el 992 | #else 993 | #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) 994 | CPU=${UNAME_MACHINE} 995 | #else 996 | CPU= 997 | #endif 998 | #endif 999 | EOF 1000 | eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` 1001 | test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } 1002 | ;; 1003 | openrisc*:Linux:*:*) 1004 | echo or1k-unknown-linux-${LIBC} 1005 | exit ;; 1006 | or32:Linux:*:* | or1k*:Linux:*:*) 1007 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1008 | exit ;; 1009 | padre:Linux:*:*) 1010 | echo sparc-unknown-linux-${LIBC} 1011 | exit ;; 1012 | parisc64:Linux:*:* | hppa64:Linux:*:*) 1013 | echo hppa64-unknown-linux-${LIBC} 1014 | exit ;; 1015 | parisc:Linux:*:* | hppa:Linux:*:*) 1016 | # Look for CPU level 1017 | case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in 1018 | PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; 1019 | PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; 1020 | *) echo hppa-unknown-linux-${LIBC} ;; 1021 | esac 1022 | exit ;; 1023 | ppc64:Linux:*:*) 1024 | echo powerpc64-unknown-linux-${LIBC} 1025 | exit ;; 1026 | ppc:Linux:*:*) 1027 | echo powerpc-unknown-linux-${LIBC} 1028 | exit ;; 1029 | ppc64le:Linux:*:*) 1030 | echo powerpc64le-unknown-linux-${LIBC} 1031 | exit ;; 1032 | ppcle:Linux:*:*) 1033 | echo powerpcle-unknown-linux-${LIBC} 1034 | exit ;; 1035 | s390:Linux:*:* | s390x:Linux:*:*) 1036 | echo ${UNAME_MACHINE}-ibm-linux-${LIBC} 1037 | exit ;; 1038 | sh64*:Linux:*:*) 1039 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1040 | exit ;; 1041 | sh*:Linux:*:*) 1042 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1043 | exit ;; 1044 | sparc:Linux:*:* | sparc64:Linux:*:*) 1045 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1046 | exit ;; 1047 | tile*:Linux:*:*) 1048 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1049 | exit ;; 1050 | vax:Linux:*:*) 1051 | echo ${UNAME_MACHINE}-dec-linux-${LIBC} 1052 | exit ;; 1053 | x86_64:Linux:*:*) 1054 | echo ${UNAME_MACHINE}-pc-linux-${LIBC} 1055 | exit ;; 1056 | xtensa*:Linux:*:*) 1057 | echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 1058 | exit ;; 1059 | i*86:DYNIX/ptx:4*:*) 1060 | # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. 1061 | # earlier versions are messed up and put the nodename in both 1062 | # sysname and nodename. 1063 | echo i386-sequent-sysv4 1064 | exit ;; 1065 | i*86:UNIX_SV:4.2MP:2.*) 1066 | # Unixware is an offshoot of SVR4, but it has its own version 1067 | # number series starting with 2... 1068 | # I am not positive that other SVR4 systems won't match this, 1069 | # I just have to hope. -- rms. 1070 | # Use sysv4.2uw... so that sysv4* matches it. 1071 | echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} 1072 | exit ;; 1073 | i*86:OS/2:*:*) 1074 | # If we were able to find `uname', then EMX Unix compatibility 1075 | # is probably installed. 1076 | echo ${UNAME_MACHINE}-pc-os2-emx 1077 | exit ;; 1078 | i*86:XTS-300:*:STOP) 1079 | echo ${UNAME_MACHINE}-unknown-stop 1080 | exit ;; 1081 | i*86:atheos:*:*) 1082 | echo ${UNAME_MACHINE}-unknown-atheos 1083 | exit ;; 1084 | i*86:syllable:*:*) 1085 | echo ${UNAME_MACHINE}-pc-syllable 1086 | exit ;; 1087 | i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) 1088 | echo i386-unknown-lynxos${UNAME_RELEASE} 1089 | exit ;; 1090 | i*86:*DOS:*:*) 1091 | echo ${UNAME_MACHINE}-pc-msdosdjgpp 1092 | exit ;; 1093 | i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) 1094 | UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` 1095 | if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then 1096 | echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} 1097 | else 1098 | echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} 1099 | fi 1100 | exit ;; 1101 | i*86:*:5:[678]*) 1102 | # UnixWare 7.x, OpenUNIX and OpenServer 6. 1103 | case `/bin/uname -X | grep "^Machine"` in 1104 | *486*) UNAME_MACHINE=i486 ;; 1105 | *Pentium) UNAME_MACHINE=i586 ;; 1106 | *Pent*|*Celeron) UNAME_MACHINE=i686 ;; 1107 | esac 1108 | echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} 1109 | exit ;; 1110 | i*86:*:3.2:*) 1111 | if test -f /usr/options/cb.name; then 1112 | UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then 1115 | UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` 1116 | (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 1117 | (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ 1118 | && UNAME_MACHINE=i586 1119 | (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ 1120 | && UNAME_MACHINE=i686 1121 | (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ 1122 | && UNAME_MACHINE=i686 1123 | echo ${UNAME_MACHINE}-pc-sco$UNAME_REL 1124 | else 1125 | echo ${UNAME_MACHINE}-pc-sysv32 1126 | fi 1127 | exit ;; 1128 | pc:*:*:*) 1129 | # Left here for compatibility: 1130 | # uname -m prints for DJGPP always 'pc', but it prints nothing about 1131 | # the processor, so we play safe by assuming i586. 1132 | # Note: whatever this is, it MUST be the same as what config.sub 1133 | # prints for the "djgpp" host, or else GDB configure will decide that 1134 | # this is a cross-build. 1135 | echo i586-pc-msdosdjgpp 1136 | exit ;; 1137 | Intel:Mach:3*:*) 1138 | echo i386-pc-mach3 1139 | exit ;; 1140 | paragon:*:*:*) 1141 | echo i860-intel-osf1 1142 | exit ;; 1143 | i860:*:4.*:*) # i860-SVR4 1144 | if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then 1145 | echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 1146 | else # Add other i860-SVR4 vendors below as they are discovered. 1147 | echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 1148 | fi 1149 | exit ;; 1150 | mini*:CTIX:SYS*5:*) 1151 | # "miniframe" 1152 | echo m68010-convergent-sysv 1153 | exit ;; 1154 | mc68k:UNIX:SYSTEM5:3.51m) 1155 | echo m68k-convergent-sysv 1156 | exit ;; 1157 | M680?0:D-NIX:5.3:*) 1158 | echo m68k-diab-dnix 1159 | exit ;; 1160 | M68*:*:R3V[5678]*:*) 1161 | test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 1162 | 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) 1163 | OS_REL='' 1164 | test -r /etc/.relid \ 1165 | && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` 1166 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ 1167 | && { echo i486-ncr-sysv4.3${OS_REL}; exit; } 1168 | /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ 1169 | && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 1170 | 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) 1171 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ 1172 | && { echo i486-ncr-sysv4; exit; } ;; 1173 | NCR*:*:4.2:* | MPRAS*:*:4.2:*) 1174 | OS_REL='.3' 1175 | test -r /etc/.relid \ 1176 | && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` 1177 | /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ 1178 | && { echo i486-ncr-sysv4.3${OS_REL}; exit; } 1179 | /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ 1180 | && { echo i586-ncr-sysv4.3${OS_REL}; exit; } 1181 | /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ 1182 | && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 1183 | m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) 1184 | echo m68k-unknown-lynxos${UNAME_RELEASE} 1185 | exit ;; 1186 | mc68030:UNIX_System_V:4.*:*) 1187 | echo m68k-atari-sysv4 1188 | exit ;; 1189 | TSUNAMI:LynxOS:2.*:*) 1190 | echo sparc-unknown-lynxos${UNAME_RELEASE} 1191 | exit ;; 1192 | rs6000:LynxOS:2.*:*) 1193 | echo rs6000-unknown-lynxos${UNAME_RELEASE} 1194 | exit ;; 1195 | PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) 1196 | echo powerpc-unknown-lynxos${UNAME_RELEASE} 1197 | exit ;; 1198 | SM[BE]S:UNIX_SV:*:*) 1199 | echo mips-dde-sysv${UNAME_RELEASE} 1200 | exit ;; 1201 | RM*:ReliantUNIX-*:*:*) 1202 | echo mips-sni-sysv4 1203 | exit ;; 1204 | RM*:SINIX-*:*:*) 1205 | echo mips-sni-sysv4 1206 | exit ;; 1207 | *:SINIX-*:*:*) 1208 | if uname -p 2>/dev/null >/dev/null ; then 1209 | UNAME_MACHINE=`(uname -p) 2>/dev/null` 1210 | echo ${UNAME_MACHINE}-sni-sysv4 1211 | else 1212 | echo ns32k-sni-sysv 1213 | fi 1214 | exit ;; 1215 | PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort 1216 | # says 1217 | echo i586-unisys-sysv4 1218 | exit ;; 1219 | *:UNIX_System_V:4*:FTX*) 1220 | # From Gerald Hewes . 1221 | # How about differentiating between stratus architectures? -djm 1222 | echo hppa1.1-stratus-sysv4 1223 | exit ;; 1224 | *:*:*:FTX*) 1225 | # From seanf@swdc.stratus.com. 1226 | echo i860-stratus-sysv4 1227 | exit ;; 1228 | i*86:VOS:*:*) 1229 | # From Paul.Green@stratus.com. 1230 | echo ${UNAME_MACHINE}-stratus-vos 1231 | exit ;; 1232 | *:VOS:*:*) 1233 | # From Paul.Green@stratus.com. 1234 | echo hppa1.1-stratus-vos 1235 | exit ;; 1236 | mc68*:A/UX:*:*) 1237 | echo m68k-apple-aux${UNAME_RELEASE} 1238 | exit ;; 1239 | news*:NEWS-OS:6*:*) 1240 | echo mips-sony-newsos6 1241 | exit ;; 1242 | R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) 1243 | if [ -d /usr/nec ]; then 1244 | echo mips-nec-sysv${UNAME_RELEASE} 1245 | else 1246 | echo mips-unknown-sysv${UNAME_RELEASE} 1247 | fi 1248 | exit ;; 1249 | BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. 1250 | echo powerpc-be-beos 1251 | exit ;; 1252 | BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. 1253 | echo powerpc-apple-beos 1254 | exit ;; 1255 | BePC:BeOS:*:*) # BeOS running on Intel PC compatible. 1256 | echo i586-pc-beos 1257 | exit ;; 1258 | BePC:Haiku:*:*) # Haiku running on Intel PC compatible. 1259 | echo i586-pc-haiku 1260 | exit ;; 1261 | x86_64:Haiku:*:*) 1262 | echo x86_64-unknown-haiku 1263 | exit ;; 1264 | SX-4:SUPER-UX:*:*) 1265 | echo sx4-nec-superux${UNAME_RELEASE} 1266 | exit ;; 1267 | SX-5:SUPER-UX:*:*) 1268 | echo sx5-nec-superux${UNAME_RELEASE} 1269 | exit ;; 1270 | SX-6:SUPER-UX:*:*) 1271 | echo sx6-nec-superux${UNAME_RELEASE} 1272 | exit ;; 1273 | SX-7:SUPER-UX:*:*) 1274 | echo sx7-nec-superux${UNAME_RELEASE} 1275 | exit ;; 1276 | SX-8:SUPER-UX:*:*) 1277 | echo sx8-nec-superux${UNAME_RELEASE} 1278 | exit ;; 1279 | SX-8R:SUPER-UX:*:*) 1280 | echo sx8r-nec-superux${UNAME_RELEASE} 1281 | exit ;; 1282 | SX-ACE:SUPER-UX:*:*) 1283 | echo sxace-nec-superux${UNAME_RELEASE} 1284 | exit ;; 1285 | Power*:Rhapsody:*:*) 1286 | echo powerpc-apple-rhapsody${UNAME_RELEASE} 1287 | exit ;; 1288 | *:Rhapsody:*:*) 1289 | echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} 1290 | exit ;; 1291 | *:Darwin:*:*) 1292 | UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown 1293 | eval $set_cc_for_build 1294 | if test "$UNAME_PROCESSOR" = unknown ; then 1295 | UNAME_PROCESSOR=powerpc 1296 | fi 1297 | if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then 1298 | if [ "$CC_FOR_BUILD" != no_compiler_found ]; then 1299 | if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ 1300 | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ 1301 | grep IS_64BIT_ARCH >/dev/null 1302 | then 1303 | case $UNAME_PROCESSOR in 1304 | i386) UNAME_PROCESSOR=x86_64 ;; 1305 | powerpc) UNAME_PROCESSOR=powerpc64 ;; 1306 | esac 1307 | fi 1308 | fi 1309 | elif test "$UNAME_PROCESSOR" = i386 ; then 1310 | # Avoid executing cc on OS X 10.9, as it ships with a stub 1311 | # that puts up a graphical alert prompting to install 1312 | # developer tools. Any system running Mac OS X 10.7 or 1313 | # later (Darwin 11 and later) is required to have a 64-bit 1314 | # processor. This is not true of the ARM version of Darwin 1315 | # that Apple uses in portable devices. 1316 | UNAME_PROCESSOR=x86_64 1317 | fi 1318 | echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} 1319 | exit ;; 1320 | *:procnto*:*:* | *:QNX:[0123456789]*:*) 1321 | UNAME_PROCESSOR=`uname -p` 1322 | if test "$UNAME_PROCESSOR" = x86; then 1323 | UNAME_PROCESSOR=i386 1324 | UNAME_MACHINE=pc 1325 | fi 1326 | echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} 1327 | exit ;; 1328 | *:QNX:*:4*) 1329 | echo i386-pc-qnx 1330 | exit ;; 1331 | NEO-?:NONSTOP_KERNEL:*:*) 1332 | echo neo-tandem-nsk${UNAME_RELEASE} 1333 | exit ;; 1334 | NSE-*:NONSTOP_KERNEL:*:*) 1335 | echo nse-tandem-nsk${UNAME_RELEASE} 1336 | exit ;; 1337 | NSR-?:NONSTOP_KERNEL:*:*) 1338 | echo nsr-tandem-nsk${UNAME_RELEASE} 1339 | exit ;; 1340 | *:NonStop-UX:*:*) 1341 | echo mips-compaq-nonstopux 1342 | exit ;; 1343 | BS2000:POSIX*:*:*) 1344 | echo bs2000-siemens-sysv 1345 | exit ;; 1346 | DS/*:UNIX_System_V:*:*) 1347 | echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} 1348 | exit ;; 1349 | *:Plan9:*:*) 1350 | # "uname -m" is not consistent, so use $cputype instead. 386 1351 | # is converted to i386 for consistency with other x86 1352 | # operating systems. 1353 | if test "$cputype" = 386; then 1354 | UNAME_MACHINE=i386 1355 | else 1356 | UNAME_MACHINE="$cputype" 1357 | fi 1358 | echo ${UNAME_MACHINE}-unknown-plan9 1359 | exit ;; 1360 | *:TOPS-10:*:*) 1361 | echo pdp10-unknown-tops10 1362 | exit ;; 1363 | *:TENEX:*:*) 1364 | echo pdp10-unknown-tenex 1365 | exit ;; 1366 | KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) 1367 | echo pdp10-dec-tops20 1368 | exit ;; 1369 | XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) 1370 | echo pdp10-xkl-tops20 1371 | exit ;; 1372 | *:TOPS-20:*:*) 1373 | echo pdp10-unknown-tops20 1374 | exit ;; 1375 | *:ITS:*:*) 1376 | echo pdp10-unknown-its 1377 | exit ;; 1378 | SEI:*:*:SEIUX) 1379 | echo mips-sei-seiux${UNAME_RELEASE} 1380 | exit ;; 1381 | *:DragonFly:*:*) 1382 | echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` 1383 | exit ;; 1384 | *:*VMS:*:*) 1385 | UNAME_MACHINE=`(uname -p) 2>/dev/null` 1386 | case "${UNAME_MACHINE}" in 1387 | A*) echo alpha-dec-vms ; exit ;; 1388 | I*) echo ia64-dec-vms ; exit ;; 1389 | V*) echo vax-dec-vms ; exit ;; 1390 | esac ;; 1391 | *:XENIX:*:SysV) 1392 | echo i386-pc-xenix 1393 | exit ;; 1394 | i*86:skyos:*:*) 1395 | echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` 1396 | exit ;; 1397 | i*86:rdos:*:*) 1398 | echo ${UNAME_MACHINE}-pc-rdos 1399 | exit ;; 1400 | i*86:AROS:*:*) 1401 | echo ${UNAME_MACHINE}-pc-aros 1402 | exit ;; 1403 | x86_64:VMkernel:*:*) 1404 | echo ${UNAME_MACHINE}-unknown-esx 1405 | exit ;; 1406 | amd64:Isilon\ OneFS:*:*) 1407 | echo x86_64-unknown-onefs 1408 | exit ;; 1409 | esac 1410 | 1411 | cat >&2 </dev/null || echo unknown` 1429 | uname -r = `(uname -r) 2>/dev/null || echo unknown` 1430 | uname -s = `(uname -s) 2>/dev/null || echo unknown` 1431 | uname -v = `(uname -v) 2>/dev/null || echo unknown` 1432 | 1433 | /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` 1434 | /bin/uname -X = `(/bin/uname -X) 2>/dev/null` 1435 | 1436 | hostinfo = `(hostinfo) 2>/dev/null` 1437 | /bin/universe = `(/bin/universe) 2>/dev/null` 1438 | /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` 1439 | /bin/arch = `(/bin/arch) 2>/dev/null` 1440 | /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` 1441 | /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` 1442 | 1443 | UNAME_MACHINE = ${UNAME_MACHINE} 1444 | UNAME_RELEASE = ${UNAME_RELEASE} 1445 | UNAME_SYSTEM = ${UNAME_SYSTEM} 1446 | UNAME_VERSION = ${UNAME_VERSION} 1447 | EOF 1448 | 1449 | exit 1 1450 | 1451 | # Local variables: 1452 | # eval: (add-hook 'write-file-hooks 'time-stamp) 1453 | # time-stamp-start: "timestamp='" 1454 | # time-stamp-format: "%:y-%02m-%02d" 1455 | # time-stamp-end: "'" 1456 | # End: 1457 | -------------------------------------------------------------------------------- /config.sub: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Configuration validation subroutine script. 3 | # Copyright 1992-2016 Free Software Foundation, Inc. 4 | 5 | timestamp='2016-06-20' 6 | 7 | # This file is free software; you can redistribute it and/or modify it 8 | # under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, see . 19 | # 20 | # As a special exception to the GNU General Public License, if you 21 | # distribute this file as part of a program that contains a 22 | # configuration script generated by Autoconf, you may include it under 23 | # the same distribution terms that you use for the rest of that 24 | # program. This Exception is an additional permission under section 7 25 | # of the GNU General Public License, version 3 ("GPLv3"). 26 | 27 | 28 | # Please send patches to . 29 | # 30 | # Configuration subroutine to validate and canonicalize a configuration type. 31 | # Supply the specified configuration type as an argument. 32 | # If it is invalid, we print an error message on stderr and exit with code 1. 33 | # Otherwise, we print the canonical config type on stdout and succeed. 34 | 35 | # You can get the latest version of this script from: 36 | # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub 37 | 38 | # This file is supposed to be the same for all GNU packages 39 | # and recognize all the CPU types, system types and aliases 40 | # that are meaningful with *any* GNU software. 41 | # Each package is responsible for reporting which valid configurations 42 | # it does not support. The user should be able to distinguish 43 | # a failure to support a valid configuration from a meaningless 44 | # configuration. 45 | 46 | # The goal of this file is to map all the various variations of a given 47 | # machine specification into a single specification in the form: 48 | # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM 49 | # or in some cases, the newer four-part form: 50 | # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM 51 | # It is wrong to echo any other type of specification. 52 | 53 | me=`echo "$0" | sed -e 's,.*/,,'` 54 | 55 | usage="\ 56 | Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS 57 | 58 | Canonicalize a configuration name. 59 | 60 | Operation modes: 61 | -h, --help print this help, then exit 62 | -t, --time-stamp print date of last modification, then exit 63 | -v, --version print version number, then exit 64 | 65 | Report bugs and patches to ." 66 | 67 | version="\ 68 | GNU config.sub ($timestamp) 69 | 70 | Copyright 1992-2016 Free Software Foundation, Inc. 71 | 72 | This is free software; see the source for copying conditions. There is NO 73 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." 74 | 75 | help=" 76 | Try \`$me --help' for more information." 77 | 78 | # Parse command line 79 | while test $# -gt 0 ; do 80 | case $1 in 81 | --time-stamp | --time* | -t ) 82 | echo "$timestamp" ; exit ;; 83 | --version | -v ) 84 | echo "$version" ; exit ;; 85 | --help | --h* | -h ) 86 | echo "$usage"; exit ;; 87 | -- ) # Stop option processing 88 | shift; break ;; 89 | - ) # Use stdin as input. 90 | break ;; 91 | -* ) 92 | echo "$me: invalid option $1$help" 93 | exit 1 ;; 94 | 95 | *local*) 96 | # First pass through any local machine types. 97 | echo $1 98 | exit ;; 99 | 100 | * ) 101 | break ;; 102 | esac 103 | done 104 | 105 | case $# in 106 | 0) echo "$me: missing argument$help" >&2 107 | exit 1;; 108 | 1) ;; 109 | *) echo "$me: too many arguments$help" >&2 110 | exit 1;; 111 | esac 112 | 113 | # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). 114 | # Here we must recognize all the valid KERNEL-OS combinations. 115 | maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` 116 | case $maybe_os in 117 | nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ 118 | linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ 119 | knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ 120 | kopensolaris*-gnu* | \ 121 | storm-chaos* | os2-emx* | rtmk-nova*) 122 | os=-$maybe_os 123 | basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` 124 | ;; 125 | android-linux) 126 | os=-linux-android 127 | basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown 128 | ;; 129 | *) 130 | basic_machine=`echo $1 | sed 's/-[^-]*$//'` 131 | if [ $basic_machine != $1 ] 132 | then os=`echo $1 | sed 's/.*-/-/'` 133 | else os=; fi 134 | ;; 135 | esac 136 | 137 | ### Let's recognize common machines as not being operating systems so 138 | ### that things like config.sub decstation-3100 work. We also 139 | ### recognize some manufacturers as not being operating systems, so we 140 | ### can provide default operating systems below. 141 | case $os in 142 | -sun*os*) 143 | # Prevent following clause from handling this invalid input. 144 | ;; 145 | -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ 146 | -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ 147 | -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ 148 | -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ 149 | -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ 150 | -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ 151 | -apple | -axis | -knuth | -cray | -microblaze*) 152 | os= 153 | basic_machine=$1 154 | ;; 155 | -bluegene*) 156 | os=-cnk 157 | ;; 158 | -sim | -cisco | -oki | -wec | -winbond) 159 | os= 160 | basic_machine=$1 161 | ;; 162 | -scout) 163 | ;; 164 | -wrs) 165 | os=-vxworks 166 | basic_machine=$1 167 | ;; 168 | -chorusos*) 169 | os=-chorusos 170 | basic_machine=$1 171 | ;; 172 | -chorusrdb) 173 | os=-chorusrdb 174 | basic_machine=$1 175 | ;; 176 | -hiux*) 177 | os=-hiuxwe2 178 | ;; 179 | -sco6) 180 | os=-sco5v6 181 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 182 | ;; 183 | -sco5) 184 | os=-sco3.2v5 185 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 186 | ;; 187 | -sco4) 188 | os=-sco3.2v4 189 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 190 | ;; 191 | -sco3.2.[4-9]*) 192 | os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` 193 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 194 | ;; 195 | -sco3.2v[4-9]*) 196 | # Don't forget version if it is 3.2v4 or newer. 197 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 198 | ;; 199 | -sco5v6*) 200 | # Don't forget version if it is 3.2v4 or newer. 201 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 202 | ;; 203 | -sco*) 204 | os=-sco3.2v2 205 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 206 | ;; 207 | -udk*) 208 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 209 | ;; 210 | -isc) 211 | os=-isc2.2 212 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 213 | ;; 214 | -clix*) 215 | basic_machine=clipper-intergraph 216 | ;; 217 | -isc*) 218 | basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 219 | ;; 220 | -lynx*178) 221 | os=-lynxos178 222 | ;; 223 | -lynx*5) 224 | os=-lynxos5 225 | ;; 226 | -lynx*) 227 | os=-lynxos 228 | ;; 229 | -ptx*) 230 | basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` 231 | ;; 232 | -windowsnt*) 233 | os=`echo $os | sed -e 's/windowsnt/winnt/'` 234 | ;; 235 | -psos*) 236 | os=-psos 237 | ;; 238 | -mint | -mint[0-9]*) 239 | basic_machine=m68k-atari 240 | os=-mint 241 | ;; 242 | esac 243 | 244 | # Decode aliases for certain CPU-COMPANY combinations. 245 | case $basic_machine in 246 | # Recognize the basic CPU types without company name. 247 | # Some are omitted here because they have special meanings below. 248 | 1750a | 580 \ 249 | | a29k \ 250 | | aarch64 | aarch64_be \ 251 | | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ 252 | | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ 253 | | am33_2.0 \ 254 | | arc | arceb \ 255 | | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ 256 | | avr | avr32 \ 257 | | ba \ 258 | | be32 | be64 \ 259 | | bfin \ 260 | | c4x | c8051 | clipper \ 261 | | d10v | d30v | dlx | dsp16xx \ 262 | | e2k | epiphany \ 263 | | fido | fr30 | frv | ft32 \ 264 | | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ 265 | | hexagon \ 266 | | i370 | i860 | i960 | ia64 \ 267 | | ip2k | iq2000 \ 268 | | k1om \ 269 | | le32 | le64 \ 270 | | lm32 \ 271 | | m32c | m32r | m32rle | m68000 | m68k | m88k \ 272 | | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ 273 | | mips | mipsbe | mipseb | mipsel | mipsle \ 274 | | mips16 \ 275 | | mips64 | mips64el \ 276 | | mips64octeon | mips64octeonel \ 277 | | mips64orion | mips64orionel \ 278 | | mips64r5900 | mips64r5900el \ 279 | | mips64vr | mips64vrel \ 280 | | mips64vr4100 | mips64vr4100el \ 281 | | mips64vr4300 | mips64vr4300el \ 282 | | mips64vr5000 | mips64vr5000el \ 283 | | mips64vr5900 | mips64vr5900el \ 284 | | mipsisa32 | mipsisa32el \ 285 | | mipsisa32r2 | mipsisa32r2el \ 286 | | mipsisa32r6 | mipsisa32r6el \ 287 | | mipsisa64 | mipsisa64el \ 288 | | mipsisa64r2 | mipsisa64r2el \ 289 | | mipsisa64r6 | mipsisa64r6el \ 290 | | mipsisa64sb1 | mipsisa64sb1el \ 291 | | mipsisa64sr71k | mipsisa64sr71kel \ 292 | | mipsr5900 | mipsr5900el \ 293 | | mipstx39 | mipstx39el \ 294 | | mn10200 | mn10300 \ 295 | | moxie \ 296 | | mt \ 297 | | msp430 \ 298 | | nds32 | nds32le | nds32be \ 299 | | nios | nios2 | nios2eb | nios2el \ 300 | | ns16k | ns32k \ 301 | | open8 | or1k | or1knd | or32 \ 302 | | pdp10 | pdp11 | pj | pjl \ 303 | | powerpc | powerpc64 | powerpc64le | powerpcle \ 304 | | pyramid \ 305 | | riscv32 | riscv64 \ 306 | | rl78 | rx \ 307 | | score \ 308 | | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ 309 | | sh64 | sh64le \ 310 | | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ 311 | | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ 312 | | spu \ 313 | | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ 314 | | ubicom32 \ 315 | | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ 316 | | visium \ 317 | | we32k \ 318 | | x86 | xc16x | xstormy16 | xtensa \ 319 | | z8k | z80) 320 | basic_machine=$basic_machine-unknown 321 | ;; 322 | c54x) 323 | basic_machine=tic54x-unknown 324 | ;; 325 | c55x) 326 | basic_machine=tic55x-unknown 327 | ;; 328 | c6x) 329 | basic_machine=tic6x-unknown 330 | ;; 331 | leon|leon[3-9]) 332 | basic_machine=sparc-$basic_machine 333 | ;; 334 | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) 335 | basic_machine=$basic_machine-unknown 336 | os=-none 337 | ;; 338 | m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) 339 | ;; 340 | ms1) 341 | basic_machine=mt-unknown 342 | ;; 343 | 344 | strongarm | thumb | xscale) 345 | basic_machine=arm-unknown 346 | ;; 347 | xgate) 348 | basic_machine=$basic_machine-unknown 349 | os=-none 350 | ;; 351 | xscaleeb) 352 | basic_machine=armeb-unknown 353 | ;; 354 | 355 | xscaleel) 356 | basic_machine=armel-unknown 357 | ;; 358 | 359 | # We use `pc' rather than `unknown' 360 | # because (1) that's what they normally are, and 361 | # (2) the word "unknown" tends to confuse beginning users. 362 | i*86 | x86_64) 363 | basic_machine=$basic_machine-pc 364 | ;; 365 | # Object if more than one company name word. 366 | *-*-*) 367 | echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 368 | exit 1 369 | ;; 370 | # Recognize the basic CPU types with company name. 371 | 580-* \ 372 | | a29k-* \ 373 | | aarch64-* | aarch64_be-* \ 374 | | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ 375 | | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ 376 | | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ 377 | | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ 378 | | avr-* | avr32-* \ 379 | | ba-* \ 380 | | be32-* | be64-* \ 381 | | bfin-* | bs2000-* \ 382 | | c[123]* | c30-* | [cjt]90-* | c4x-* \ 383 | | c8051-* | clipper-* | craynv-* | cydra-* \ 384 | | d10v-* | d30v-* | dlx-* \ 385 | | e2k-* | elxsi-* \ 386 | | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ 387 | | h8300-* | h8500-* \ 388 | | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ 389 | | hexagon-* \ 390 | | i*86-* | i860-* | i960-* | ia64-* \ 391 | | ip2k-* | iq2000-* \ 392 | | k1om-* \ 393 | | le32-* | le64-* \ 394 | | lm32-* \ 395 | | m32c-* | m32r-* | m32rle-* \ 396 | | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ 397 | | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ 398 | | microblaze-* | microblazeel-* \ 399 | | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ 400 | | mips16-* \ 401 | | mips64-* | mips64el-* \ 402 | | mips64octeon-* | mips64octeonel-* \ 403 | | mips64orion-* | mips64orionel-* \ 404 | | mips64r5900-* | mips64r5900el-* \ 405 | | mips64vr-* | mips64vrel-* \ 406 | | mips64vr4100-* | mips64vr4100el-* \ 407 | | mips64vr4300-* | mips64vr4300el-* \ 408 | | mips64vr5000-* | mips64vr5000el-* \ 409 | | mips64vr5900-* | mips64vr5900el-* \ 410 | | mipsisa32-* | mipsisa32el-* \ 411 | | mipsisa32r2-* | mipsisa32r2el-* \ 412 | | mipsisa32r6-* | mipsisa32r6el-* \ 413 | | mipsisa64-* | mipsisa64el-* \ 414 | | mipsisa64r2-* | mipsisa64r2el-* \ 415 | | mipsisa64r6-* | mipsisa64r6el-* \ 416 | | mipsisa64sb1-* | mipsisa64sb1el-* \ 417 | | mipsisa64sr71k-* | mipsisa64sr71kel-* \ 418 | | mipsr5900-* | mipsr5900el-* \ 419 | | mipstx39-* | mipstx39el-* \ 420 | | mmix-* \ 421 | | mt-* \ 422 | | msp430-* \ 423 | | nds32-* | nds32le-* | nds32be-* \ 424 | | nios-* | nios2-* | nios2eb-* | nios2el-* \ 425 | | none-* | np1-* | ns16k-* | ns32k-* \ 426 | | open8-* \ 427 | | or1k*-* \ 428 | | orion-* \ 429 | | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ 430 | | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ 431 | | pyramid-* \ 432 | | riscv32-* | riscv64-* \ 433 | | rl78-* | romp-* | rs6000-* | rx-* \ 434 | | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ 435 | | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ 436 | | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ 437 | | sparclite-* \ 438 | | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ 439 | | tahoe-* \ 440 | | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ 441 | | tile*-* \ 442 | | tron-* \ 443 | | ubicom32-* \ 444 | | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ 445 | | vax-* \ 446 | | visium-* \ 447 | | we32k-* \ 448 | | x86-* | x86_64-* | xc16x-* | xps100-* \ 449 | | xstormy16-* | xtensa*-* \ 450 | | ymp-* \ 451 | | z8k-* | z80-*) 452 | ;; 453 | # Recognize the basic CPU types without company name, with glob match. 454 | xtensa*) 455 | basic_machine=$basic_machine-unknown 456 | ;; 457 | # Recognize the various machine names and aliases which stand 458 | # for a CPU type and a company and sometimes even an OS. 459 | 386bsd) 460 | basic_machine=i386-unknown 461 | os=-bsd 462 | ;; 463 | 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) 464 | basic_machine=m68000-att 465 | ;; 466 | 3b*) 467 | basic_machine=we32k-att 468 | ;; 469 | a29khif) 470 | basic_machine=a29k-amd 471 | os=-udi 472 | ;; 473 | abacus) 474 | basic_machine=abacus-unknown 475 | ;; 476 | adobe68k) 477 | basic_machine=m68010-adobe 478 | os=-scout 479 | ;; 480 | alliant | fx80) 481 | basic_machine=fx80-alliant 482 | ;; 483 | altos | altos3068) 484 | basic_machine=m68k-altos 485 | ;; 486 | am29k) 487 | basic_machine=a29k-none 488 | os=-bsd 489 | ;; 490 | amd64) 491 | basic_machine=x86_64-pc 492 | ;; 493 | amd64-*) 494 | basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` 495 | ;; 496 | amdahl) 497 | basic_machine=580-amdahl 498 | os=-sysv 499 | ;; 500 | amiga | amiga-*) 501 | basic_machine=m68k-unknown 502 | ;; 503 | amigaos | amigados) 504 | basic_machine=m68k-unknown 505 | os=-amigaos 506 | ;; 507 | amigaunix | amix) 508 | basic_machine=m68k-unknown 509 | os=-sysv4 510 | ;; 511 | apollo68) 512 | basic_machine=m68k-apollo 513 | os=-sysv 514 | ;; 515 | apollo68bsd) 516 | basic_machine=m68k-apollo 517 | os=-bsd 518 | ;; 519 | aros) 520 | basic_machine=i386-pc 521 | os=-aros 522 | ;; 523 | asmjs) 524 | basic_machine=asmjs-unknown 525 | ;; 526 | aux) 527 | basic_machine=m68k-apple 528 | os=-aux 529 | ;; 530 | balance) 531 | basic_machine=ns32k-sequent 532 | os=-dynix 533 | ;; 534 | blackfin) 535 | basic_machine=bfin-unknown 536 | os=-linux 537 | ;; 538 | blackfin-*) 539 | basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` 540 | os=-linux 541 | ;; 542 | bluegene*) 543 | basic_machine=powerpc-ibm 544 | os=-cnk 545 | ;; 546 | c54x-*) 547 | basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` 548 | ;; 549 | c55x-*) 550 | basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` 551 | ;; 552 | c6x-*) 553 | basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` 554 | ;; 555 | c90) 556 | basic_machine=c90-cray 557 | os=-unicos 558 | ;; 559 | cegcc) 560 | basic_machine=arm-unknown 561 | os=-cegcc 562 | ;; 563 | convex-c1) 564 | basic_machine=c1-convex 565 | os=-bsd 566 | ;; 567 | convex-c2) 568 | basic_machine=c2-convex 569 | os=-bsd 570 | ;; 571 | convex-c32) 572 | basic_machine=c32-convex 573 | os=-bsd 574 | ;; 575 | convex-c34) 576 | basic_machine=c34-convex 577 | os=-bsd 578 | ;; 579 | convex-c38) 580 | basic_machine=c38-convex 581 | os=-bsd 582 | ;; 583 | cray | j90) 584 | basic_machine=j90-cray 585 | os=-unicos 586 | ;; 587 | craynv) 588 | basic_machine=craynv-cray 589 | os=-unicosmp 590 | ;; 591 | cr16 | cr16-*) 592 | basic_machine=cr16-unknown 593 | os=-elf 594 | ;; 595 | crds | unos) 596 | basic_machine=m68k-crds 597 | ;; 598 | crisv32 | crisv32-* | etraxfs*) 599 | basic_machine=crisv32-axis 600 | ;; 601 | cris | cris-* | etrax*) 602 | basic_machine=cris-axis 603 | ;; 604 | crx) 605 | basic_machine=crx-unknown 606 | os=-elf 607 | ;; 608 | da30 | da30-*) 609 | basic_machine=m68k-da30 610 | ;; 611 | decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) 612 | basic_machine=mips-dec 613 | ;; 614 | decsystem10* | dec10*) 615 | basic_machine=pdp10-dec 616 | os=-tops10 617 | ;; 618 | decsystem20* | dec20*) 619 | basic_machine=pdp10-dec 620 | os=-tops20 621 | ;; 622 | delta | 3300 | motorola-3300 | motorola-delta \ 623 | | 3300-motorola | delta-motorola) 624 | basic_machine=m68k-motorola 625 | ;; 626 | delta88) 627 | basic_machine=m88k-motorola 628 | os=-sysv3 629 | ;; 630 | dicos) 631 | basic_machine=i686-pc 632 | os=-dicos 633 | ;; 634 | djgpp) 635 | basic_machine=i586-pc 636 | os=-msdosdjgpp 637 | ;; 638 | dpx20 | dpx20-*) 639 | basic_machine=rs6000-bull 640 | os=-bosx 641 | ;; 642 | dpx2* | dpx2*-bull) 643 | basic_machine=m68k-bull 644 | os=-sysv3 645 | ;; 646 | e500v[12]) 647 | basic_machine=powerpc-unknown 648 | os=$os"spe" 649 | ;; 650 | e500v[12]-*) 651 | basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` 652 | os=$os"spe" 653 | ;; 654 | ebmon29k) 655 | basic_machine=a29k-amd 656 | os=-ebmon 657 | ;; 658 | elxsi) 659 | basic_machine=elxsi-elxsi 660 | os=-bsd 661 | ;; 662 | encore | umax | mmax) 663 | basic_machine=ns32k-encore 664 | ;; 665 | es1800 | OSE68k | ose68k | ose | OSE) 666 | basic_machine=m68k-ericsson 667 | os=-ose 668 | ;; 669 | fx2800) 670 | basic_machine=i860-alliant 671 | ;; 672 | genix) 673 | basic_machine=ns32k-ns 674 | ;; 675 | gmicro) 676 | basic_machine=tron-gmicro 677 | os=-sysv 678 | ;; 679 | go32) 680 | basic_machine=i386-pc 681 | os=-go32 682 | ;; 683 | h3050r* | hiux*) 684 | basic_machine=hppa1.1-hitachi 685 | os=-hiuxwe2 686 | ;; 687 | h8300hms) 688 | basic_machine=h8300-hitachi 689 | os=-hms 690 | ;; 691 | h8300xray) 692 | basic_machine=h8300-hitachi 693 | os=-xray 694 | ;; 695 | h8500hms) 696 | basic_machine=h8500-hitachi 697 | os=-hms 698 | ;; 699 | harris) 700 | basic_machine=m88k-harris 701 | os=-sysv3 702 | ;; 703 | hp300-*) 704 | basic_machine=m68k-hp 705 | ;; 706 | hp300bsd) 707 | basic_machine=m68k-hp 708 | os=-bsd 709 | ;; 710 | hp300hpux) 711 | basic_machine=m68k-hp 712 | os=-hpux 713 | ;; 714 | hp3k9[0-9][0-9] | hp9[0-9][0-9]) 715 | basic_machine=hppa1.0-hp 716 | ;; 717 | hp9k2[0-9][0-9] | hp9k31[0-9]) 718 | basic_machine=m68000-hp 719 | ;; 720 | hp9k3[2-9][0-9]) 721 | basic_machine=m68k-hp 722 | ;; 723 | hp9k6[0-9][0-9] | hp6[0-9][0-9]) 724 | basic_machine=hppa1.0-hp 725 | ;; 726 | hp9k7[0-79][0-9] | hp7[0-79][0-9]) 727 | basic_machine=hppa1.1-hp 728 | ;; 729 | hp9k78[0-9] | hp78[0-9]) 730 | # FIXME: really hppa2.0-hp 731 | basic_machine=hppa1.1-hp 732 | ;; 733 | hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) 734 | # FIXME: really hppa2.0-hp 735 | basic_machine=hppa1.1-hp 736 | ;; 737 | hp9k8[0-9][13679] | hp8[0-9][13679]) 738 | basic_machine=hppa1.1-hp 739 | ;; 740 | hp9k8[0-9][0-9] | hp8[0-9][0-9]) 741 | basic_machine=hppa1.0-hp 742 | ;; 743 | hppa-next) 744 | os=-nextstep3 745 | ;; 746 | hppaosf) 747 | basic_machine=hppa1.1-hp 748 | os=-osf 749 | ;; 750 | hppro) 751 | basic_machine=hppa1.1-hp 752 | os=-proelf 753 | ;; 754 | i370-ibm* | ibm*) 755 | basic_machine=i370-ibm 756 | ;; 757 | i*86v32) 758 | basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` 759 | os=-sysv32 760 | ;; 761 | i*86v4*) 762 | basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` 763 | os=-sysv4 764 | ;; 765 | i*86v) 766 | basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` 767 | os=-sysv 768 | ;; 769 | i*86sol2) 770 | basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` 771 | os=-solaris2 772 | ;; 773 | i386mach) 774 | basic_machine=i386-mach 775 | os=-mach 776 | ;; 777 | i386-vsta | vsta) 778 | basic_machine=i386-unknown 779 | os=-vsta 780 | ;; 781 | iris | iris4d) 782 | basic_machine=mips-sgi 783 | case $os in 784 | -irix*) 785 | ;; 786 | *) 787 | os=-irix4 788 | ;; 789 | esac 790 | ;; 791 | isi68 | isi) 792 | basic_machine=m68k-isi 793 | os=-sysv 794 | ;; 795 | leon-*|leon[3-9]-*) 796 | basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` 797 | ;; 798 | m68knommu) 799 | basic_machine=m68k-unknown 800 | os=-linux 801 | ;; 802 | m68knommu-*) 803 | basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` 804 | os=-linux 805 | ;; 806 | m88k-omron*) 807 | basic_machine=m88k-omron 808 | ;; 809 | magnum | m3230) 810 | basic_machine=mips-mips 811 | os=-sysv 812 | ;; 813 | merlin) 814 | basic_machine=ns32k-utek 815 | os=-sysv 816 | ;; 817 | microblaze*) 818 | basic_machine=microblaze-xilinx 819 | ;; 820 | mingw64) 821 | basic_machine=x86_64-pc 822 | os=-mingw64 823 | ;; 824 | mingw32) 825 | basic_machine=i686-pc 826 | os=-mingw32 827 | ;; 828 | mingw32ce) 829 | basic_machine=arm-unknown 830 | os=-mingw32ce 831 | ;; 832 | miniframe) 833 | basic_machine=m68000-convergent 834 | ;; 835 | *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) 836 | basic_machine=m68k-atari 837 | os=-mint 838 | ;; 839 | mips3*-*) 840 | basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` 841 | ;; 842 | mips3*) 843 | basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown 844 | ;; 845 | monitor) 846 | basic_machine=m68k-rom68k 847 | os=-coff 848 | ;; 849 | morphos) 850 | basic_machine=powerpc-unknown 851 | os=-morphos 852 | ;; 853 | moxiebox) 854 | basic_machine=moxie-unknown 855 | os=-moxiebox 856 | ;; 857 | msdos) 858 | basic_machine=i386-pc 859 | os=-msdos 860 | ;; 861 | ms1-*) 862 | basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` 863 | ;; 864 | msys) 865 | basic_machine=i686-pc 866 | os=-msys 867 | ;; 868 | mvs) 869 | basic_machine=i370-ibm 870 | os=-mvs 871 | ;; 872 | nacl) 873 | basic_machine=le32-unknown 874 | os=-nacl 875 | ;; 876 | ncr3000) 877 | basic_machine=i486-ncr 878 | os=-sysv4 879 | ;; 880 | netbsd386) 881 | basic_machine=i386-unknown 882 | os=-netbsd 883 | ;; 884 | netwinder) 885 | basic_machine=armv4l-rebel 886 | os=-linux 887 | ;; 888 | news | news700 | news800 | news900) 889 | basic_machine=m68k-sony 890 | os=-newsos 891 | ;; 892 | news1000) 893 | basic_machine=m68030-sony 894 | os=-newsos 895 | ;; 896 | news-3600 | risc-news) 897 | basic_machine=mips-sony 898 | os=-newsos 899 | ;; 900 | necv70) 901 | basic_machine=v70-nec 902 | os=-sysv 903 | ;; 904 | next | m*-next ) 905 | basic_machine=m68k-next 906 | case $os in 907 | -nextstep* ) 908 | ;; 909 | -ns2*) 910 | os=-nextstep2 911 | ;; 912 | *) 913 | os=-nextstep3 914 | ;; 915 | esac 916 | ;; 917 | nh3000) 918 | basic_machine=m68k-harris 919 | os=-cxux 920 | ;; 921 | nh[45]000) 922 | basic_machine=m88k-harris 923 | os=-cxux 924 | ;; 925 | nindy960) 926 | basic_machine=i960-intel 927 | os=-nindy 928 | ;; 929 | mon960) 930 | basic_machine=i960-intel 931 | os=-mon960 932 | ;; 933 | nonstopux) 934 | basic_machine=mips-compaq 935 | os=-nonstopux 936 | ;; 937 | np1) 938 | basic_machine=np1-gould 939 | ;; 940 | neo-tandem) 941 | basic_machine=neo-tandem 942 | ;; 943 | nse-tandem) 944 | basic_machine=nse-tandem 945 | ;; 946 | nsr-tandem) 947 | basic_machine=nsr-tandem 948 | ;; 949 | op50n-* | op60c-*) 950 | basic_machine=hppa1.1-oki 951 | os=-proelf 952 | ;; 953 | openrisc | openrisc-*) 954 | basic_machine=or32-unknown 955 | ;; 956 | os400) 957 | basic_machine=powerpc-ibm 958 | os=-os400 959 | ;; 960 | OSE68000 | ose68000) 961 | basic_machine=m68000-ericsson 962 | os=-ose 963 | ;; 964 | os68k) 965 | basic_machine=m68k-none 966 | os=-os68k 967 | ;; 968 | pa-hitachi) 969 | basic_machine=hppa1.1-hitachi 970 | os=-hiuxwe2 971 | ;; 972 | paragon) 973 | basic_machine=i860-intel 974 | os=-osf 975 | ;; 976 | parisc) 977 | basic_machine=hppa-unknown 978 | os=-linux 979 | ;; 980 | parisc-*) 981 | basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` 982 | os=-linux 983 | ;; 984 | pbd) 985 | basic_machine=sparc-tti 986 | ;; 987 | pbb) 988 | basic_machine=m68k-tti 989 | ;; 990 | pc532 | pc532-*) 991 | basic_machine=ns32k-pc532 992 | ;; 993 | pc98) 994 | basic_machine=i386-pc 995 | ;; 996 | pc98-*) 997 | basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` 998 | ;; 999 | pentium | p5 | k5 | k6 | nexgen | viac3) 1000 | basic_machine=i586-pc 1001 | ;; 1002 | pentiumpro | p6 | 6x86 | athlon | athlon_*) 1003 | basic_machine=i686-pc 1004 | ;; 1005 | pentiumii | pentium2 | pentiumiii | pentium3) 1006 | basic_machine=i686-pc 1007 | ;; 1008 | pentium4) 1009 | basic_machine=i786-pc 1010 | ;; 1011 | pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) 1012 | basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` 1013 | ;; 1014 | pentiumpro-* | p6-* | 6x86-* | athlon-*) 1015 | basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` 1016 | ;; 1017 | pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) 1018 | basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` 1019 | ;; 1020 | pentium4-*) 1021 | basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` 1022 | ;; 1023 | pn) 1024 | basic_machine=pn-gould 1025 | ;; 1026 | power) basic_machine=power-ibm 1027 | ;; 1028 | ppc | ppcbe) basic_machine=powerpc-unknown 1029 | ;; 1030 | ppc-* | ppcbe-*) 1031 | basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` 1032 | ;; 1033 | ppcle | powerpclittle | ppc-le | powerpc-little) 1034 | basic_machine=powerpcle-unknown 1035 | ;; 1036 | ppcle-* | powerpclittle-*) 1037 | basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` 1038 | ;; 1039 | ppc64) basic_machine=powerpc64-unknown 1040 | ;; 1041 | ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` 1042 | ;; 1043 | ppc64le | powerpc64little | ppc64-le | powerpc64-little) 1044 | basic_machine=powerpc64le-unknown 1045 | ;; 1046 | ppc64le-* | powerpc64little-*) 1047 | basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` 1048 | ;; 1049 | ps2) 1050 | basic_machine=i386-ibm 1051 | ;; 1052 | pw32) 1053 | basic_machine=i586-unknown 1054 | os=-pw32 1055 | ;; 1056 | rdos | rdos64) 1057 | basic_machine=x86_64-pc 1058 | os=-rdos 1059 | ;; 1060 | rdos32) 1061 | basic_machine=i386-pc 1062 | os=-rdos 1063 | ;; 1064 | rom68k) 1065 | basic_machine=m68k-rom68k 1066 | os=-coff 1067 | ;; 1068 | rm[46]00) 1069 | basic_machine=mips-siemens 1070 | ;; 1071 | rtpc | rtpc-*) 1072 | basic_machine=romp-ibm 1073 | ;; 1074 | s390 | s390-*) 1075 | basic_machine=s390-ibm 1076 | ;; 1077 | s390x | s390x-*) 1078 | basic_machine=s390x-ibm 1079 | ;; 1080 | sa29200) 1081 | basic_machine=a29k-amd 1082 | os=-udi 1083 | ;; 1084 | sb1) 1085 | basic_machine=mipsisa64sb1-unknown 1086 | ;; 1087 | sb1el) 1088 | basic_machine=mipsisa64sb1el-unknown 1089 | ;; 1090 | sde) 1091 | basic_machine=mipsisa32-sde 1092 | os=-elf 1093 | ;; 1094 | sei) 1095 | basic_machine=mips-sei 1096 | os=-seiux 1097 | ;; 1098 | sequent) 1099 | basic_machine=i386-sequent 1100 | ;; 1101 | sh) 1102 | basic_machine=sh-hitachi 1103 | os=-hms 1104 | ;; 1105 | sh5el) 1106 | basic_machine=sh5le-unknown 1107 | ;; 1108 | sh64) 1109 | basic_machine=sh64-unknown 1110 | ;; 1111 | sparclite-wrs | simso-wrs) 1112 | basic_machine=sparclite-wrs 1113 | os=-vxworks 1114 | ;; 1115 | sps7) 1116 | basic_machine=m68k-bull 1117 | os=-sysv2 1118 | ;; 1119 | spur) 1120 | basic_machine=spur-unknown 1121 | ;; 1122 | st2000) 1123 | basic_machine=m68k-tandem 1124 | ;; 1125 | stratus) 1126 | basic_machine=i860-stratus 1127 | os=-sysv4 1128 | ;; 1129 | strongarm-* | thumb-*) 1130 | basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` 1131 | ;; 1132 | sun2) 1133 | basic_machine=m68000-sun 1134 | ;; 1135 | sun2os3) 1136 | basic_machine=m68000-sun 1137 | os=-sunos3 1138 | ;; 1139 | sun2os4) 1140 | basic_machine=m68000-sun 1141 | os=-sunos4 1142 | ;; 1143 | sun3os3) 1144 | basic_machine=m68k-sun 1145 | os=-sunos3 1146 | ;; 1147 | sun3os4) 1148 | basic_machine=m68k-sun 1149 | os=-sunos4 1150 | ;; 1151 | sun4os3) 1152 | basic_machine=sparc-sun 1153 | os=-sunos3 1154 | ;; 1155 | sun4os4) 1156 | basic_machine=sparc-sun 1157 | os=-sunos4 1158 | ;; 1159 | sun4sol2) 1160 | basic_machine=sparc-sun 1161 | os=-solaris2 1162 | ;; 1163 | sun3 | sun3-*) 1164 | basic_machine=m68k-sun 1165 | ;; 1166 | sun4) 1167 | basic_machine=sparc-sun 1168 | ;; 1169 | sun386 | sun386i | roadrunner) 1170 | basic_machine=i386-sun 1171 | ;; 1172 | sv1) 1173 | basic_machine=sv1-cray 1174 | os=-unicos 1175 | ;; 1176 | symmetry) 1177 | basic_machine=i386-sequent 1178 | os=-dynix 1179 | ;; 1180 | t3e) 1181 | basic_machine=alphaev5-cray 1182 | os=-unicos 1183 | ;; 1184 | t90) 1185 | basic_machine=t90-cray 1186 | os=-unicos 1187 | ;; 1188 | tile*) 1189 | basic_machine=$basic_machine-unknown 1190 | os=-linux-gnu 1191 | ;; 1192 | tx39) 1193 | basic_machine=mipstx39-unknown 1194 | ;; 1195 | tx39el) 1196 | basic_machine=mipstx39el-unknown 1197 | ;; 1198 | toad1) 1199 | basic_machine=pdp10-xkl 1200 | os=-tops20 1201 | ;; 1202 | tower | tower-32) 1203 | basic_machine=m68k-ncr 1204 | ;; 1205 | tpf) 1206 | basic_machine=s390x-ibm 1207 | os=-tpf 1208 | ;; 1209 | udi29k) 1210 | basic_machine=a29k-amd 1211 | os=-udi 1212 | ;; 1213 | ultra3) 1214 | basic_machine=a29k-nyu 1215 | os=-sym1 1216 | ;; 1217 | v810 | necv810) 1218 | basic_machine=v810-nec 1219 | os=-none 1220 | ;; 1221 | vaxv) 1222 | basic_machine=vax-dec 1223 | os=-sysv 1224 | ;; 1225 | vms) 1226 | basic_machine=vax-dec 1227 | os=-vms 1228 | ;; 1229 | vpp*|vx|vx-*) 1230 | basic_machine=f301-fujitsu 1231 | ;; 1232 | vxworks960) 1233 | basic_machine=i960-wrs 1234 | os=-vxworks 1235 | ;; 1236 | vxworks68) 1237 | basic_machine=m68k-wrs 1238 | os=-vxworks 1239 | ;; 1240 | vxworks29k) 1241 | basic_machine=a29k-wrs 1242 | os=-vxworks 1243 | ;; 1244 | w65*) 1245 | basic_machine=w65-wdc 1246 | os=-none 1247 | ;; 1248 | w89k-*) 1249 | basic_machine=hppa1.1-winbond 1250 | os=-proelf 1251 | ;; 1252 | xbox) 1253 | basic_machine=i686-pc 1254 | os=-mingw32 1255 | ;; 1256 | xps | xps100) 1257 | basic_machine=xps100-honeywell 1258 | ;; 1259 | xscale-* | xscalee[bl]-*) 1260 | basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` 1261 | ;; 1262 | ymp) 1263 | basic_machine=ymp-cray 1264 | os=-unicos 1265 | ;; 1266 | z8k-*-coff) 1267 | basic_machine=z8k-unknown 1268 | os=-sim 1269 | ;; 1270 | z80-*-coff) 1271 | basic_machine=z80-unknown 1272 | os=-sim 1273 | ;; 1274 | none) 1275 | basic_machine=none-none 1276 | os=-none 1277 | ;; 1278 | 1279 | # Here we handle the default manufacturer of certain CPU types. It is in 1280 | # some cases the only manufacturer, in others, it is the most popular. 1281 | w89k) 1282 | basic_machine=hppa1.1-winbond 1283 | ;; 1284 | op50n) 1285 | basic_machine=hppa1.1-oki 1286 | ;; 1287 | op60c) 1288 | basic_machine=hppa1.1-oki 1289 | ;; 1290 | romp) 1291 | basic_machine=romp-ibm 1292 | ;; 1293 | mmix) 1294 | basic_machine=mmix-knuth 1295 | ;; 1296 | rs6000) 1297 | basic_machine=rs6000-ibm 1298 | ;; 1299 | vax) 1300 | basic_machine=vax-dec 1301 | ;; 1302 | pdp10) 1303 | # there are many clones, so DEC is not a safe bet 1304 | basic_machine=pdp10-unknown 1305 | ;; 1306 | pdp11) 1307 | basic_machine=pdp11-dec 1308 | ;; 1309 | we32k) 1310 | basic_machine=we32k-att 1311 | ;; 1312 | sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) 1313 | basic_machine=sh-unknown 1314 | ;; 1315 | sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) 1316 | basic_machine=sparc-sun 1317 | ;; 1318 | cydra) 1319 | basic_machine=cydra-cydrome 1320 | ;; 1321 | orion) 1322 | basic_machine=orion-highlevel 1323 | ;; 1324 | orion105) 1325 | basic_machine=clipper-highlevel 1326 | ;; 1327 | mac | mpw | mac-mpw) 1328 | basic_machine=m68k-apple 1329 | ;; 1330 | pmac | pmac-mpw) 1331 | basic_machine=powerpc-apple 1332 | ;; 1333 | *-unknown) 1334 | # Make sure to match an already-canonicalized machine name. 1335 | ;; 1336 | *) 1337 | echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 1338 | exit 1 1339 | ;; 1340 | esac 1341 | 1342 | # Here we canonicalize certain aliases for manufacturers. 1343 | case $basic_machine in 1344 | *-digital*) 1345 | basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` 1346 | ;; 1347 | *-commodore*) 1348 | basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` 1349 | ;; 1350 | *) 1351 | ;; 1352 | esac 1353 | 1354 | # Decode manufacturer-specific aliases for certain operating systems. 1355 | 1356 | if [ x"$os" != x"" ] 1357 | then 1358 | case $os in 1359 | # First match some system type aliases 1360 | # that might get confused with valid system types. 1361 | # -solaris* is a basic system type, with this one exception. 1362 | -auroraux) 1363 | os=-auroraux 1364 | ;; 1365 | -solaris1 | -solaris1.*) 1366 | os=`echo $os | sed -e 's|solaris1|sunos4|'` 1367 | ;; 1368 | -solaris) 1369 | os=-solaris2 1370 | ;; 1371 | -svr4*) 1372 | os=-sysv4 1373 | ;; 1374 | -unixware*) 1375 | os=-sysv4.2uw 1376 | ;; 1377 | -gnu/linux*) 1378 | os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` 1379 | ;; 1380 | # First accept the basic system types. 1381 | # The portable systems comes first. 1382 | # Each alternative MUST END IN A *, to match a version number. 1383 | # -sysv* is not here because it comes later, after sysvr4. 1384 | -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ 1385 | | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ 1386 | | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ 1387 | | -sym* | -kopensolaris* | -plan9* \ 1388 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ 1389 | | -aos* | -aros* | -cloudabi* | -sortix* \ 1390 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ 1391 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ 1392 | | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ 1393 | | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ 1394 | | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ 1395 | | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ 1396 | | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ 1397 | | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ 1398 | | -chorusos* | -chorusrdb* | -cegcc* \ 1399 | | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ 1400 | | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ 1401 | | -linux-newlib* | -linux-musl* | -linux-uclibc* \ 1402 | | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ 1403 | | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ 1404 | | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ 1405 | | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ 1406 | | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ 1407 | | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ 1408 | | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ 1409 | | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ 1410 | | -onefs* | -tirtos* | -phoenix*) 1411 | # Remember, each alternative MUST END IN *, to match a version number. 1412 | ;; 1413 | -qnx*) 1414 | case $basic_machine in 1415 | x86-* | i*86-*) 1416 | ;; 1417 | *) 1418 | os=-nto$os 1419 | ;; 1420 | esac 1421 | ;; 1422 | -nto-qnx*) 1423 | ;; 1424 | -nto*) 1425 | os=`echo $os | sed -e 's|nto|nto-qnx|'` 1426 | ;; 1427 | -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ 1428 | | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ 1429 | | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) 1430 | ;; 1431 | -mac*) 1432 | os=`echo $os | sed -e 's|mac|macos|'` 1433 | ;; 1434 | -linux-dietlibc) 1435 | os=-linux-dietlibc 1436 | ;; 1437 | -linux*) 1438 | os=`echo $os | sed -e 's|linux|linux-gnu|'` 1439 | ;; 1440 | -sunos5*) 1441 | os=`echo $os | sed -e 's|sunos5|solaris2|'` 1442 | ;; 1443 | -sunos6*) 1444 | os=`echo $os | sed -e 's|sunos6|solaris3|'` 1445 | ;; 1446 | -opened*) 1447 | os=-openedition 1448 | ;; 1449 | -os400*) 1450 | os=-os400 1451 | ;; 1452 | -wince*) 1453 | os=-wince 1454 | ;; 1455 | -osfrose*) 1456 | os=-osfrose 1457 | ;; 1458 | -osf*) 1459 | os=-osf 1460 | ;; 1461 | -utek*) 1462 | os=-bsd 1463 | ;; 1464 | -dynix*) 1465 | os=-bsd 1466 | ;; 1467 | -acis*) 1468 | os=-aos 1469 | ;; 1470 | -atheos*) 1471 | os=-atheos 1472 | ;; 1473 | -syllable*) 1474 | os=-syllable 1475 | ;; 1476 | -386bsd) 1477 | os=-bsd 1478 | ;; 1479 | -ctix* | -uts*) 1480 | os=-sysv 1481 | ;; 1482 | -nova*) 1483 | os=-rtmk-nova 1484 | ;; 1485 | -ns2 ) 1486 | os=-nextstep2 1487 | ;; 1488 | -nsk*) 1489 | os=-nsk 1490 | ;; 1491 | # Preserve the version number of sinix5. 1492 | -sinix5.*) 1493 | os=`echo $os | sed -e 's|sinix|sysv|'` 1494 | ;; 1495 | -sinix*) 1496 | os=-sysv4 1497 | ;; 1498 | -tpf*) 1499 | os=-tpf 1500 | ;; 1501 | -triton*) 1502 | os=-sysv3 1503 | ;; 1504 | -oss*) 1505 | os=-sysv3 1506 | ;; 1507 | -svr4) 1508 | os=-sysv4 1509 | ;; 1510 | -svr3) 1511 | os=-sysv3 1512 | ;; 1513 | -sysvr4) 1514 | os=-sysv4 1515 | ;; 1516 | # This must come after -sysvr4. 1517 | -sysv*) 1518 | ;; 1519 | -ose*) 1520 | os=-ose 1521 | ;; 1522 | -es1800*) 1523 | os=-ose 1524 | ;; 1525 | -xenix) 1526 | os=-xenix 1527 | ;; 1528 | -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) 1529 | os=-mint 1530 | ;; 1531 | -aros*) 1532 | os=-aros 1533 | ;; 1534 | -zvmoe) 1535 | os=-zvmoe 1536 | ;; 1537 | -dicos*) 1538 | os=-dicos 1539 | ;; 1540 | -nacl*) 1541 | ;; 1542 | -ios) 1543 | ;; 1544 | -none) 1545 | ;; 1546 | *) 1547 | # Get rid of the `-' at the beginning of $os. 1548 | os=`echo $os | sed 's/[^-]*-//'` 1549 | echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 1550 | exit 1 1551 | ;; 1552 | esac 1553 | else 1554 | 1555 | # Here we handle the default operating systems that come with various machines. 1556 | # The value should be what the vendor currently ships out the door with their 1557 | # machine or put another way, the most popular os provided with the machine. 1558 | 1559 | # Note that if you're going to try to match "-MANUFACTURER" here (say, 1560 | # "-sun"), then you have to tell the case statement up towards the top 1561 | # that MANUFACTURER isn't an operating system. Otherwise, code above 1562 | # will signal an error saying that MANUFACTURER isn't an operating 1563 | # system, and we'll never get to this point. 1564 | 1565 | case $basic_machine in 1566 | score-*) 1567 | os=-elf 1568 | ;; 1569 | spu-*) 1570 | os=-elf 1571 | ;; 1572 | *-acorn) 1573 | os=-riscix1.2 1574 | ;; 1575 | arm*-rebel) 1576 | os=-linux 1577 | ;; 1578 | arm*-semi) 1579 | os=-aout 1580 | ;; 1581 | c4x-* | tic4x-*) 1582 | os=-coff 1583 | ;; 1584 | c8051-*) 1585 | os=-elf 1586 | ;; 1587 | hexagon-*) 1588 | os=-elf 1589 | ;; 1590 | tic54x-*) 1591 | os=-coff 1592 | ;; 1593 | tic55x-*) 1594 | os=-coff 1595 | ;; 1596 | tic6x-*) 1597 | os=-coff 1598 | ;; 1599 | # This must come before the *-dec entry. 1600 | pdp10-*) 1601 | os=-tops20 1602 | ;; 1603 | pdp11-*) 1604 | os=-none 1605 | ;; 1606 | *-dec | vax-*) 1607 | os=-ultrix4.2 1608 | ;; 1609 | m68*-apollo) 1610 | os=-domain 1611 | ;; 1612 | i386-sun) 1613 | os=-sunos4.0.2 1614 | ;; 1615 | m68000-sun) 1616 | os=-sunos3 1617 | ;; 1618 | m68*-cisco) 1619 | os=-aout 1620 | ;; 1621 | mep-*) 1622 | os=-elf 1623 | ;; 1624 | mips*-cisco) 1625 | os=-elf 1626 | ;; 1627 | mips*-*) 1628 | os=-elf 1629 | ;; 1630 | or32-*) 1631 | os=-coff 1632 | ;; 1633 | *-tti) # must be before sparc entry or we get the wrong os. 1634 | os=-sysv3 1635 | ;; 1636 | sparc-* | *-sun) 1637 | os=-sunos4.1.1 1638 | ;; 1639 | *-be) 1640 | os=-beos 1641 | ;; 1642 | *-haiku) 1643 | os=-haiku 1644 | ;; 1645 | *-ibm) 1646 | os=-aix 1647 | ;; 1648 | *-knuth) 1649 | os=-mmixware 1650 | ;; 1651 | *-wec) 1652 | os=-proelf 1653 | ;; 1654 | *-winbond) 1655 | os=-proelf 1656 | ;; 1657 | *-oki) 1658 | os=-proelf 1659 | ;; 1660 | *-hp) 1661 | os=-hpux 1662 | ;; 1663 | *-hitachi) 1664 | os=-hiux 1665 | ;; 1666 | i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) 1667 | os=-sysv 1668 | ;; 1669 | *-cbm) 1670 | os=-amigaos 1671 | ;; 1672 | *-dg) 1673 | os=-dgux 1674 | ;; 1675 | *-dolphin) 1676 | os=-sysv3 1677 | ;; 1678 | m68k-ccur) 1679 | os=-rtu 1680 | ;; 1681 | m88k-omron*) 1682 | os=-luna 1683 | ;; 1684 | *-next ) 1685 | os=-nextstep 1686 | ;; 1687 | *-sequent) 1688 | os=-ptx 1689 | ;; 1690 | *-crds) 1691 | os=-unos 1692 | ;; 1693 | *-ns) 1694 | os=-genix 1695 | ;; 1696 | i370-*) 1697 | os=-mvs 1698 | ;; 1699 | *-next) 1700 | os=-nextstep3 1701 | ;; 1702 | *-gould) 1703 | os=-sysv 1704 | ;; 1705 | *-highlevel) 1706 | os=-bsd 1707 | ;; 1708 | *-encore) 1709 | os=-bsd 1710 | ;; 1711 | *-sgi) 1712 | os=-irix 1713 | ;; 1714 | *-siemens) 1715 | os=-sysv4 1716 | ;; 1717 | *-masscomp) 1718 | os=-rtu 1719 | ;; 1720 | f30[01]-fujitsu | f700-fujitsu) 1721 | os=-uxpv 1722 | ;; 1723 | *-rom68k) 1724 | os=-coff 1725 | ;; 1726 | *-*bug) 1727 | os=-coff 1728 | ;; 1729 | *-apple) 1730 | os=-macos 1731 | ;; 1732 | *-atari*) 1733 | os=-mint 1734 | ;; 1735 | *) 1736 | os=-none 1737 | ;; 1738 | esac 1739 | fi 1740 | 1741 | # Here we handle the case where we know the os, and the CPU type, but not the 1742 | # manufacturer. We pick the logical manufacturer. 1743 | vendor=unknown 1744 | case $basic_machine in 1745 | *-unknown) 1746 | case $os in 1747 | -riscix*) 1748 | vendor=acorn 1749 | ;; 1750 | -sunos*) 1751 | vendor=sun 1752 | ;; 1753 | -cnk*|-aix*) 1754 | vendor=ibm 1755 | ;; 1756 | -beos*) 1757 | vendor=be 1758 | ;; 1759 | -hpux*) 1760 | vendor=hp 1761 | ;; 1762 | -mpeix*) 1763 | vendor=hp 1764 | ;; 1765 | -hiux*) 1766 | vendor=hitachi 1767 | ;; 1768 | -unos*) 1769 | vendor=crds 1770 | ;; 1771 | -dgux*) 1772 | vendor=dg 1773 | ;; 1774 | -luna*) 1775 | vendor=omron 1776 | ;; 1777 | -genix*) 1778 | vendor=ns 1779 | ;; 1780 | -mvs* | -opened*) 1781 | vendor=ibm 1782 | ;; 1783 | -os400*) 1784 | vendor=ibm 1785 | ;; 1786 | -ptx*) 1787 | vendor=sequent 1788 | ;; 1789 | -tpf*) 1790 | vendor=ibm 1791 | ;; 1792 | -vxsim* | -vxworks* | -windiss*) 1793 | vendor=wrs 1794 | ;; 1795 | -aux*) 1796 | vendor=apple 1797 | ;; 1798 | -hms*) 1799 | vendor=hitachi 1800 | ;; 1801 | -mpw* | -macos*) 1802 | vendor=apple 1803 | ;; 1804 | -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) 1805 | vendor=atari 1806 | ;; 1807 | -vos*) 1808 | vendor=stratus 1809 | ;; 1810 | esac 1811 | basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` 1812 | ;; 1813 | esac 1814 | 1815 | echo $basic_machine$os 1816 | exit 1817 | 1818 | # Local variables: 1819 | # eval: (add-hook 'write-file-hooks 'time-stamp) 1820 | # time-stamp-start: "timestamp='" 1821 | # time-stamp-format: "%:y-%02m-%02d" 1822 | # time-stamp-end: "'" 1823 | # End: 1824 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.69]) 5 | AC_INIT([uniprof], [1.2], [florian.schmidt@neclab.eu], [], [https://github.com/sysml/uniprof/]) 6 | AC_CONFIG_SRCDIR([uniprof.c]) 7 | AC_CONFIG_HEADERS([include/config.h]) 8 | 9 | # Parse options 10 | AC_ARG_WITH([libxc], [AS_HELP_STRING([--with-libxc],[use libxc hypercall interface])], [with_libxc="y"]) 11 | AC_ARG_WITH([libxencall], [AS_HELP_STRING([--with-libxencall],[use libxencall hypercall interface])], [with_libxencall="y"]) 12 | AS_IF([test "x$with_libxc" == "xy"], 13 | AS_IF([test "x$with_libxencall" == "xy"], 14 | [AC_MSG_ERROR([Cannot specify both --with-libxc and --with-libxencall at the same time.])] 15 | ) 16 | ) 17 | AC_ARG_WITH([xen], [AS_HELP_STRING([--with-xen=DIR],[build against Xen sources in directory @<:@default: build against installed headers/libraries@:>@])], [xenroot=$withval], AC_SUBST(use_syslibs,"y")) 18 | AS_IF([test "x$xenroot" != "x"], 19 | [AC_CHECK_FILE([$xenroot/tools],[],[AC_MSG_WARN([$xenroot does not look like a xen source directory!])])]) 20 | AC_SUBST(xenroot) 21 | AC_ARG_WITH([libunwind], [AS_HELP_STRING([--without-libunwind],[disable libunwind support even if available @<:@default: build against patched libunwind if available@:>@])], [], [with_libunwind=check]) 22 | AC_ARG_ENABLE([debug], 23 | [AS_HELP_STRING([--enable-debug],[compile with debugging symbols and print debugging output at runtime])], 24 | [AC_DEFINE([DEBUG], [1], [enable debugging output]) AC_SUBST(oflags,"-O0 -ggdb")], 25 | [AC_SUBST(oflags,"-O3")]) 26 | 27 | AC_CANONICAL_TARGET 28 | AS_CASE([$target_cpu], [arm*|aarch*], [target_arch="arm"], [i345686|x86*], [target_arch="x86"], [AC_MSG_ERROR([Unsupported CPU architecture $target_cpu])]) 29 | AC_SUBST(target_arch) 30 | 31 | AS_IF([test "x$with_libxc" == "xy"], 32 | AS_IF([test "$target_arch" == "arm"], 33 | [AC_MSG_ERROR([libxc support lacks functionality to support stack tracing on ARM. Use libxencall instead.])] 34 | ) 35 | ) 36 | 37 | # Checks for programs. 38 | AC_PROG_CXX 39 | AC_PROG_CC 40 | AC_PROG_MAKE_SET 41 | 42 | # Checks for libraries. 43 | AC_CHECK_LIB([xenctrl], [xc_domain_pause], [xc_available="y"]) 44 | AC_CHECK_LIB([xencall], [xencall1], 45 | AC_CHECK_LIB([xenforeignmemory], [xenforeignmemory_map], 46 | [libxencall_available="y"] #note LIBxencall_available, we need to test for the headers too 47 | ) 48 | ) 49 | AC_CHECK_LIB([unwind-xen], [_UXEN_create], [unwind_available="y"], [], [-lunwind-generic]) 50 | 51 | 52 | # Checks for header files. 53 | AC_CHECK_HEADERS([inttypes.h stdlib.h string.h xenctrl.h], [], [AC_MSG_ERROR([Missing required header file.])]) 54 | AC_CHECK_HEADERS([xencall.h], [headerxencall_available="y"], [headerxencall_available="n"]) 55 | AC_CHECK_HEADERS([xenforeignmemory.h], [headerxencall_available="y"], [headerxencall_available="n"]) 56 | AC_CHECK_HEADERS([libunwind-xen.h], [headerunwind_available="y"], [headerunwind_available="n"]) 57 | 58 | # libxencall is available if both headers and libs are available 59 | AS_IF([test "x$libxencall_available" == "xy"], 60 | AS_IF([test "x$headerxencall_available" == "xy"], 61 | [xencall_available="y"] 62 | ) 63 | ) 64 | # libunwind with xen support is available if both headers and libs are available 65 | AS_IF([test "x$libunwind_available" == "xy"], 66 | AS_IF([test "x$headerunwind_available" == "xy"], 67 | [unwind_available="y"] 68 | ) 69 | ) 70 | 71 | AS_IF([test "x$with_libxc" == "xy"], 72 | AS_IF([test "x$xc_available" != "xy"], 73 | [AC_MSG_ERROR([libxc not available.])], 74 | [use_libxc="y"] 75 | ) 76 | ) 77 | 78 | AS_IF([test "x$with_libxencall" == "xy"], 79 | AS_IF([test "x$xencall_available" != "xy"], 80 | [AC_MSG_ERROR([libxencall not available.])], 81 | [use_libxencall="y"] 82 | ) 83 | ) 84 | 85 | # default case: if neither --with-libxc nor --with-libxencall is specified, prefer libxencall if available, otherwise use libxc 86 | AS_IF([test "x$with_libxc" != "xy"], 87 | AS_IF([test "x$with_libxencall" != "xy"], 88 | AS_IF([test "x$xencall_available" == "xy"], 89 | [use_libxencall="y"], 90 | AS_IF([test "x$xc_available" == "xy"], 91 | [use_libxc="y"], 92 | AC_MSG_ERROR([Neither libxc nor libxencall/libxenforeignmemory found.]) 93 | ) 94 | ) 95 | ) 96 | ) 97 | 98 | # sanity check: use_libxc and use_libxencall should never be set at the same time 99 | AS_IF([test "x$use_libxc" == "xy"], 100 | AS_IF([test "x$use_libxencall" == "xy"], 101 | AC_MSG_ERROR([Internal error: use_libxc and use_libxencall set at the same time.]) 102 | ) 103 | ) 104 | 105 | # default case: if libunwind-xen is available, compile with support for it unless specifically disabled 106 | AS_IF([test "x$with_libunwind" != "xno"], 107 | AS_IF([test "x$unwind_available" == "xy"], 108 | [ 109 | AC_SUBST([libunwind], ["-lunwind-generic -lunwind-xen"]) 110 | AC_DEFINE([WITH_UNWIND], [1], [libunwind with xen patch is available]) 111 | ], 112 | AS_IF([test "x$with_libunwind" != "xcheck"], 113 | AC_MSG_ERROR([libunwind-xen not found. Have you compiled and installed the patched libunwind?]), 114 | ) 115 | ), 116 | ) 117 | 118 | # add header defines 119 | AS_IF([test "x$use_libxc" == "xy"], AC_DEFINE([HYPERCALL_LIBXC], [1], [Use libxc as hypercall interface])) 120 | AS_IF([test "x$use_libxc" == "xy"], AC_SUBST([hypercall_lib],[libxc])) 121 | AS_IF([test "x$use_libxencall" == "xy"], AC_DEFINE([HYPERCALL_XENCALL], [1], [Use libxencall as hypercall interface])) 122 | AS_IF([test "x$use_libxencall" == "xy"], AC_SUBST([hypercall_lib],[libxencall])) 123 | 124 | # ARM needs libxencall/libxenforeignmemory 125 | AS_IF([test "$target_arch" == "arm"], 126 | AS_IF([test "x$use_libxencall" != "xy"], 127 | [AC_MSG_ERROR([need libxencall/libxenforeignmemory support from Xen 4.7 for ARM])], 128 | ) 129 | ) 130 | 131 | # Checks for typedefs, structures, and compiler characteristics. 132 | AC_CHECK_HEADER_STDBOOL 133 | AC_TYPE_SIZE_T 134 | AC_TYPE_UINT16_T 135 | AC_TYPE_UINT32_T 136 | AC_TYPE_UINT64_T 137 | 138 | # Checks for library functions. 139 | AC_FUNC_MALLOC 140 | AC_CHECK_FUNCS([clock_gettime strerror strtol strtoul strtoull]) 141 | 142 | AC_CONFIG_FILES([Makefile]) 143 | AC_OUTPUT 144 | -------------------------------------------------------------------------------- /include/binsearch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uniprof: static-size data structure for fast binary search 3 | * 4 | * Authors: Florian Schmidt 5 | * 6 | * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | #ifndef _BINSEARCH_H 36 | #define _BINSEARCH_H 37 | /** 38 | * binsearch.h 39 | * 40 | * Binary search implementation. This expects a static set of items to search 41 | * through, with a continuous amount of memory allocated first, then filling 42 | * it, then searching it. So no online inserts and deletes. But fast lookups, 43 | * also for queries such as "give me the largest element smaller than x". 44 | */ 45 | 46 | #include 47 | #include 48 | 49 | #undef DBG 50 | #ifdef BINSEARCH_DEBUG 51 | #include 52 | #define DBG(string, args...) printf("[DBG %s:%s] "string, __FILE__, __func__, ##args) 53 | #else 54 | #define DBG(args...) 55 | #endif /* BINSEARCH_DEBUG */ 56 | 57 | /* control information at the head of the binary search array */ 58 | typedef struct { 59 | unsigned int num; 60 | } control_block_t; 61 | /* the elements inside the array. One int as "key", one union of an int, 62 | * character pointer, and void pointer as "value" that can either carry 63 | * the value directly, or point to somewhere outside the search array for 64 | * more complicated values. 65 | */ 66 | typedef struct { 67 | unsigned int key; 68 | union { 69 | int value; 70 | char *c; 71 | void *p; 72 | } val; 73 | } element_t; 74 | 75 | /** allocate a continuous memory block, starting at head, of size 76 | * sizeof(control_block_t) + sizeof(element_t) * num bytes, to 77 | * contain num elements, plus a control block at the beginning; 78 | * Returns pointer to beginning of array on success, 0 otherwise. 79 | */ 80 | void *binsearch_alloc(unsigned int num) 81 | { 82 | void *head; 83 | control_block_t *cb; 84 | head = malloc(sizeof(control_block_t) + num * sizeof(element_t)); 85 | if (!head) 86 | return NULL; 87 | cb = head; 88 | cb->num = num; 89 | return head; 90 | } 91 | 92 | /** 93 | * push elements into array allocated with binsearch_alloc. 94 | * Returns 0 on success, otherwise an error code. 95 | */ 96 | int binsearch_fill(void *head, element_t *ele) 97 | { 98 | static unsigned int filled = 0; 99 | control_block_t *cb = head; 100 | element_t *put = head + sizeof(control_block_t) + filled * sizeof(element_t); 101 | DBG("filling array position %u\n", filled); 102 | 103 | if (++filled > cb->num) 104 | return -ENOMEM; 105 | 106 | *put = *ele; 107 | return 0; 108 | } 109 | 110 | element_t *__binsearch_find_exact(void *head, unsigned int key, unsigned int first, unsigned int last) 111 | { 112 | unsigned int median = first + (last-first)/2; 113 | element_t *fele = (element_t *)(head + sizeof(control_block_t) + first * sizeof(element_t)); 114 | element_t *lele = (element_t *)(head + sizeof(control_block_t) + last * sizeof(element_t)); 115 | element_t *mele = (element_t *)(head + sizeof(control_block_t) + median * sizeof(element_t)); 116 | 117 | DBG("search array %p from element %u (key %u) to %u (key %u)\n", head, first, fele->key, last, lele->key); 118 | if (key == fele->key) 119 | return fele; 120 | else if (key < fele->key) 121 | return NULL; 122 | else if (key == lele->key) 123 | return lele; 124 | else if (key > lele->key) 125 | return NULL; 126 | else if (key == mele->key) 127 | return mele; 128 | else if (key < mele->key) 129 | return __binsearch_find_exact(head, key, first, median-1); 130 | else 131 | return __binsearch_find_exact(head, key, median+1, last); 132 | } 133 | 134 | element_t *__binsearch_find_not_above(void *head, unsigned int key, unsigned int first, unsigned int last) 135 | { 136 | unsigned int median = first + (last-first)/2; 137 | element_t *fele = (element_t *)(head + sizeof(control_block_t) + first * sizeof(element_t)); 138 | element_t *lele = (element_t *)(head + sizeof(control_block_t) + last * sizeof(element_t)); 139 | element_t *mele = (element_t *)(head + sizeof(control_block_t) + median * sizeof(element_t)); 140 | 141 | DBG("search array %p from element %u (key %u) to %u (key %u)\n", head, first, fele->key, last, lele->key); 142 | if (key < fele->key) 143 | return NULL; 144 | if ((key >= fele->key) && (key < (fele+1)->key)) 145 | return fele; 146 | else if (key >= lele->key) 147 | return lele; 148 | else if (key < mele->key) 149 | return __binsearch_find_not_above(head, key, first, median-1); 150 | else 151 | return __binsearch_find_not_above(head, key, median, last); 152 | } 153 | 154 | element_t *binsearch_find_exact(void *head, unsigned int key) 155 | { 156 | control_block_t *cb = head; 157 | if (cb->num == 0) 158 | return NULL; 159 | return __binsearch_find_exact(head, key, 0, cb->num-1); 160 | } 161 | 162 | element_t *binsearch_find_not_above(void *head, unsigned int key) 163 | { 164 | control_block_t *cb = head; 165 | if (cb->num == 0) 166 | return NULL; 167 | return __binsearch_find_not_above(head, key, 0, cb->num-1); 168 | } 169 | 170 | #ifdef BINSEARCH_DEBUG 171 | void binsearch_debug_dump_array(void *head) 172 | { 173 | unsigned int num = ((control_block_t *)head)->num; 174 | element_t *ele; 175 | unsigned int i; 176 | 177 | printf("binary search array starting at %p can contain %u elements\n",head, num); 178 | for (i=0; i < num; i++) { 179 | ele = (element_t *)(head + sizeof(control_block_t) + (i * sizeof(element_t))); 180 | printf("Element %u contains key %u->%s\n", i, ele->key, ele->val.c); 181 | } 182 | } 183 | #endif /* BINSEARCH_DEBUG */ 184 | 185 | 186 | #endif /* _BINSEARCH_H */ 187 | -------------------------------------------------------------------------------- /include/config.h.in: -------------------------------------------------------------------------------- 1 | /* include/config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* enable debugging output */ 4 | #undef DEBUG 5 | 6 | /* Define to 1 if you have the `clock_gettime' function. */ 7 | #undef HAVE_CLOCK_GETTIME 8 | 9 | /* Define to 1 if you have the header file. */ 10 | #undef HAVE_INTTYPES_H 11 | 12 | /* Define to 1 if you have the header file. */ 13 | #undef HAVE_LIBUNWIND_XEN_H 14 | 15 | /* Define to 1 if your system has a GNU libc compatible `malloc' function, and 16 | to 0 otherwise. */ 17 | #undef HAVE_MALLOC 18 | 19 | /* Define to 1 if you have the header file. */ 20 | #undef HAVE_MEMORY_H 21 | 22 | /* Define to 1 if you have the header file. */ 23 | #undef HAVE_STDINT_H 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #undef HAVE_STDLIB_H 27 | 28 | /* Define to 1 if you have the `strerror' function. */ 29 | #undef HAVE_STRERROR 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #undef HAVE_STRINGS_H 33 | 34 | /* Define to 1 if you have the header file. */ 35 | #undef HAVE_STRING_H 36 | 37 | /* Define to 1 if you have the `strtol' function. */ 38 | #undef HAVE_STRTOL 39 | 40 | /* Define to 1 if you have the `strtoul' function. */ 41 | #undef HAVE_STRTOUL 42 | 43 | /* Define to 1 if you have the `strtoull' function. */ 44 | #undef HAVE_STRTOULL 45 | 46 | /* Define to 1 if you have the header file. */ 47 | #undef HAVE_SYS_STAT_H 48 | 49 | /* Define to 1 if you have the header file. */ 50 | #undef HAVE_SYS_TYPES_H 51 | 52 | /* Define to 1 if you have the header file. */ 53 | #undef HAVE_UNISTD_H 54 | 55 | /* Define to 1 if you have the header file. */ 56 | #undef HAVE_XENCALL_H 57 | 58 | /* Define to 1 if you have the header file. */ 59 | #undef HAVE_XENCTRL_H 60 | 61 | /* Define to 1 if you have the header file. */ 62 | #undef HAVE_XENFOREIGNMEMORY_H 63 | 64 | /* Define to 1 if the system has the type `_Bool'. */ 65 | #undef HAVE__BOOL 66 | 67 | /* Use libxc as hypercall interface */ 68 | #undef HYPERCALL_LIBXC 69 | 70 | /* Use libxencall as hypercall interface */ 71 | #undef HYPERCALL_XENCALL 72 | 73 | /* Define to the address where bug reports for this package should be sent. */ 74 | #undef PACKAGE_BUGREPORT 75 | 76 | /* Define to the full name of this package. */ 77 | #undef PACKAGE_NAME 78 | 79 | /* Define to the full name and version of this package. */ 80 | #undef PACKAGE_STRING 81 | 82 | /* Define to the one symbol short name of this package. */ 83 | #undef PACKAGE_TARNAME 84 | 85 | /* Define to the home page for this package. */ 86 | #undef PACKAGE_URL 87 | 88 | /* Define to the version of this package. */ 89 | #undef PACKAGE_VERSION 90 | 91 | /* Define to 1 if you have the ANSI C header files. */ 92 | #undef STDC_HEADERS 93 | 94 | /* libunwind with xen patch is available */ 95 | #undef WITH_UNWIND 96 | 97 | /* Define for Solaris 2.5.1 so the uint32_t typedef from , 98 | , or is not used. If the typedef were allowed, the 99 | #define below would cause a syntax error. */ 100 | #undef _UINT32_T 101 | 102 | /* Define for Solaris 2.5.1 so the uint64_t typedef from , 103 | , or is not used. If the typedef were allowed, the 104 | #define below would cause a syntax error. */ 105 | #undef _UINT64_T 106 | 107 | /* Define to rpl_malloc if the replacement function should be used. */ 108 | #undef malloc 109 | 110 | /* Define to `unsigned int' if does not define. */ 111 | #undef size_t 112 | 113 | /* Define to the type of an unsigned integer type of width exactly 16 bits if 114 | such a type exists and the standard includes do not define it. */ 115 | #undef uint16_t 116 | 117 | /* Define to the type of an unsigned integer type of width exactly 32 bits if 118 | such a type exists and the standard includes do not define it. */ 119 | #undef uint32_t 120 | 121 | /* Define to the type of an unsigned integer type of width exactly 64 bits if 122 | such a type exists and the standard includes do not define it. */ 123 | #undef uint64_t 124 | -------------------------------------------------------------------------------- /include/xen-interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uniprof: Xen interface 3 | * 4 | * Authors: Florian Schmidt 5 | * 6 | * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | #ifndef __XEN_INTERFACE_H 36 | #define __XEN_INTERFACE_H 37 | 38 | #include 39 | 40 | #if defined(HYPERCALL_XENCALL) + defined(HYPERCALL_LIBXC) == 0 41 | #error Define exactly one of HYPERCALL_LIBXC, HYPERCALL_XENCALL 42 | #elif defined(HYPERCALL_XENCALL) + defined(HYPERCALL_LIBXC) > 1 43 | #warning You defined more than one of HYPERCALL_LIBXC, HYPERCALL_XENCALL. This might lead to unexpected results. 44 | #endif 45 | 46 | #undef DBG 47 | #ifdef DEBUG 48 | #define DBG(string, args...) printf("[DBG %s:%s] "string, __FILE__, __func__, ##args) 49 | #else 50 | #define DBG(args...) 51 | #endif /* DEBUG */ 52 | 53 | #if defined(HYPERCALL_XENCALL) 54 | #include 55 | #include 56 | #include 57 | #define HYPERCALL_NAME "libxencall" 58 | typedef vcpu_guest_context_t vcpu_guest_context_transparent_t; 59 | extern xencall_handle *callh; 60 | extern xenforeignmemory_handle *fmemh; 61 | #elif defined(HYPERCALL_LIBXC) 62 | #define XC_WANT_COMPAT_MAP_FOREIGN_API 63 | #include 64 | #define HYPERCALL_NAME "libxc" 65 | typedef vcpu_guest_context_any_t vcpu_guest_context_transparent_t; 66 | extern xc_interface *xc_handle; 67 | #endif 68 | 69 | #ifndef __maybe_unused 70 | #define __maybe_unused __attribute__((unused)) 71 | #endif 72 | 73 | #define PAGE_SHIFT XC_PAGE_SHIFT 74 | #define PAGE_SIZE XC_PAGE_SIZE 75 | #define PAGE_MASK XC_PAGE_MASK 76 | 77 | // big enough for 32 bit and 64 bit 78 | typedef uint64_t guest_word_t; 79 | 80 | int xen_interface_open(void); 81 | int xen_interface_close(void); 82 | int get_word_size(int domid); 83 | guest_word_t instruction_pointer(vcpu_guest_context_transparent_t *vc); 84 | guest_word_t frame_pointer(vcpu_guest_context_transparent_t *vc); 85 | int get_vcpu_context(int domid, int vcpu, vcpu_guest_context_transparent_t *vc); 86 | void xen_map_domu_page(int domid, int vcpu, uint64_t addr, unsigned long *mfn, void **buf); 87 | int get_domain_state(int domid, unsigned int *state); 88 | int pause_domain(int domid); 89 | int unpause_domain(int domid); 90 | int get_max_vcpu_id(int domid); 91 | 92 | #endif /* __XEN_INTERFACE_H */ 93 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | echo "I'm a dummy." 2 | -------------------------------------------------------------------------------- /symbolize.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * symbol resolver (for use with uniprof) 3 | * 4 | * Authors: Florian Schmidt 5 | * 6 | * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | int main(int argc, char **argv) { 43 | std::ifstream symbolfile; 44 | std::ifstream tracefile; 45 | std::string line; 46 | std::stringstream convertor; 47 | uint64_t addr; 48 | std::string hexaddr; 49 | char type; 50 | std::string fname; 51 | std::map symbollist; 52 | std::map::iterator iter; 53 | 54 | if (argc != 3) { 55 | std::cout << "Usage: " << argv[0] << " " << std::endl; 56 | return 1; 57 | } 58 | 59 | symbolfile.open(argv[1], std::ifstream::in); 60 | if (symbolfile.fail()) { 61 | std::cout << "Failed opening symbol table file \"" << argv[1] << "\"."; 62 | return 2; 63 | } 64 | tracefile.open(argv[2], std::ifstream::in); 65 | if (tracefile.fail()) { 66 | std::cout << "Failed opening trace file \"" << argv[2] << "\"."; 67 | return 2; 68 | } 69 | 70 | while (std::getline(symbolfile, line)) { 71 | convertor.str(line); 72 | convertor >> std::hex >> addr >> type >> fname; 73 | convertor.clear(); 74 | symbollist[addr] = fname; 75 | } 76 | symbolfile.close(); 77 | 78 | while (std::getline(tracefile, line)) { 79 | if (line.empty()) 80 | std::cout << std::endl; 81 | else if (line == "1") 82 | std::cout << "1" << std::endl; 83 | // comments; by convention, the header lines start with a comment sign 84 | else if (line[0] == '#') 85 | std::cout << line << std::endl; 86 | else { 87 | convertor.str(line); 88 | convertor >> std::hex >> addr; 89 | convertor.clear(); 90 | iter = symbollist.upper_bound(addr); 91 | if (iter != symbollist.begin()) 92 | iter--; 93 | if (addr == iter->first) 94 | std::cout << iter->second.c_str() << std::endl; 95 | else 96 | std::cout << iter->second.c_str() << "+0x" << std::hex << addr - iter->first << std::endl; 97 | } 98 | } 99 | tracefile.close(); 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /uniprof.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uniprof, a stack tracer/profiler for Xen domains 3 | * 4 | * Authors: Florian Schmidt 5 | * 6 | * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #ifdef WITH_UNWIND 47 | #include 48 | #include 49 | #endif 50 | 51 | typedef struct mapped_page { 52 | guest_word_t base; // page number, i.e. addr>>PAGE_SHIFT 53 | unsigned long mfn; 54 | void *buf; 55 | struct mapped_page *next; 56 | } mapped_page_t; 57 | 58 | static bool verbose = false; 59 | #define VERBOSE(args...) if (verbose) printf(args); 60 | 61 | /* since some versions of sys/time.h do not include the 62 | * timespecadd/sub function, here's a macro (adapted from 63 | * the macros in sys/time.h) to do the job. */ 64 | #ifndef timespecadd 65 | #define timespecadd(a, b, result) \ 66 | do { \ 67 | (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ 68 | (result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \ 69 | if ((result)->tv_nsec >= 1000000000) { \ 70 | ++(result)->tv_sec; \ 71 | (result)->tv_nsec -= 1000000000; \ 72 | } \ 73 | } while (0) 74 | #endif /* timespecadd */ 75 | #ifndef timespecsub 76 | #define timespecsub(a, b, result) \ 77 | do { \ 78 | (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ 79 | (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \ 80 | if ((result)->tv_nsec < 0) { \ 81 | --(result)->tv_sec; \ 82 | (result)->tv_nsec += 1000000000; \ 83 | } \ 84 | } while (0) 85 | #endif /* timespecsub */ 86 | #ifndef timespeccmp 87 | #define timespeccmp(a, b, CMP) \ 88 | (((a)->tv_sec == (b)->tv_sec) ? \ 89 | ((a)->tv_nsec CMP (b)->tv_nsec) : \ 90 | ((a)->tv_sec CMP (b)->tv_sec)) 91 | #endif /* timespeccmp */ 92 | /* invert a negative value (e.g., -300usecs = -1.000700000) 93 | * to a positive value (300 usecs = 0.000300000). This is 94 | * useful to print negative timespec values. */ 95 | #define timespecnegtopos(a, b) \ 96 | do { \ 97 | (b)->tv_sec = -((a)->tv_sec+1); \ 98 | (b)->tv_nsec = 1000000000 - (a)->tv_nsec; \ 99 | } while (0) 100 | 101 | static unsigned long get_time_nsec(void) 102 | { 103 | struct timespec ts; 104 | clock_gettime(CLOCK_MONOTONIC, &ts); 105 | return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 106 | } 107 | static void busywait(unsigned long nsecs) 108 | { 109 | unsigned long deadline = get_time_nsec() + nsecs; 110 | do { 111 | } while (get_time_nsec() < deadline); 112 | } 113 | 114 | static void measure_overheads(struct timespec *gettime_overhead, struct timespec *minsleep, int rounds) 115 | { 116 | int i; 117 | struct timespec before = { .tv_sec = 0, .tv_nsec = 0 }; 118 | struct timespec after = { .tv_sec = 0, .tv_nsec = 0 }; 119 | struct timespec sleep = { .tv_sec = 0, .tv_nsec = 0 }; 120 | unsigned long long sleepsecs = 0, sleepnanosecs = 0, timesecs = 0, timenanosecs = 0; 121 | 122 | for (i=0; itv_sec = timesecs / rounds; 138 | gettime_overhead->tv_nsec = timenanosecs / rounds; 139 | minsleep->tv_sec = (sleepsecs + timesecs) / rounds; 140 | minsleep->tv_nsec = (sleepnanosecs + timenanosecs) / rounds; 141 | } 142 | 143 | int domain_shut_down(int domid) { 144 | const unsigned int dying_and_shutdown = XEN_DOMINF_dying | XEN_DOMINF_shutdown; 145 | unsigned int domstate; 146 | 147 | // error handling: if get_domain_state() signals an error (e.g., 148 | // from the hypercall), we signal that the domain is shut down, 149 | // because we won't be able to do anything sensible with a domain 150 | // on which hypercalls fail. 151 | if (get_domain_state(domid, &domstate)) 152 | return 1; 153 | if ((domstate & dying_and_shutdown) == dying_and_shutdown) 154 | return 1; 155 | 156 | return 0; 157 | } 158 | 159 | void *guest_to_host(int domid, int vcpu, guest_word_t gaddr) { 160 | static mapped_page_t *map_head = NULL; 161 | mapped_page_t *map_iter; 162 | mapped_page_t *new_item; 163 | guest_word_t base = gaddr & PAGE_MASK; 164 | guest_word_t offset = gaddr & ~PAGE_MASK; 165 | 166 | map_iter = map_head; 167 | while (map_iter != NULL) { 168 | if (base == map_iter->base) 169 | return map_iter->buf + offset; 170 | // preserve last item in map_iter by jumping out 171 | if (map_iter->next == NULL) 172 | break; 173 | map_iter = map_iter->next; 174 | } 175 | 176 | // no matching page found, we need to map a new one. 177 | // At this pointer, map_iter conveniently points to the last item. 178 | new_item = malloc(sizeof(mapped_page_t)); 179 | if (new_item == NULL) { 180 | fprintf(stderr, "failed to allocate memory for page struct.\n"); 181 | return NULL; 182 | } 183 | new_item->base = base; 184 | xen_map_domu_page(domid, vcpu, base, &new_item->mfn, &new_item->buf); 185 | VERBOSE("mapping new page %#"PRIx64"->%p\n", new_item->base, new_item->buf); 186 | if (new_item->buf == NULL) { 187 | fprintf(stderr, "failed to allocate memory mapping page.\n"); 188 | goto out_free; 189 | } 190 | if (new_item->mfn == 0) { 191 | fprintf(stderr, "failed to resolve virtual address.\n"); 192 | goto out_free; 193 | } 194 | new_item->next = NULL; 195 | if (map_head == NULL) 196 | map_head = new_item; 197 | else 198 | map_iter->next = new_item; 199 | return new_item->buf + offset; 200 | 201 | out_free: 202 | free(new_item); 203 | return NULL; 204 | } 205 | 206 | void resolve_and_print_symbol(void *symbol_table, guest_word_t address, FILE *file) { 207 | element_t *ele; 208 | 209 | if (!symbol_table) { 210 | fprintf(file, "%#"PRIx64"\n", address); 211 | return; 212 | } 213 | 214 | ele = binsearch_find_not_above(symbol_table, address); 215 | if (!ele) 216 | fprintf(file, "%#"PRIx64"\n", address); 217 | else { 218 | if (address == ele->key) 219 | fprintf(file, "%#"PRIx64"\n", address); 220 | else 221 | fprintf(file, "%s+%#"PRIx64"\n", ele->val.c, address - ele->key); 222 | } 223 | } 224 | 225 | void walk_stack_fp(int domid, int vcpu, int wordsize, FILE *file, void *symbol_table) { 226 | int ret; 227 | guest_word_t fp, retaddr; 228 | void *hfp, *hrp; 229 | vcpu_guest_context_transparent_t vc; 230 | 231 | DBG("tracing vcpu %d\n", vcpu); 232 | if ((ret = get_vcpu_context(domid, vcpu, &vc)) < 0) { 233 | printf("Failed to get context for VCPU %d, skipping trace. (ret=%d)\n", vcpu, ret); 234 | return; 235 | } 236 | 237 | // our first "return" address is the instruction pointer 238 | retaddr = instruction_pointer(&vc); 239 | fp = frame_pointer(&vc); 240 | DBG("vcpu %d, initial (register-based) fp = %#"PRIx64", retaddr = %#"PRIx64"\n", vcpu, fp, retaddr); 241 | while (fp != 0) { 242 | if (symbol_table) 243 | resolve_and_print_symbol(symbol_table, retaddr, file); 244 | else 245 | fprintf(file, "%#"PRIx64"\n", retaddr); 246 | /* walk the stack: on x86, the fp points to the address of the previous 247 | * frame pointers, so new_fp = *old_fp. On ARM, the fp points to the 248 | * first address of the next frame, with the frame pointer the first 249 | * (=highest) value in the new frame, so new_fp = *old_fp-wordsize. 250 | * The return address is the following word-sized values on the stack, 251 | * so new_ret = new_fp + wordsize. 252 | * We just have to be careful if the new values reside in different 253 | * 4k pages. In that case, we have to map both separately, because 254 | * they might not be in contiguous memory. 255 | * Otherwise, we can just add wordsize to the fp and get retaddr. */ 256 | #if defined(__i386__) || defined(__x86_64__) 257 | hfp = guest_to_host(domid, vcpu, fp); 258 | #elif defined(__arm__) 259 | hfp = guest_to_host(domid, vcpu, fp-wordsize); 260 | #endif 261 | if (!hfp) { 262 | fprintf(file, "0\n\n"); 263 | return; 264 | } 265 | if ((fp & PAGE_MASK) != ((fp+wordsize) & PAGE_MASK)) 266 | hrp = guest_to_host(domid, vcpu, fp+wordsize); 267 | else 268 | hrp = hfp+wordsize; 269 | memcpy(&fp, hfp, wordsize); 270 | memcpy(&retaddr, hrp, wordsize); 271 | DBG("vcpu %d, fp = %#"PRIx64"->%p->%#"PRIx64", return addr = %#"PRIx64"->%p->%#"PRIx64"\n", 272 | vcpu, fp, hfp, *((uint64_t*)hfp), fp+wordsize, hrp, retaddr); 273 | } 274 | fprintf(file, "1\n\n"); 275 | } 276 | 277 | /** 278 | * Walk the stack via the frame pointer. Returns 0 on success. 279 | */ 280 | int do_stack_trace_fp(int domid, unsigned int max_vcpu_id, int wordsize, FILE *file, void *symbol_table) { 281 | unsigned int vcpu; 282 | 283 | if (pause_domain(domid) < 0) { 284 | fprintf(stderr, "Could not pause domid %d\n", domid); 285 | return -7; 286 | } 287 | for (vcpu = 0; vcpu <= max_vcpu_id; vcpu++) { 288 | walk_stack_fp(domid, vcpu, wordsize, file, symbol_table); 289 | } 290 | if (unpause_domain(domid) < 0) { 291 | fprintf(stderr, "Could not unpause domid %d\n", domid); 292 | return -7; 293 | } 294 | return 0; 295 | } 296 | 297 | 298 | #ifdef WITH_UNWIND 299 | void walk_stack_libunwind(struct UXEN_info *ui, unw_addr_space_t as, FILE *file, bool resolve_symbols) { 300 | unw_cursor_t cursor; 301 | unw_word_t addr; 302 | const unsigned int BUFLEN = 64; 303 | char buf[BUFLEN]; 304 | 305 | // This needs to be reinitalized for every stack walk round, 306 | // so no reason to save it anywhere outside for re-use. 307 | unw_init_remote(&cursor, as, ui); 308 | 309 | // our first "return" address is the instruction pointer 310 | unw_get_reg(&cursor, UNW_REG_IP, &addr); 311 | 312 | if (resolve_symbols && !unw_get_proc_name(&cursor, buf, BUFLEN, &addr)) 313 | fprintf(file, "%s+%#"PRIxPTR"\n", buf, addr); 314 | else 315 | fprintf(file, "%#"PRIxPTR"\n", addr); 316 | 317 | while (unw_step(&cursor) > 0) { 318 | unw_get_reg(&cursor, UNW_REG_IP, &addr); 319 | if (!addr) 320 | break; 321 | if (resolve_symbols && !unw_get_proc_name(&cursor, buf, BUFLEN, &addr)) 322 | fprintf(file, "%s+%#"PRIxPTR"\n", buf, addr); 323 | else 324 | fprintf(file, "%#"PRIxPTR"\n", addr); 325 | } 326 | fprintf(file, "1\n\n"); 327 | } 328 | 329 | /** 330 | * Walk the stack via eh_frame information parsed by libunwind. Returns 0 on success. 331 | */ 332 | int do_stack_trace_libunwind(int domid, unsigned int max_vcpu_id, FILE *file, 333 | struct UXEN_info *ui, unw_addr_space_t as, bool resolve_symbols) { 334 | unsigned int vcpu; 335 | 336 | if (pause_domain(domid) < 0) { 337 | fprintf(stderr, "Could not pause domid %d\n", domid); 338 | return -7; 339 | } 340 | for (vcpu = 0; vcpu <= max_vcpu_id; vcpu++) { 341 | _UXEN_change_vcpu(ui, vcpu); 342 | walk_stack_libunwind(ui, as, file, resolve_symbols); 343 | } 344 | if (unpause_domain(domid) < 0) { 345 | fprintf(stderr, "Could not unpause domid %d\n", domid); 346 | return -7; 347 | } 348 | return 0; 349 | } 350 | #endif 351 | 352 | void *read_symbol_table(char *symbol_table_file_name) 353 | { 354 | char line[256]; 355 | char *p, *symbol; 356 | size_t len; 357 | int count = 0; 358 | FILE *f; 359 | int ch, i; 360 | void *head; 361 | element_t element; 362 | 363 | f = fopen(symbol_table_file_name, "r"); 364 | if (f == NULL) { 365 | fprintf(stderr, "failed to open symbol table file %s, will not resolve symbols!\n", 366 | symbol_table_file_name); 367 | return NULL; 368 | } 369 | 370 | // count number of lines, i.e., elements in the file: 371 | while((ch = fgetc(f)) != EOF) 372 | if (ch == '\n') 373 | count++; 374 | 375 | if (count == 0) { 376 | fprintf(stderr, "Symbol table file %s contained no valid entries!\n", symbol_table_file_name); 377 | fprintf(stderr, "Disabling symbol resolution.\n"); 378 | return NULL; 379 | } 380 | 381 | rewind(f); 382 | head = binsearch_alloc(count); 383 | if (!head) 384 | return NULL; 385 | for (i=0; i \n\n", name); 436 | printf("options:\n"); 437 | printf(" -F n --frequency=n Frequency of traces (in per second, default 1)\n"); 438 | printf(" -T n --time=n How long to run the tracer (in seconds, default 1)\n"); 439 | printf(" -M --missed-deadlines Print a warning to STDERR whenever a deadline is\n"); 440 | printf(" missed. Note that this may exacerbate the problem,\n"); 441 | printf(" or it may treacherously appear to improve it,\n"); 442 | printf(" while it actually doesn't (due to timing quirks)\n"); 443 | printf(" -s TAB --symbol-table=TAB Resolve stack addresses with symbols from TAB.\n"); 444 | printf(" The file is expected to contain information\n"); 445 | printf(" formatted like the output of 'nm -n'. Please\n"); 446 | printf(" note that this slows down tracing.\n"); 447 | #ifdef WITH_UNWIND 448 | printf(" -s, -e, and -E are mutually exclusive.\n"); 449 | printf(" -e ELF --elf-file=ELF Use libunwind to unwind the stack, using the\n"); 450 | printf(" .eh_frame section of the provided ELF file instead\n"); 451 | printf(" of the frame pointer. This allows unwinding code\n"); 452 | printf(" compiled with -fomit-frame-pointer, but is slower.\n"); 453 | printf(" -s, -e, and -E are mutually exclusive.\n"); 454 | printf(" -E ELF --elf-resolve=ELF In addition to using the provided ELF file to\n"); 455 | printf(" unwind the stack (as the -e option does), use the\n"); 456 | printf(" information in the file's .debug sections to also\n"); 457 | printf(" resolve symbols. This requires an unstripped\n"); 458 | printf(" binary and is naturally slower than the -e option.\n"); 459 | printf(" -s, -e, and -E are mutually exclusive.\n"); 460 | #endif 461 | printf(" -v --verbose Show some more informational output.\n"); 462 | printf(" -V --version Show version information.\n"); 463 | printf(" -h --help Print this help message.\n"); 464 | } 465 | 466 | int main(int argc, char **argv) { 467 | int domid, ret; 468 | FILE *outfile; 469 | int max_vcpu_id; 470 | int wordsize; 471 | const int measure_rounds = 100; 472 | struct timespec gettime_overhead, minsleep, sleep; 473 | struct timespec begin, end, ts; 474 | #ifdef WITH_UNWIND 475 | static const char *sopts = "hF:T:Ms:e:E:vV"; 476 | #else 477 | static const char *sopts = "hF:T:Ms:vV"; 478 | #endif 479 | static const struct option lopts[] = { 480 | {"help", no_argument, NULL, 'h'}, 481 | {"frequency", required_argument, NULL, 'F'}, 482 | {"time", required_argument, NULL, 'T'}, 483 | {"missed-deadlines", no_argument, NULL, 'M'}, 484 | {"symbol-table", required_argument, NULL, 's'}, 485 | #ifdef WITH_UNWIND 486 | {"elf-file", required_argument, NULL, 'e'}, 487 | {"elf-resolve", required_argument, NULL, 'E'}, 488 | #endif 489 | {"verbose", no_argument, NULL, 'v'}, 490 | {"version", no_argument, NULL, 'V'}, 491 | {0, 0, 0, 0} 492 | }; 493 | char *resolver_file_name = NULL; 494 | void *symbol_table = NULL; 495 | #ifdef WITH_UNWIND 496 | struct UXEN_info *ui = NULL; 497 | unw_addr_space_t as = NULL; 498 | bool have_seE = false; 499 | bool resolver_is_elf = false; 500 | bool resolve_symbols_from_elf = false; 501 | #endif 502 | char *exename, *outname; 503 | int opt; 504 | unsigned int freq = 1; 505 | unsigned int time = 1; 506 | bool warn_missed_deadlines = false; 507 | unsigned int i,j; 508 | unsigned long long missed_deadlines = 0; 509 | 510 | while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { 511 | switch(opt) { 512 | case 'h': 513 | print_usage(argv[0]); 514 | return 0; 515 | case 'F': 516 | freq = strtoul(optarg, NULL, 10); 517 | break; 518 | case 'T': 519 | time = strtoul(optarg, NULL, 10); 520 | break; 521 | case 'M': 522 | warn_missed_deadlines = true; 523 | break; 524 | case 's': 525 | resolver_file_name = optarg; 526 | #ifdef WITH_UNWIND 527 | if (have_seE) { 528 | printf("-s, -e, and -E are mutually exclusive.\n"); 529 | return -1; 530 | } 531 | have_seE = true; 532 | break; 533 | case 'E': 534 | resolve_symbols_from_elf = true; 535 | // fallthrough 536 | case 'e': 537 | if (have_seE) { 538 | printf("-s, -e, and -E are mutually exclusive.\n"); 539 | return -1; 540 | } 541 | have_seE = true; 542 | resolver_file_name = optarg; 543 | resolver_is_elf = true; 544 | #endif 545 | break; 546 | case 'v': 547 | verbose = true; 548 | break; 549 | case 'V': 550 | printf("uniprof version %s\n", PACKAGE_VERSION); 551 | printf("source code available at %s\n", PACKAGE_URL); 552 | return 0; 553 | case '?': 554 | fprintf(stderr, "%s --help for usage\n", argv[0]); 555 | return -1; 556 | } 557 | } 558 | sleep.tv_sec = 0; sleep.tv_nsec = (1000000000/freq); 559 | exename = argv[0]; 560 | argv += optind; argc -= optind; 561 | outname = argv[0]; 562 | 563 | if (argc < 2 || argc > 3) { 564 | print_usage(exename); 565 | return -1; 566 | } 567 | 568 | domid = strtol(argv[1], NULL, 10); 569 | if (domid == 0) { 570 | fprintf(stderr, "invalid domid (unparseable domid string %s, or cannot trace dom0)\n", argv[1]); 571 | return -2; 572 | } 573 | 574 | if ((strlen(outname) == 1) && (!(strncmp(outname, "-", 1)))) { 575 | outfile = stdout; 576 | } 577 | else { 578 | outfile = fopen(outname, "w"); 579 | if (!outfile) { 580 | fprintf(stderr, "cannot open file %s: %s\n", outname, strerror(errno)); 581 | return -3; 582 | } 583 | } 584 | 585 | if (xen_interface_open()) { 586 | fprintf(stderr, "Cannot connect to the hypervisor. (Is this Xen?)\n"); 587 | return -4; 588 | } 589 | 590 | max_vcpu_id = get_max_vcpu_id(domid); 591 | if (max_vcpu_id < 0) { 592 | fprintf(stderr, "Could not access information for domid %d. (Does domid %d exist?)\n", domid, domid); 593 | return -5; 594 | } 595 | 596 | wordsize = get_word_size(domid); 597 | if (wordsize < 0) { 598 | fprintf(stderr, "Failed to retrieve word size for domid %d (returned %d)\n", domid, wordsize); 599 | return -6; 600 | } 601 | else if ((wordsize != 8) && (wordsize != 4)) { 602 | fprintf(stderr, "Unexpected wordsize (%d) for domid %d, cannot trace.\n", wordsize, domid); 603 | return -6; 604 | } 605 | DBG("wordsize is %d\n", wordsize); 606 | 607 | #ifdef WITH_UNWIND 608 | if (resolver_is_elf) { 609 | // this implies the ELF file name is set 610 | ui = _UXEN_create(domid, 0, resolver_file_name); 611 | if (!ui) { 612 | fprintf(stderr, "Cannot read elf file %s. File unreadable or invalid!\n", resolver_file_name); 613 | return -7; 614 | } 615 | as = unw_create_addr_space(&_UXEN_accessors, 0); 616 | } 617 | else 618 | #endif 619 | if (resolver_file_name) { 620 | symbol_table = read_symbol_table(resolver_file_name); 621 | } 622 | 623 | // Initialization stuff: write file header, measure overhead of clock_gettime/minimal sleeptime, etc. 624 | write_file_header(outfile, domid); 625 | measure_overheads(&gettime_overhead, &minsleep, measure_rounds); 626 | DBG("gettime overhead is %ld.%09ld, minimal nanosleep() sleep time is %ld.%09ld\n", 627 | gettime_overhead.tv_sec, gettime_overhead.tv_nsec, minsleep.tv_sec, minsleep.tv_nsec); 628 | 629 | // The actual stack tracing loop 630 | for (i = 0; i < time; i++) { 631 | // is the domain done and just hanging around for our sake? 632 | if (domain_shut_down(domid)) { 633 | return -8; 634 | } 635 | for (j = 0; j < freq; j++) { 636 | clock_gettime(CLOCK_MONOTONIC, &begin); 637 | #ifdef WITH_UNWIND 638 | if (resolver_is_elf) 639 | ret = do_stack_trace_libunwind(domid, max_vcpu_id, outfile, ui, as, resolve_symbols_from_elf); 640 | else 641 | #endif 642 | ret = do_stack_trace_fp(domid, max_vcpu_id, wordsize, outfile, symbol_table); 643 | if (ret) { 644 | return ret; 645 | } 646 | clock_gettime(CLOCK_MONOTONIC, &end); 647 | timespecadd(&begin, &sleep, &ts); 648 | if (timespeccmp(&ts, &end, <)) { 649 | missed_deadlines++; 650 | // don't sleep, but warn if --missed-deadlines is set 651 | if (warn_missed_deadlines) { 652 | timespecsub(&ts, &end, &ts); 653 | timespecnegtopos(&ts, &ts); 654 | fprintf(stderr, "we're falling behind by %ld.%09ld!\n", ts.tv_sec, ts.tv_nsec); 655 | } 656 | } 657 | else if ( (i < (time-1)) || (j < (freq-1)) ) { 658 | // only sleep if it's not the very last round 659 | timespecsub(&ts, &end, &ts); 660 | if (timespeccmp(&ts, &minsleep, <)) { 661 | // we finished so close to the next deadline that nanosleep() cannot 662 | // reliably wake us up in time, so do busywaiting 663 | busywait(ts.tv_nsec); 664 | } 665 | else { 666 | nanosleep(&ts, NULL); 667 | } 668 | } 669 | } 670 | } 671 | 672 | if (xen_interface_close()) 673 | printf("error closing interface to hypervisor. (?!)\n"); 674 | 675 | if (missed_deadlines) 676 | printf("Missed %lld deadlines\n", missed_deadlines); 677 | 678 | return 0; 679 | } 680 | -------------------------------------------------------------------------------- /xen-interface-arm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uniprof: ARM-specfic Xen interface functions 3 | * 4 | * Authors: Florian Schmidt 5 | * 6 | * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include "xen-interface.h" 39 | 40 | /* On x86, we might have 32-bit domains running on 64-bit machines, 41 | * so we ask the hypervisor. On ARM, we simply return arch size. */ 42 | int get_word_size(int __maybe_unused domid) { 43 | #if defined(__arm__) 44 | return 4; 45 | #elif defined(__aarch64__) 46 | return 8; 47 | #endif 48 | } 49 | 50 | #if defined(HYPERCALL_XENCALL) 51 | unsigned long xen_translate_foreign_address(int domid, int vcpu, unsigned long long virt) 52 | { 53 | vcpu_guest_context_t ctx; 54 | uint32_t pt_base_addr; 55 | int arm_pt_base_length = 18; 56 | int arm_pt_index_length = 12; 57 | uint32_t addr, offset; 58 | unsigned int N; /* N as defined in the the ARM TCBR specification */ 59 | int err, entry_type; 60 | void *map; 61 | 62 | get_vcpu_context(domid, vcpu, &ctx); 63 | /* N defines the split between the two page tables. If all the most-significant 64 | * N bits of a virtual address are 0, then use page table 0, otherwise use 65 | * page table 1. */ 66 | N = ctx.ttbcr & 0x7; 67 | if (virt & (N<<29)) { 68 | fprintf(stderr, "warning: TTBR1 support not tested at all!\n"); 69 | pt_base_addr = ctx.ttbr1 & ~((1<<(32-arm_pt_base_length))-1); 70 | } 71 | else { 72 | /* Update translate base and table index width from their 73 | * default values according to N. */ 74 | arm_pt_base_length += N; 75 | arm_pt_index_length -= N; 76 | pt_base_addr = ctx.ttbr0 & ~((1<<(32-arm_pt_base_length))-1); 77 | } 78 | addr = pt_base_addr>>PAGE_SHIFT; 79 | map = xenforeignmemory_map(fmemh, domid, PROT_READ, 1, (xen_pfn_t *)&addr, &err); 80 | if (err) 81 | goto out_unmap; 82 | DBG("mapped page table base 0x%x to %p, err = %d\n", pt_base_addr, map, err); 83 | 84 | /* See ARMv7 Reference Manual, Figure B3-9, or B3-10 on how to get a first-level 85 | * descriptor address: 86 | * We take bits 31 to (14-N) from TTBR0 (i.e., pt_base_addr) and map them to 31..(14-N). 87 | * We then take bits (31-N) to 20 from the virtual address and map them to (13-N)..2. 88 | * Bits 1..0 are 0x0. */ 89 | addr = (virt & (~((1<> 20; 90 | DBG("PT virt part is 0x%x\n", addr); 91 | addr = pt_base_addr + (addr<<2); 92 | offset = addr - pt_base_addr; 93 | DBG("address-to-lookup is 0x%x, offset to base is 0x%x\n", addr, addr-pt_base_addr); 94 | 95 | memcpy(&addr, map + offset, 4); 96 | DBG("content of %p is 0x%x\n", map + offset, addr); 97 | 98 | /* we now have to check which type of table entry this is */ 99 | entry_type = addr & 0x3; 100 | DBG("entry type is 0x%x\n", entry_type); 101 | switch (entry_type) { 102 | case 0x0: 103 | /* page fault. Should never happen, since we want to look at used memory. */ 104 | fprintf(stderr, "Page fault while trying to resolve guest address!\n"); 105 | goto out_unmap; 106 | case 0x1: 107 | /* Large page. We need to do a second-level lookup. (cf. Fig. B3-10) 108 | * The page table address base (bits 31..10) is in addr[31..10], the 109 | * L2 table index (bits 9..2) is in virt[19..12]. Bits 1..0 are 0x0. */ 110 | fprintf(stderr, "Warning: multi-level page walking code not tested at all!\n"); 111 | addr &= (addr & 0xFFFFFC00); 112 | addr |= ((virt & 0xFF000)>>10); 113 | if ((addr>>PAGE_SHIFT) != (pt_base_addr>>PAGE_SHIFT)) { 114 | /* New address is in a different mage, get that one. */ 115 | xenforeignmemory_unmap(fmemh, map, 1); 116 | map = xenforeignmemory_map(fmemh, domid, PROT_READ, 1, (xen_pfn_t *)&addr, &err); 117 | if (err) 118 | goto out_unmap; 119 | } 120 | offset = addr - pt_base_addr; 121 | memcpy(&addr, map + offset, 4); 122 | /* For the output address, the base (bits 31..16) is in addr[31..16], the 123 | * page index (bits 15..0) is in virt[15..0]. So splice them together. 124 | * The astute reader will notice there is an overlap, and bits 12..15 125 | * are used both in the second-level lookup and as part of the address. */ 126 | addr = (addr & ~((1<<16)-1)) | (virt & ((1<<16)-1)); 127 | break; 128 | case 0x2: 129 | /* Section entry. We're done with lookups. (cf. Fig. B3-9) 130 | * The base (bits 31..20) is in addr[31..20], the 131 | * index (bits 19..0) is in virt[19..0]. So splice them together. */ 132 | addr = (addr & ~((1<<20)-1)) | (virt & ((1<<20)-1)); 133 | break; 134 | case 0x3: 135 | /* Small page. We need to do a second-level lookup (cf. Fig. B3-11) 136 | * This first step is exactly the same as for large pages above. */ 137 | fprintf(stderr, "Warning: multi-level page walking code not tested at all!\n"); 138 | addr &= (addr & 0xFFFFFC00); 139 | addr |= ((virt & 0xFF000)>>10); 140 | if ((addr>>PAGE_SHIFT) != (pt_base_addr>>PAGE_SHIFT)) { 141 | /* New address is in a different mage, get that one. */ 142 | xenforeignmemory_unmap(fmemh, map, 1); 143 | map = xenforeignmemory_map(fmemh, domid, PROT_READ, 1, (xen_pfn_t *)&addr, &err); 144 | if (err) 145 | goto out_unmap; 146 | } 147 | offset = addr - pt_base_addr; 148 | memcpy(&addr, map + offset, 4); 149 | /* For the output address, the base (bits 31..12) is in addr[31..12], the 150 | * page index (bits 11..0) is in virt[11..0]. So splice them together. */ 151 | addr = (addr & ~((1<<12)-1)) | (virt & ((1<<12)-1)); 152 | break; 153 | } 154 | /* We now have the machine addres. But actually, we want an 155 | * MFN, so shift the address accordingly. */ 156 | addr >>= PAGE_SHIFT; 157 | DBG("found section entry for %llx to mfn 0x%x\n", virt, addr); 158 | xenforeignmemory_unmap(fmemh, map, 1); 159 | return addr; 160 | 161 | out_unmap: 162 | xenforeignmemory_unmap(fmemh, map, 1); 163 | fprintf(stderr, "error trying to map domU memory (bogus frame pointers?)\n"); 164 | return 0; 165 | } 166 | #endif /* HYPERCALL_XENCALL */ 167 | 168 | void xen_map_domu_page(int domid, int vcpu, uint64_t addr, unsigned long *mfn, void **buf) { 169 | int err __maybe_unused = 0; 170 | DBG("mapping page for virt addr %"PRIx64"\n", addr); 171 | #if defined(HYPERCALL_XENCALL) 172 | *mfn = xen_translate_foreign_address(domid, vcpu, addr); 173 | if (*mfn) { 174 | // This works since size is 1, so the array has size 1, so it's just a pointer to an int 175 | *buf = xenforeignmemory_map(fmemh, domid, PROT_READ, 1, (xen_pfn_t *)mfn, &err); 176 | if (err) { 177 | xenforeignmemory_unmap(fmemh, *buf, 1); 178 | *buf = 0; 179 | } 180 | } 181 | else { 182 | *buf = 0; 183 | } 184 | #elif defined(HYPERCALL_LIBXC) 185 | *mfn = xc_translate_foreign_address(xc_handle, domid, vcpu, addr); 186 | DBG("addr = %"PRIx64", mfn = %lx\n", addr, *mfn); 187 | *buf = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE, PROT_READ, *mfn); 188 | #endif 189 | DBG("virt addr %"PRIx64" has mfn %lx and was mapped to %p\n", addr, *mfn, *buf); 190 | } 191 | 192 | guest_word_t frame_pointer(vcpu_guest_context_transparent_t *vc) { 193 | // this only works for ARM mode so far! 194 | // also, it might not work at all on AACPI ABI! 195 | #if defined(HYPERCALL_XENCALL) 196 | return vc->user_regs.r11_usr; 197 | #elif defined(HYPERCALL_LIBXC) 198 | return vc->c.user_regs.r11_usr; 199 | #endif 200 | } 201 | 202 | guest_word_t instruction_pointer(vcpu_guest_context_transparent_t *vc) { 203 | // this only works for ARM mode so far! 204 | #if defined(HYPERCALL_XENCALL) 205 | return vc->user_regs.pc32; 206 | #elif defined(HYPERCALL_LIBXC) 207 | return vc->c.user_regs.pc32; 208 | #endif 209 | } 210 | -------------------------------------------------------------------------------- /xen-interface-common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uniprof: architecture-independent Xen interface functions 3 | * 4 | * Authors: Florian Schmidt 5 | * 6 | * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #if defined(HYPERCALL_XENCALL) 40 | xencall_handle *callh; 41 | xenforeignmemory_handle *fmemh; 42 | #endif 43 | #if defined(HYPERCALL_LIBXC) 44 | xc_interface *xc_handle; 45 | #endif 46 | 47 | int xen_interface_open(void) { 48 | #if defined(HYPERCALL_XENCALL) 49 | callh = xencall_open(NULL, XENCALL_OPENFLAG_NON_REENTRANT); 50 | if (callh == NULL) 51 | return -1; 52 | fmemh = xenforeignmemory_open(NULL, 0); 53 | if (fmemh == NULL) 54 | return -2; 55 | #endif 56 | #if defined(HYPERCALL_LIBXC) 57 | xc_handle = xc_interface_open(0,0,0); 58 | if (xc_handle == NULL) 59 | return -1; 60 | #endif 61 | return 0; 62 | } 63 | 64 | int xen_interface_close(void) { 65 | #if defined(HYPERCALL_XENCALL) 66 | if (xenforeignmemory_close(fmemh)) 67 | return -2; 68 | if (xencall_close(callh)) 69 | return -1; 70 | #elif defined(HYPERCALL_LIBXC) 71 | if (xc_interface_close(xc_handle)) 72 | return -1; 73 | #endif 74 | return 0; 75 | } 76 | 77 | int get_domain_state(int domid, unsigned int *state) { 78 | int retval; 79 | #if defined(HYPERCALL_XENCALL) 80 | struct xen_domctl domctl; 81 | domctl.domain = (domid_t)domid; 82 | domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION; 83 | domctl.cmd = XEN_DOMCTL_getdomaininfo; 84 | retval = xencall1(callh, __HYPERVISOR_domctl, (unsigned long)(&domctl)); 85 | *state = domctl.u.getdomaininfo.flags; 86 | return retval; 87 | #elif defined(HYPERCALL_LIBXC) 88 | xc_dominfo_t info; 89 | retval = xc_domain_getinfo(xc_handle, domid, 1, &info); 90 | *state |= (info.shutdown_reason << XEN_DOMINF_shutdownshift); 91 | if (info.dying) 92 | *state |= XEN_DOMINF_dying; 93 | if (info.hvm) 94 | *state |= XEN_DOMINF_hvm_guest; 95 | if (info.shutdown || info.crashed) 96 | *state |= XEN_DOMINF_shutdown; 97 | if (info.paused) 98 | *state |= XEN_DOMINF_paused; 99 | if (info.blocked) 100 | *state |= XEN_DOMINF_blocked; 101 | if (info.running) 102 | *state |= XEN_DOMINF_running; 103 | if (info.debugged) 104 | *state |= XEN_DOMINF_debugged; 105 | if (retval == 1) 106 | return 0; 107 | return retval; 108 | #endif 109 | } 110 | 111 | int get_vcpu_context(int domid, int vcpu, vcpu_guest_context_transparent_t *vc) { 112 | #if defined(HYPERCALL_XENCALL) 113 | struct xen_domctl domctl; 114 | domctl.domain = (domid_t)domid; 115 | domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION; 116 | domctl.cmd = XEN_DOMCTL_getvcpucontext; 117 | domctl.u.vcpucontext.vcpu = (uint16_t)vcpu; 118 | domctl.u.vcpucontext.ctxt.p = (vcpu_guest_context_t *)vc; 119 | return xencall1(callh, __HYPERVISOR_domctl, (unsigned long)(&domctl)); 120 | #elif defined(HYPERCALL_LIBXC) 121 | return xc_vcpu_getcontext(xc_handle, domid, vcpu, vc); 122 | #endif 123 | } 124 | 125 | int pause_domain(int domid) { 126 | #if defined(HYPERCALL_XENCALL) 127 | struct xen_domctl domctl; 128 | domctl.domain = (domid_t)domid; 129 | domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION; 130 | domctl.cmd = XEN_DOMCTL_pausedomain; 131 | return xencall1(callh, __HYPERVISOR_domctl, (unsigned long)(&domctl)); 132 | #elif defined(HYPERCALL_LIBXC) 133 | return xc_domain_pause(xc_handle, domid); 134 | #endif 135 | } 136 | 137 | int unpause_domain(int domid) { 138 | #if defined(HYPERCALL_XENCALL) 139 | struct xen_domctl domctl; 140 | domctl.domain = (domid_t)domid; 141 | domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION; 142 | domctl.cmd = XEN_DOMCTL_unpausedomain; 143 | return xencall1(callh, __HYPERVISOR_domctl, (unsigned long)(&domctl)); 144 | #elif defined(HYPERCALL_LIBXC) 145 | return xc_domain_unpause(xc_handle, domid); 146 | #endif 147 | } 148 | 149 | int get_max_vcpu_id(int domid) { 150 | #if defined(HYPERCALL_XENCALL) 151 | int ret; 152 | struct xen_domctl domctl; 153 | domctl.domain = (domid_t)domid; 154 | domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION; 155 | domctl.cmd = XEN_DOMCTL_getdomaininfo; 156 | ret = xencall1(callh, __HYPERVISOR_domctl, (unsigned long)(&domctl)); 157 | if (ret < 0) 158 | return -5; 159 | else 160 | return domctl.u.getdomaininfo.max_vcpu_id; 161 | #elif defined(HYPERCALL_LIBXC) 162 | int ret; 163 | xc_dominfo_t dominfo; 164 | ret = xc_domain_getinfo(xc_handle, domid, 1, &dominfo); 165 | if (ret < 0) 166 | return -5; 167 | else 168 | return dominfo.max_vcpu_id; 169 | #endif 170 | } 171 | -------------------------------------------------------------------------------- /xen-interface-x86.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uniprof: x86-specific Xen interface functions 3 | * 4 | * Authors: Florian Schmidt 5 | * 6 | * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | #define _GNU_SOURCE 1 36 | #include 37 | #include 38 | #include 39 | #include "xen-interface.h" 40 | 41 | /* On x86, we might have 32-bit domains running on 64-bit machines, 42 | * so we ask the hypervisor. On ARM, we simply return arch size. */ 43 | int get_word_size(int domid) { 44 | //TODO: support for HVM 45 | #if defined(HYPERCALL_XENCALL) 46 | struct xen_domctl domctl; 47 | domctl.domain = (domid_t)domid; 48 | domctl.interface_version = XEN_DOMCTL_INTERFACE_VERSION; 49 | domctl.cmd = XEN_DOMCTL_get_address_size; 50 | if (xencall1(callh, __HYPERVISOR_domctl, (unsigned long)(&domctl))) 51 | return -1; 52 | return (domctl.u.address_size.size / 8); 53 | #elif defined(HYPERCALL_LIBXC) 54 | unsigned int guest_word_size; 55 | 56 | if (xc_domain_get_guest_width(xc_handle, domid, &guest_word_size)) 57 | return -1; 58 | return guest_word_size; 59 | #endif 60 | } 61 | 62 | #if defined(HYPERCALL_XENCALL) 63 | /* libxenforeignmemory doesn't provide an address translation method like libxc does, 64 | * so it needs a replacement function to walk the page tables. 65 | */ 66 | unsigned long xen_translate_foreign_address(int domid, int vcpu, unsigned long long virt) 67 | { 68 | vcpu_guest_context_t ctx; 69 | int wordsize, levels; 70 | int i, err; 71 | uint64_t addr, mask, clamp, offset; 72 | xen_pfn_t pfn; 73 | void *map; 74 | 75 | get_vcpu_context(domid, vcpu, &ctx); 76 | wordsize = get_word_size(domid); 77 | 78 | if (wordsize == 8) { 79 | /* 64-bit has a 4-level page table */ 80 | levels = 4; 81 | /* clamp values to 48 bit virtual address range */ 82 | clamp = (1ULL<<48) - 1; 83 | addr = (uint64_t)xen_cr3_to_pfn_x86_64(ctx.ctrlreg[3]) << PAGE_SHIFT; 84 | addr &= clamp; 85 | } 86 | else { /* wordsize == 4, any weird other values throw and error much earlier */ 87 | /* 32-bit has a 3-level page table */ 88 | levels = 3; 89 | /* clamp value to 32 bit address range */ 90 | clamp = (1ULL<<32) - 1; 91 | addr = (uint32_t)xen_cr3_to_pfn_x86_32(ctx.ctrlreg[3]) << PAGE_SHIFT; 92 | } 93 | DBG("page table base address is 0x%lx\n", addr); 94 | /* See AMD64 Architecture Programmer's Manual, Volume 2: System Programming, 95 | * rev 3.22, p. 127, Fig. 5-9 for 32-bit and p, 132, Fig. 5-17 for 64-bit. */ 96 | /* Each page table considers a 9-bit range. 97 | * The lowest level considers bits 12-21 (hence the <<12 shift), 98 | * each higher level the next-significant 9 bits. 99 | * Note that the highest level is truncated and only considers 100 | * 2 bits for 32-bit archictures. */ 101 | mask = ((((1ULL<<9)-1) << 12) << ((levels-1)*9)); 102 | 103 | for (i = levels; i > 0; i--) { 104 | /* See AMD64 Architecture Programmer's Manual, Volume 2: System 105 | * Programming, rev 3.22, p. 128, Figs. 5-10 to 5-12 for 32-bit 106 | * and p, 133, Figs. 5-18 to 5-21 for 64-bit. */ 107 | /* Take the respective bits for the level, shift them to the 108 | * very right, and interpret them as a "page table entry number". 109 | * Since PTEs are 8 bytes for both 64-bit and 32-bit (Xen doesn't 110 | * seem to emulate legacy non-PAE setups with 4-byte PTEs), 111 | * multiply the page table entry number by 8. */ 112 | offset = ((virt & mask) >> (ffsll(mask) - 1)) * 8; 113 | DBG("level %d page walk gives us offset 0x%lx\n", i, offset); 114 | /* But before we can read from there, we will need to map in that memory */ 115 | pfn = addr >> PAGE_SHIFT; 116 | map = xenforeignmemory_map(fmemh, domid, PROT_READ, 1, &pfn, &err); 117 | if (err) 118 | goto out_unmap; 119 | memcpy(&addr, map + offset, 8); 120 | xenforeignmemory_unmap(fmemh, map, 1); 121 | /* However, addr is not really an address right now, but rather a PTE, 122 | * which contains the base address in bits 51..12. No shifting necessary, 123 | * because the base address in the PTE is a PFN. */ 124 | addr &= 0x000FFFFFFFFFF000ULL; 125 | DBG("level %d page table tells us to look at address 0x%lx\n", i, addr); 126 | /* Move the mask by 9 bits, and go on to the next round */ 127 | mask >>= 9; 128 | } 129 | /* We now have the machine addres. But actually, we want an 130 | * MFN, so shift the address accordingly. */ 131 | addr >>= PAGE_SHIFT; 132 | DBG("found section entry for %llx to mfn 0x%lx\n", virt, addr); 133 | xenforeignmemory_unmap(fmemh, map, 1); 134 | return addr; 135 | 136 | out_unmap: 137 | xenforeignmemory_unmap(fmemh, map, 1); 138 | return 0; 139 | } 140 | #endif /* HYPERCALL_XENCALL */ 141 | 142 | void xen_map_domu_page(int domid, int vcpu, uint64_t addr, unsigned long *mfn, void **buf) { 143 | int err __maybe_unused = 0; 144 | DBG("mapping page for virt addr %"PRIx64"\n", addr); 145 | #if defined(HYPERCALL_XENCALL) 146 | *mfn = xen_translate_foreign_address(domid, vcpu, addr); 147 | if (*mfn) { 148 | // This works since size is 1, so the array has size 1, so it's just a pointer to an int 149 | *buf = xenforeignmemory_map(fmemh, domid, PROT_READ, 1, (xen_pfn_t *)mfn, &err); 150 | if (err) { 151 | xenforeignmemory_unmap(fmemh, *buf, 1); 152 | *buf = 0; 153 | } 154 | } 155 | else { 156 | *buf = 0; 157 | } 158 | #elif defined(HYPERCALL_LIBXC) 159 | *mfn = xc_translate_foreign_address(xc_handle, domid, vcpu, addr); 160 | DBG("addr = %"PRIx64", mfn = %lx\n", addr, *mfn); 161 | *buf = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE, PROT_READ, *mfn); 162 | #endif 163 | DBG("virt addr %"PRIx64" has mfn %lx and was mapped to %p\n", addr, *mfn, *buf); 164 | } 165 | 166 | guest_word_t frame_pointer(vcpu_guest_context_transparent_t *vc) { 167 | // only possible word sizes are 4 and 8, everything else leads to an 168 | // early exit during initialization, since we can't handle it 169 | #if defined(__i386__) 170 | #if defined(HYPERCALL_XENCALL) 171 | return vc->user_regs.ebp; 172 | #elif defined(HYPERCALL_LIBXC) 173 | return vc->x32.user_regs.ebp; 174 | #endif /* libxc/hypercall */ 175 | #elif defined(__x86_64__) 176 | #if defined(HYPERCALL_XENCALL) 177 | return vc->user_regs.rbp; 178 | #elif defined(HYPERCALL_LIBXC) 179 | return vc->x64.user_regs.rbp; 180 | #endif /* libxc/hypercall */ 181 | #endif /* architecture */ 182 | } 183 | 184 | guest_word_t instruction_pointer(vcpu_guest_context_transparent_t *vc) { 185 | //TODO: currently no support for real-mode 32 bit 186 | #if defined(__i386__) 187 | #if defined(HYPERCALL_XENCALL) 188 | return vc->user_regs.eip; 189 | #elif defined(HYPERCALL_LIBXC) 190 | return vc->x32.user_regs.eip; 191 | #endif /* libxc/hypercall */ 192 | #elif defined(__x86_64__) 193 | #if defined(HYPERCALL_XENCALL) 194 | return vc->user_regs.rip; 195 | #elif defined(HYPERCALL_LIBXC) 196 | return vc->x64.user_regs.rip; 197 | #endif /* libxc/hypercall */ 198 | #endif /* architecture */ 199 | } 200 | --------------------------------------------------------------------------------