Big Ben

一个半吊子的编码爱好者

0%

本文主要基于[2], 提取出核心的描述,并理清思路

seccomp的前世今生

seccomp最早出现在Linux kernel 2.6.12,时间是2005年。2012年的Linux 3.5版本,加入了"seccomp mode 2" (or "seccomp filter mode")功能。
It added a second mode for seccomp: SECCOMP_MODE_FILTER. Using that mode, processes can specify which system calls are permitted. By using a mini-program in the Berkeley packet filter (BPF) language, processes could restrict system calls entirely or only for certain argument values.
所以我们现在用的就是这个seccomp2,或者叫seccomp-bpf。那么为啥叫seccomp-bpf?BPF到底是什么?
BPF全称是Berkeley Packet Filter。
Read more »

《SELinux介绍》一文中,阐述了一些SELinux的基本逻辑,包括TE,RBAC和MLS。那么在一个发型版上怎么将SELinux跑起来呢?我们能对策略文件做点什么呢?这个策略文件能不能动态修改呢?本篇主要目的是回答这几个问题。我不打算做成step by step的教程,具体的步骤可以google之。但会对主要的资源做一些索引,并通过我的思路将它们串联起来。

Fedora上的SELinux

Fedora/RHEL是默认支持SELinux的,且默认就是enforcing状态。如果需要修改,可以

  • 临时关闭(不用重启机器):
setenforce 0         ##设置SELinux 成为permissive模式
  • 修改配置文件需要重启机器:
    修改/etc/selinux/config文件, 将SELINUX=enforcing改为SELINUX=disabled

Fedora policy文件的位置在/etc/selinux/targeted/policy/policy.31。31表示版本号。具体的文件格式信息,需要查看Linux源码policydb_read函数,位置在security/selinux/ss/policydb.c

值得注意的是,Ubuntu使用的是AppArmore,而不是SELinux
可以认为:SELinux和AppArmore都是基于LSM(Linux Secure Module)的两个平行的模块。如果希望在Ubuntu上使能SELinux,需要disable AppArmore。如果直接安装并使能SELinux而不关闭AppArmore,系统会挂死。因为2个安全系统拥有不同的文件系统读写配置,形成死锁。网上有很多相关的帖子,可以尝试着做一做实验。我已经以身试法上面说的挂死的情况了。请莫效仿。

Labelling

SELinux的核心思想就是一个标签体系(security context,简称SContext)。那么这个标签是怎么打上去的?这个打标签的过程称为labelling。那么labelling是怎么和内核启动相结合以及如何与终端用户(或者管理员用户)交互的呢?
如果暂时放下SELinux,我们想一想应该怎么做?我认为如果是我,可能会:

  • 先给所有的process打上类似user_u:role_r:type_t:s0-s1:c0,c1-c255这样的标签
  • 然后给所有的file(此处的file,应该是Linux中万物皆文件的file)也打上类似的标签,不过role就是固定的object_r了

那么看看SELinux到底是不是这样做的呢?

给进程打标签

First of all, know that SELinux supports inheritance of contexts. Furthermore more, inheritance of contexts is the default behavior: if there is no policy in SELinux that specifies otherwise, then anything created will inherit the context of its parent.[1]

我们知道Linux的所有进程都是kernel启动时的1号进程通过fork系统调用叫起来的。1号进程可能是openrc或者systemd之类的进程。所以所有的进程一上来都会继承init进程的所有标签,然后再根据具体的policy设定进行type transition。
正好,SELinux就支持这种Domain/Type Transition的语法(当然不是正好,是SELinux设计者们就是这么设计的)。

注:通过《SELinux介绍》一文,我们可以知道Domain其实就是进程的Type

举个Domain Transition的例子

type_transition init_t apache_exec_t : process apache_t

翻译成人类语言就是:
init_t Domain中的进程执行type为apache_exec_t类型的可执行文件(fork并execv)时(文件的class为process),所属Domain(对process而言,肯定是指Domain)需要切换到apache_t域。

要做到这个type transition,那显然要涉及到以下3个权限:
1.首先,你得让init_t域中的进程能够执行type为apache_exec_t的文件
allow init_t apache_exec_t : file execute;
2.然后,你还得告诉SELiux,允许init_t做DT切换以进入apache_t域
allow init_t apache_t : process transition;
3.最后,你还得告诉SELinux,切换入口(对应为entrypoint权限)为执行apache_exec_t类型的文件
allow apache_t apache_exec_t : file entrypoint;

所以一条type transition的规则就要搭配另外至少3条规则(事实上,具体的发行版可能会更多)来运行。于是SELinux就发明了宏,类似函数来方便定义进程的标签转换。参考安卓的实现[1]:

# [external/sepolicy/te_macros]
# 定义domain_trans宏。$1,$2等等代表宏的第一个,第二个....参数

define(`domain_trans', `
    allow $1 $2:file { getattr open read execute };
    allow $1 $3:process transition;
    allow $3 $2:file { entrypoint read execute };
    ...
')

#定义domain_auto_trans宏,这个宏才是我们在te中直接使用的

define(`domain_auto_trans', `
    domain_trans($1,$2,$3)
    type_transition $1 $2:process $3;
')

对应到之前的例子,如果apache_exec_t类型的文件被init进程叫起来以后,要切换到apache_t域就要用下面这条宏调用。

domain_auto_trans(init_t, apache_exec_t, apache_t)

以一个真实的例子结束这一段:

# 在external/sepolicy/init_shell.te中就有上述宏的用法:
./init_shell.te:4:domain_auto_trans(init, shell_exec, init_shell)

给文件打标签

进程的标签是从init进程继承,并按照策略文件进行响应的domain transition来的。那么文件的标签是从哪来的呢?例如u:object_r:cache_file:s0
事实上初始的文件系统也是有个初始值的,这个初始值通常放在一个叫file_contexts的文件里。例如Android的在external/sepolicy/file_contexts。再摘去一段看看,这个file_contexts到底是啥:

/dev(/.*)?        u:object_r:device:s0
/dev/akm8973.*        u:object_r:akm_device:s0
/dev/accelerometer    u:object_r:accelerometer_device:s0
/dev/alarm        u:object_r:alarm_device:s0
/dev/android_adb.*    u:object_r:adb_device:s0
/dev/ashmem        u:object_r:ashmem_device:s0
/dev/audio.*        u:object_r:audio_device:s0

可见file_contexts描述的就是一些文件和文件夹的安全标签(SContext)。
那么新建一个目录或者一个文件,他的标签又怎么来呢?
当创建一个新文件时(目录也是一种文件),实际上它的标签会继承自其父目录,之后按照规则文件规定的做type transition。和进程的打标签过程是不是很类似?
具体的语法可以参考[1]

特殊的标签sid

可以参考[5]。[2]中阐述了sid以及sid_context的语法。但是对为什么有这两个东西,并且它们有什么用上,没有说清楚。[5]做了比较好的解释。
总结一下就是,Linux kernel在init进程加载policy之前,也需要一些基本的标签,而这些标签也就是所谓的sid(secure ID)。每个sid对应一个sid_context。这些都是固化在内核里的。在init加载以后,所有sid对应的标签都会被转换到正常的设置。

策略/标签文件从哪来?

先看实例,Android的策略文件的位置在
Android系统策略文件(.te)位置在system/sepolicy,device/<manufacturer>/<device-name>/sepolicy

#############################
# Default HALs
#
/(vendor|system/vendor)/bin/hw/android\.hardware\.audio@2\.0-service          u:object_r:hal_audio_default_exec:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.automotive\.audiocontrol@1\.0-service  u:object_r:hal_audiocontrol_default_exec:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.automotive\.evs@1\.0-service  u:object_r:hal_evs_default_exec:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.automotive\.vehicle@2\.0-service  u:object_r:hal_vehicle_default_exec:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.bluetooth@1\.0-service      u:object_r:hal_bluetooth_default_exec:s0

既然和写代码一样,那就也有开发环境了,参考[2]的7.6一节。在此不做深究。
安卓上编译策略文件的流程如下图:

策略更新

策略加载的流程通常都是由1号进程完成的。它负责读取配置文件,加载编译后的策略文件,并传入内核的LSM(Linux Secure Module)来完成SELinux的初始化。那么如果我们要修改策略(增删改),那势必要重新编译,重新部署。这一部分可以参考[3]。虽然里面的软件版本比较旧,但核心的思路不变。我理解的大致流程如下(我还没有试验过,可以找一个虚拟机试试看):

  • 编译策略文件,生成二进制的策略文件policy.bin
  • 将policy.bin放入/etc/目录
  • 使用setfiles重新标记文件系统
  • 使用semanage创建管理员账号
  • 重启生效

以上的操作都要由root账号来完成。可见root还是很无敌啊。

用户态工具链

引用[4]中的文字:

The policycoreutils package installs the following utilities:

  • fixfiles: Fixes the security context on file systems
  • load_policy: Loads a new SELinux policy into the kernel
  • restorecon: Resets the security context on one or more files
  • setfiles: Initializes the security context on one or more files
  • secon: Displays the SELinux context from a file, program, or user input
  • semodule_package: Creates an SELinux policy module package
  • restorecond: Is a daemon that watches for file creation and sets the default file context
  • semodule: Manages SELinux policy modules
  • sestatus: Displays SELinux status
  • setsebool: Sets SELinux Boolean value

我所用过的:

  • checkpolicy: 编译策略文件(.te)
  • setfiles: 给文件系统打标签
  • semanage: 管理SELinux下的用户系统

参考文献

  1. Gentoo Linux - SELinux/Tutorials/How does a process get into a certain context
  2. SELinux学习笔记
  3. 从头开始生成 SELinux
  4. List of SELinux Utilities
  5. Initial Security Identifiers
%E3%80%8ASELinux%E4%BB%8B%E7%BB%8D%E3%80%8B%E4%B8%80%E6%96%87%E4%B8%AD%EF%BC%8C%E9%98%90%E8%BF%B0%E4%BA%86%E4%B8%80%E4%BA%9BSELinux%E7%9A%84%E5%9F%BA%E6%9C%AC%E9%80%BB%E8%BE%91%EF%BC%8C%E5%8C%85%E6%8B%ACTE%EF%BC%8CRBAC%E5%92%8CMLS%E3%80%82%E9%82%A3%E4%B9%88%E5%9C%A8%E4%B8%80%E4%B8%AA%E5%8F%91%E5%9E%8B%E7%89%88%E4%B8%8A%E6%80%8E%E4%B9%88%E5%B0%86SELinux%E8%B7%91%E8%B5%B7%E6%9D%A5%E5%91%A2%EF%BC%9F%E6%88%91%E4%BB%AC%E8%83%BD%E5%AF%B9%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E5%81%9A%E7%82%B9%E4%BB%80%E4%B9%88%E5%91%A2%EF%BC%9F%E8%BF%99%E4%B8%AA%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E8%83%BD%E4%B8%8D%E8%83%BD%E5%8A%A8%E6%80%81%E4%BF%AE%E6%94%B9%E5%91%A2%EF%BC%9F%E6%9C%AC%E7%AF%87%E4%B8%BB%E8%A6%81%E7%9B%AE%E7%9A%84%E6%98%AF%E5%9B%9E%E7%AD%94%E8%BF%99%E5%87%A0%E4%B8%AA%E9%97%AE%E9%A2%98%E3%80%82%E6%88%91%E4%B8%8D%E6%89%93%E7%AE%97%E5%81%9A%E6%88%90step%20by%20step%E7%9A%84%E6%95%99%E7%A8%8B%EF%BC%8C%E5%85%B7%E4%BD%93%E7%9A%84%E6%AD%A5%E9%AA%A4%E5%8F%AF%E4%BB%A5google%E4%B9%8B%E3%80%82%E4%BD%86%E4%BC%9A%E5%AF%B9%E4%B8%BB%E8%A6%81%E7%9A%84%E8%B5%84%E6%BA%90%E5%81%9A%E4%B8%80%E4%BA%9B%E7%B4%A2%E5%BC%95%EF%BC%8C%E5%B9%B6%E9%80%9A%E8%BF%87%E6%88%91%E7%9A%84%E6%80%9D%E8%B7%AF%E5%B0%86%E5%AE%83%E4%BB%AC%E4%B8%B2%E8%81%94%E8%B5%B7%E6%9D%A5%E3%80%82%0A%23%23%20Fedora%E4%B8%8A%E7%9A%84SELinux%0AFedora%2FRHEL%E6%98%AF%E9%BB%98%E8%AE%A4%E6%94%AF%E6%8C%81SELinux%E7%9A%84%EF%BC%8C%E4%B8%94%E9%BB%98%E8%AE%A4%E5%B0%B1%E6%98%AFenforcing%E7%8A%B6%E6%80%81%E3%80%82%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E4%BF%AE%E6%94%B9%EF%BC%8C%E5%8F%AF%E4%BB%A5%0A-%20%E4%B8%B4%E6%97%B6%E5%85%B3%E9%97%AD%EF%BC%88%E4%B8%8D%E7%94%A8%E9%87%8D%E5%90%AF%E6%9C%BA%E5%99%A8%EF%BC%89%EF%BC%9A%0A%60%60%60bash%0Asetenforce%200%20%20%20%20%20%20%20%20%20%23%23%E8%AE%BE%E7%BD%AESELinux%20%E6%88%90%E4%B8%BApermissive%E6%A8%A1%E5%BC%8F%0A%60%60%60%0A-%20%E4%BF%AE%E6%94%B9%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E9%9C%80%E8%A6%81%E9%87%8D%E5%90%AF%E6%9C%BA%E5%99%A8%EF%BC%9A%0A%E4%BF%AE%E6%94%B9%2Fetc%2Fselinux%2Fconfig%E6%96%87%E4%BB%B6%2C%20%E5%B0%86SELINUX%3Denforcing%E6%94%B9%E4%B8%BASELINUX%3Ddisabled%0A%0AFedora%20policy%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%8D%E7%BD%AE%E5%9C%A8%2Fetc%2Fselinux%2Ftargeted%2Fpolicy%2Fpolicy.31%E3%80%8231%E8%A1%A8%E7%A4%BA%E7%89%88%E6%9C%AC%E5%8F%B7%E3%80%82%E5%85%B7%E4%BD%93%E7%9A%84%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%E4%BF%A1%E6%81%AF%EF%BC%8C%E9%9C%80%E8%A6%81%E6%9F%A5%E7%9C%8BLinux%E6%BA%90%E7%A0%81%60policydb_read%60%E5%87%BD%E6%95%B0%EF%BC%8C%E4%BD%8D%E7%BD%AE%E5%9C%A8%60security%2Fselinux%2Fss%2Fpolicydb.c%60%0A%3E%20%E5%80%BC%E5%BE%97%E6%B3%A8%E6%84%8F%E7%9A%84%E6%98%AF%EF%BC%8CUbuntu%E4%BD%BF%E7%94%A8%E7%9A%84%E6%98%AFAppArmore%EF%BC%8C%E8%80%8C%E4%B8%8D%E6%98%AFSELinux%0A%3E%20%E5%8F%AF%E4%BB%A5%E8%AE%A4%E4%B8%BA%EF%BC%9ASELinux%E5%92%8CAppArmore%E9%83%BD%E6%98%AF%E5%9F%BA%E4%BA%8ELSM%EF%BC%88Linux%20Secure%20Module%EF%BC%89%E7%9A%84%E4%B8%A4%E4%B8%AA%E5%B9%B3%E8%A1%8C%E7%9A%84%E6%A8%A1%E5%9D%97%E3%80%82%E5%A6%82%E6%9E%9C%E5%B8%8C%E6%9C%9B%E5%9C%A8Ubuntu%E4%B8%8A%E4%BD%BF%E8%83%BDSELinux%EF%BC%8C%E9%9C%80%E8%A6%81disable%20AppArmore%E3%80%82%E5%A6%82%E6%9E%9C%E7%9B%B4%E6%8E%A5%E5%AE%89%E8%A3%85%E5%B9%B6%E4%BD%BF%E8%83%BDSELinux%E8%80%8C%E4%B8%8D%E5%85%B3%E9%97%ADAppArmore%EF%BC%8C%E7%B3%BB%E7%BB%9F%E4%BC%9A%E6%8C%82%E6%AD%BB%E3%80%82%E5%9B%A0%E4%B8%BA2%E4%B8%AA%E5%AE%89%E5%85%A8%E7%B3%BB%E7%BB%9F%E6%8B%A5%E6%9C%89%E4%B8%8D%E5%90%8C%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E8%AF%BB%E5%86%99%E9%85%8D%E7%BD%AE%EF%BC%8C%E5%BD%A2%E6%88%90%E6%AD%BB%E9%94%81%E3%80%82%E7%BD%91%E4%B8%8A%E6%9C%89%E5%BE%88%E5%A4%9A%E7%9B%B8%E5%85%B3%E7%9A%84%E5%B8%96%E5%AD%90%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%B0%9D%E8%AF%95%E7%9D%80%E5%81%9A%E4%B8%80%E5%81%9A%E5%AE%9E%E9%AA%8C%E3%80%82%E6%88%91%E5%B7%B2%E7%BB%8F%E4%BB%A5%E8%BA%AB%E8%AF%95%E6%B3%95%E4%B8%8A%E9%9D%A2%E8%AF%B4%E7%9A%84%E6%8C%82%E6%AD%BB%E7%9A%84%E6%83%85%E5%86%B5%E4%BA%86%E3%80%82%E8%AF%B7%E8%8E%AB%E6%95%88%E4%BB%BF%E3%80%82%0A%23%23%20Labelling%0ASELinux%E7%9A%84%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%E5%B0%B1%E6%98%AF%E4%B8%80%E4%B8%AA%E6%A0%87%E7%AD%BE%E4%BD%93%E7%B3%BB%EF%BC%88security%20context%EF%BC%8C%E7%AE%80%E7%A7%B0SContext%EF%BC%89%E3%80%82%E9%82%A3%E4%B9%88%E8%BF%99%E4%B8%AA%E6%A0%87%E7%AD%BE%E6%98%AF%E6%80%8E%E4%B9%88%E6%89%93%E4%B8%8A%E5%8E%BB%E7%9A%84%EF%BC%9F%E8%BF%99%E4%B8%AA%E6%89%93%E6%A0%87%E7%AD%BE%E7%9A%84%E8%BF%87%E7%A8%8B%E7%A7%B0%E4%B8%BAlabelling%E3%80%82%E9%82%A3%E4%B9%88labelling%E6%98%AF%E6%80%8E%E4%B9%88%E5%92%8C%E5%86%85%E6%A0%B8%E5%90%AF%E5%8A%A8%E7%9B%B8%E7%BB%93%E5%90%88%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E4%B8%8E%E7%BB%88%E7%AB%AF%E7%94%A8%E6%88%B7%EF%BC%88%E6%88%96%E8%80%85%E7%AE%A1%E7%90%86%E5%91%98%E7%94%A8%E6%88%B7%EF%BC%89%E4%BA%A4%E4%BA%92%E7%9A%84%E5%91%A2%EF%BC%9F%0A%E5%A6%82%E6%9E%9C%E6%9A%82%E6%97%B6%E6%94%BE%E4%B8%8BSELinux%EF%BC%8C%E6%88%91%E4%BB%AC%E6%83%B3%E4%B8%80%E6%83%B3%E5%BA%94%E8%AF%A5%E6%80%8E%E4%B9%88%E5%81%9A%EF%BC%9F%E6%88%91%E8%AE%A4%E4%B8%BA%E5%A6%82%E6%9E%9C%E6%98%AF%E6%88%91%EF%BC%8C%E5%8F%AF%E8%83%BD%E4%BC%9A%EF%BC%9A%0A-%20%E5%85%88%E7%BB%99%E6%89%80%E6%9C%89%E7%9A%84process%E6%89%93%E4%B8%8A%E7%B1%BB%E4%BC%BC%60user_u%3Arole_r%3Atype_t%3As0-s1%3Ac0%2Cc1-c255%60%E8%BF%99%E6%A0%B7%E7%9A%84%E6%A0%87%E7%AD%BE%0A-%20%E7%84%B6%E5%90%8E%E7%BB%99%E6%89%80%E6%9C%89%E7%9A%84file%EF%BC%88%E6%AD%A4%E5%A4%84%E7%9A%84file%EF%BC%8C%E5%BA%94%E8%AF%A5%E6%98%AFLinux%E4%B8%AD%E4%B8%87%E7%89%A9%E7%9A%86%E6%96%87%E4%BB%B6%E7%9A%84file%EF%BC%89%E4%B9%9F%E6%89%93%E4%B8%8A%E7%B1%BB%E4%BC%BC%E7%9A%84%E6%A0%87%E7%AD%BE%EF%BC%8C%E4%B8%8D%E8%BF%87role%E5%B0%B1%E6%98%AF%E5%9B%BA%E5%AE%9A%E7%9A%84object_r%E4%BA%86%0A%0A%E9%82%A3%E4%B9%88%E7%9C%8B%E7%9C%8BSELinux%E5%88%B0%E5%BA%95%E6%98%AF%E4%B8%8D%E6%98%AF%E8%BF%99%E6%A0%B7%E5%81%9A%E7%9A%84%E5%91%A2%EF%BC%9F%0A%23%23%23%20%E7%BB%99%E8%BF%9B%E7%A8%8B%E6%89%93%E6%A0%87%E7%AD%BE%0A%3EFirst%20of%20all%2C%20know%20that%20SELinux%20supports%20inheritance%20of%20contexts.%20Furthermore%20more%2C%20inheritance%20of%20contexts%20is%20the%20default%20behavior%3A%20if%20there%20is%20no%20policy%20in%20SELinux%20that%20specifies%20otherwise%2C%20then%20anything%20created%20will%20inherit%20the%20context%20of%20its%20parent.%5B1%5D%0A%0A%E6%88%91%E4%BB%AC%E7%9F%A5%E9%81%93Linux%E7%9A%84%E6%89%80%E6%9C%89%E8%BF%9B%E7%A8%8B%E9%83%BD%E6%98%AFkernel%E5%90%AF%E5%8A%A8%E6%97%B6%E7%9A%841%E5%8F%B7%E8%BF%9B%E7%A8%8B%E9%80%9A%E8%BF%87fork%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E5%8F%AB%E8%B5%B7%E6%9D%A5%E7%9A%84%E3%80%821%E5%8F%B7%E8%BF%9B%E7%A8%8B%E5%8F%AF%E8%83%BD%E6%98%AFopenrc%E6%88%96%E8%80%85systemd%E4%B9%8B%E7%B1%BB%E7%9A%84%E8%BF%9B%E7%A8%8B%E3%80%82%E6%89%80%E4%BB%A5%E6%89%80%E6%9C%89%E7%9A%84%E8%BF%9B%E7%A8%8B%E4%B8%80%E4%B8%8A%E6%9D%A5%E9%83%BD%E4%BC%9A%E7%BB%A7%E6%89%BFinit%E8%BF%9B%E7%A8%8B%E7%9A%84%E6%89%80%E6%9C%89%E6%A0%87%E7%AD%BE%EF%BC%8C%E7%84%B6%E5%90%8E%E5%86%8D%E6%A0%B9%E6%8D%AE%E5%85%B7%E4%BD%93%E7%9A%84policy%E8%AE%BE%E5%AE%9A%E8%BF%9B%E8%A1%8Ctype%20transition%E3%80%82%0A%E6%AD%A3%E5%A5%BD%EF%BC%8CSELinux%E5%B0%B1%E6%94%AF%E6%8C%81%E8%BF%99%E7%A7%8DDomain%2FType%20Transition%E7%9A%84%E8%AF%AD%E6%B3%95%EF%BC%88%E5%BD%93%E7%84%B6%E4%B8%8D%E6%98%AF%E6%AD%A3%E5%A5%BD%EF%BC%8C%E6%98%AFSELinux%E8%AE%BE%E8%AE%A1%E8%80%85%E4%BB%AC%E5%B0%B1%E6%98%AF%E8%BF%99%E4%B9%88%E8%AE%BE%E8%AE%A1%E7%9A%84%EF%BC%89%E3%80%82%0A%3E%E6%B3%A8%EF%BC%9A%E9%80%9A%E8%BF%87%E3%80%8ASELinux%E4%BB%8B%E7%BB%8D%E3%80%8B%E4%B8%80%E6%96%87%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E7%9F%A5%E9%81%93Domain%E5%85%B6%E5%AE%9E%E5%B0%B1%E6%98%AF%E8%BF%9B%E7%A8%8B%E7%9A%84Type%0A%0A%E4%B8%BE%E4%B8%AADomain%20Transition%E7%9A%84%E4%BE%8B%E5%AD%90%0A%60%60%60%0Atype_transition%20init_t%20apache_exec_t%20%3A%20process%20apache_t%0A%60%60%60%0A%E7%BF%BB%E8%AF%91%E6%88%90%E4%BA%BA%E7%B1%BB%E8%AF%AD%E8%A8%80%E5%B0%B1%E6%98%AF%EF%BC%9A%0A%E5%BD%93**init_t%20Domain**%E4%B8%AD%E7%9A%84%E8%BF%9B%E7%A8%8B**%E6%89%A7%E8%A1%8C**type%E4%B8%BA**apache_exec_t**%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%EF%BC%88fork%E5%B9%B6execv%EF%BC%89%E6%97%B6%EF%BC%88%E6%96%87%E4%BB%B6%E7%9A%84class%E4%B8%BAprocess%EF%BC%89%EF%BC%8C%E6%89%80%E5%B1%9EDomain%EF%BC%88%E5%AF%B9process%E8%80%8C%E8%A8%80%EF%BC%8C%E8%82%AF%E5%AE%9A%E6%98%AF%E6%8C%87Domain%EF%BC%89%E9%9C%80%E8%A6%81%E5%88%87%E6%8D%A2%E5%88%B0apache_t%E5%9F%9F%E3%80%82%0A%0A%E8%A6%81%E5%81%9A%E5%88%B0%E8%BF%99%E4%B8%AAtype%20transition%EF%BC%8C%E9%82%A3%E6%98%BE%E7%84%B6%E8%A6%81%E6%B6%89%E5%8F%8A%E5%88%B0%E4%BB%A5%E4%B8%8B3%E4%B8%AA%E6%9D%83%E9%99%90%EF%BC%9A%0A1.%E9%A6%96%E5%85%88%EF%BC%8C%E4%BD%A0%E5%BE%97%E8%AE%A9init_t%E5%9F%9F%E4%B8%AD%E7%9A%84%E8%BF%9B%E7%A8%8B%E8%83%BD%E5%A4%9F%E6%89%A7%E8%A1%8Ctype%E4%B8%BAapache_exec_t%E7%9A%84%E6%96%87%E4%BB%B6%0A%60allow%20init_t%20apache_exec_t%20%3A%20file%20execute%3B%60%0A2.%E7%84%B6%E5%90%8E%EF%BC%8C%E4%BD%A0%E8%BF%98%E5%BE%97%E5%91%8A%E8%AF%89SELiux%EF%BC%8C%E5%85%81%E8%AE%B8init_t%E5%81%9ADT%E5%88%87%E6%8D%A2%E4%BB%A5%E8%BF%9B%E5%85%A5apache_t%E5%9F%9F%0A%60allow%20init_t%20apache_t%20%3A%20process%20transition%3B%60%0A3.%E6%9C%80%E5%90%8E%EF%BC%8C%E4%BD%A0%E8%BF%98%E5%BE%97%E5%91%8A%E8%AF%89SELinux%EF%BC%8C%E5%88%87%E6%8D%A2%E5%85%A5%E5%8F%A3%EF%BC%88%E5%AF%B9%E5%BA%94%E4%B8%BAentrypoint%E6%9D%83%E9%99%90%EF%BC%89%E4%B8%BA%E6%89%A7%E8%A1%8Capache_exec_t%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%96%87%E4%BB%B6%0A%60allow%20apache_t%20apache_exec_t%20%3A%20file%20entrypoint%3B%60%0A%0A%E6%89%80%E4%BB%A5%E4%B8%80%E6%9D%A1type%20transition%E7%9A%84%E8%A7%84%E5%88%99%E5%B0%B1%E8%A6%81%E6%90%AD%E9%85%8D%E5%8F%A6%E5%A4%96%E8%87%B3%E5%B0%913%E6%9D%A1%E8%A7%84%E5%88%99%EF%BC%88%E4%BA%8B%E5%AE%9E%E4%B8%8A%EF%BC%8C%E5%85%B7%E4%BD%93%E7%9A%84%E5%8F%91%E8%A1%8C%E7%89%88%E5%8F%AF%E8%83%BD%E4%BC%9A%E6%9B%B4%E5%A4%9A%EF%BC%89%E6%9D%A5%E8%BF%90%E8%A1%8C%E3%80%82%E4%BA%8E%E6%98%AFSELinux%E5%B0%B1%E5%8F%91%E6%98%8E%E4%BA%86%E5%AE%8F%EF%BC%8C%E7%B1%BB%E4%BC%BC%E5%87%BD%E6%95%B0%E6%9D%A5%E6%96%B9%E4%BE%BF%E5%AE%9A%E4%B9%89%E8%BF%9B%E7%A8%8B%E7%9A%84%E6%A0%87%E7%AD%BE%E8%BD%AC%E6%8D%A2%E3%80%82%E5%8F%82%E8%80%83%E5%AE%89%E5%8D%93%E7%9A%84%E5%AE%9E%E7%8E%B0%5B1%5D%3A%0A%60%60%60bash%0A%23%20%5Bexternal%2Fsepolicy%2Fte_macros%5D%0A%23%20%E5%AE%9A%E4%B9%89domain_trans%E5%AE%8F%E3%80%82%241%2C%242%E7%AD%89%E7%AD%89%E4%BB%A3%E8%A1%A8%E5%AE%8F%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%EF%BC%8C%E7%AC%AC%E4%BA%8C%E4%B8%AA....%E5%8F%82%E6%95%B0%0A%0Adefine(%60domain_trans'%2C%20%60%0A%20%20%20%20allow%20%241%20%242%3Afile%20%7B%20getattr%20open%20read%20execute%20%7D%3B%0A%20%20%20%20allow%20%241%20%243%3Aprocess%20transition%3B%0A%20%20%20%20allow%20%243%20%242%3Afile%20%7B%20entrypoint%20read%20execute%20%7D%3B%0A%20%20%20%20...%0A')%0A%0A%23%E5%AE%9A%E4%B9%89domain_auto_trans%E5%AE%8F%EF%BC%8C%E8%BF%99%E4%B8%AA%E5%AE%8F%E6%89%8D%E6%98%AF%E6%88%91%E4%BB%AC%E5%9C%A8te%E4%B8%AD%E7%9B%B4%E6%8E%A5%E4%BD%BF%E7%94%A8%E7%9A%84%0A%0Adefine(%60domain_auto_trans'%2C%20%60%0A%20%20%20%20domain_trans(%241%2C%242%2C%243)%0A%20%20%20%20type_transition%20%241%20%242%3Aprocess%20%243%3B%0A')%0A%60%60%60%0A%E5%AF%B9%E5%BA%94%E5%88%B0%E4%B9%8B%E5%89%8D%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%8C%E5%A6%82%E6%9E%9Capache_exec_t%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%96%87%E4%BB%B6%E8%A2%ABinit%E8%BF%9B%E7%A8%8B%E5%8F%AB%E8%B5%B7%E6%9D%A5%E4%BB%A5%E5%90%8E%EF%BC%8C%E8%A6%81%E5%88%87%E6%8D%A2%E5%88%B0apache_t%E5%9F%9F%E5%B0%B1%E8%A6%81%E7%94%A8%E4%B8%8B%E9%9D%A2%E8%BF%99%E6%9D%A1%E5%AE%8F%E8%B0%83%E7%94%A8%E3%80%82%0A%60%60%60%0Adomain_auto_trans(init_t%2C%20apache_exec_t%2C%20apache_t)%0A%60%60%60%0A%E4%BB%A5%E4%B8%80%E4%B8%AA%E7%9C%9F%E5%AE%9E%E7%9A%84%E4%BE%8B%E5%AD%90%E7%BB%93%E6%9D%9F%E8%BF%99%E4%B8%80%E6%AE%B5%EF%BC%9A%0A%60%60%60bash%0A%23%20%E5%9C%A8external%2Fsepolicy%2Finit_shell.te%E4%B8%AD%E5%B0%B1%E6%9C%89%E4%B8%8A%E8%BF%B0%E5%AE%8F%E7%9A%84%E7%94%A8%E6%B3%95%EF%BC%9A%0A.%2Finit_shell.te%3A4%3Adomain_auto_trans(init%2C%20shell_exec%2C%20init_shell)%0A%60%60%60%0A%23%23%23%20%E7%BB%99%E6%96%87%E4%BB%B6%E6%89%93%E6%A0%87%E7%AD%BE%0A%E8%BF%9B%E7%A8%8B%E7%9A%84%E6%A0%87%E7%AD%BE%E6%98%AF%E4%BB%8Einit%E8%BF%9B%E7%A8%8B%E7%BB%A7%E6%89%BF%EF%BC%8C%E5%B9%B6%E6%8C%89%E7%85%A7%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E5%93%8D%E5%BA%94%E7%9A%84domain%20transition%E6%9D%A5%E7%9A%84%E3%80%82%E9%82%A3%E4%B9%88%E6%96%87%E4%BB%B6%E7%9A%84%E6%A0%87%E7%AD%BE%E6%98%AF%E4%BB%8E%E5%93%AA%E6%9D%A5%E7%9A%84%E5%91%A2%EF%BC%9F%E4%BE%8B%E5%A6%82%60u%3Aobject_r%3Acache_file%3As0%60%E3%80%82%0A%E4%BA%8B%E5%AE%9E%E4%B8%8A%E5%88%9D%E5%A7%8B%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E4%B9%9F%E6%98%AF%E6%9C%89%E4%B8%AA%E5%88%9D%E5%A7%8B%E5%80%BC%E7%9A%84%EF%BC%8C%E8%BF%99%E4%B8%AA%E5%88%9D%E5%A7%8B%E5%80%BC%E9%80%9A%E5%B8%B8%E6%94%BE%E5%9C%A8%E4%B8%80%E4%B8%AA%E5%8F%ABfile_contexts%E7%9A%84%E6%96%87%E4%BB%B6%E9%87%8C%E3%80%82%E4%BE%8B%E5%A6%82Android%E7%9A%84%E5%9C%A8%60external%2Fsepolicy%2Ffile_contexts%60%E3%80%82%E5%86%8D%E6%91%98%E5%8E%BB%E4%B8%80%E6%AE%B5%E7%9C%8B%E7%9C%8B%EF%BC%8C%E8%BF%99%E4%B8%AAfile_contexts%E5%88%B0%E5%BA%95%E6%98%AF%E5%95%A5%EF%BC%9A%0A%60%60%60%0A%2Fdev(%2F.*)%3F%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20u%3Aobject_r%3Adevice%3As0%0A%2Fdev%2Fakm8973.*%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20u%3Aobject_r%3Aakm_device%3As0%0A%2Fdev%2Faccelerometer%C2%A0%C2%A0%C2%A0%20u%3Aobject_r%3Aaccelerometer_device%3As0%0A%2Fdev%2Falarm%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20u%3Aobject_r%3Aalarm_device%3As0%0A%2Fdev%2Fandroid_adb.*%C2%A0%C2%A0%C2%A0%20u%3Aobject_r%3Aadb_device%3As0%0A%2Fdev%2Fashmem%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20u%3Aobject_r%3Aashmem_device%3As0%0A%2Fdev%2Faudio.*%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20u%3Aobject_r%3Aaudio_device%3As0%0A%60%60%60%0A%E5%8F%AF%E8%A7%81file_contexts%E6%8F%8F%E8%BF%B0%E7%9A%84%E5%B0%B1%E6%98%AF%E4%B8%80%E4%BA%9B%E6%96%87%E4%BB%B6%E5%92%8C%E6%96%87%E4%BB%B6%E5%A4%B9%E7%9A%84%E5%AE%89%E5%85%A8%E6%A0%87%E7%AD%BE%EF%BC%88SContext)%E3%80%82%0A%E9%82%A3%E4%B9%88%E6%96%B0%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%9B%AE%E5%BD%95%E6%88%96%E8%80%85%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%EF%BC%8C%E4%BB%96%E7%9A%84%E6%A0%87%E7%AD%BE%E5%8F%88%E6%80%8E%E4%B9%88%E6%9D%A5%E5%91%A2%EF%BC%9F%0A%E5%BD%93%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E6%96%B0%E6%96%87%E4%BB%B6%E6%97%B6%EF%BC%88%E7%9B%AE%E5%BD%95%E4%B9%9F%E6%98%AF%E4%B8%80%E7%A7%8D%E6%96%87%E4%BB%B6%EF%BC%89%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E5%AE%83%E7%9A%84%E6%A0%87%E7%AD%BE%E4%BC%9A%E7%BB%A7%E6%89%BF%E8%87%AA%E5%85%B6%E7%88%B6%E7%9B%AE%E5%BD%95%EF%BC%8C%E4%B9%8B%E5%90%8E%E6%8C%89%E7%85%A7%E8%A7%84%E5%88%99%E6%96%87%E4%BB%B6%E8%A7%84%E5%AE%9A%E7%9A%84%E5%81%9Atype%20transition%E3%80%82%E5%92%8C%E8%BF%9B%E7%A8%8B%E7%9A%84%E6%89%93%E6%A0%87%E7%AD%BE%E8%BF%87%E7%A8%8B%E6%98%AF%E4%B8%8D%E6%98%AF%E5%BE%88%E7%B1%BB%E4%BC%BC%EF%BC%9F%0A%E5%85%B7%E4%BD%93%E7%9A%84%E8%AF%AD%E6%B3%95%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5B1%5D%0A%0A%23%23%23%20%E7%89%B9%E6%AE%8A%E7%9A%84%E6%A0%87%E7%AD%BEsid%0A%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5B5%5D%E3%80%82%5B2%5D%E4%B8%AD%E9%98%90%E8%BF%B0%E4%BA%86sid%E4%BB%A5%E5%8F%8Asid_context%E7%9A%84%E8%AF%AD%E6%B3%95%E3%80%82%E4%BD%86%E6%98%AF%E5%AF%B9%E4%B8%BA%E4%BB%80%E4%B9%88%E6%9C%89%E8%BF%99%E4%B8%A4%E4%B8%AA%E4%B8%9C%E8%A5%BF%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%AE%83%E4%BB%AC%E6%9C%89%E4%BB%80%E4%B9%88%E7%94%A8%E4%B8%8A%EF%BC%8C%E6%B2%A1%E6%9C%89%E8%AF%B4%E6%B8%85%E6%A5%9A%E3%80%82%5B5%5D%E5%81%9A%E4%BA%86%E6%AF%94%E8%BE%83%E5%A5%BD%E7%9A%84%E8%A7%A3%E9%87%8A%E3%80%82%0A%E6%80%BB%E7%BB%93%E4%B8%80%E4%B8%8B%E5%B0%B1%E6%98%AF%EF%BC%8CLinux%20kernel%E5%9C%A8init%E8%BF%9B%E7%A8%8B%E5%8A%A0%E8%BD%BDpolicy%E4%B9%8B%E5%89%8D%EF%BC%8C%E4%B9%9F%E9%9C%80%E8%A6%81%E4%B8%80%E4%BA%9B%E5%9F%BA%E6%9C%AC%E7%9A%84%E6%A0%87%E7%AD%BE%EF%BC%8C%E8%80%8C%E8%BF%99%E4%BA%9B%E6%A0%87%E7%AD%BE%E4%B9%9F%E5%B0%B1%E6%98%AF%E6%89%80%E8%B0%93%E7%9A%84sid%EF%BC%88secure%20ID%EF%BC%89%E3%80%82%E6%AF%8F%E4%B8%AAsid%E5%AF%B9%E5%BA%94%E4%B8%80%E4%B8%AAsid_context%E3%80%82%E8%BF%99%E4%BA%9B%E9%83%BD%E6%98%AF%E5%9B%BA%E5%8C%96%E5%9C%A8%E5%86%85%E6%A0%B8%E9%87%8C%E7%9A%84%E3%80%82%E5%9C%A8init%E5%8A%A0%E8%BD%BD%E4%BB%A5%E5%90%8E%EF%BC%8C%E6%89%80%E6%9C%89sid%E5%AF%B9%E5%BA%94%E7%9A%84%E6%A0%87%E7%AD%BE%E9%83%BD%E4%BC%9A%E8%A2%AB%E8%BD%AC%E6%8D%A2%E5%88%B0%E6%AD%A3%E5%B8%B8%E7%9A%84%E8%AE%BE%E7%BD%AE%E3%80%82%0A%0A%23%23%23%20%E7%AD%96%E7%95%A5%2F%E6%A0%87%E7%AD%BE%E6%96%87%E4%BB%B6%E4%BB%8E%E5%93%AA%E6%9D%A5%3F%0A%E5%85%88%E7%9C%8B%E5%AE%9E%E4%BE%8B%EF%BC%8CAndroid%E7%9A%84%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%8D%E7%BD%AE%E5%9C%A8%0AAndroid%E7%B3%BB%E7%BB%9F%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6(.te)%E4%BD%8D%E7%BD%AE%E5%9C%A8%60system%2Fsepolicy%60%2C%60device%2F%3Cmanufacturer%3E%2F%3Cdevice-name%3E%2Fsepolicy%60%0A!%5B87292b4c69317c24eb8af5269259a41b.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6234)%0A%E8%BF%99%E4%BA%9B.te%E6%96%87%E4%BB%B6%E9%80%9A%E9%80%9A%E9%83%BD%E6%98%AF%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%EF%BC%8C%E8%80%8C%E4%B8%94%E9%80%9A%E9%80%9A%E9%83%BD%E6%98%AF%E6%89%8B%E5%8A%A8%E7%A0%81%E5%87%BA%E6%9D%A5%E7%9A%84%E5%93%A6%E3%80%82%E5%92%8C%E5%86%99%E4%BB%A3%E7%A0%81%E4%B8%80%E6%A0%B7%E3%80%82%E4%B8%8B%E5%9B%BE%E6%98%AF%E7%BC%96%E8%AF%91%E5%AE%89%E5%8D%93%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E7%9A%84%E6%B5%81%E7%A8%8B%E3%80%82%0Afile_contexts%E5%9C%A8%60%2Fsystem%2Fsepolicy%2Fprebuilts%2Fapi%2F28.0%2Fprivate%2Ffile_contexts%60%2C%E7%9E%84%E4%B8%80%E7%9C%BC%2C%20%E9%9A%8F%E4%BE%BF%E6%88%AA%E4%BA%86%E4%B8%80%E5%B0%8F%E6%AE%B5%EF%BC%8C%E6%98%AF%E4%B8%8D%E6%98%AF%E5%BE%88%E5%A4%8D%E6%9D%82%EF%BC%9A%0A%60%60%60bash%0A%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%0A%23%20Default%20HALs%0A%23%0A%2F(vendor%7Csystem%2Fvendor)%2Fbin%2Fhw%2Fandroid%5C.hardware%5C.audio%402%5C.0-service%20%20%20%20%20%20%20%20%20%20u%3Aobject_r%3Ahal_audio_default_exec%3As0%0A%2F(vendor%7Csystem%2Fvendor)%2Fbin%2Fhw%2Fandroid%5C.hardware%5C.automotive%5C.audiocontrol%401%5C.0-service%20%20u%3Aobject_r%3Ahal_audiocontrol_default_exec%3As0%0A%2F(vendor%7Csystem%2Fvendor)%2Fbin%2Fhw%2Fandroid%5C.hardware%5C.automotive%5C.evs%401%5C.0-service%20%20u%3Aobject_r%3Ahal_evs_default_exec%3As0%0A%2F(vendor%7Csystem%2Fvendor)%2Fbin%2Fhw%2Fandroid%5C.hardware%5C.automotive%5C.vehicle%402%5C.0-service%20%20u%3Aobject_r%3Ahal_vehicle_default_exec%3As0%0A%2F(vendor%7Csystem%2Fvendor)%2Fbin%2Fhw%2Fandroid%5C.hardware%5C.bluetooth%401%5C.0-service%20%20%20%20%20%20u%3Aobject_r%3Ahal_bluetooth_default_exec%3As0%0A%60%60%60%0A%E6%97%A2%E7%84%B6%E5%92%8C%E5%86%99%E4%BB%A3%E7%A0%81%E4%B8%80%E6%A0%B7%EF%BC%8C%E9%82%A3%E5%B0%B1%E4%B9%9F%E6%9C%89%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E4%BA%86%EF%BC%8C%E5%8F%82%E8%80%83%5B2%5D%E7%9A%847.6%E4%B8%80%E8%8A%82%E3%80%82%E5%9C%A8%E6%AD%A4%E4%B8%8D%E5%81%9A%E6%B7%B1%E7%A9%B6%E3%80%82%0A%E5%AE%89%E5%8D%93%E4%B8%8A%E7%BC%96%E8%AF%91%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E7%9A%84%E6%B5%81%E7%A8%8B%E5%A6%82%E4%B8%8B%E5%9B%BE%EF%BC%9A%0A!%5B60b0f175f725e78e2472b2571d499c1f.gif%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6233)%0A%0A%23%23%20%E7%AD%96%E7%95%A5%E6%9B%B4%E6%96%B0%0A%E7%AD%96%E7%95%A5%E5%8A%A0%E8%BD%BD%E7%9A%84%E6%B5%81%E7%A8%8B%E9%80%9A%E5%B8%B8%E9%83%BD%E6%98%AF%E7%94%B11%E5%8F%B7%E8%BF%9B%E7%A8%8B%E5%AE%8C%E6%88%90%E7%9A%84%E3%80%82%E5%AE%83%E8%B4%9F%E8%B4%A3%E8%AF%BB%E5%8F%96%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%EF%BC%8C%E5%8A%A0%E8%BD%BD%E7%BC%96%E8%AF%91%E5%90%8E%E7%9A%84%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%EF%BC%8C%E5%B9%B6%E4%BC%A0%E5%85%A5%E5%86%85%E6%A0%B8%E7%9A%84LSM%EF%BC%88Linux%20Secure%20Module%EF%BC%89%E6%9D%A5%E5%AE%8C%E6%88%90SELinux%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%82%E9%82%A3%E4%B9%88%E5%A6%82%E6%9E%9C%E6%88%91%E4%BB%AC%E8%A6%81%E4%BF%AE%E6%94%B9%E7%AD%96%E7%95%A5%EF%BC%88%E5%A2%9E%E5%88%A0%E6%94%B9%EF%BC%89%EF%BC%8C%E9%82%A3%E5%8A%BF%E5%BF%85%E8%A6%81%E9%87%8D%E6%96%B0%E7%BC%96%E8%AF%91%EF%BC%8C%E9%87%8D%E6%96%B0%E9%83%A8%E7%BD%B2%E3%80%82%E8%BF%99%E4%B8%80%E9%83%A8%E5%88%86%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5B3%5D%E3%80%82%E8%99%BD%E7%84%B6%E9%87%8C%E9%9D%A2%E7%9A%84%E8%BD%AF%E4%BB%B6%E7%89%88%E6%9C%AC%E6%AF%94%E8%BE%83%E6%97%A7%EF%BC%8C%E4%BD%86%E6%A0%B8%E5%BF%83%E7%9A%84%E6%80%9D%E8%B7%AF%E4%B8%8D%E5%8F%98%E3%80%82%E6%88%91%E7%90%86%E8%A7%A3%E7%9A%84%E5%A4%A7%E8%87%B4%E6%B5%81%E7%A8%8B%E5%A6%82%E4%B8%8B%EF%BC%88%E6%88%91%E8%BF%98%E6%B2%A1%E6%9C%89%E8%AF%95%E9%AA%8C%E8%BF%87%EF%BC%8C%E5%8F%AF%E4%BB%A5%E6%89%BE%E4%B8%80%E4%B8%AA%E8%99%9A%E6%8B%9F%E6%9C%BA%E8%AF%95%E8%AF%95%E7%9C%8B%EF%BC%89%EF%BC%9A%0A-%20%E7%BC%96%E8%AF%91%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%EF%BC%8C%E7%94%9F%E6%88%90%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%9A%84%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6policy.bin%0A-%20%E5%B0%86policy.bin%E6%94%BE%E5%85%A5%2Fetc%2F%E7%9B%AE%E5%BD%95%0A-%20%E4%BD%BF%E7%94%A8setfiles%E9%87%8D%E6%96%B0%E6%A0%87%E8%AE%B0%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%0A-%20%E4%BD%BF%E7%94%A8semanage%E5%88%9B%E5%BB%BA%E7%AE%A1%E7%90%86%E5%91%98%E8%B4%A6%E5%8F%B7%0A-%20%E9%87%8D%E5%90%AF%E7%94%9F%E6%95%88%0A%0A%E4%BB%A5%E4%B8%8A%E7%9A%84%E6%93%8D%E4%BD%9C%E9%83%BD%E8%A6%81%E7%94%B1root%E8%B4%A6%E5%8F%B7%E6%9D%A5%E5%AE%8C%E6%88%90%E3%80%82%E5%8F%AF%E8%A7%81root%E8%BF%98%E6%98%AF%E5%BE%88%E6%97%A0%E6%95%8C%E5%95%8A%E3%80%82%0A%23%23%20%E7%94%A8%E6%88%B7%E6%80%81%E5%B7%A5%E5%85%B7%E9%93%BE%0A%E5%BC%95%E7%94%A8%5B4%5D%E4%B8%AD%E7%9A%84%E6%96%87%E5%AD%97%EF%BC%9A%0A%3EThe%20policycoreutils%20package%20installs%20the%20following%20utilities%3A%0A%3E%0A%3E-%20fixfiles%3A%20Fixes%20the%20security%20context%20on%20file%20systems%0A%3E-%20load_policy%3A%20Loads%20a%20new%20SELinux%20policy%20into%20the%20kernel%0A%3E-%20restorecon%3A%20Resets%20the%20security%20context%20on%20one%20or%20more%20files%0A%3E-%20setfiles%3A%20Initializes%20the%20security%20context%20on%20one%20or%20more%20files%0A%3E-%20secon%3A%20Displays%20the%20SELinux%20context%20from%20a%20file%2C%20program%2C%20or%20user%20input%0A%3E-%20semodule_package%3A%20Creates%20an%20SELinux%20policy%20module%20package%0A%3E-%20restorecond%3A%20Is%20a%20daemon%20that%20watches%20for%20file%20creation%20and%20sets%20the%20default%20file%20context%0A%3E-%20semodule%3A%20Manages%20SELinux%20policy%20modules%0A%3E-%20sestatus%3A%20Displays%20SELinux%20status%0A%3E-%20setsebool%3A%20Sets%20SELinux%20Boolean%20value%0A%0A%E6%88%91%E6%89%80%E7%94%A8%E8%BF%87%E7%9A%84%EF%BC%9A%0A-%20checkpolicy%3A%20%E7%BC%96%E8%AF%91%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6(.te)%0A-%20setfiles%3A%20%E7%BB%99%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E6%89%93%E6%A0%87%E7%AD%BE%0A-%20semanage%3A%20%E7%AE%A1%E7%90%86SELinux%E4%B8%8B%E7%9A%84%E7%94%A8%E6%88%B7%E7%B3%BB%E7%BB%9F%0A%0A%23%23%20%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%0A1.%20%5BGentoo%20Linux%20-%20SELinux%2FTutorials%2FHow%20does%20a%20process%20get%20into%20a%20certain%20context%5D(https%3A%2F%2Fwiki.gentoo.org%2Fwiki%2FSELinux%2FTutorials%2FHow_does_a_process_get_into_a_certain_context)%0A2.%20%5BSELinux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%5D(https%3A%2F%2Fm.open-open.com%2Fpdf%2Fe88821debd374d1cab7b4f54ae14161e.html)%0A3.%20%5B%E4%BB%8E%E5%A4%B4%E5%BC%80%E5%A7%8B%E7%94%9F%E6%88%90%20SELinux%5D(https%3A%2F%2Fwww.ibm.com%2Fdeveloperworks%2Fcn%2Flinux%2Fl-selinux.html)%0A4.%20%5BList%20of%20SELinux%20Utilities%5D(https%3A%2F%2Fwww.thegeekdiary.com%2Flist-of-selinux-utilities%2F)%0A5.%20%5BInitial%20Security%20Identifiers%5D(https%3A%2F%2Fflylib.com%2Fbooks%2Fen%2F2.803.1.79%2F1%2F)%0A%0A

SELinux = Security Enhanced Linux

Wiki: Security-Enhanced Linux
Security-Enhanced Linux (SELinux) is a Linux kernel security module that provides a mechanism for supporting access control security policies, including mandatory access controls (MAC).
SELinux is a set of kernel modifications and user-space tools that have been added to various Linux distributions.

SELinux起源于美国国安局(NSA)。它的前身是NSA的一个叫Flask的项目,后来,NSA觉得Linux更具发展和普及前景,所以就在Linux系统上重新实现了FLASK,称之为SELinux。

在网络上浏览了不少资料。有几篇写的非常好,罗列在参考文献中,方便读者参考引用。

[1]介绍了SELinux的基本概念,非常值得入门阅读。包括DAC,MAC,TEAC(简称TE),RBAC,以及policy文件的语法

[2]是[1]的姊妹篇,介绍了File Context和MLS的概念,以及编译构建SELinux的步骤。着重于动手部分

[3]本来是一个非常好的从头至尾指导动手构建SELinux的教程,可惜文章中涉及的源码版本过于老了(Linux 2.6,Gentoo 2006版)。编译构建的时候错误不断。只能意会了,可惜可惜。

[4]是一份文档,最新版本是2012年更新的版本,足有444页,完全可以当一本SELinux的入门书籍来阅读。我目前还没看完,但是从目录结构来看,感觉该有的都有值得好好看一看。

[5][6]是一些比较general的知识的帖子,也有可取之处,可以作为参考

[7]阐述了MLS的由来以及基本概念,由MLS开发者公司写的,似乎比较权威

[8]提到了一些代码入口,阅读代码的话可以从其中扩展开去

本文主要注重理清SELinux实现安全防护的思路,不涉及具体语法解释。另外还会再写一篇着重介绍在Linux用户态使能SELinux,并修改或添加SELinux策略

如果需要理解具体语法可以参考文献[1]。以及Android源码为例,可参考链接实现 SELinux。Android系统策略文件(.te)位置在system/sepolicy,device/<manufacturer>/<device-name>/sepolicy

SELinux提供的防护手段

从Wiki SELinux的定义就能看出,SELinux的核心就是提供了一套MAC的权限管理。MAC全称为Mandatory Access Control(个人理解:MACTEAC)。再辅以其他一系列辅助手段,来达到绝对的安全(当然世界上只有相对安全,没有绝对的安全)。本章就逐一介绍这些手段。

DAC vs. MAC

DAC = Discretionary Access Control,也就是Linux系统提供给我们的基本的权限管理,例如如下ls -l输出:

drwx------+ 19 user  staff       608 10 27 10:07 Desktop
drwx------+ 17 user  staff       544  8 16 21:39 Documents
drwx------+ 31 user  staff       992 11 27 19:51 Downloads
  • user就是该文件的拥有者ID(即UID),staff是user的组ID(GID)
  • rwx------就是我们通常说的权限组,每三个字母代表一种权限标记
    • rwx分别表示可读,可写,可执行
    • [1..3] 表示拥有者的权限
    • [4..6] 表示与拥有者同组的用户的权限
    • [7..9] 表示其他用户的权限
    • rwx------换算成8进制,也就是我们常说的700权限,什么644啊,777啊都可以这样换算

Linux基于基本的UID和GID即可以有基本的权限控制。DAC的缺陷在于,他有一个超级用户root,当一旦黑客通过漏洞完成了提权操作,那么所有的这些权限控制就失效了。所以NSA才做了这么一套MAC机制。

MAC的处世哲学非常简单:即任何进程想在SELinux系统中干任何事情,都必须先在安全策略配置文件中赋予权限。凡是没有出现在安全策略配置文件中的权限,进程就没有该权限。[1]

TEAC

TEAC = Type Enforcement Accesc Control,简称TE。

Linux中有两种东西,一种死的(Inactive),一种活的(Active)。死的东西就是文件(Linux哲学,万物皆文件。注意,万不可狭义解释为File),而活的东西就是进程。此处的“死”和“活”是一种比喻,映射到软件层面的意思是:进程能发起动作,例如它能打开文件并操作它。而文件只能被进程操作。[1]

所谓的TEAC就是两个东西的Type要匹配上。Type是啥?

进程的Type

对于进程,看一下ps -Z命令的输出:

LABEL                          USER           PID  PPID     VSZ    RSS WCHAN
u:r:shell:s0                   shell         3097  1427    5752   3024 sigsuspe+
u:r:shell:s0                   shell         3100  3097    7320   3228 0

上面的命令在Android adb shell中运行输出。这个u:r:shell:s0就是一个进程的标签,其中:

  • u:SELinux定义的一个用户,这个用户不同于Linux的系统用户,具体参看后面的用户与角色一节。
  • r:SELinux定义的一个角色(role),在policy描述语言中,可以用role关键字来定义
  • shell:就是我们要的Type了,SELinux中称为Domain,在policy描述语言中,可以用type或者attribute关键字来定义
  • s0:是安全级别,MLS会用到的东西

特别注意:对初学者而言,attribute和type的关系最难理解,因为“attribute”这个关键词实在是没取好名字,很容易产生误解:

实际上,type和attribute位于同一个命名空间,即不能用type命令和attribute命令定义相同名字的东西。
其实,attribute真正的意思应该是类似type(或domain) group这样的概念。比如,将type A和attribute B关联起来,就是说type A属于group B中的一员。

文件的Type

对于文件,可以参考ls -Z的输出:

u:object_r:cgroup:s0           acct
u:object_r:rootfs:s0           bugreports
u:object_r:cache_file:s0       cache
u:object_r:rootfs:s0           charger
u:object_r:configfs:s0         config

u:object_r:rootfs:s0就是一个文件的标签。是不是和进程的非常类似?

  • u: 代表创建这个文件的SELinux user ID。注意是SELinux定义的用户,并不直接对应Linux的用户系统,两者有一个映射关系
  • object_r: 是这个文件的role,所有的文件的role都是object_r
  • rootfs: 就是这个文件的Type
  • s0: 和进程一样,这个也是安全级别,用于MLS的

如何关联这两个Type?

当每一个进程和每一个文件有了Type之后,SELinux就可以匹配两者之间的Type来鉴权。具体的做法,也就是policy文件做的事情——定义规则。下面是一个规则的例子:

allow netd proc:file write

翻译成人类语言就是:允许netd类型的process,使用(访问)type为proc,class为file的文件的write操作。

  • allow是定义规则的动词,类似的还有allowaudit、dontaudit、neverallow等。
  • netd是进程的Type
  • proc是文件的Type
  • file是文件的class,因为不同class的文件有不同的操作类型,例如socket文件和普通文件肯定不同,设备文件和普通文件也一定不同等等。class同policy语言的其他类型一样,也可以在文件中定义,其使用的关键字就是class
  • write是该规则涉及的权限集(PermSet),它可以不只一个,如果是多个权限,则用大括号包起来

总结

所以,整个TE的核心就是,定义一组进程Type和文件Type,以及一组class和class permset,然后用规则文件将它们关联起来

另外值得注意的是,TEAC是一种白名单机制,只有策略文件描述的权限才会生效,否则默认是没有对应的权限。
那么问题来了,既然是白名单机制,那么neverallow有啥用?
neverallow的作用是为了验证allow定义的规则是否完备,当你按照allow的补集定义neverallow规则时,发生了权限错误,那么可以肯定的是allow规则定义出了问题。

RBAC

RBAC = Role Based Access Control, 是对TE的一种补充。准确的说,是在TE之上提供了一层约束,增强了策略文件定义的可操作性,同时提供了Linux系统用户的权限约束实现。

SELinux 并不直接建立用户和 domain 之间的联系,而是通过角色作为桥梁。此举好处如下:

  1. 降低 policy 复杂度:可能有上百个用户和上千种 domain/type,但是不同用户所扮演的不同角色只有 有限几个;role 作为 user 和 type 之间的“中间层”,便于限制 user 的能力; 2. 给不同用户赋予不同的优先级:用户通过扮演某种角色才能获得那种角色的能力。特权角色只能由特 权用户来扮演;[4]

翻译一下,我的理解是:
我们知道TE是SELinux MAC的核心,TE通过比对object type和process type来决定process是否有权限使用这个object。一条TE规则绑定了这两者。假如系统有M个Process,N个Object,那是不是系统的规则数就是M*N个?(M和N可能是很大的数哦)
答案是:规则数并不等于M*N。否则策略文件要写的累死。
解决的方法就是定义role,一个role就对应了若干个type,在策略文件中通过role关键字完成role和type的绑定,例如:

role user_r types user_t;
role user_r types passwd_t;

user_r这个role一下对应了两个type,分别是user_t和passwd_t

user joe roles { user_r };

这条语句就绑定了user joe和role user_r。那么当joe是user_r role的时候,就具备了user_t和passwd_t的标签,那么joe就能访问定义了user_t和passwd_t的TE规则,所指定的资源(object)。

角色是一套Type(进程的Type又称为域Domain)类型的集合

知道了这层关系,那么就可以理解role的操作,包括:

  • 角色转换role_transition
  • 角色控制role_dominance

用户与角色

SELinux有一套用户系统,Linux系统也有一套用户系统。它们之间有什么关系?首先可以确定的是,它们不是直接等价的。例如, 以root用户启动Browser,那么Browser就有root用户的权限,在Linux系统上能干任何事情。而root在SELinux中可能就是一个没权限,没地位,打打酱油的”路人甲“。当然,这一切都由SELinux安全策略的制定者来决定。
SELinux用户和Linux系统用户的映射关系可以通过semanage工具来查看:

[root@zion ~]# semanage login -l

Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *
system_u             system_u             s0-s0:c0.c1023       *

当一个普通用户登录时,其映射到SELinux过程可以参考文献[5]的介绍。大致流程如下:

PHN2ZyBpZD0iZDgwbjNhbDAweHkiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDQ2Mi42Nzk2ODc1cHg7IiB2aWV3Qm94PSIwIDAgNDYyLjY3OTY4NzUgNTYzLjk5Mzc0Mzg5NjQ4NDQiPjxzdHlsZT4KCgojZDgwbjNhbDAweHkgLmxhYmVsIHsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGNvbG9yOiAjMzMzOyB9CgojZDgwbjNhbDAweHkgLm5vZGUgcmVjdCwKI2Q4MG4zYWwwMHh5IC5ub2RlIGNpcmNsZSwKI2Q4MG4zYWwwMHh5IC5ub2RlIGVsbGlwc2UsCiNkODBuM2FsMDB4eSAubm9kZSBwb2x5Z29uIHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDFweDsgfQoKI2Q4MG4zYWwwMHh5IC5ub2RlLmNsaWNrYWJsZSB7CiAgY3Vyc29yOiBwb2ludGVyOyB9CgojZDgwbjNhbDAweHkgLmFycm93aGVhZFBhdGggewogIGZpbGw6ICMzMzMzMzM7IH0KCiNkODBuM2FsMDB4eSAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzMzMzMzMzsKICBzdHJva2Utd2lkdGg6IDEuNXB4OyB9CgojZDgwbjNhbDAweHkgLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2U4ZThlODsgfQoKI2Q4MG4zYWwwMHh5IC5jbHVzdGVyIHJlY3QgewogIGZpbGw6ICNmZmZmZGUgIWltcG9ydGFudDsKICBzdHJva2U6ICNhYWFhMzMgIWltcG9ydGFudDsKICBzdHJva2Utd2lkdGg6IDFweCAhaW1wb3J0YW50OyB9CgojZDgwbjNhbDAweHkgLmNsdXN0ZXIgdGV4dCB7CiAgZmlsbDogIzMzMzsgfQoKI2Q4MG4zYWwwMHh5IGRpdi5tZXJtYWlkVG9vbHRpcCB7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBtYXgtd2lkdGg6IDIwMHB4OwogIHBhZGRpbmc6IDJweDsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTJweDsKICBiYWNrZ3JvdW5kOiAjZmZmZmRlOwogIGJvcmRlcjogMXB4IHNvbGlkICNhYWFhMzM7CiAgYm9yZGVyLXJhZGl1czogMnB4OwogIHBvaW50ZXItZXZlbnRzOiBub25lOwogIHotaW5kZXg6IDEwMDsgfQoKI2Q4MG4zYWwwMHh5IC5hY3RvciB7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOwogIGZpbGw6ICNFQ0VDRkY7IH0KCiNkODBuM2FsMDB4eSB0ZXh0LmFjdG9yIHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkODBuM2FsMDB4eSAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiBncmV5OyB9CgojZDgwbjNhbDAweHkgLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMzMzOyB9CgojZDgwbjNhbDAweHkgLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMzMzOyB9CgojZDgwbjNhbDAweHkgI2Fycm93aGVhZCB7CiAgZmlsbDogIzMzMzsgfQoKI2Q4MG4zYWwwMHh5ICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzMzMyAhaW1wb3J0YW50OwogIHN0cm9rZTogIzMzMyAhaW1wb3J0YW50OyB9CgojZDgwbjNhbDAweHkgLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMzMzOwogIHN0cm9rZTogbm9uZTsgfQoKI2Q4MG4zYWwwMHh5IC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOwogIGZpbGw6ICNFQ0VDRkY7IH0KCiNkODBuM2FsMDB4eSAubGFiZWxUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkODBuM2FsMDB4eSAubG9vcFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2Q4MG4zYWwwMHh5IC5sb29wTGluZSB7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogI0NDQ0NGRjsgfQoKI2Q4MG4zYWwwMHh5IC5ub3RlIHsKICBzdHJva2U6ICNhYWFhMzM7CiAgZmlsbDogI2ZmZjVhZDsgfQoKI2Q4MG4zYWwwMHh5IC5ub3RlVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxNHB4OyB9CgojZDgwbjNhbDAweHkgLmFjdGl2YXRpb24wIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2Q4MG4zYWwwMHh5IC5hY3RpdmF0aW9uMSB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNkODBuM2FsMDB4eSAuYWN0aXZhdGlvbjIgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgoKI2Q4MG4zYWwwMHh5IC5zZWN0aW9uIHsKICBzdHJva2U6IG5vbmU7CiAgb3BhY2l0eTogMC4yOyB9CgojZDgwbjNhbDAweHkgLnNlY3Rpb24wIHsKICBmaWxsOiByZ2JhKDEwMiwgMTAyLCAyNTUsIDAuNDkpOyB9CgojZDgwbjNhbDAweHkgLnNlY3Rpb24yIHsKICBmaWxsOiAjZmZmNDAwOyB9CgojZDgwbjNhbDAweHkgLnNlY3Rpb24xLAojZDgwbjNhbDAweHkgLnNlY3Rpb24zIHsKICBmaWxsOiB3aGl0ZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkODBuM2FsMDB4eSAuc2VjdGlvblRpdGxlMCB7CiAgZmlsbDogIzMzMzsgfQoKI2Q4MG4zYWwwMHh5IC5zZWN0aW9uVGl0bGUxIHsKICBmaWxsOiAjMzMzOyB9CgojZDgwbjNhbDAweHkgLnNlY3Rpb25UaXRsZTIgewogIGZpbGw6ICMzMzM7IH0KCiNkODBuM2FsMDB4eSAuc2VjdGlvblRpdGxlMyB7CiAgZmlsbDogIzMzMzsgfQoKI2Q4MG4zYWwwMHh5IC5zZWN0aW9uVGl0bGUgewogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7CiAgdGV4dC1oZWlnaHQ6IDE0cHg7IH0KCgojZDgwbjNhbDAweHkgLmdyaWQgLnRpY2sgewogIHN0cm9rZTogbGlnaHRncmV5OwogIG9wYWNpdHk6IDAuMzsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkODBuM2FsMDB4eSAuZ3JpZCBwYXRoIHsKICBzdHJva2Utd2lkdGg6IDA7IH0KCgojZDgwbjNhbDAweHkgLnRvZGF5IHsKICBmaWxsOiBub25lOwogIHN0cm9rZTogcmVkOwogIHN0cm9rZS13aWR0aDogMnB4OyB9CgoKCiNkODBuM2FsMDB4eSAudGFzayB7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZDgwbjNhbDAweHkgLnRhc2tUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMTFweDsgfQoKI2Q4MG4zYWwwMHh5IC50YXNrVGV4dE91dHNpZGVSaWdodCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsgfQoKI2Q4MG4zYWwwMHh5IC50YXNrVGV4dE91dHNpZGVMZWZ0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogZW5kOwogIGZvbnQtc2l6ZTogMTFweDsgfQoKCiNkODBuM2FsMDB4eSAudGFza1RleHQwLAojZDgwbjNhbDAweHkgLnRhc2tUZXh0MSwKI2Q4MG4zYWwwMHh5IC50YXNrVGV4dDIsCiNkODBuM2FsMDB4eSAudGFza1RleHQzIHsKICBmaWxsOiB3aGl0ZTsgfQoKI2Q4MG4zYWwwMHh5IC50YXNrMCwKI2Q4MG4zYWwwMHh5IC50YXNrMSwKI2Q4MG4zYWwwMHh5IC50YXNrMiwKI2Q4MG4zYWwwMHh5IC50YXNrMyB7CiAgZmlsbDogIzhhOTBkZDsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNkODBuM2FsMDB4eSAudGFza1RleHRPdXRzaWRlMCwKI2Q4MG4zYWwwMHh5IC50YXNrVGV4dE91dHNpZGUyIHsKICBmaWxsOiBibGFjazsgfQoKI2Q4MG4zYWwwMHh5IC50YXNrVGV4dE91dHNpZGUxLAojZDgwbjNhbDAweHkgLnRhc2tUZXh0T3V0c2lkZTMgewogIGZpbGw6IGJsYWNrOyB9CgoKI2Q4MG4zYWwwMHh5IC5hY3RpdmUwLAojZDgwbjNhbDAweHkgLmFjdGl2ZTEsCiNkODBuM2FsMDB4eSAuYWN0aXZlMiwKI2Q4MG4zYWwwMHh5IC5hY3RpdmUzIHsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2Q4MG4zYWwwMHh5IC5hY3RpdmVUZXh0MCwKI2Q4MG4zYWwwMHh5IC5hY3RpdmVUZXh0MSwKI2Q4MG4zYWwwMHh5IC5hY3RpdmVUZXh0MiwKI2Q4MG4zYWwwMHh5IC5hY3RpdmVUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKCiNkODBuM2FsMDB4eSAuZG9uZTAsCiNkODBuM2FsMDB4eSAuZG9uZTEsCiNkODBuM2FsMDB4eSAuZG9uZTIsCiNkODBuM2FsMDB4eSAuZG9uZTMgewogIHN0cm9rZTogZ3JleTsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZDgwbjNhbDAweHkgLmRvbmVUZXh0MCwKI2Q4MG4zYWwwMHh5IC5kb25lVGV4dDEsCiNkODBuM2FsMDB4eSAuZG9uZVRleHQyLAojZDgwbjNhbDAweHkgLmRvbmVUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKCiNkODBuM2FsMDB4eSAuY3JpdDAsCiNkODBuM2FsMDB4eSAuY3JpdDEsCiNkODBuM2FsMDB4eSAuY3JpdDIsCiNkODBuM2FsMDB4eSAuY3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZDgwbjNhbDAweHkgLmFjdGl2ZUNyaXQwLAojZDgwbjNhbDAweHkgLmFjdGl2ZUNyaXQxLAojZDgwbjNhbDAweHkgLmFjdGl2ZUNyaXQyLAojZDgwbjNhbDAweHkgLmFjdGl2ZUNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkODBuM2FsMDB4eSAuZG9uZUNyaXQwLAojZDgwbjNhbDAweHkgLmRvbmVDcml0MSwKI2Q4MG4zYWwwMHh5IC5kb25lQ3JpdDIsCiNkODBuM2FsMDB4eSAuZG9uZUNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsKICBjdXJzb3I6IHBvaW50ZXI7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZDgwbjNhbDAweHkgLmRvbmVDcml0VGV4dDAsCiNkODBuM2FsMDB4eSAuZG9uZUNyaXRUZXh0MSwKI2Q4MG4zYWwwMHh5IC5kb25lQ3JpdFRleHQyLAojZDgwbjNhbDAweHkgLmRvbmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkODBuM2FsMDB4eSAuYWN0aXZlQ3JpdFRleHQwLAojZDgwbjNhbDAweHkgLmFjdGl2ZUNyaXRUZXh0MSwKI2Q4MG4zYWwwMHh5IC5hY3RpdmVDcml0VGV4dDIsCiNkODBuM2FsMDB4eSAuYWN0aXZlQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZDgwbjNhbDAweHkgLnRpdGxlVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDE4cHg7CiAgZmlsbDogYmxhY2s7IH0KCiNkODBuM2FsMDB4eSBnLmNsYXNzR3JvdXAgdGV4dCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkODBuM2FsMDB4eSBnLmNsYXNzR3JvdXAgcmVjdCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7IH0KCiNkODBuM2FsMDB4eSBnLmNsYXNzR3JvdXAgbGluZSB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2Q4MG4zYWwwMHh5IC5jbGFzc0xhYmVsIC5ib3ggewogIHN0cm9rZTogbm9uZTsKICBzdHJva2Utd2lkdGg6IDA7CiAgZmlsbDogI0VDRUNGRjsKICBvcGFjaXR5OiAwLjU7IH0KCiNkODBuM2FsMDB4eSAuY2xhc3NMYWJlbCAubGFiZWwgewogIGZpbGw6ICM5MzcwREI7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZDgwbjNhbDAweHkgLnJlbGF0aW9uIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOwogIGZpbGw6IG5vbmU7IH0KCiNkODBuM2FsMDB4eSAjY29tcG9zaXRpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDgwbjNhbDAweHkgI2NvbXBvc2l0aW9uRW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkODBuM2FsMDB4eSAjYWdncmVnYXRpb25TdGFydCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDgwbjNhbDAweHkgI2FnZ3JlZ2F0aW9uRW5kIHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkODBuM2FsMDB4eSAjZGVwZW5kZW5jeVN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkODBuM2FsMDB4eSAjZGVwZW5kZW5jeUVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDgwbjNhbDAweHkgI2V4dGVuc2lvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkODBuM2FsMDB4eSAjZXh0ZW5zaW9uRW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkODBuM2FsMDB4eSAuY29tbWl0LWlkLAojZDgwbjNhbDAweHkgLmNvbW1pdC1tc2csCiNkODBuM2FsMDB4eSAuYnJhbmNoLWxhYmVsIHsKICBmaWxsOiBsaWdodGdyZXk7CiAgY29sb3I6IGxpZ2h0Z3JleTsgfQoKCgojZDgwbjNhbDAweHkgLmxhYmVsewogIGNvbG9yOiMxOEIxNEU7Cn0KI2Q4MG4zYWwwMHh5IC50ZS1tZC1jb250YWluZXItLWRhcmsgLm5vZGUgcmVjdCB7CiAgZmlsbDogcmVkOwp9CgojZDgwbjNhbDAweHkgLm5vZGUgcmVjdCwKI2Q4MG4zYWwwMHh5IC5ub2RlIGNpcmNsZSwKI2Q4MG4zYWwwMHh5IC5ub2RlIGVsbGlwc2UsCiNkODBuM2FsMDB4eSAubm9kZSBwb2x5Z29uIHsKICBmaWxsOiAjRjlGRkZCOzsKICBzdHJva2U6ICMyREJENjA7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsKfQojZDgwbjNhbDAweHkgLmFycm93aGVhZFBhdGh7CiAgZmlsbDogIzJEQkQ2MDsKfQojZDgwbjNhbDAweHkgLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMyREJENjA7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7Cn0KI2Q4MG4zYWwwMHh5IC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNmZmY7Cn0KI2Q4MG4zYWwwMHh5IC5jbHVzdGVyIHJlY3QgewogIGZpbGw6ICNGOUZGRkIgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2Utd2lkdGg6IDFweCAhaW1wb3J0YW50Owp9CgojZDgwbjNhbDAweHkgLmNsdXN0ZXIgdGV4dCB7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2Q4MG4zYWwwMHh5IGRpdi5tZXJtYWlkVG9vbHRpcCB7CiAgYmFja2dyb3VuZDogI0Y5RkZGQjsKICBib3JkZXI6IDFweCBzb2xpZCAjMkRCRDYwOwp9CgoKI2Q4MG4zYWwwMHh5IC5hY3RvciB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkODBuM2FsMDB4eSB0ZXh0LmFjdG9yIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2Q4MG4zYWwwMHh5IC5hY3Rvci1saW5lIHsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkODBuM2FsMDB4eSAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkODBuM2FsMDB4eSAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkODBuM2FsMDB4eSAjYXJyb3doZWFkIHsKICBmaWxsOiAjMkRCRDYwOwp9CgojZDgwbjNhbDAweHkgI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7Cn0KCiNkODBuM2FsMDB4eSAubWVzc2FnZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZDgwbjNhbDAweHkgLmxhYmVsQm94IHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2Q4MG4zYWwwMHh5IC5sYWJlbFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZDgwbjNhbDAweHkgLmxvb3BUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2Q4MG4zYWwwMHh5IC5sb29wTGluZSB7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2Q4MG4zYWwwMHh5IC5ub3RlIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2Q4MG4zYWwwMHh5IC5ub3RlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCgojZDgwbjNhbDAweHkgLnNlY3Rpb257CiAgb3BhY2l0eToxOwp9CiNkODBuM2FsMDB4eSAuc2VjdGlvbjAsI2Q4MG4zYWwwMHh5ICAuc2VjdGlvbjIgewogIGZpbGw6ICNFQ0Y3RjA7Cn0KCiNkODBuM2FsMDB4eSAuc2VjdGlvbjEsCiNkODBuM2FsMDB4eSAuc2VjdGlvbjMgewogIGZpbGw6ICNGRkY7Cn0KI2Q4MG4zYWwwMHh5IC50YXNrVGV4dDAsCiNkODBuM2FsMDB4eSAudGFza1RleHQxLAojZDgwbjNhbDAweHkgLnRhc2tUZXh0MiwKI2Q4MG4zYWwwMHh5IC50YXNrVGV4dDMgewogIGZpbGw6ICNmZmY7Cn0KCiNkODBuM2FsMDB4eSAudGFzazAsCiNkODBuM2FsMDB4eSAudGFzazEsCiNkODBuM2FsMDB4eSAudGFzazIsCiNkODBuM2FsMDB4eSAudGFzazMgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMzU5RjVBOwp9Cjwvc3R5bGU+PHN0eWxlPiNkODBuM2FsMDB4eSB7CiAgICBjb2xvcjogcmdiKDI0NCwgMjQ0LCAyNDQpOwogICAgZm9udDogbm9ybWFsIG5vcm1hbCBub3JtYWwgbm9ybWFsIDE0cHgvMjIuMzk5OTk5NjE4NTMwMjczcHggbW9ub3NwYWNlOwogIH08L3N0eWxlPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMiwgLTEyKSI+PGcgY2xhc3M9Im91dHB1dCI+PGcgY2xhc3M9ImNsdXN0ZXJzIj48L2c+PGcgY2xhc3M9ImVkZ2VQYXRocyI+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjU5Ljc4MTI1LDU2LjI4MTI1TDI1OS43ODEyNSw4MS4yODEyNUwyNjAuMjgxMjUsMTA2Ljc4MTI1MzA1MTc1Nzg3IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDgzNCkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkODM0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjA1LjkxNzEyMTU1OTc2NzA1LDMyNS4yODU4Njg1MDgwMDkzTDE0Ny40NTMxMjUsNDEyLjI5MDYxODg5NjQ4NDRMMTQ3LjQ1MzEyNSw0NDUuNDMxMjQzODk2NDg0NCIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ4MzUpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDgzNSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTMxNC42NDUzODA4NzIyNjE1NywzMjUuMjg1ODcyMTc5NDk2MjdMMzcyLjEwOTM3NSw0MTIuMjkwNjE4ODk2NDg0NEwzNzIuMTA5Mzc1LDQ0NS40MzEyNDM4OTY0ODQ0IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDgzNikiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkODM2IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTQ3LjQ1MzEyNSw0ODEuNzEyNDkzODk2NDg0NEwxNDcuNDUzMTI1LDUwNi43MTI0OTM4OTY0ODQ0TDE0Ny40NTMxMjUsNTMxLjcxMjQ5Mzg5NjQ4NDQiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkODM3KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ4MzciIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbHMiPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE0Ny40NTMxMjUsNDEyLjI5MDYxODg5NjQ4NDQpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI4LjkzNzUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPk48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM3Mi4xMDkzNzUsNDEyLjI5MDYxODg5NjQ4NDQpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI4IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5ZPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGVzIj48ZyBjbGFzcz0ibm9kZSIgaWQ9IkEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1OS43ODEyNSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTY3LjIwMzEyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjEzNC40MDYyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU3LjIwMzEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+TGludXjns7vnu5/nlKjmiLfnmbvlvZU8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1OS43ODEyNSwyNDIuNzE1NjIxOTQ4MjQyMikiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBvbHlnb24gcG9pbnRzPSIxMzYuNDM0Mzc1MDAwMDAwMDIsMCAyNzIuODY4NzUwMDAwMDAwMDMsLTEzNi40MzQzNzUwMDAwMDAwMiAxMzYuNDM0Mzc1MDAwMDAwMDIsLTI3Mi44Njg3NTAwMDAwMDAwMyAwLC0xMzYuNDM0Mzc1MDAwMDAwMDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzNi40MzQzNzUwMDAwMDAwMiwxMzYuNDM0Mzc1MDAwMDAwMDIpIj48L3BvbHlnb24+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIzLjQ1MzEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+57O757uf5paH5Lu25piv5ZCm5o+P6L+w5LqG55So5oi36Ze055qE5pig5bCE5YWz57O777yfPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJDIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNDcuNDUzMTI1LDQ2My41NzE4Njg4OTY0ODQ0KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii04MC4wODU5Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTYwLjE3MTg3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTcwLjA4NTkzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPueUqOaIt+aYoOWwhOS4ul9fZGVmYXVsdF9fPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJEIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNzIuMTA5Mzc1LDQ2My41NzE4Njg4OTY0ODQ0KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii05NC41NzAzMTI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTg5LjE0MDYyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTg0LjU3MDMxMjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPueUqOaIt+ebtOaOpeaYoOWwhOWIsFNFTGludXjnlKjmiLc8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE0Ny40NTMxMjUsNTQ5Ljg1MzExODg5NjQ4NDQpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTEyNy40NTMxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIyNTQuOTA2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMTcuNDUzMTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5fX2RlZmF1bHRfX+eUqOaIt+iiq+aYoOWwhOS4unVuY29uZmluZWRfdTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==

上面提到的系统文件为/etc/selinux/specified-policy/seusers
通过上面的流程也可以看出,SELinux的策略文件并没有专门定义有哪些SELinux用户,而是通过seusers文件中描述的映射关系来表明有哪些SELinux用户。用户再通过role映射到type,最后通过TE系统来确定权限关系。大致关系如下:

PHN2ZyBpZD0iZHE5cHNkaTVid2siIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDcxMi4wMzEyNXB4OyIgdmlld0JveD0iMCAwIDcxMi4wMzEyNSA1Mi4yODEyNSI+PHN0eWxlPgoKCiNkcTlwc2RpNWJ3ayAubGFiZWwgewogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgY29sb3I6ICMzMzM7IH0KCiNkcTlwc2RpNWJ3ayAubm9kZSByZWN0LAojZHE5cHNkaTVid2sgLm5vZGUgY2lyY2xlLAojZHE5cHNkaTVid2sgLm5vZGUgZWxsaXBzZSwKI2RxOXBzZGk1YndrIC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMXB4OyB9CgojZHE5cHNkaTVid2sgLm5vZGUuY2xpY2thYmxlIHsKICBjdXJzb3I6IHBvaW50ZXI7IH0KCiNkcTlwc2RpNWJ3ayAuYXJyb3doZWFkUGF0aCB7CiAgZmlsbDogIzMzMzMzMzsgfQoKI2RxOXBzZGk1YndrIC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMzMzMzMzOwogIHN0cm9rZS13aWR0aDogMS41cHg7IH0KCiNkcTlwc2RpNWJ3ayAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZThlOGU4OyB9CgojZHE5cHNkaTVid2sgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI2ZmZmZkZSAhaW1wb3J0YW50OwogIHN0cm9rZTogI2FhYWEzMyAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7IH0KCiNkcTlwc2RpNWJ3ayAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjMzMzOyB9CgojZHE5cHNkaTVid2sgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1heC13aWR0aDogMjAwcHg7CiAgcGFkZGluZzogMnB4OwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMnB4OwogIGJhY2tncm91bmQ6ICNmZmZmZGU7CiAgYm9yZGVyOiAxcHggc29saWQgI2FhYWEzMzsKICBib3JkZXItcmFkaXVzOiAycHg7CiAgcG9pbnRlci1ldmVudHM6IG5vbmU7CiAgei1pbmRleDogMTAwOyB9CgojZHE5cHNkaTVid2sgLmFjdG9yIHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RxOXBzZGk1YndrIHRleHQuYWN0b3IgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RxOXBzZGk1YndrIC5hY3Rvci1saW5lIHsKICBzdHJva2U6IGdyZXk7IH0KCiNkcTlwc2RpNWJ3ayAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkcTlwc2RpNWJ3ayAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkcTlwc2RpNWJ3ayAjYXJyb3doZWFkIHsKICBmaWxsOiAjMzMzOyB9CgojZHE5cHNkaTVid2sgI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMzMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMzMzICFpbXBvcnRhbnQ7IH0KCiNkcTlwc2RpNWJ3ayAubWVzc2FnZVRleHQgewogIGZpbGw6ICMzMzM7CiAgc3Ryb2tlOiBub25lOyB9CgojZHE5cHNkaTVid2sgLmxhYmVsQm94IHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RxOXBzZGk1YndrIC5sYWJlbFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RxOXBzZGk1YndrIC5sb29wVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHE5cHNkaTVid2sgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOyB9CgojZHE5cHNkaTVid2sgLm5vdGUgewogIHN0cm9rZTogI2FhYWEzMzsKICBmaWxsOiAjZmZmNWFkOyB9CgojZHE5cHNkaTVid2sgLm5vdGVUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDE0cHg7IH0KCiNkcTlwc2RpNWJ3ayAuYWN0aXZhdGlvbjAgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZHE5cHNkaTVid2sgLmFjdGl2YXRpb24xIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2RxOXBzZGk1YndrIC5hY3RpdmF0aW9uMiB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCgojZHE5cHNkaTVid2sgLnNlY3Rpb24gewogIHN0cm9rZTogbm9uZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkcTlwc2RpNWJ3ayAuc2VjdGlvbjAgewogIGZpbGw6IHJnYmEoMTAyLCAxMDIsIDI1NSwgMC40OSk7IH0KCiNkcTlwc2RpNWJ3ayAuc2VjdGlvbjIgewogIGZpbGw6ICNmZmY0MDA7IH0KCiNkcTlwc2RpNWJ3ayAuc2VjdGlvbjEsCiNkcTlwc2RpNWJ3ayAuc2VjdGlvbjMgewogIGZpbGw6IHdoaXRlOwogIG9wYWNpdHk6IDAuMjsgfQoKI2RxOXBzZGk1YndrIC5zZWN0aW9uVGl0bGUwIHsKICBmaWxsOiAjMzMzOyB9CgojZHE5cHNkaTVid2sgLnNlY3Rpb25UaXRsZTEgewogIGZpbGw6ICMzMzM7IH0KCiNkcTlwc2RpNWJ3ayAuc2VjdGlvblRpdGxlMiB7CiAgZmlsbDogIzMzMzsgfQoKI2RxOXBzZGk1YndrIC5zZWN0aW9uVGl0bGUzIHsKICBmaWxsOiAjMzMzOyB9CgojZHE5cHNkaTVid2sgLnNlY3Rpb25UaXRsZSB7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsKICB0ZXh0LWhlaWdodDogMTRweDsgfQoKCiNkcTlwc2RpNWJ3ayAuZ3JpZCAudGljayB7CiAgc3Ryb2tlOiBsaWdodGdyZXk7CiAgb3BhY2l0eTogMC4zOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2RxOXBzZGk1YndrIC5ncmlkIHBhdGggewogIHN0cm9rZS13aWR0aDogMDsgfQoKCiNkcTlwc2RpNWJ3ayAudG9kYXkgewogIGZpbGw6IG5vbmU7CiAgc3Ryb2tlOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAycHg7IH0KCgoKI2RxOXBzZGk1YndrIC50YXNrIHsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcTlwc2RpNWJ3ayAudGFza1RleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHE5cHNkaTVid2sgLnRhc2tUZXh0T3V0c2lkZVJpZ2h0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHE5cHNkaTVid2sgLnRhc2tUZXh0T3V0c2lkZUxlZnQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBlbmQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgoKI2RxOXBzZGk1YndrIC50YXNrVGV4dDAsCiNkcTlwc2RpNWJ3ayAudGFza1RleHQxLAojZHE5cHNkaTVid2sgLnRhc2tUZXh0MiwKI2RxOXBzZGk1YndrIC50YXNrVGV4dDMgewogIGZpbGw6IHdoaXRlOyB9CgojZHE5cHNkaTVid2sgLnRhc2swLAojZHE5cHNkaTVid2sgLnRhc2sxLAojZHE5cHNkaTVid2sgLnRhc2syLAojZHE5cHNkaTVid2sgLnRhc2szIHsKICBmaWxsOiAjOGE5MGRkOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2RxOXBzZGk1YndrIC50YXNrVGV4dE91dHNpZGUwLAojZHE5cHNkaTVid2sgLnRhc2tUZXh0T3V0c2lkZTIgewogIGZpbGw6IGJsYWNrOyB9CgojZHE5cHNkaTVid2sgLnRhc2tUZXh0T3V0c2lkZTEsCiNkcTlwc2RpNWJ3ayAudGFza1RleHRPdXRzaWRlMyB7CiAgZmlsbDogYmxhY2s7IH0KCgojZHE5cHNkaTVid2sgLmFjdGl2ZTAsCiNkcTlwc2RpNWJ3ayAuYWN0aXZlMSwKI2RxOXBzZGk1YndrIC5hY3RpdmUyLAojZHE5cHNkaTVid2sgLmFjdGl2ZTMgewogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZHE5cHNkaTVid2sgLmFjdGl2ZVRleHQwLAojZHE5cHNkaTVid2sgLmFjdGl2ZVRleHQxLAojZHE5cHNkaTVid2sgLmFjdGl2ZVRleHQyLAojZHE5cHNkaTVid2sgLmFjdGl2ZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RxOXBzZGk1YndrIC5kb25lMCwKI2RxOXBzZGk1YndrIC5kb25lMSwKI2RxOXBzZGk1YndrIC5kb25lMiwKI2RxOXBzZGk1YndrIC5kb25lMyB7CiAgc3Ryb2tlOiBncmV5OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcTlwc2RpNWJ3ayAuZG9uZVRleHQwLAojZHE5cHNkaTVid2sgLmRvbmVUZXh0MSwKI2RxOXBzZGk1YndrIC5kb25lVGV4dDIsCiNkcTlwc2RpNWJ3ayAuZG9uZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RxOXBzZGk1YndrIC5jcml0MCwKI2RxOXBzZGk1YndrIC5jcml0MSwKI2RxOXBzZGk1YndrIC5jcml0MiwKI2RxOXBzZGk1YndrIC5jcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IHJlZDsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcTlwc2RpNWJ3ayAuYWN0aXZlQ3JpdDAsCiNkcTlwc2RpNWJ3ayAuYWN0aXZlQ3JpdDEsCiNkcTlwc2RpNWJ3ayAuYWN0aXZlQ3JpdDIsCiNkcTlwc2RpNWJ3ayAuYWN0aXZlQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2RxOXBzZGk1YndrIC5kb25lQ3JpdDAsCiNkcTlwc2RpNWJ3ayAuZG9uZUNyaXQxLAojZHE5cHNkaTVid2sgLmRvbmVDcml0MiwKI2RxOXBzZGk1YndrIC5kb25lQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIGN1cnNvcjogcG9pbnRlcjsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkcTlwc2RpNWJ3ayAuZG9uZUNyaXRUZXh0MCwKI2RxOXBzZGk1YndrIC5kb25lQ3JpdFRleHQxLAojZHE5cHNkaTVid2sgLmRvbmVDcml0VGV4dDIsCiNkcTlwc2RpNWJ3ayAuZG9uZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2RxOXBzZGk1YndrIC5hY3RpdmVDcml0VGV4dDAsCiNkcTlwc2RpNWJ3ayAuYWN0aXZlQ3JpdFRleHQxLAojZHE5cHNkaTVid2sgLmFjdGl2ZUNyaXRUZXh0MiwKI2RxOXBzZGk1YndrIC5hY3RpdmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkcTlwc2RpNWJ3ayAudGl0bGVUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMThweDsKICBmaWxsOiBibGFjazsgfQoKI2RxOXBzZGk1YndrIGcuY2xhc3NHcm91cCB0ZXh0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2RxOXBzZGk1YndrIGcuY2xhc3NHcm91cCByZWN0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsgfQoKI2RxOXBzZGk1YndrIGcuY2xhc3NHcm91cCBsaW5lIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHE5cHNkaTVid2sgLmNsYXNzTGFiZWwgLmJveCB7CiAgc3Ryb2tlOiBub25lOwogIHN0cm9rZS13aWR0aDogMDsKICBmaWxsOiAjRUNFQ0ZGOwogIG9wYWNpdHk6IDAuNTsgfQoKI2RxOXBzZGk1YndrIC5jbGFzc0xhYmVsIC5sYWJlbCB7CiAgZmlsbDogIzkzNzBEQjsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkcTlwc2RpNWJ3ayAucmVsYXRpb24gewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7CiAgZmlsbDogbm9uZTsgfQoKI2RxOXBzZGk1YndrICNjb21wb3NpdGlvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcTlwc2RpNWJ3ayAjY29tcG9zaXRpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxOXBzZGk1YndrICNhZ2dyZWdhdGlvblN0YXJ0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcTlwc2RpNWJ3ayAjYWdncmVnYXRpb25FbmQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxOXBzZGk1YndrICNkZXBlbmRlbmN5U3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxOXBzZGk1YndrICNkZXBlbmRlbmN5RW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcTlwc2RpNWJ3ayAjZXh0ZW5zaW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxOXBzZGk1YndrICNleHRlbnNpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxOXBzZGk1YndrIC5jb21taXQtaWQsCiNkcTlwc2RpNWJ3ayAuY29tbWl0LW1zZywKI2RxOXBzZGk1YndrIC5icmFuY2gtbGFiZWwgewogIGZpbGw6IGxpZ2h0Z3JleTsKICBjb2xvcjogbGlnaHRncmV5OyB9CgoKCiNkcTlwc2RpNWJ3ayAubGFiZWx7CiAgY29sb3I6IzE4QjE0RTsKfQojZHE5cHNkaTVid2sgLnRlLW1kLWNvbnRhaW5lci0tZGFyayAubm9kZSByZWN0IHsKICBmaWxsOiByZWQ7Cn0KCiNkcTlwc2RpNWJ3ayAubm9kZSByZWN0LAojZHE5cHNkaTVid2sgLm5vZGUgY2lyY2xlLAojZHE5cHNkaTVid2sgLm5vZGUgZWxsaXBzZSwKI2RxOXBzZGk1YndrIC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNGOUZGRkI7OwogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDEuNXB4Owp9CiNkcTlwc2RpNWJ3ayAuYXJyb3doZWFkUGF0aHsKICBmaWxsOiAjMkRCRDYwOwp9CiNkcTlwc2RpNWJ3ayAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDFweDsKfQojZHE5cHNkaTVid2sgLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsKfQojZHE5cHNkaTVid2sgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI0Y5RkZGQiAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7Cn0KCiNkcTlwc2RpNWJ3ayAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHE5cHNkaTVid2sgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBiYWNrZ3JvdW5kOiAjRjlGRkZCOwogIGJvcmRlcjogMXB4IHNvbGlkICMyREJENjA7Cn0KCgojZHE5cHNkaTVid2sgLmFjdG9yIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RxOXBzZGk1YndrIHRleHQuYWN0b3IgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZHE5cHNkaTVid2sgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxOXBzZGk1YndrIC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxOXBzZGk1YndrIC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxOXBzZGk1YndrICNhcnJvd2hlYWQgewogIGZpbGw6ICMyREJENjA7Cn0KCiNkcTlwc2RpNWJ3ayAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKfQoKI2RxOXBzZGk1YndrIC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkcTlwc2RpNWJ3ayAubGFiZWxCb3ggewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHE5cHNkaTVid2sgLmxhYmVsVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkcTlwc2RpNWJ3ayAubG9vcFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHE5cHNkaTVid2sgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHE5cHNkaTVid2sgLm5vdGUgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHE5cHNkaTVid2sgLm5vdGVUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKCiNkcTlwc2RpNWJ3ayAuc2VjdGlvbnsKICBvcGFjaXR5OjE7Cn0KI2RxOXBzZGk1YndrIC5zZWN0aW9uMCwjZHE5cHNkaTVid2sgIC5zZWN0aW9uMiB7CiAgZmlsbDogI0VDRjdGMDsKfQoKI2RxOXBzZGk1YndrIC5zZWN0aW9uMSwKI2RxOXBzZGk1YndrIC5zZWN0aW9uMyB7CiAgZmlsbDogI0ZGRjsKfQojZHE5cHNkaTVid2sgLnRhc2tUZXh0MCwKI2RxOXBzZGk1YndrIC50YXNrVGV4dDEsCiNkcTlwc2RpNWJ3ayAudGFza1RleHQyLAojZHE5cHNkaTVid2sgLnRhc2tUZXh0MyB7CiAgZmlsbDogI2ZmZjsKfQoKI2RxOXBzZGk1YndrIC50YXNrMCwKI2RxOXBzZGk1YndrIC50YXNrMSwKI2RxOXBzZGk1YndrIC50YXNrMiwKI2RxOXBzZGk1YndrIC50YXNrMyB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMzNTlGNUE7Cn0KPC9zdHlsZT48c3R5bGU+I2RxOXBzZGk1YndrIHsKICAgIGNvbG9yOiByZ2IoMjQ0LCAyNDQsIDI0NCk7CiAgICBmb250OiBub3JtYWwgbm9ybWFsIG5vcm1hbCBub3JtYWwgMTRweC8yMi4zOTk5OTk2MTg1MzAyNzNweCBtb25vc3BhY2U7CiAgfTwvc3R5bGU+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLCAtMTIpIj48ZyBjbGFzcz0ib3V0cHV0Ij48ZyBjbGFzcz0iY2x1c3RlcnMiPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGhzIj48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xMjcsMzguMTQwNjI1TDE1MiwzOC4xNDA2MjVMMTc3LDM4LjE0MDYyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ4NjApIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDg2MCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTI3MC4yMzQzNzUsMzguMTQwNjI1TDI5NS4yMzQzNzUsMzguMTQwNjI1TDMyMC4yMzQzNzUsMzguMTQwNjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDg2MSkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkODYxIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMzc5LjEwOTM3NSwzOC4xNDA2MjVMNDA0LjEwOTM3NSwzOC4xNDA2MjVMNDI5LjEwOTM3NSwzOC4xNDA2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkODYyKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ4NjIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik00OTEuMTU2MjUsMzguMTQwNjI1TDU1MS4yMjY1NjI1LDM4LjE0MDYyNUw2MTEuMjk2ODc1LDM4LjE0MDYyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ4NjMpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDg2MyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVscyI+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTUxLjIyNjU2MjUsMzguMTQwNjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzUuNjU2MjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iNjkuODQzNzUiIGhlaWdodD0iMTYuMjAzMTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5UReadg+mZkOajgOafpTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlcyI+PGcgY2xhc3M9Im5vZGUiIGlkPSJBIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3My41LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNTMuNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjEwNyIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQzLjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPkxpbnV457O757uf55So5oi3PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjMuNjE3MTg3NSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTQ2LjYxNzE4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI5My4yMzQzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNi42MTcxODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5TRUxpbnV455So5oi3PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJDIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDkuNjcxODc1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMjkuNDM3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjU4Ljg3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5LjQzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnJvbGUocyk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ2MC4xMzI4MTI1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMzEuMDIzNDM3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjYyLjA0Njg3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIxLjAyMzQzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnR5cGUocyk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDY2My42NjQwNjI1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNTIuMzY3MTg3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjEwNC43MzQzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00Mi4zNjcxODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5vYmplY3QgdHlwZShzKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==

constrain

前面讲了RBAC与TE结合提供的权限检查,RBAC还提供了一种直接的user/role权限检查方法,成为constrain。举个例子:

# 标准格式:constrain <object_class_set> <perm_set> <expression> ;
constrain file write (u1 == u2 and r1 == r2) ;

限制只有文件的创建者user/role与进程user/role相等时,才可以对文件进行写操作。注意这里是object class,控制的是一类资源,而不是具体哪一个object。
可以使用的逻辑运算符有:

  • ==, !=:user/role都可用
  • 仅针对role的eq, dom, domby, incomp

总结

PHN2ZyBpZD0iZHhrM2V5em95M3AiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDM3NS45MjE4NzVweDsiIHZpZXdCb3g9IjAgMCAzNzUuOTIxODc1IDM0My42ODc1Ij48c3R5bGU+CgoKI2R4azNleXpveTNwIC5sYWJlbCB7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBjb2xvcjogIzMzMzsgfQoKI2R4azNleXpveTNwIC5ub2RlIHJlY3QsCiNkeGszZXl6b3kzcCAubm9kZSBjaXJjbGUsCiNkeGszZXl6b3kzcCAubm9kZSBlbGxpcHNlLAojZHhrM2V5em95M3AgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7IH0KCiNkeGszZXl6b3kzcCAubm9kZS5jbGlja2FibGUgewogIGN1cnNvcjogcG9pbnRlcjsgfQoKI2R4azNleXpveTNwIC5hcnJvd2hlYWRQYXRoIHsKICBmaWxsOiAjMzMzMzMzOyB9CgojZHhrM2V5em95M3AgLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMzMzMzMzM7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsgfQoKI2R4azNleXpveTNwIC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNlOGU4ZTg7IH0KCiNkeGszZXl6b3kzcCAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjZmZmZmRlICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjYWFhYTMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsgfQoKI2R4azNleXpveTNwIC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICMzMzM7IH0KCiNkeGszZXl6b3kzcCBkaXYubWVybWFpZFRvb2x0aXAgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWF4LXdpZHRoOiAyMDBweDsKICBwYWRkaW5nOiAycHg7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEycHg7CiAgYmFja2dyb3VuZDogI2ZmZmZkZTsKICBib3JkZXI6IDFweCBzb2xpZCAjYWFhYTMzOwogIGJvcmRlci1yYWRpdXM6IDJweDsKICBwb2ludGVyLWV2ZW50czogbm9uZTsKICB6LWluZGV4OiAxMDA7IH0KCiNkeGszZXl6b3kzcCAuYWN0b3IgewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZHhrM2V5em95M3AgdGV4dC5hY3RvciB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHhrM2V5em95M3AgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogZ3JleTsgfQoKI2R4azNleXpveTNwIC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2R4azNleXpveTNwIC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2R4azNleXpveTNwICNhcnJvd2hlYWQgewogIGZpbGw6ICMzMzM7IH0KCiNkeGszZXl6b3kzcCAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMzMzMgIWltcG9ydGFudDsKICBzdHJva2U6ICMzMzMgIWltcG9ydGFudDsgfQoKI2R4azNleXpveTNwIC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzMzMzsKICBzdHJva2U6IG5vbmU7IH0KCiNkeGszZXl6b3kzcCAubGFiZWxCb3ggewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZHhrM2V5em95M3AgLmxhYmVsVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHhrM2V5em95M3AgLmxvb3BUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkeGszZXl6b3kzcCAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICNDQ0NDRkY7IH0KCiNkeGszZXl6b3kzcCAubm90ZSB7CiAgc3Ryb2tlOiAjYWFhYTMzOwogIGZpbGw6ICNmZmY1YWQ7IH0KCiNkeGszZXl6b3kzcCAubm90ZVRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTRweDsgfQoKI2R4azNleXpveTNwIC5hY3RpdmF0aW9uMCB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNkeGszZXl6b3kzcCAuYWN0aXZhdGlvbjEgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZHhrM2V5em95M3AgLmFjdGl2YXRpb24yIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKCiNkeGszZXl6b3kzcCAuc2VjdGlvbiB7CiAgc3Ryb2tlOiBub25lOwogIG9wYWNpdHk6IDAuMjsgfQoKI2R4azNleXpveTNwIC5zZWN0aW9uMCB7CiAgZmlsbDogcmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KTsgfQoKI2R4azNleXpveTNwIC5zZWN0aW9uMiB7CiAgZmlsbDogI2ZmZjQwMDsgfQoKI2R4azNleXpveTNwIC5zZWN0aW9uMSwKI2R4azNleXpveTNwIC5zZWN0aW9uMyB7CiAgZmlsbDogd2hpdGU7CiAgb3BhY2l0eTogMC4yOyB9CgojZHhrM2V5em95M3AgLnNlY3Rpb25UaXRsZTAgewogIGZpbGw6ICMzMzM7IH0KCiNkeGszZXl6b3kzcCAuc2VjdGlvblRpdGxlMSB7CiAgZmlsbDogIzMzMzsgfQoKI2R4azNleXpveTNwIC5zZWN0aW9uVGl0bGUyIHsKICBmaWxsOiAjMzMzOyB9CgojZHhrM2V5em95M3AgLnNlY3Rpb25UaXRsZTMgewogIGZpbGw6ICMzMzM7IH0KCiNkeGszZXl6b3kzcCAuc2VjdGlvblRpdGxlIHsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OwogIHRleHQtaGVpZ2h0OiAxNHB4OyB9CgoKI2R4azNleXpveTNwIC5ncmlkIC50aWNrIHsKICBzdHJva2U6IGxpZ2h0Z3JleTsKICBvcGFjaXR5OiAwLjM7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZHhrM2V5em95M3AgLmdyaWQgcGF0aCB7CiAgc3Ryb2tlLXdpZHRoOiAwOyB9CgoKI2R4azNleXpveTNwIC50b2RheSB7CiAgZmlsbDogbm9uZTsKICBzdHJva2U6IHJlZDsKICBzdHJva2Utd2lkdGg6IDJweDsgfQoKCgojZHhrM2V5em95M3AgLnRhc2sgewogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R4azNleXpveTNwIC50YXNrVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDExcHg7IH0KCiNkeGszZXl6b3kzcCAudGFza1RleHRPdXRzaWRlUmlnaHQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7IH0KCiNkeGszZXl6b3kzcCAudGFza1RleHRPdXRzaWRlTGVmdCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IGVuZDsKICBmb250LXNpemU6IDExcHg7IH0KCgojZHhrM2V5em95M3AgLnRhc2tUZXh0MCwKI2R4azNleXpveTNwIC50YXNrVGV4dDEsCiNkeGszZXl6b3kzcCAudGFza1RleHQyLAojZHhrM2V5em95M3AgLnRhc2tUZXh0MyB7CiAgZmlsbDogd2hpdGU7IH0KCiNkeGszZXl6b3kzcCAudGFzazAsCiNkeGszZXl6b3kzcCAudGFzazEsCiNkeGszZXl6b3kzcCAudGFzazIsCiNkeGszZXl6b3kzcCAudGFzazMgewogIGZpbGw6ICM4YTkwZGQ7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZHhrM2V5em95M3AgLnRhc2tUZXh0T3V0c2lkZTAsCiNkeGszZXl6b3kzcCAudGFza1RleHRPdXRzaWRlMiB7CiAgZmlsbDogYmxhY2s7IH0KCiNkeGszZXl6b3kzcCAudGFza1RleHRPdXRzaWRlMSwKI2R4azNleXpveTNwIC50YXNrVGV4dE91dHNpZGUzIHsKICBmaWxsOiBibGFjazsgfQoKCiNkeGszZXl6b3kzcCAuYWN0aXZlMCwKI2R4azNleXpveTNwIC5hY3RpdmUxLAojZHhrM2V5em95M3AgLmFjdGl2ZTIsCiNkeGszZXl6b3kzcCAuYWN0aXZlMyB7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNkeGszZXl6b3kzcCAuYWN0aXZlVGV4dDAsCiNkeGszZXl6b3kzcCAuYWN0aXZlVGV4dDEsCiNkeGszZXl6b3kzcCAuYWN0aXZlVGV4dDIsCiNkeGszZXl6b3kzcCAuYWN0aXZlVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZHhrM2V5em95M3AgLmRvbmUwLAojZHhrM2V5em95M3AgLmRvbmUxLAojZHhrM2V5em95M3AgLmRvbmUyLAojZHhrM2V5em95M3AgLmRvbmUzIHsKICBzdHJva2U6IGdyZXk7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R4azNleXpveTNwIC5kb25lVGV4dDAsCiNkeGszZXl6b3kzcCAuZG9uZVRleHQxLAojZHhrM2V5em95M3AgLmRvbmVUZXh0MiwKI2R4azNleXpveTNwIC5kb25lVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZHhrM2V5em95M3AgLmNyaXQwLAojZHhrM2V5em95M3AgLmNyaXQxLAojZHhrM2V5em95M3AgLmNyaXQyLAojZHhrM2V5em95M3AgLmNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogcmVkOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R4azNleXpveTNwIC5hY3RpdmVDcml0MCwKI2R4azNleXpveTNwIC5hY3RpdmVDcml0MSwKI2R4azNleXpveTNwIC5hY3RpdmVDcml0MiwKI2R4azNleXpveTNwIC5hY3RpdmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZHhrM2V5em95M3AgLmRvbmVDcml0MCwKI2R4azNleXpveTNwIC5kb25lQ3JpdDEsCiNkeGszZXl6b3kzcCAuZG9uZUNyaXQyLAojZHhrM2V5em95M3AgLmRvbmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7CiAgY3Vyc29yOiBwb2ludGVyOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2R4azNleXpveTNwIC5kb25lQ3JpdFRleHQwLAojZHhrM2V5em95M3AgLmRvbmVDcml0VGV4dDEsCiNkeGszZXl6b3kzcCAuZG9uZUNyaXRUZXh0MiwKI2R4azNleXpveTNwIC5kb25lQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZHhrM2V5em95M3AgLmFjdGl2ZUNyaXRUZXh0MCwKI2R4azNleXpveTNwIC5hY3RpdmVDcml0VGV4dDEsCiNkeGszZXl6b3kzcCAuYWN0aXZlQ3JpdFRleHQyLAojZHhrM2V5em95M3AgLmFjdGl2ZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2R4azNleXpveTNwIC50aXRsZVRleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxOHB4OwogIGZpbGw6IGJsYWNrOyB9CgojZHhrM2V5em95M3AgZy5jbGFzc0dyb3VwIHRleHQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZHhrM2V5em95M3AgZy5jbGFzc0dyb3VwIHJlY3QgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOyB9CgojZHhrM2V5em95M3AgZy5jbGFzc0dyb3VwIGxpbmUgewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkeGszZXl6b3kzcCAuY2xhc3NMYWJlbCAuYm94IHsKICBzdHJva2U6IG5vbmU7CiAgc3Ryb2tlLXdpZHRoOiAwOwogIGZpbGw6ICNFQ0VDRkY7CiAgb3BhY2l0eTogMC41OyB9CgojZHhrM2V5em95M3AgLmNsYXNzTGFiZWwgLmxhYmVsIHsKICBmaWxsOiAjOTM3MERCOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2R4azNleXpveTNwIC5yZWxhdGlvbiB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsKICBmaWxsOiBub25lOyB9CgojZHhrM2V5em95M3AgI2NvbXBvc2l0aW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R4azNleXpveTNwICNjb21wb3NpdGlvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHhrM2V5em95M3AgI2FnZ3JlZ2F0aW9uU3RhcnQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R4azNleXpveTNwICNhZ2dyZWdhdGlvbkVuZCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHhrM2V5em95M3AgI2RlcGVuZGVuY3lTdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHhrM2V5em95M3AgI2RlcGVuZGVuY3lFbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R4azNleXpveTNwICNleHRlbnNpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHhrM2V5em95M3AgI2V4dGVuc2lvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHhrM2V5em95M3AgLmNvbW1pdC1pZCwKI2R4azNleXpveTNwIC5jb21taXQtbXNnLAojZHhrM2V5em95M3AgLmJyYW5jaC1sYWJlbCB7CiAgZmlsbDogbGlnaHRncmV5OwogIGNvbG9yOiBsaWdodGdyZXk7IH0KCgoKI2R4azNleXpveTNwIC5sYWJlbHsKICBjb2xvcjojMThCMTRFOwp9CiNkeGszZXl6b3kzcCAudGUtbWQtY29udGFpbmVyLS1kYXJrIC5ub2RlIHJlY3QgewogIGZpbGw6IHJlZDsKfQoKI2R4azNleXpveTNwIC5ub2RlIHJlY3QsCiNkeGszZXl6b3kzcCAubm9kZSBjaXJjbGUsCiNkeGszZXl6b3kzcCAubm9kZSBlbGxpcHNlLAojZHhrM2V5em95M3AgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0Y5RkZGQjs7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMS41cHg7Cn0KI2R4azNleXpveTNwIC5hcnJvd2hlYWRQYXRoewogIGZpbGw6ICMyREJENjA7Cn0KI2R4azNleXpveTNwIC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMXB4Owp9CiNkeGszZXl6b3kzcCAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOwp9CiNkeGszZXl6b3kzcCAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjRjlGRkZCICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsKfQoKI2R4azNleXpveTNwIC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkeGszZXl6b3kzcCBkaXYubWVybWFpZFRvb2x0aXAgewogIGJhY2tncm91bmQ6ICNGOUZGRkI7CiAgYm9yZGVyOiAxcHggc29saWQgIzJEQkQ2MDsKfQoKCiNkeGszZXl6b3kzcCAuYWN0b3IgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHhrM2V5em95M3AgdGV4dC5hY3RvciB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkeGszZXl6b3kzcCAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHhrM2V5em95M3AgLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHhrM2V5em95M3AgLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHhrM2V5em95M3AgI2Fycm93aGVhZCB7CiAgZmlsbDogIzJEQkQ2MDsKfQoKI2R4azNleXpveTNwICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50Owp9CgojZHhrM2V5em95M3AgLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2R4azNleXpveTNwIC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkeGszZXl6b3kzcCAubGFiZWxUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R4azNleXpveTNwIC5sb29wVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkeGszZXl6b3kzcCAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkeGszZXl6b3kzcCAubm90ZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkeGszZXl6b3kzcCAubm90ZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgoKI2R4azNleXpveTNwIC5zZWN0aW9uewogIG9wYWNpdHk6MTsKfQojZHhrM2V5em95M3AgLnNlY3Rpb24wLCNkeGszZXl6b3kzcCAgLnNlY3Rpb24yIHsKICBmaWxsOiAjRUNGN0YwOwp9CgojZHhrM2V5em95M3AgLnNlY3Rpb24xLAojZHhrM2V5em95M3AgLnNlY3Rpb24zIHsKICBmaWxsOiAjRkZGOwp9CiNkeGszZXl6b3kzcCAudGFza1RleHQwLAojZHhrM2V5em95M3AgLnRhc2tUZXh0MSwKI2R4azNleXpveTNwIC50YXNrVGV4dDIsCiNkeGszZXl6b3kzcCAudGFza1RleHQzIHsKICBmaWxsOiAjZmZmOwp9CgojZHhrM2V5em95M3AgLnRhc2swLAojZHhrM2V5em95M3AgLnRhc2sxLAojZHhrM2V5em95M3AgLnRhc2syLAojZHhrM2V5em95M3AgLnRhc2szIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzM1OUY1QTsKfQo8L3N0eWxlPjxzdHlsZT4jZHhrM2V5em95M3AgewogICAgY29sb3I6IHJnYigyNDQsIDI0NCwgMjQ0KTsKICAgIGZvbnQ6IG5vcm1hbCBub3JtYWwgbm9ybWFsIG5vcm1hbCAxNHB4LzIyLjM5OTk5OTYxODUzMDI3M3B4IG1vbm9zcGFjZTsKICB9PC9zdHlsZT48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIsIC0xMikiPjxnIGNsYXNzPSJvdXRwdXQiPjxnIGNsYXNzPSJjbHVzdGVycyI+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aHMiPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTYzLjMyMDMxMjUsNTYuMjgxMjVMNjMuMzIwMzEyNSw4MS4yODEyNUwxNzQuMDU0Njg3NSwxMTYuMjQyNjY5MDI1MTU3MjMiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkODg0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ4ODQiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xOTkuOTYwOTM3NSw1Ni4yODEyNUwxOTkuOTYwOTM3NSw4MS4yODEyNUwxOTkuOTYwOTM3NSwxMDYuMjgxMjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkODg1KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ4ODUiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0zMzYuNjAxNTYyNSw1Ni4yODEyNUwzMzYuNjAxNTYyNSw4MS4yODEyNUwyMjUuODY3MTg3NSwxMTYuMjQyNjY5MDI1MTU3MjMiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkODg2KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ4ODYiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xOTkuOTYwOTM3NSwxNDIuNTYyNUwxOTkuOTYwOTM3NSwxNzUuNzAzMTI1TDE5OS45NjA5Mzc1LDIwOC44NDM3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ4ODcpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDg4NyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE5OS45NjA5Mzc1LDI0NS4xMjVMMTk5Ljk2MDkzNzUsMjc4LjI2NTYyNUwxOTkuOTYwOTM3NSwzMTEuNDA2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkODg4KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ4ODgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbHMiPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5OS45NjA5Mzc1LDE3NS43MDMxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MC42NjQwNjI1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjU3Ljc4MTI1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj51c2VyLCByb2xlPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTkuOTYwOTM3NSwyNzguMjY1NjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjQuOTYwOTM3NSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIxMDMuODQzNzUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPlRFQUMgJmFtcDsgY29uc3RyYWluPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGVzIj48ZyBjbGFzcz0ibm9kZSIgaWQ9IkEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYzLjMyMDMxMjUsMzguMTQwNjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii00My4zMjAzMTI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iODYuNjQwNjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzMuMzIwMzEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+TGludXjnlKjmiLcxPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTkuOTYwOTM3NSwxMjQuNDIxODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0yNS45MDYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjUxLjgxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNS45MDYyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+UkJBQzwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iQyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTk5Ljk2MDkzNzUsMzguMTQwNjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii00My4zMjAzMTI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iODYuNjQwNjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzMuMzIwMzEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+TGludXjnlKjmiLcyPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJEIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMzYuNjAxNTYyNSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTQzLjMyMDMxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI4Ni42NDA2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zMy4zMjAzMTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5MaW51eOeUqOaItzM8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5OS45NjA5Mzc1LDIyNi45ODQzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTU1LjI1NzgxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxMTAuNTE1NjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDUuMjU3ODEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+cHJvY2VzcyB0eXBlKHMpPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJHIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxOTkuOTYwOTM3NSwzMjkuNTQ2ODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii01Mi4zNjcxODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTA0LjczNDM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQyLjM2NzE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPm9iamVjdCB0eXBlKHMpPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PC9zdmc+

MLS/MCS

MLS从Linux 2.6.12开始进入Linux内核,而SELinux大约是2.6.0开始进入内核。MLS与原始的SELinux支持的TE, RBAC鉴权手段是一种互补。具体可以阅读参考文献[7]。这篇文章来自Trusted Computer Solutions, Inc.(TCS)这家公司,是Linux内核MLS模块主要的设计者。文章写于2006年,估计是MLS合入内核不久。

A combination of MLS and TE creates a stronger, more functional system that benefits from the strengths of the two complementary models.
MLS models do not lend themselves easily to static analysis.
TE has deficiencies in handling a large number of labels or a dynamic work set of label names, especially in contrast to integrity concerns.

现在的MLS借助了RBAC定义的constrain机制,扩展了constrain语法,定义了所谓的mlsconstrain语法规则。为SELinux提供了基于Classification(Sensitivity Level)和Compartment(Category)语意的权限检查。
MLS是原始SELinux的扩展,所以在使能SELinux的时候也是可选的。你可以选择带MLS的SELinux,也可以选择不带MLS的SELinux。例如,在Fedora下的步骤如下:

  1. Install SELinux package
dnf install selinux-policy-mls
  1. Configure /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#       enforcing - SELinux security policy is enforced.
#       permissive - SELinux prints warnings instead of enforcing.
#       disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these two values:
#       targeted - Targeted processes are protected,
#       mls - Multi Level Security protection.
SELINUXTYPE=mls

核心概念

MLS的核心理念由下图阐释了。

引用[2]中的一段话:

MLS在安全策略上有一个形象的描述叫no write down和no read up:

  • 高级别的东西不能往低级别的东西里边写数据:这样可能导致高级别的数据泄露到低级别中。
  • 高级别的东西只能从低级别的东西里边读数据

如图4中,Process的级别是Confidential,它可以往同级别的File B中读写数据,但是只能往高级别的File A(级别是Secret)里边写东西。Process可以从File C和File D中读数据,但是不能往File C和File D上写数据。

反过来说:

  • 低级别的东西只能往高级别的东西里边写数据
  • 低级别的东西不能从高级别的东西那边读数据

注:这里只考虑泄不泄密,不考虑溢出攻击

实现MLS的具体手段

主要就是在TE,RBAC的secure context之上,加了sensitivity和category两个字段。使能了MLS的secure context,格式如下:

user:role:type:sensitivity[:category,...]- sensitivity [:category,...]

举个实际的例子:

user_u:role_r:type_t:s0-s1:c0,c1-c255

s0 -- 最低sensitivity
s1:c0,c1-c255 -- 最高sensitivity

注:s0啥都不带代表
s0 is the lowest classification and contains no compartments, thus dominated by every label on the system.

那么怎么利用这组标签?MLS引入了扩展的constrain语法,称为mlsconstrain,格式为:

mlsconstrain class perm_set expression;

对比constrain语法:

constrain object_class_set perm_set expression;

一样啊,没有区别啊!区别在于expression。MLS的expression多了下面几个东西:

  • l1, l2:小写的L。l1表示源的low senstivity level。l2表示target的low sensitivity。
  • h1, h2:小写的H。h1表示源的high senstivity level。h2表示target的high sensitivity。
  • l和h的关系,包括dom,domby,eq和incomp。

举个实际的例子:

 # Datagram send: Sender must be dominated by receiver unless one of them is trusted.
 mlsconstrain unix_dgram_socket { sendto }
          (l1 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
# mlstrustedsubject 是attribute

只有在以下3个条件之一成立的情况下,subject才能调用unix_dgram_socket class的object的sendto permission:

  • l1 domby l2, l1 sensitivity小于l2 sensitivity
  • t1匹配或者t2匹配标签mlstrustedsubject

总结

引用[6]中的几张图做个总结。

SELinux 顶层架构

SELinux 决策流程

Show me the code

参考[8], 下图是MLS的鉴权流程,但实际上SELinux的TE,RABC,MLS都是通过secure context的判断来鉴权的,它们的实现位置应该是在一起的。

参考文献

  1. 深入理解SELinux SEAndroid(第一部分)
  2. 深入理解SELinux SEAndroid之二
  3. 从头开始生成 SELinux
  4. SELinux学习笔记
  5. SELinux初始化登录用户安全上下文的方法
  6. Linux 基础 - 13. SELinux
  7. Chad Hanson, "SELinux and MLS: Putting the Pieces Together",Trusted Computer Solutions, Inc., 2006
  8. Linux强制访问控制机制模块详细描述(1)
SELinux%20%3D%20Security%20Enhanced%20Linux%0A%3E%20%20%5BWiki%3A%20Security-Enhanced%20Linux%5D(https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FSecurity-Enhanced_Linux)%0A%3E%20**Security-Enhanced%20Linux%20(SELinux)**%20is%20a%20Linux%20kernel%20security%20module%20that%20provides%20a%20mechanism%20for%20supporting%20access%20control%20security%20policies%2C%20including%20mandatory%20access%20controls%20(MAC).%0A%3E%20SELinux%20is%20**a%20set%20of%20kernel%20modifications**%20and%20**user-space%20tools**%20that%20have%20been%20added%20to%20various%20Linux%20distributions.%20%0A%0ASELinux%E8%B5%B7%E6%BA%90%E4%BA%8E%E7%BE%8E%E5%9B%BD%E5%9B%BD%E5%AE%89%E5%B1%80(NSA)%E3%80%82%E5%AE%83%E7%9A%84%E5%89%8D%E8%BA%AB%E6%98%AFNSA%E7%9A%84%E4%B8%80%E4%B8%AA%E5%8F%ABFlask%E7%9A%84%E9%A1%B9%E7%9B%AE%EF%BC%8C%E5%90%8E%E6%9D%A5%EF%BC%8CNSA%E8%A7%89%E5%BE%97Linux%E6%9B%B4%E5%85%B7%E5%8F%91%E5%B1%95%E5%92%8C%E6%99%AE%E5%8F%8A%E5%89%8D%E6%99%AF%EF%BC%8C%E6%89%80%E4%BB%A5%E5%B0%B1%E5%9C%A8Linux%E7%B3%BB%E7%BB%9F%E4%B8%8A%E9%87%8D%E6%96%B0%E5%AE%9E%E7%8E%B0%E4%BA%86FLASK%EF%BC%8C%E7%A7%B0%E4%B9%8B%E4%B8%BASELinux%E3%80%82%0A%0A%E5%9C%A8%E7%BD%91%E7%BB%9C%E4%B8%8A%E6%B5%8F%E8%A7%88%E4%BA%86%E4%B8%8D%E5%B0%91%E8%B5%84%E6%96%99%E3%80%82%E6%9C%89%E5%87%A0%E7%AF%87%E5%86%99%E7%9A%84%E9%9D%9E%E5%B8%B8%E5%A5%BD%2C%E7%BD%97%E5%88%97%E5%9C%A8%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%E4%B8%AD%2C%E6%96%B9%E4%BE%BF%E8%AF%BB%E8%80%85%E5%8F%82%E8%80%83%E5%BC%95%E7%94%A8%E3%80%82%0A%5B1%5D%E4%BB%8B%E7%BB%8D%E4%BA%86SELinux%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5%EF%BC%8C%E9%9D%9E%E5%B8%B8%E5%80%BC%E5%BE%97%E5%85%A5%E9%97%A8%E9%98%85%E8%AF%BB%E3%80%82%E5%8C%85%E6%8B%ACDAC%EF%BC%8CMAC%EF%BC%8CTEAC%EF%BC%88%E7%AE%80%E7%A7%B0TE%EF%BC%89%EF%BC%8CRBAC%EF%BC%8C%E4%BB%A5%E5%8F%8Apolicy%E6%96%87%E4%BB%B6%E7%9A%84%E8%AF%AD%E6%B3%95%0A%5B2%5D%E6%98%AF%5B1%5D%E7%9A%84%E5%A7%8A%E5%A6%B9%E7%AF%87%EF%BC%8C%E4%BB%8B%E7%BB%8D%E4%BA%86File%20Context%E5%92%8CMLS%E7%9A%84%E6%A6%82%E5%BF%B5%EF%BC%8C%E4%BB%A5%E5%8F%8A%E7%BC%96%E8%AF%91%E6%9E%84%E5%BB%BASELinux%E7%9A%84%E6%AD%A5%E9%AA%A4%E3%80%82%E7%9D%80%E9%87%8D%E4%BA%8E%E5%8A%A8%E6%89%8B%E9%83%A8%E5%88%86%0A%5B3%5D%E6%9C%AC%E6%9D%A5%E6%98%AF%E4%B8%80%E4%B8%AA%E9%9D%9E%E5%B8%B8%E5%A5%BD%E7%9A%84%E4%BB%8E%E5%A4%B4%E8%87%B3%E5%B0%BE%E6%8C%87%E5%AF%BC%E5%8A%A8%E6%89%8B%E6%9E%84%E5%BB%BASELinux%E7%9A%84%E6%95%99%E7%A8%8B%EF%BC%8C%E5%8F%AF%E6%83%9C%E6%96%87%E7%AB%A0%E4%B8%AD%E6%B6%89%E5%8F%8A%E7%9A%84%E6%BA%90%E7%A0%81%E7%89%88%E6%9C%AC%E8%BF%87%E4%BA%8E%E8%80%81%E4%BA%86%EF%BC%88Linux%202.6%EF%BC%8CGentoo%202006%E7%89%88%EF%BC%89%E3%80%82%E7%BC%96%E8%AF%91%E6%9E%84%E5%BB%BA%E7%9A%84%E6%97%B6%E5%80%99%E9%94%99%E8%AF%AF%E4%B8%8D%E6%96%AD%E3%80%82%E5%8F%AA%E8%83%BD%E6%84%8F%E4%BC%9A%E4%BA%86%EF%BC%8C%E5%8F%AF%E6%83%9C%E5%8F%AF%E6%83%9C%E3%80%82%0A%5B4%5D%E6%98%AF%E4%B8%80%E4%BB%BD%E6%96%87%E6%A1%A3%EF%BC%8C%E6%9C%80%E6%96%B0%E7%89%88%E6%9C%AC%E6%98%AF2012%E5%B9%B4%E6%9B%B4%E6%96%B0%E7%9A%84%E7%89%88%E6%9C%AC%EF%BC%8C%E8%B6%B3%E6%9C%89444%E9%A1%B5%EF%BC%8C%E5%AE%8C%E5%85%A8%E5%8F%AF%E4%BB%A5%E5%BD%93%E4%B8%80%E6%9C%ACSELinux%E7%9A%84%E5%85%A5%E9%97%A8%E4%B9%A6%E7%B1%8D%E6%9D%A5%E9%98%85%E8%AF%BB%E3%80%82%E6%88%91%E7%9B%AE%E5%89%8D%E8%BF%98%E6%B2%A1%E7%9C%8B%E5%AE%8C%EF%BC%8C%E4%BD%86%E6%98%AF%E4%BB%8E%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84%E6%9D%A5%E7%9C%8B%EF%BC%8C%E6%84%9F%E8%A7%89%E8%AF%A5%E6%9C%89%E7%9A%84%E9%83%BD%E6%9C%89%E5%80%BC%E5%BE%97%E5%A5%BD%E5%A5%BD%E7%9C%8B%E4%B8%80%E7%9C%8B%E3%80%82%0A%5B5%5D%5B6%5D%E6%98%AF%E4%B8%80%E4%BA%9B%E6%AF%94%E8%BE%83general%E7%9A%84%E7%9F%A5%E8%AF%86%E7%9A%84%E5%B8%96%E5%AD%90%EF%BC%8C%E4%B9%9F%E6%9C%89%E5%8F%AF%E5%8F%96%E4%B9%8B%E5%A4%84%EF%BC%8C%E5%8F%AF%E4%BB%A5%E4%BD%9C%E4%B8%BA%E5%8F%82%E8%80%83%0A%5B7%5D%E9%98%90%E8%BF%B0%E4%BA%86MLS%E7%9A%84%E7%94%B1%E6%9D%A5%E4%BB%A5%E5%8F%8A%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5%EF%BC%8C%E7%94%B1MLS%E5%BC%80%E5%8F%91%E8%80%85%E5%85%AC%E5%8F%B8%E5%86%99%E7%9A%84%EF%BC%8C%E4%BC%BC%E4%B9%8E%E6%AF%94%E8%BE%83%E6%9D%83%E5%A8%81%0A%5B8%5D%E6%8F%90%E5%88%B0%E4%BA%86%E4%B8%80%E4%BA%9B%E4%BB%A3%E7%A0%81%E5%85%A5%E5%8F%A3%EF%BC%8C%E9%98%85%E8%AF%BB%E4%BB%A3%E7%A0%81%E7%9A%84%E8%AF%9D%E5%8F%AF%E4%BB%A5%E4%BB%8E%E5%85%B6%E4%B8%AD%E6%89%A9%E5%B1%95%E5%BC%80%E5%8E%BB%0A%0A%E6%9C%AC%E6%96%87%E4%B8%BB%E8%A6%81%E6%B3%A8%E9%87%8D%E7%90%86%E6%B8%85SELinux%E5%AE%9E%E7%8E%B0%E5%AE%89%E5%85%A8%E9%98%B2%E6%8A%A4%E7%9A%84%E6%80%9D%E8%B7%AF%EF%BC%8C%E4%B8%8D%E6%B6%89%E5%8F%8A%E5%85%B7%E4%BD%93%E8%AF%AD%E6%B3%95%E8%A7%A3%E9%87%8A%E3%80%82%E5%8F%A6%E5%A4%96%E8%BF%98%E4%BC%9A%E5%86%8D%E5%86%99%E4%B8%80%E7%AF%87%E7%9D%80%E9%87%8D%E4%BB%8B%E7%BB%8D%E5%9C%A8Linux%E7%94%A8%E6%88%B7%E6%80%81%E4%BD%BF%E8%83%BDSELinux%EF%BC%8C%E5%B9%B6%E4%BF%AE%E6%94%B9%E6%88%96%E6%B7%BB%E5%8A%A0SELinux%E7%AD%96%E7%95%A5%20%0A%0A%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E7%90%86%E8%A7%A3%E5%85%B7%E4%BD%93%E8%AF%AD%E6%B3%95%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%5B1%5D%E3%80%82%E4%BB%A5%E5%8F%8AAndroid%E6%BA%90%E7%A0%81%E4%B8%BA%E4%BE%8B%EF%BC%8C%E5%8F%AF%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5%5B%E5%AE%9E%E7%8E%B0%20SELinux%5D(https%3A%2F%2Fsource.android.com%2Fsecurity%2Fselinux%2Fimplement)%E3%80%82Android%E7%B3%BB%E7%BB%9F%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6(.te)%E4%BD%8D%E7%BD%AE%E5%9C%A8%60system%2Fsepolicy%60%2C%60device%2F%3Cmanufacturer%3E%2F%3Cdevice-name%3E%2Fsepolicy%60%E3%80%82%0A%0A%23%23%20SELinux%E6%8F%90%E4%BE%9B%E7%9A%84%E9%98%B2%E6%8A%A4%E6%89%8B%E6%AE%B5%0A%E4%BB%8EWiki%20SELinux%E7%9A%84%E5%AE%9A%E4%B9%89%E5%B0%B1%E8%83%BD%E7%9C%8B%E5%87%BA%EF%BC%8CSELinux%E7%9A%84%E6%A0%B8%E5%BF%83%E5%B0%B1%E6%98%AF%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%80%E5%A5%97MAC%E7%9A%84%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86%E3%80%82MAC%E5%85%A8%E7%A7%B0%E4%B8%BAMandatory%20Access%20Control%EF%BC%88%E4%B8%AA%E4%BA%BA%E7%90%86%E8%A7%A3%EF%BC%9AMAC%24%5Capprox%24TEAC%EF%BC%89%E3%80%82%E5%86%8D%E8%BE%85%E4%BB%A5%E5%85%B6%E4%BB%96%E4%B8%80%E7%B3%BB%E5%88%97%E8%BE%85%E5%8A%A9%E6%89%8B%E6%AE%B5%EF%BC%8C%E6%9D%A5%E8%BE%BE%E5%88%B0%E7%BB%9D%E5%AF%B9%E7%9A%84%E5%AE%89%E5%85%A8%EF%BC%88%E5%BD%93%E7%84%B6%E4%B8%96%E7%95%8C%E4%B8%8A%E5%8F%AA%E6%9C%89%E7%9B%B8%E5%AF%B9%E5%AE%89%E5%85%A8%EF%BC%8C%E6%B2%A1%E6%9C%89%E7%BB%9D%E5%AF%B9%E7%9A%84%E5%AE%89%E5%85%A8%EF%BC%89%E3%80%82%E6%9C%AC%E7%AB%A0%E5%B0%B1%E9%80%90%E4%B8%80%E4%BB%8B%E7%BB%8D%E8%BF%99%E4%BA%9B%E6%89%8B%E6%AE%B5%E3%80%82%0A%23%23%23%20DAC%20vs.%20MAC%0ADAC%20%3D%20Discretionary%20Access%20Control%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AFLinux%E7%B3%BB%E7%BB%9F%E6%8F%90%E4%BE%9B%E7%BB%99%E6%88%91%E4%BB%AC%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%9A%84%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86%EF%BC%8C%E4%BE%8B%E5%A6%82%E5%A6%82%E4%B8%8B%60ls%20-l%60%E8%BE%93%E5%87%BA%EF%BC%9A%0A%60%60%60%0Adrwx------%2B%2019%20user%20%20staff%20%20%20%20%20%20%20608%2010%2027%2010%3A07%20Desktop%0Adrwx------%2B%2017%20user%20%20staff%20%20%20%20%20%20%20544%20%208%2016%2021%3A39%20Documents%0Adrwx------%2B%2031%20user%20%20staff%20%20%20%20%20%20%20992%2011%2027%2019%3A51%20Downloads%0A%60%60%60%0A-%20user%E5%B0%B1%E6%98%AF%E8%AF%A5%E6%96%87%E4%BB%B6%E7%9A%84%E6%8B%A5%E6%9C%89%E8%80%85ID%EF%BC%88%E5%8D%B3UID%EF%BC%89%EF%BC%8Cstaff%E6%98%AFuser%E7%9A%84%E7%BB%84ID%EF%BC%88GID%EF%BC%89%0A-%20%60rwx------%60%E5%B0%B1%E6%98%AF%E6%88%91%E4%BB%AC%E9%80%9A%E5%B8%B8%E8%AF%B4%E7%9A%84%E6%9D%83%E9%99%90%E7%BB%84%EF%BC%8C%E6%AF%8F%E4%B8%89%E4%B8%AA%E5%AD%97%E6%AF%8D%E4%BB%A3%E8%A1%A8%E4%B8%80%E7%A7%8D%E6%9D%83%E9%99%90%E6%A0%87%E8%AE%B0%0A%20%20%20%20-%20rwx%E5%88%86%E5%88%AB%E8%A1%A8%E7%A4%BA%E5%8F%AF%E8%AF%BB%EF%BC%8C%E5%8F%AF%E5%86%99%EF%BC%8C%E5%8F%AF%E6%89%A7%E8%A1%8C%20%20%0A%20%20%20%20-%20%5B1..3%5D%20%E8%A1%A8%E7%A4%BA%E6%8B%A5%E6%9C%89%E8%80%85%E7%9A%84%E6%9D%83%E9%99%90%0A%20%20%20%20-%20%5B4..6%5D%20%E8%A1%A8%E7%A4%BA%E4%B8%8E%E6%8B%A5%E6%9C%89%E8%80%85%E5%90%8C%E7%BB%84%E7%9A%84%E7%94%A8%E6%88%B7%E7%9A%84%E6%9D%83%E9%99%90%0A%20%20%20%20-%20%5B7..9%5D%20%E8%A1%A8%E7%A4%BA%E5%85%B6%E4%BB%96%E7%94%A8%E6%88%B7%E7%9A%84%E6%9D%83%E9%99%90%0A%20%20%20%20-%20%60rwx------%60%E6%8D%A2%E7%AE%97%E6%88%908%E8%BF%9B%E5%88%B6%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AF%E6%88%91%E4%BB%AC%E5%B8%B8%E8%AF%B4%E7%9A%84700%E6%9D%83%E9%99%90%EF%BC%8C%E4%BB%80%E4%B9%88644%E5%95%8A%EF%BC%8C777%E5%95%8A%E9%83%BD%E5%8F%AF%E4%BB%A5%E8%BF%99%E6%A0%B7%E6%8D%A2%E7%AE%97%0A%20%20%20%20%0ALinux%E5%9F%BA%E4%BA%8E%E5%9F%BA%E6%9C%AC%E7%9A%84UID%E5%92%8CGID%E5%8D%B3%E5%8F%AF%E4%BB%A5%E6%9C%89%E5%9F%BA%E6%9C%AC%E7%9A%84%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6%E3%80%82DAC%E7%9A%84%E7%BC%BA%E9%99%B7%E5%9C%A8%E4%BA%8E%EF%BC%8C%E4%BB%96%E6%9C%89%E4%B8%80%E4%B8%AA%E8%B6%85%E7%BA%A7%E7%94%A8%E6%88%B7root%EF%BC%8C%E5%BD%93%E4%B8%80%E6%97%A6%E9%BB%91%E5%AE%A2%E9%80%9A%E8%BF%87%E6%BC%8F%E6%B4%9E%E5%AE%8C%E6%88%90%E4%BA%86%E6%8F%90%E6%9D%83%E6%93%8D%E4%BD%9C%EF%BC%8C%E9%82%A3%E4%B9%88%E6%89%80%E6%9C%89%E7%9A%84%E8%BF%99%E4%BA%9B%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6%E5%B0%B1%E5%A4%B1%E6%95%88%E4%BA%86%E3%80%82%E6%89%80%E4%BB%A5NSA%E6%89%8D%E5%81%9A%E4%BA%86%E8%BF%99%E4%B9%88%E4%B8%80%E5%A5%97MAC%E6%9C%BA%E5%88%B6%E3%80%82%0A%3E%20MAC%E7%9A%84%E5%A4%84%E4%B8%96%E5%93%B2%E5%AD%A6%E9%9D%9E%E5%B8%B8%E7%AE%80%E5%8D%95%EF%BC%9A%E5%8D%B3%E4%BB%BB%E4%BD%95%E8%BF%9B%E7%A8%8B%E6%83%B3%E5%9C%A8SELinux%E7%B3%BB%E7%BB%9F%E4%B8%AD%E5%B9%B2%E4%BB%BB%E4%BD%95%E4%BA%8B%E6%83%85%EF%BC%8C%E9%83%BD%E5%BF%85%E9%A1%BB%E5%85%88%E5%9C%A8**%E5%AE%89%E5%85%A8%E7%AD%96%E7%95%A5%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6**%E4%B8%AD%E8%B5%8B%E4%BA%88%E6%9D%83%E9%99%90%E3%80%82%E5%87%A1%E6%98%AF%E6%B2%A1%E6%9C%89%E5%87%BA%E7%8E%B0%E5%9C%A8%E5%AE%89%E5%85%A8%E7%AD%96%E7%95%A5%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%9D%83%E9%99%90%EF%BC%8C%E8%BF%9B%E7%A8%8B%E5%B0%B1%E6%B2%A1%E6%9C%89%E8%AF%A5%E6%9D%83%E9%99%90%E3%80%82%5B1%5D%0A%0A%23%23%23%20TEAC%0ATEAC%20%3D%20Type%20Enforcement%20Accesc%20Control%EF%BC%8C%E7%AE%80%E7%A7%B0TE%E3%80%82%0A%3ELinux%E4%B8%AD%E6%9C%89%E4%B8%A4%E7%A7%8D%E4%B8%9C%E8%A5%BF%EF%BC%8C%E4%B8%80%E7%A7%8D%E6%AD%BB%E7%9A%84%EF%BC%88Inactive%EF%BC%89%EF%BC%8C%E4%B8%80%E7%A7%8D%E6%B4%BB%E7%9A%84%EF%BC%88Active%EF%BC%89%E3%80%82%E6%AD%BB%E7%9A%84%E4%B8%9C%E8%A5%BF%E5%B0%B1%E6%98%AF%E6%96%87%E4%BB%B6%EF%BC%88Linux%E5%93%B2%E5%AD%A6%EF%BC%8C%E4%B8%87%E7%89%A9%E7%9A%86%E6%96%87%E4%BB%B6%E3%80%82%E6%B3%A8%E6%84%8F%EF%BC%8C%E4%B8%87%E4%B8%8D%E5%8F%AF%E7%8B%AD%E4%B9%89%E8%A7%A3%E9%87%8A%E4%B8%BAFile%EF%BC%89%EF%BC%8C%E8%80%8C%E6%B4%BB%E7%9A%84%E4%B8%9C%E8%A5%BF%E5%B0%B1%E6%98%AF%E8%BF%9B%E7%A8%8B%E3%80%82%E6%AD%A4%E5%A4%84%E7%9A%84%E2%80%9C%E6%AD%BB%E2%80%9D%E5%92%8C%E2%80%9C%E6%B4%BB%E2%80%9D%E6%98%AF%E4%B8%80%E7%A7%8D%E6%AF%94%E5%96%BB%EF%BC%8C%E6%98%A0%E5%B0%84%E5%88%B0%E8%BD%AF%E4%BB%B6%E5%B1%82%E9%9D%A2%E7%9A%84%E6%84%8F%E6%80%9D%E6%98%AF%EF%BC%9A%E8%BF%9B%E7%A8%8B%E8%83%BD%E5%8F%91%E8%B5%B7%E5%8A%A8%E4%BD%9C%EF%BC%8C%E4%BE%8B%E5%A6%82%E5%AE%83%E8%83%BD%E6%89%93%E5%BC%80%E6%96%87%E4%BB%B6%E5%B9%B6%E6%93%8D%E4%BD%9C%E5%AE%83%E3%80%82%E8%80%8C%E6%96%87%E4%BB%B6%E5%8F%AA%E8%83%BD%E8%A2%AB%E8%BF%9B%E7%A8%8B%E6%93%8D%E4%BD%9C%E3%80%82%5B1%5D%0A%0A%E6%89%80%E8%B0%93%E7%9A%84TEAC%E5%B0%B1%E6%98%AF%E4%B8%A4%E4%B8%AA%E4%B8%9C%E8%A5%BF%E7%9A%84Type%E8%A6%81%E5%8C%B9%E9%85%8D%E4%B8%8A%E3%80%82Type%E6%98%AF%E5%95%A5%EF%BC%9F%0A%23%23%23%23%20%E8%BF%9B%E7%A8%8B%E7%9A%84Type%0A%E5%AF%B9%E4%BA%8E%E8%BF%9B%E7%A8%8B%EF%BC%8C%E7%9C%8B%E4%B8%80%E4%B8%8B%60ps%20-Z%60%E5%91%BD%E4%BB%A4%E7%9A%84%E8%BE%93%E5%87%BA%EF%BC%9A%0A%60%60%60%0ALABEL%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20USER%20%20%20%20%20%20%20%20%20%20%20PID%20%20PPID%20%20%20%20%20VSZ%20%20%20%20RSS%20WCHAN%0Au%3Ar%3Ashell%3As0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shell%20%20%20%20%20%20%20%20%203097%20%201427%20%20%20%205752%20%20%203024%20sigsuspe%2B%0Au%3Ar%3Ashell%3As0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shell%20%20%20%20%20%20%20%20%203100%20%203097%20%20%20%207320%20%20%203228%200%0A%60%60%60%0A%E4%B8%8A%E9%9D%A2%E7%9A%84%E5%91%BD%E4%BB%A4%E5%9C%A8Android%20adb%20shell%E4%B8%AD%E8%BF%90%E8%A1%8C%E8%BE%93%E5%87%BA%E3%80%82%E8%BF%99%E4%B8%AA%60u%3Ar%3Ashell%3As0%60%E5%B0%B1%E6%98%AF%E4%B8%80%E4%B8%AA%E8%BF%9B%E7%A8%8B%E7%9A%84%E6%A0%87%E7%AD%BE%EF%BC%8C%E5%85%B6%E4%B8%AD%EF%BC%9A%0A-%20u%3ASELinux%E5%AE%9A%E4%B9%89%E7%9A%84%E4%B8%80%E4%B8%AA%E7%94%A8%E6%88%B7%EF%BC%8C%E8%BF%99%E4%B8%AA%E7%94%A8%E6%88%B7%E4%B8%8D%E5%90%8C%E4%BA%8ELinux%E7%9A%84%E7%B3%BB%E7%BB%9F%E7%94%A8%E6%88%B7%EF%BC%8C%E5%85%B7%E4%BD%93%E5%8F%82%E7%9C%8B%E5%90%8E%E9%9D%A2%E7%9A%84%E7%94%A8%E6%88%B7%E4%B8%8E%E8%A7%92%E8%89%B2%E4%B8%80%E8%8A%82%E3%80%82%0A-%20r%3ASELinux%E5%AE%9A%E4%B9%89%E7%9A%84%E4%B8%80%E4%B8%AA%E8%A7%92%E8%89%B2%EF%BC%88role%EF%BC%89%EF%BC%8C%E5%9C%A8policy%E6%8F%8F%E8%BF%B0%E8%AF%AD%E8%A8%80%E4%B8%AD%EF%BC%8C%E5%8F%AF%E4%BB%A5%E7%94%A8%60role%60%E5%85%B3%E9%94%AE%E5%AD%97%E6%9D%A5%E5%AE%9A%E4%B9%89%0A-%20shell%3A%E5%B0%B1%E6%98%AF%E6%88%91%E4%BB%AC%E8%A6%81%E7%9A%84Type%E4%BA%86%EF%BC%8CSELinux%E4%B8%AD%E7%A7%B0%E4%B8%BADomain%EF%BC%8C%E5%9C%A8policy%E6%8F%8F%E8%BF%B0%E8%AF%AD%E8%A8%80%E4%B8%AD%EF%BC%8C%E5%8F%AF%E4%BB%A5%E7%94%A8%60type%60%E6%88%96%E8%80%85%60attribute%60%E5%85%B3%E9%94%AE%E5%AD%97%E6%9D%A5%E5%AE%9A%E4%B9%89%0A-%20s0%3A%E6%98%AF%E5%AE%89%E5%85%A8%E7%BA%A7%E5%88%AB%EF%BC%8CMLS%E4%BC%9A%E7%94%A8%E5%88%B0%E7%9A%84%E4%B8%9C%E8%A5%BF%0A%0A%3E**%E7%89%B9%E5%88%AB%E6%B3%A8%E6%84%8F**%EF%BC%9A%E5%AF%B9%E5%88%9D%E5%AD%A6%E8%80%85%E8%80%8C%E8%A8%80%EF%BC%8Cattribute%E5%92%8Ctype%E7%9A%84%E5%85%B3%E7%B3%BB%E6%9C%80%E9%9A%BE%E7%90%86%E8%A7%A3%EF%BC%8C%E5%9B%A0%E4%B8%BA%E2%80%9Cattribute%E2%80%9D%E8%BF%99%E4%B8%AA%E5%85%B3%E9%94%AE%E8%AF%8D%E5%AE%9E%E5%9C%A8%E6%98%AF%E6%B2%A1%E5%8F%96%E5%A5%BD%E5%90%8D%E5%AD%97%EF%BC%8C%E5%BE%88%E5%AE%B9%E6%98%93%E4%BA%A7%E7%94%9F%E8%AF%AF%E8%A7%A3%EF%BC%9A%0A%3E%0A%3E%E5%AE%9E%E9%99%85%E4%B8%8A%EF%BC%8C**type%E5%92%8Cattribute%E4%BD%8D%E4%BA%8E%E5%90%8C%E4%B8%80%E4%B8%AA%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4**%EF%BC%8C%E5%8D%B3%E4%B8%8D%E8%83%BD%E7%94%A8type%E5%91%BD%E4%BB%A4%E5%92%8Cattribute%E5%91%BD%E4%BB%A4%E5%AE%9A%E4%B9%89%E7%9B%B8%E5%90%8C%E5%90%8D%E5%AD%97%E7%9A%84%E4%B8%9C%E8%A5%BF%E3%80%82%0A%E5%85%B6%E5%AE%9E%EF%BC%8Cattribute%E7%9C%9F%E6%AD%A3%E7%9A%84%E6%84%8F%E6%80%9D%E5%BA%94%E8%AF%A5%E6%98%AF%E7%B1%BB%E4%BC%BCtype%EF%BC%88%E6%88%96domain%EF%BC%89%20group%E8%BF%99%E6%A0%B7%E7%9A%84%E6%A6%82%E5%BF%B5%E3%80%82%E6%AF%94%E5%A6%82%EF%BC%8C%E5%B0%86type%20A%E5%92%8Cattribute%20B%E5%85%B3%E8%81%94%E8%B5%B7%E6%9D%A5%EF%BC%8C%E5%B0%B1%E6%98%AF%E8%AF%B4type%20A%E5%B1%9E%E4%BA%8Egroup%20B%E4%B8%AD%E7%9A%84%E4%B8%80%E5%91%98%E3%80%82%0A%0A%23%23%23%23%20%E6%96%87%E4%BB%B6%E7%9A%84Type%0A%E5%AF%B9%E4%BA%8E%E6%96%87%E4%BB%B6%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%60ls%20-Z%60%E7%9A%84%E8%BE%93%E5%87%BA%EF%BC%9A%0A%60%60%60%0Au%3Aobject_r%3Acgroup%3As0%20%20%20%20%20%20%20%20%20%20%20acct%0Au%3Aobject_r%3Arootfs%3As0%20%20%20%20%20%20%20%20%20%20%20bugreports%0Au%3Aobject_r%3Acache_file%3As0%20%20%20%20%20%20%20cache%0Au%3Aobject_r%3Arootfs%3As0%20%20%20%20%20%20%20%20%20%20%20charger%0Au%3Aobject_r%3Aconfigfs%3As0%20%20%20%20%20%20%20%20%20config%0A%60%60%60%0A%60u%3Aobject_r%3Arootfs%3As0%60%E5%B0%B1%E6%98%AF%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84%E6%A0%87%E7%AD%BE%E3%80%82%E6%98%AF%E4%B8%8D%E6%98%AF%E5%92%8C%E8%BF%9B%E7%A8%8B%E7%9A%84%E9%9D%9E%E5%B8%B8%E7%B1%BB%E4%BC%BC%EF%BC%9F%0A-%20u%3A%20%E4%BB%A3%E8%A1%A8%E5%88%9B%E5%BB%BA%E8%BF%99%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84SELinux%20user%20ID%E3%80%82%E6%B3%A8%E6%84%8F%E6%98%AFSELinux%E5%AE%9A%E4%B9%89%E7%9A%84%E7%94%A8%E6%88%B7%EF%BC%8C%E5%B9%B6%E4%B8%8D%E7%9B%B4%E6%8E%A5%E5%AF%B9%E5%BA%94Linux%E7%9A%84%E7%94%A8%E6%88%B7%E7%B3%BB%E7%BB%9F%EF%BC%8C%E4%B8%A4%E8%80%85%E6%9C%89%E4%B8%80%E4%B8%AA%E6%98%A0%E5%B0%84%E5%85%B3%E7%B3%BB%0A-%20object_r%3A%20%E6%98%AF%E8%BF%99%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84role%EF%BC%8C%E6%89%80%E6%9C%89%E7%9A%84%E6%96%87%E4%BB%B6%E7%9A%84role%E9%83%BD%E6%98%AFobject_r%0A-%20rootfs%3A%20%E5%B0%B1%E6%98%AF%E8%BF%99%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84Type%0A-%20s0%3A%20%E5%92%8C%E8%BF%9B%E7%A8%8B%E4%B8%80%E6%A0%B7%EF%BC%8C%E8%BF%99%E4%B8%AA%E4%B9%9F%E6%98%AF%E5%AE%89%E5%85%A8%E7%BA%A7%E5%88%AB%EF%BC%8C%E7%94%A8%E4%BA%8EMLS%E7%9A%84%0A%0A%23%23%23%23%20%E5%A6%82%E4%BD%95%E5%85%B3%E8%81%94%E8%BF%99%E4%B8%A4%E4%B8%AAType%EF%BC%9F%0A%E5%BD%93%E6%AF%8F%E4%B8%80%E4%B8%AA%E8%BF%9B%E7%A8%8B%E5%92%8C%E6%AF%8F%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E6%9C%89%E4%BA%86Type%E4%B9%8B%E5%90%8E%EF%BC%8CSELinux%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%8C%B9%E9%85%8D%E4%B8%A4%E8%80%85%E4%B9%8B%E9%97%B4%E7%9A%84Type%E6%9D%A5%E9%89%B4%E6%9D%83%E3%80%82%E5%85%B7%E4%BD%93%E7%9A%84%E5%81%9A%E6%B3%95%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AFpolicy%E6%96%87%E4%BB%B6%E5%81%9A%E7%9A%84%E4%BA%8B%E6%83%85%E2%80%94%E2%80%94%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E3%80%82%E4%B8%8B%E9%9D%A2%E6%98%AF%E4%B8%80%E4%B8%AA%E8%A7%84%E5%88%99%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%60%60%60%0Aallow%20netd%20proc%3Afile%20write%0A%60%60%60%0A%E7%BF%BB%E8%AF%91%E6%88%90%E4%BA%BA%E7%B1%BB%E8%AF%AD%E8%A8%80%E5%B0%B1%E6%98%AF%EF%BC%9A%E5%85%81%E8%AE%B8netd%E7%B1%BB%E5%9E%8B%E7%9A%84process%EF%BC%8C%E4%BD%BF%E7%94%A8%EF%BC%88%E8%AE%BF%E9%97%AE%EF%BC%89type%E4%B8%BAproc%EF%BC%8Cclass%E4%B8%BAfile%E7%9A%84%E6%96%87%E4%BB%B6%E7%9A%84write%E6%93%8D%E4%BD%9C%E3%80%82%0A-%20allow%E6%98%AF%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E7%9A%84%E5%8A%A8%E8%AF%8D%EF%BC%8C%E7%B1%BB%E4%BC%BC%E7%9A%84%E8%BF%98%E6%9C%89allowaudit%E3%80%81dontaudit%E3%80%81neverallow%E7%AD%89%E3%80%82%0A-%20netd%E6%98%AF%E8%BF%9B%E7%A8%8B%E7%9A%84Type%0A-%20proc%E6%98%AF%E6%96%87%E4%BB%B6%E7%9A%84Type%0A-%20file%E6%98%AF%E6%96%87%E4%BB%B6%E7%9A%84class%EF%BC%8C%E5%9B%A0%E4%B8%BA%E4%B8%8D%E5%90%8Cclass%E7%9A%84%E6%96%87%E4%BB%B6%E6%9C%89%E4%B8%8D%E5%90%8C%E7%9A%84%E6%93%8D%E4%BD%9C%E7%B1%BB%E5%9E%8B%EF%BC%8C%E4%BE%8B%E5%A6%82socket%E6%96%87%E4%BB%B6%E5%92%8C%E6%99%AE%E9%80%9A%E6%96%87%E4%BB%B6%E8%82%AF%E5%AE%9A%E4%B8%8D%E5%90%8C%EF%BC%8C%E8%AE%BE%E5%A4%87%E6%96%87%E4%BB%B6%E5%92%8C%E6%99%AE%E9%80%9A%E6%96%87%E4%BB%B6%E4%B9%9F%E4%B8%80%E5%AE%9A%E4%B8%8D%E5%90%8C%E7%AD%89%E7%AD%89%E3%80%82class%E5%90%8Cpolicy%E8%AF%AD%E8%A8%80%E7%9A%84%E5%85%B6%E4%BB%96%E7%B1%BB%E5%9E%8B%E4%B8%80%E6%A0%B7%EF%BC%8C%E4%B9%9F%E5%8F%AF%E4%BB%A5%E5%9C%A8%E6%96%87%E4%BB%B6%E4%B8%AD%E5%AE%9A%E4%B9%89%EF%BC%8C%E5%85%B6%E4%BD%BF%E7%94%A8%E7%9A%84%E5%85%B3%E9%94%AE%E5%AD%97%E5%B0%B1%E6%98%AFclass%0A-%20write%E6%98%AF%E8%AF%A5%E8%A7%84%E5%88%99%E6%B6%89%E5%8F%8A%E7%9A%84%E6%9D%83%E9%99%90%E9%9B%86(PermSet)%EF%BC%8C%E5%AE%83%E5%8F%AF%E4%BB%A5%E4%B8%8D%E5%8F%AA%E4%B8%80%E4%B8%AA%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%98%AF%E5%A4%9A%E4%B8%AA%E6%9D%83%E9%99%90%EF%BC%8C%E5%88%99%E7%94%A8%E5%A4%A7%E6%8B%AC%E5%8F%B7%E5%8C%85%E8%B5%B7%E6%9D%A5%0A%0A%23%23%23%23%20%E6%80%BB%E7%BB%93%0A%E6%89%80%E4%BB%A5%EF%BC%8C%E6%95%B4%E4%B8%AATE%E7%9A%84%E6%A0%B8%E5%BF%83%E5%B0%B1%E6%98%AF%EF%BC%8C**%E5%AE%9A%E4%B9%89%E4%B8%80%E7%BB%84%E8%BF%9B%E7%A8%8BType%E5%92%8C%E6%96%87%E4%BB%B6Type%EF%BC%8C%E4%BB%A5%E5%8F%8A%E4%B8%80%E7%BB%84class%E5%92%8Cclass%20permset%EF%BC%8C%E7%84%B6%E5%90%8E%E7%94%A8%E8%A7%84%E5%88%99%E6%96%87%E4%BB%B6%E5%B0%86%E5%AE%83%E4%BB%AC%E5%85%B3%E8%81%94%E8%B5%B7%E6%9D%A5**%E3%80%82%0A%0A%3E%20%E5%8F%A6%E5%A4%96%E5%80%BC%E5%BE%97%E6%B3%A8%E6%84%8F%E7%9A%84%E6%98%AF%EF%BC%8CTEAC%E6%98%AF%E4%B8%80%E7%A7%8D%E7%99%BD%E5%90%8D%E5%8D%95%E6%9C%BA%E5%88%B6%EF%BC%8C%E5%8F%AA%E6%9C%89%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%9A%84%E6%9D%83%E9%99%90%E6%89%8D%E4%BC%9A%E7%94%9F%E6%95%88%EF%BC%8C%E5%90%A6%E5%88%99%E9%BB%98%E8%AE%A4%E6%98%AF%E6%B2%A1%E6%9C%89%E5%AF%B9%E5%BA%94%E7%9A%84%E6%9D%83%E9%99%90%E3%80%82%0A%3E%20%E9%82%A3%E4%B9%88%E9%97%AE%E9%A2%98%E6%9D%A5%E4%BA%86%EF%BC%8C%E6%97%A2%E7%84%B6%E6%98%AF%E7%99%BD%E5%90%8D%E5%8D%95%E6%9C%BA%E5%88%B6%EF%BC%8C%E9%82%A3%E4%B9%88neverallow%E6%9C%89%E5%95%A5%E7%94%A8%EF%BC%9F%0A%3E%20neverallow%E7%9A%84%E4%BD%9C%E7%94%A8%E6%98%AF%E4%B8%BA%E4%BA%86%E9%AA%8C%E8%AF%81allow%E5%AE%9A%E4%B9%89%E7%9A%84%E8%A7%84%E5%88%99%E6%98%AF%E5%90%A6%E5%AE%8C%E5%A4%87%EF%BC%8C%E5%BD%93%E4%BD%A0%E6%8C%89%E7%85%A7allow%E7%9A%84%E8%A1%A5%E9%9B%86%E5%AE%9A%E4%B9%89neverallow%E8%A7%84%E5%88%99%E6%97%B6%EF%BC%8C%E5%8F%91%E7%94%9F%E4%BA%86%E6%9D%83%E9%99%90%E9%94%99%E8%AF%AF%EF%BC%8C%E9%82%A3%E4%B9%88%E5%8F%AF%E4%BB%A5%E8%82%AF%E5%AE%9A%E7%9A%84%E6%98%AFallow%E8%A7%84%E5%88%99%E5%AE%9A%E4%B9%89%E5%87%BA%E4%BA%86%E9%97%AE%E9%A2%98%E3%80%82%0A%0A%23%23%23%20RBAC%0ARBAC%20%3D%20Role%20Based%20Access%20Control%2C%20%E6%98%AF%E5%AF%B9TE%E7%9A%84%E4%B8%80%E7%A7%8D%E8%A1%A5%E5%85%85%E3%80%82%E5%87%86%E7%A1%AE%E7%9A%84%E8%AF%B4%EF%BC%8C%E6%98%AF%E5%9C%A8TE%E4%B9%8B%E4%B8%8A%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%80%E5%B1%82%E7%BA%A6%E6%9D%9F%EF%BC%8C%E5%A2%9E%E5%BC%BA%E4%BA%86%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E5%AE%9A%E4%B9%89%E7%9A%84%E5%8F%AF%E6%93%8D%E4%BD%9C%E6%80%A7%EF%BC%8C%E5%90%8C%E6%97%B6%E6%8F%90%E4%BE%9B%E4%BA%86Linux%E7%B3%BB%E7%BB%9F%E7%94%A8%E6%88%B7%E7%9A%84%E6%9D%83%E9%99%90%E7%BA%A6%E6%9D%9F%E5%AE%9E%E7%8E%B0%E3%80%82%0A%3ESELinux%20%E5%B9%B6%E4%B8%8D%E7%9B%B4%E6%8E%A5%E5%BB%BA%E7%AB%8B%E7%94%A8%E6%88%B7%E5%92%8C%20domain%20%E4%B9%8B%E9%97%B4%E7%9A%84%E8%81%94%E7%B3%BB%EF%BC%8C%E8%80%8C%E6%98%AF%E9%80%9A%E8%BF%87%E8%A7%92%E8%89%B2%E4%BD%9C%E4%B8%BA%E6%A1%A5%E6%A2%81%E3%80%82%E6%AD%A4%E4%B8%BE%E5%A5%BD%E5%A4%84%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%3E%201.%20%E9%99%8D%E4%BD%8E%20policy%20%E5%A4%8D%E6%9D%82%E5%BA%A6%EF%BC%9A%E5%8F%AF%E8%83%BD%E6%9C%89%E4%B8%8A%E7%99%BE%E4%B8%AA%E7%94%A8%E6%88%B7%E5%92%8C%E4%B8%8A%E5%8D%83%E7%A7%8D%20domain%2Ftype%EF%BC%8C%E4%BD%86%E6%98%AF%E4%B8%8D%E5%90%8C%E7%94%A8%E6%88%B7%E6%89%80%E6%89%AE%E6%BC%94%E7%9A%84%E4%B8%8D%E5%90%8C%E8%A7%92%E8%89%B2%E5%8F%AA%E6%9C%89%20%E6%9C%89%E9%99%90%E5%87%A0%E4%B8%AA%EF%BC%9Brole%20%E4%BD%9C%E4%B8%BA%20user%20%E5%92%8C%20type%20%E4%B9%8B%E9%97%B4%E7%9A%84%E2%80%9C%E4%B8%AD%E9%97%B4%E5%B1%82%E2%80%9D%EF%BC%8C%E4%BE%BF%E4%BA%8E%E9%99%90%E5%88%B6%20user%20%E7%9A%84%E8%83%BD%E5%8A%9B%EF%BC%9B%20%0A%3E%202.%20%E7%BB%99%E4%B8%8D%E5%90%8C%E7%94%A8%E6%88%B7%E8%B5%8B%E4%BA%88%E4%B8%8D%E5%90%8C%E7%9A%84%E4%BC%98%E5%85%88%E7%BA%A7%EF%BC%9A%E7%94%A8%E6%88%B7%E9%80%9A%E8%BF%87%E6%89%AE%E6%BC%94%E6%9F%90%E7%A7%8D%E8%A7%92%E8%89%B2%E6%89%8D%E8%83%BD%E8%8E%B7%E5%BE%97%E9%82%A3%E7%A7%8D%E8%A7%92%E8%89%B2%E7%9A%84%E8%83%BD%E5%8A%9B%E3%80%82%E7%89%B9%E6%9D%83%E8%A7%92%E8%89%B2%E5%8F%AA%E8%83%BD%E7%94%B1%E7%89%B9%20%E6%9D%83%E7%94%A8%E6%88%B7%E6%9D%A5%E6%89%AE%E6%BC%94%EF%BC%9B%5B4%5D%0A%0A%E7%BF%BB%E8%AF%91%E4%B8%80%E4%B8%8B%EF%BC%8C%E6%88%91%E7%9A%84%E7%90%86%E8%A7%A3%E6%98%AF%EF%BC%9A%0A%E6%88%91%E4%BB%AC%E7%9F%A5%E9%81%93TE%E6%98%AFSELinux%20MAC%E7%9A%84%E6%A0%B8%E5%BF%83%EF%BC%8CTE%E9%80%9A%E8%BF%87%E6%AF%94%E5%AF%B9object%20type%E5%92%8Cprocess%20type%E6%9D%A5%E5%86%B3%E5%AE%9Aprocess%E6%98%AF%E5%90%A6%E6%9C%89%E6%9D%83%E9%99%90%E4%BD%BF%E7%94%A8%E8%BF%99%E4%B8%AAobject%E3%80%82%E4%B8%80%E6%9D%A1TE%E8%A7%84%E5%88%99%E7%BB%91%E5%AE%9A%E4%BA%86%E8%BF%99%E4%B8%A4%E8%80%85%E3%80%82%E5%81%87%E5%A6%82%E7%B3%BB%E7%BB%9F%E6%9C%89M%E4%B8%AAProcess%EF%BC%8CN%E4%B8%AAObject%EF%BC%8C%E9%82%A3%E6%98%AF%E4%B8%8D%E6%98%AF%E7%B3%BB%E7%BB%9F%E7%9A%84%E8%A7%84%E5%88%99%E6%95%B0%E5%B0%B1%E6%98%AFM%5C*N%E4%B8%AA%EF%BC%9F(M%E5%92%8CN%E5%8F%AF%E8%83%BD%E6%98%AF%E5%BE%88%E5%A4%A7%E7%9A%84%E6%95%B0%E5%93%A6)%0A%E7%AD%94%E6%A1%88%E6%98%AF%3A**%E8%A7%84%E5%88%99%E6%95%B0%E5%B9%B6%E4%B8%8D%E7%AD%89%E4%BA%8EM%5C*N**%E3%80%82%E5%90%A6%E5%88%99%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E8%A6%81%E5%86%99%E7%9A%84%E7%B4%AF%E6%AD%BB%E3%80%82%0A%E8%A7%A3%E5%86%B3%E7%9A%84%E6%96%B9%E6%B3%95%E5%B0%B1%E6%98%AF%E5%AE%9A%E4%B9%89role%EF%BC%8C%E4%B8%80%E4%B8%AArole%E5%B0%B1%E5%AF%B9%E5%BA%94%E4%BA%86%E8%8B%A5%E5%B9%B2%E4%B8%AAtype%EF%BC%8C%E5%9C%A8%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E4%B8%AD%E9%80%9A%E8%BF%87role%E5%85%B3%E9%94%AE%E5%AD%97%E5%AE%8C%E6%88%90role%E5%92%8Ctype%E7%9A%84%E7%BB%91%E5%AE%9A%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%9A%0A%60%60%60%0Arole%20user_r%20types%20user_t%3B%0Arole%20user_r%20types%20passwd_t%3B%0A%60%60%60%0Auser_r%E8%BF%99%E4%B8%AArole%E4%B8%80%E4%B8%8B%E5%AF%B9%E5%BA%94%E4%BA%86%E4%B8%A4%E4%B8%AAtype%EF%BC%8C%E5%88%86%E5%88%AB%E6%98%AFuser_t%E5%92%8Cpasswd_t%0A%60%60%60%0Auser%20joe%20roles%20%7B%20user_r%20%7D%3B%0A%60%60%60%0A%E8%BF%99%E6%9D%A1%E8%AF%AD%E5%8F%A5%E5%B0%B1%E7%BB%91%E5%AE%9A%E4%BA%86user%20joe%E5%92%8Crole%20user_r%E3%80%82%E9%82%A3%E4%B9%88%E5%BD%93joe%E6%98%AFuser_r%20role%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E5%B0%B1%E5%85%B7%E5%A4%87%E4%BA%86user_t%E5%92%8Cpasswd_t%E7%9A%84%E6%A0%87%E7%AD%BE%EF%BC%8C%E9%82%A3%E4%B9%88joe%E5%B0%B1%E8%83%BD%E8%AE%BF%E9%97%AE%E5%AE%9A%E4%B9%89%E4%BA%86user_t%E5%92%8Cpasswd_t%E7%9A%84TE%E8%A7%84%E5%88%99%EF%BC%8C%E6%89%80%E6%8C%87%E5%AE%9A%E7%9A%84%E8%B5%84%E6%BA%90%EF%BC%88object%EF%BC%89%E3%80%82%0A%0A%3E%20%E8%A7%92%E8%89%B2%E6%98%AF%E4%B8%80%E5%A5%97Type%EF%BC%88%E8%BF%9B%E7%A8%8B%E7%9A%84Type%E5%8F%88%E7%A7%B0%E4%B8%BA%E5%9F%9FDomain%EF%BC%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%9B%86%E5%90%88%0A%0A%E7%9F%A5%E9%81%93%E4%BA%86%E8%BF%99%E5%B1%82%E5%85%B3%E7%B3%BB%EF%BC%8C%E9%82%A3%E4%B9%88%E5%B0%B1%E5%8F%AF%E4%BB%A5%E7%90%86%E8%A7%A3role%E7%9A%84%E6%93%8D%E4%BD%9C%EF%BC%8C%E5%8C%85%E6%8B%AC%EF%BC%9A%0A-%20%E8%A7%92%E8%89%B2%E8%BD%AC%E6%8D%A2role_transition%0A-%20%E8%A7%92%E8%89%B2%E6%8E%A7%E5%88%B6role_dominance%0A%0A%23%23%23%23%20%E7%94%A8%E6%88%B7%E4%B8%8E%E8%A7%92%E8%89%B2%0ASELinux%E6%9C%89%E4%B8%80%E5%A5%97%E7%94%A8%E6%88%B7%E7%B3%BB%E7%BB%9F%EF%BC%8CLinux%E7%B3%BB%E7%BB%9F%E4%B9%9F%E6%9C%89%E4%B8%80%E5%A5%97%E7%94%A8%E6%88%B7%E7%B3%BB%E7%BB%9F%E3%80%82%E5%AE%83%E4%BB%AC%E4%B9%8B%E9%97%B4%E6%9C%89%E4%BB%80%E4%B9%88%E5%85%B3%E7%B3%BB%EF%BC%9F%E9%A6%96%E5%85%88%E5%8F%AF%E4%BB%A5%E7%A1%AE%E5%AE%9A%E7%9A%84%E6%98%AF%EF%BC%8C%E5%AE%83%E4%BB%AC%E4%B8%8D%E6%98%AF%E7%9B%B4%E6%8E%A5%E7%AD%89%E4%BB%B7%E7%9A%84%E3%80%82%E4%BE%8B%E5%A6%82%2C%20%E4%BB%A5root%E7%94%A8%E6%88%B7%E5%90%AF%E5%8A%A8Browser%EF%BC%8C%E9%82%A3%E4%B9%88Browser%E5%B0%B1%E6%9C%89root%E7%94%A8%E6%88%B7%E7%9A%84%E6%9D%83%E9%99%90%EF%BC%8C%E5%9C%A8Linux%E7%B3%BB%E7%BB%9F%E4%B8%8A%E8%83%BD%E5%B9%B2%E4%BB%BB%E4%BD%95%E4%BA%8B%E6%83%85%E3%80%82%E8%80%8Croot%E5%9C%A8SELinux%E4%B8%AD%E5%8F%AF%E8%83%BD%E5%B0%B1%E6%98%AF%E4%B8%80%E4%B8%AA%E6%B2%A1%E6%9D%83%E9%99%90%EF%BC%8C%E6%B2%A1%E5%9C%B0%E4%BD%8D%EF%BC%8C%E6%89%93%E6%89%93%E9%85%B1%E6%B2%B9%E7%9A%84%E2%80%9D%E8%B7%AF%E4%BA%BA%E7%94%B2%E2%80%9C%E3%80%82%E5%BD%93%E7%84%B6%EF%BC%8C%E8%BF%99%E4%B8%80%E5%88%87%E9%83%BD%E7%94%B1SELinux%E5%AE%89%E5%85%A8%E7%AD%96%E7%95%A5%E7%9A%84%E5%88%B6%E5%AE%9A%E8%80%85%E6%9D%A5%E5%86%B3%E5%AE%9A%E3%80%82%0ASELinux%E7%94%A8%E6%88%B7%E5%92%8CLinux%E7%B3%BB%E7%BB%9F%E7%94%A8%E6%88%B7%E7%9A%84%E6%98%A0%E5%B0%84%E5%85%B3%E7%B3%BB%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87semanage%E5%B7%A5%E5%85%B7%E6%9D%A5%E6%9F%A5%E7%9C%8B%EF%BC%9A%0A%60%60%60%0A%5Broot%40zion%20~%5D%23%20semanage%20login%20-l%0A%0ALogin%20Name%20%20%20%20%20%20%20%20%20%20%20SELinux%20User%20%20%20%20%20%20%20%20%20MLS%2FMCS%20Range%20%20%20%20%20%20%20%20Service%0A%0A__default__%20%20%20%20%20%20%20%20%20%20unconfined_u%20%20%20%20%20%20%20%20%20s0-s0%3Ac0.c1023%20%20%20%20%20%20%20*%0Aroot%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20unconfined_u%20%20%20%20%20%20%20%20%20s0-s0%3Ac0.c1023%20%20%20%20%20%20%20*%0Asystem_u%20%20%20%20%20%20%20%20%20%20%20%20%20system_u%20%20%20%20%20%20%20%20%20%20%20%20%20s0-s0%3Ac0.c1023%20%20%20%20%20%20%20*%0A%60%60%60%0A%E5%BD%93%E4%B8%80%E4%B8%AA%E6%99%AE%E9%80%9A%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95%E6%97%B6%EF%BC%8C%E5%85%B6%E6%98%A0%E5%B0%84%E5%88%B0SELinux%E8%BF%87%E7%A8%8B%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%5B5%5D%E7%9A%84%E4%BB%8B%E7%BB%8D%E3%80%82%E5%A4%A7%E8%87%B4%E6%B5%81%E7%A8%8B%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60mermaid%0Agraph%20TD%0AA%5BLinux%E7%B3%BB%E7%BB%9F%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95%5D%0AA%20--%3E%20B%7B%22%E7%B3%BB%E7%BB%9F%E6%96%87%E4%BB%B6%E6%98%AF%E5%90%A6%E6%8F%8F%E8%BF%B0%E4%BA%86%E7%94%A8%E6%88%B7%E9%97%B4%E7%9A%84%E6%98%A0%E5%B0%84%E5%85%B3%E7%B3%BB%EF%BC%9F%22%7D%0AB%20--%3E%20%7CN%7C%20C%5B%22%E7%94%A8%E6%88%B7%E6%98%A0%E5%B0%84%E4%B8%BA__default__%22%5D%0AB%20--%3E%20%7CY%7C%20D%5B%22%E7%94%A8%E6%88%B7%E7%9B%B4%E6%8E%A5%E6%98%A0%E5%B0%84%E5%88%B0SELinux%E7%94%A8%E6%88%B7%22%5D%0AC%20--%3E%20E%5B%22__default__%E7%94%A8%E6%88%B7%E8%A2%AB%E6%98%A0%E5%B0%84%E4%B8%BAunconfined_u%22%5D%0A%60%60%60%0A%E4%B8%8A%E9%9D%A2%E6%8F%90%E5%88%B0%E7%9A%84%E7%B3%BB%E7%BB%9F%E6%96%87%E4%BB%B6%E4%B8%BA%60%2Fetc%2Fselinux%2Fspecified-policy%2Fseusers%60%E3%80%82%0A%E9%80%9A%E8%BF%87%E4%B8%8A%E9%9D%A2%E7%9A%84%E6%B5%81%E7%A8%8B%E4%B9%9F%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%87%BA%EF%BC%8CSELinux%E7%9A%84%E7%AD%96%E7%95%A5%E6%96%87%E4%BB%B6%E5%B9%B6%E6%B2%A1%E6%9C%89%E4%B8%93%E9%97%A8%E5%AE%9A%E4%B9%89%E6%9C%89%E5%93%AA%E4%BA%9BSELinux%E7%94%A8%E6%88%B7%EF%BC%8C%E8%80%8C%E6%98%AF%E9%80%9A%E8%BF%87seusers%E6%96%87%E4%BB%B6%E4%B8%AD%E6%8F%8F%E8%BF%B0%E7%9A%84%E6%98%A0%E5%B0%84%E5%85%B3%E7%B3%BB%E6%9D%A5%E8%A1%A8%E6%98%8E%E6%9C%89%E5%93%AA%E4%BA%9BSELinux%E7%94%A8%E6%88%B7%E3%80%82%E7%94%A8%E6%88%B7%E5%86%8D%E9%80%9A%E8%BF%87role%E6%98%A0%E5%B0%84%E5%88%B0type%EF%BC%8C%E6%9C%80%E5%90%8E%E9%80%9A%E8%BF%87TE%E7%B3%BB%E7%BB%9F%E6%9D%A5%E7%A1%AE%E5%AE%9A%E6%9D%83%E9%99%90%E5%85%B3%E7%B3%BB%E3%80%82%E5%A4%A7%E8%87%B4%E5%85%B3%E7%B3%BB%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60mermaid%0Agraph%20LR%3B%0AA%5B%22Linux%E7%B3%BB%E7%BB%9F%E7%94%A8%E6%88%B7%22%5D%20--%3E%20B%5B%22SELinux%E7%94%A8%E6%88%B7%22%5D%0AB%20--%3E%20C%5B%22role(s)%22%5D%0AC%20--%3E%20D%5B%22type(s)%22%5D%0AD%20--%3E%20%7C%22TE%E6%9D%83%E9%99%90%E6%A3%80%E6%9F%A5%22%7C%20E%5B%22object%20type(s)%22%5D%0A%60%60%60%0A%23%23%23%23%20constrain%0A%E5%89%8D%E9%9D%A2%E8%AE%B2%E4%BA%86RBAC%E4%B8%8ETE%E7%BB%93%E5%90%88%E6%8F%90%E4%BE%9B%E7%9A%84%E6%9D%83%E9%99%90%E6%A3%80%E6%9F%A5%EF%BC%8CRBAC%E8%BF%98%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%80%E7%A7%8D%E7%9B%B4%E6%8E%A5%E7%9A%84user%2Frole%E6%9D%83%E9%99%90%E6%A3%80%E6%9F%A5%E6%96%B9%E6%B3%95%EF%BC%8C%E6%88%90%E4%B8%BAconstrain%E3%80%82%E4%B8%BE%E4%B8%AA%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%60%60%60bash%0A%23%20%E6%A0%87%E5%87%86%E6%A0%BC%E5%BC%8F%EF%BC%9Aconstrain%20%3Cobject_class_set%3E%20%3Cperm_set%3E%20%3Cexpression%3E%20%3B%0Aconstrain%20file%20write%20(u1%20%3D%3D%20u2%20and%20r1%20%3D%3D%20r2)%20%3B%0A%60%60%60%0A%E9%99%90%E5%88%B6%E5%8F%AA%E6%9C%89%E6%96%87%E4%BB%B6%E7%9A%84%E5%88%9B%E5%BB%BA%E8%80%85user%2Frole%E4%B8%8E%E8%BF%9B%E7%A8%8Buser%2Frole%E7%9B%B8%E7%AD%89%E6%97%B6%EF%BC%8C%E6%89%8D%E5%8F%AF%E4%BB%A5%E5%AF%B9%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E5%86%99%E6%93%8D%E4%BD%9C%E3%80%82%E6%B3%A8%E6%84%8F%E8%BF%99%E9%87%8C%E6%98%AFobject%20class%EF%BC%8C%E6%8E%A7%E5%88%B6%E7%9A%84%E6%98%AF%E4%B8%80%E7%B1%BB%E8%B5%84%E6%BA%90%EF%BC%8C%E8%80%8C%E4%B8%8D%E6%98%AF%E5%85%B7%E4%BD%93%E5%93%AA%E4%B8%80%E4%B8%AAobject%E3%80%82%0A%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E7%9A%84%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97%E7%AC%A6%E6%9C%89%EF%BC%9A%0A-%20%3D%3D%2C%20!%3D%EF%BC%9Auser%2Frole%E9%83%BD%E5%8F%AF%E7%94%A8%0A-%20%E4%BB%85%E9%92%88%E5%AF%B9role%E7%9A%84eq%2C%20dom%2C%20domby%2C%20incomp%0A%23%23%23%23%20%E6%80%BB%E7%BB%93%0A%60%60%60mermaid%0Agraph%20TD%3B%0AA%5B%22Linux%E7%94%A8%E6%88%B71%22%5D%20--%3E%20B%5B%22RBAC%22%5D%0AC%5B%22Linux%E7%94%A8%E6%88%B72%22%5D%20--%3E%20B%0AD%5B%22Linux%E7%94%A8%E6%88%B73%22%5D%20--%3E%20B%0AB%20--%3E%20%7Cuser%2C%20role%7C%20E%5B%22process%20type(s)%22%5D%0AE%20--%3E%20%7CTEAC%20%26%20constrain%7C%20G%5B%22object%20type(s)%22%5D%0A%60%60%60%0A%23%23%23%20MLS%2FMCS%0AMLS%E4%BB%8ELinux%202.6.12%E5%BC%80%E5%A7%8B%E8%BF%9B%E5%85%A5Linux%E5%86%85%E6%A0%B8%EF%BC%8C%E8%80%8CSELinux%E5%A4%A7%E7%BA%A6%E6%98%AF2.6.0%E5%BC%80%E5%A7%8B%E8%BF%9B%E5%85%A5%E5%86%85%E6%A0%B8%E3%80%82MLS%E4%B8%8E%E5%8E%9F%E5%A7%8B%E7%9A%84SELinux%E6%94%AF%E6%8C%81%E7%9A%84TE%2C%20RBAC%E9%89%B4%E6%9D%83%E6%89%8B%E6%AE%B5%E6%98%AF%E4%B8%80%E7%A7%8D%E4%BA%92%E8%A1%A5%E3%80%82%E5%85%B7%E4%BD%93%E5%8F%AF%E4%BB%A5%E9%98%85%E8%AF%BB%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%5B7%5D%E3%80%82%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E6%9D%A5%E8%87%AATrusted%20Computer%20Solutions%2C%20Inc.%EF%BC%88TCS%EF%BC%89%E8%BF%99%E5%AE%B6%E5%85%AC%E5%8F%B8%EF%BC%8C%E6%98%AFLinux%E5%86%85%E6%A0%B8MLS%E6%A8%A1%E5%9D%97%E4%B8%BB%E8%A6%81%E7%9A%84%E8%AE%BE%E8%AE%A1%E8%80%85%E3%80%82%E6%96%87%E7%AB%A0%E5%86%99%E4%BA%8E2006%E5%B9%B4%EF%BC%8C%E4%BC%B0%E8%AE%A1%E6%98%AFMLS%E5%90%88%E5%85%A5%E5%86%85%E6%A0%B8%E4%B8%8D%E4%B9%85%E3%80%82%0A%3EA%20combination%20of%20MLS%20and%20TE%20creates%20a%20stronger%2C%20more%20functional%20system%20that%20benefits%20from%20the%20strengths%20of%20the%20two%20complementary%20models.%0A%3E**MLS**%20models%20do%20not%20lend%20themselves%20easily%20to%20static%20analysis.%0A%3E**TE**%20has%20deficiencies%20in%20handling%20a%20large%20number%20of%20labels%20or%20a%20dynamic%20work%20set%20of%20label%20names%2C%20especially%20in%20contrast%20to%20integrity%20concerns.%0A%0A%E7%8E%B0%E5%9C%A8%E7%9A%84MLS%E5%80%9F%E5%8A%A9%E4%BA%86RBAC%E5%AE%9A%E4%B9%89%E7%9A%84constrain%E6%9C%BA%E5%88%B6%EF%BC%8C%E6%89%A9%E5%B1%95%E4%BA%86constrain%E8%AF%AD%E6%B3%95%EF%BC%8C%E5%AE%9A%E4%B9%89%E4%BA%86%E6%89%80%E8%B0%93%E7%9A%84mlsconstrain%E8%AF%AD%E6%B3%95%E8%A7%84%E5%88%99%E3%80%82%E4%B8%BASELinux%E6%8F%90%E4%BE%9B%E4%BA%86%E5%9F%BA%E4%BA%8EClassification%EF%BC%88Sensitivity%20Level%EF%BC%89%E5%92%8CCompartment%EF%BC%88Category%EF%BC%89%E8%AF%AD%E6%84%8F%E7%9A%84%E6%9D%83%E9%99%90%E6%A3%80%E6%9F%A5%E3%80%82%0AMLS%E6%98%AF%E5%8E%9F%E5%A7%8BSELinux%E7%9A%84%E6%89%A9%E5%B1%95%EF%BC%8C%E6%89%80%E4%BB%A5%E5%9C%A8%E4%BD%BF%E8%83%BDSELinux%E7%9A%84%E6%97%B6%E5%80%99%E4%B9%9F%E6%98%AF%E5%8F%AF%E9%80%89%E7%9A%84%E3%80%82%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%89%E6%8B%A9%E5%B8%A6MLS%E7%9A%84SELinux%EF%BC%8C%E4%B9%9F%E5%8F%AF%E4%BB%A5%E9%80%89%E6%8B%A9%E4%B8%8D%E5%B8%A6MLS%E7%9A%84SELinux%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8C%E5%9C%A8Fedora%E4%B8%8B%E7%9A%84%E6%AD%A5%E9%AA%A4%E5%A6%82%E4%B8%8B%EF%BC%9A%0A1.%20Install%20SELinux%20package%0A%60%60%60bash%0Adnf%20install%20selinux-policy-mls%0A%60%60%60%0A2.%20Configure%20%60%2Fetc%2Fselinux%2Fconfig%60%0A%60%60%60bash%0A%23%20This%20file%20controls%20the%20state%20of%20SELinux%20on%20the%20system.%0A%23%20SELINUX%3D%20can%20take%20one%20of%20these%20three%20values%3A%0A%23%20%20%20%20%20%20%20enforcing%20-%20SELinux%20security%20policy%20is%20enforced.%0A%23%20%20%20%20%20%20%20permissive%20-%20SELinux%20prints%20warnings%20instead%20of%20enforcing.%0A%23%20%20%20%20%20%20%20disabled%20-%20No%20SELinux%20policy%20is%20loaded.%0ASELINUX%3Dpermissive%0A%23%20SELINUXTYPE%3D%20can%20take%20one%20of%20these%20two%20values%3A%0A%23%20%20%20%20%20%20%20targeted%20-%20Targeted%20processes%20are%20protected%2C%0A%23%20%20%20%20%20%20%20mls%20-%20Multi%20Level%20Security%20protection.%0ASELINUXTYPE%3Dmls%0A%60%60%60%0A%23%23%23%23%20%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5%0AMLS%E7%9A%84%E6%A0%B8%E5%BF%83%E7%90%86%E5%BF%B5%E7%94%B1%E4%B8%8B%E5%9B%BE%E9%98%90%E9%87%8A%E4%BA%86%E3%80%82%0A%0A!%5B445184ec51cafa947460ef50a7b311dc.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6228)%0A%3E%E5%BC%95%E7%94%A8%5B2%5D%E4%B8%AD%E7%9A%84%E4%B8%80%E6%AE%B5%E8%AF%9D%EF%BC%9A%0A%3E%0A%3EMLS%E5%9C%A8%E5%AE%89%E5%85%A8%E7%AD%96%E7%95%A5%E4%B8%8A%E6%9C%89%E4%B8%80%E4%B8%AA%E5%BD%A2%E8%B1%A1%E7%9A%84%E6%8F%8F%E8%BF%B0%E5%8F%ABno%20write%20down%E5%92%8Cno%20read%20up%EF%BC%9A%0A%3E%0A%3E-%20%E9%AB%98%E7%BA%A7%E5%88%AB%E7%9A%84%E4%B8%9C%E8%A5%BF%E4%B8%8D%E8%83%BD%E5%BE%80%E4%BD%8E%E7%BA%A7%E5%88%AB%E7%9A%84%E4%B8%9C%E8%A5%BF%E9%87%8C%E8%BE%B9%E5%86%99%E6%95%B0%E6%8D%AE%EF%BC%9A%E8%BF%99%E6%A0%B7%E5%8F%AF%E8%83%BD%E5%AF%BC%E8%87%B4%E9%AB%98%E7%BA%A7%E5%88%AB%E7%9A%84%E6%95%B0%E6%8D%AE%E6%B3%84%E9%9C%B2%E5%88%B0%E4%BD%8E%E7%BA%A7%E5%88%AB%E4%B8%AD%E3%80%82%0A%3E-%20%E9%AB%98%E7%BA%A7%E5%88%AB%E7%9A%84%E4%B8%9C%E8%A5%BF%E5%8F%AA%E8%83%BD%E4%BB%8E%E4%BD%8E%E7%BA%A7%E5%88%AB%E7%9A%84%E4%B8%9C%E8%A5%BF%E9%87%8C%E8%BE%B9%E8%AF%BB%E6%95%B0%E6%8D%AE%0A%3E%0A%3E%E5%A6%82%E5%9B%BE4%E4%B8%AD%EF%BC%8CProcess%E7%9A%84%E7%BA%A7%E5%88%AB%E6%98%AFConfidential%EF%BC%8C%E5%AE%83%E5%8F%AF%E4%BB%A5%E5%BE%80%E5%90%8C%E7%BA%A7%E5%88%AB%E7%9A%84File%20B%E4%B8%AD%E8%AF%BB%E5%86%99%E6%95%B0%E6%8D%AE%EF%BC%8C%E4%BD%86%E6%98%AF%E5%8F%AA%E8%83%BD%E5%BE%80%E9%AB%98%E7%BA%A7%E5%88%AB%E7%9A%84File%20A(%E7%BA%A7%E5%88%AB%E6%98%AFSecret)%E9%87%8C%E8%BE%B9%E5%86%99%E4%B8%9C%E8%A5%BF%E3%80%82Process%E5%8F%AF%E4%BB%A5%E4%BB%8EFile%20C%E5%92%8CFile%20D%E4%B8%AD%E8%AF%BB%E6%95%B0%E6%8D%AE%EF%BC%8C%E4%BD%86%E6%98%AF%E4%B8%8D%E8%83%BD%E5%BE%80File%20C%E5%92%8CFile%20D%E4%B8%8A%E5%86%99%E6%95%B0%E6%8D%AE%E3%80%82%0A%3E%0A%3E%E5%8F%8D%E8%BF%87%E6%9D%A5%E8%AF%B4%EF%BC%9A%0A%3E%0A%3E-%20%E4%BD%8E%E7%BA%A7%E5%88%AB%E7%9A%84%E4%B8%9C%E8%A5%BF%E5%8F%AA%E8%83%BD%E5%BE%80%E9%AB%98%E7%BA%A7%E5%88%AB%E7%9A%84%E4%B8%9C%E8%A5%BF%E9%87%8C%E8%BE%B9%E5%86%99%E6%95%B0%E6%8D%AE%0A%3E-%20%E4%BD%8E%E7%BA%A7%E5%88%AB%E7%9A%84%E4%B8%9C%E8%A5%BF%E4%B8%8D%E8%83%BD%E4%BB%8E%E9%AB%98%E7%BA%A7%E5%88%AB%E7%9A%84%E4%B8%9C%E8%A5%BF%E9%82%A3%E8%BE%B9%E8%AF%BB%E6%95%B0%E6%8D%AE%0A%3E%0A%3E%E6%B3%A8%EF%BC%9A%E8%BF%99%E9%87%8C%E5%8F%AA%E8%80%83%E8%99%91%E6%B3%84%E4%B8%8D%E6%B3%84%E5%AF%86%EF%BC%8C%E4%B8%8D%E8%80%83%E8%99%91%E6%BA%A2%E5%87%BA%E6%94%BB%E5%87%BB%0A%0A%23%23%23%23%20%E5%AE%9E%E7%8E%B0MLS%E7%9A%84%E5%85%B7%E4%BD%93%E6%89%8B%E6%AE%B5%0A%E4%B8%BB%E8%A6%81%E5%B0%B1%E6%98%AF%E5%9C%A8TE%EF%BC%8CRBAC%E7%9A%84secure%20context%E4%B9%8B%E4%B8%8A%EF%BC%8C%E5%8A%A0%E4%BA%86sensitivity%E5%92%8Ccategory%E4%B8%A4%E4%B8%AA%E5%AD%97%E6%AE%B5%E3%80%82%E4%BD%BF%E8%83%BD%E4%BA%86MLS%E7%9A%84secure%20context%EF%BC%8C%E6%A0%BC%E5%BC%8F%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60%0Auser%3Arole%3Atype%3Asensitivity%5B%3Acategory%2C...%5D-%20sensitivity%20%5B%3Acategory%2C...%5D%0A%60%60%60%0A%E4%B8%BE%E4%B8%AA%E5%AE%9E%E9%99%85%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%60%60%60%0Auser_u%3Arole_r%3Atype_t%3As0-s1%3Ac0%2Cc1-c255%0A%60%60%60%0As0%20--%20%E6%9C%80%E4%BD%8Esensitivity%0As1%3Ac0%2Cc1-c255%20--%20%E6%9C%80%E9%AB%98sensitivity%0A%3E%E6%B3%A8%EF%BC%9As0%E5%95%A5%E9%83%BD%E4%B8%8D%E5%B8%A6%E4%BB%A3%E8%A1%A8%0A%3Es0%20is%20the%20lowest%20classification%20and%20contains%20no%20compartments%2C%20thus%20dominated%20by%20every%20label%20on%20the%20system.%0A%0A%E9%82%A3%E4%B9%88%E6%80%8E%E4%B9%88%E5%88%A9%E7%94%A8%E8%BF%99%E7%BB%84%E6%A0%87%E7%AD%BE%EF%BC%9FMLS%E5%BC%95%E5%85%A5%E4%BA%86%E6%89%A9%E5%B1%95%E7%9A%84constrain%E8%AF%AD%E6%B3%95%EF%BC%8C%E7%A7%B0%E4%B8%BAmlsconstrain%EF%BC%8C%E6%A0%BC%E5%BC%8F%E4%B8%BA%EF%BC%9A%0A%60%60%60%0Amlsconstrain%20class%20perm_set%20expression%3B%0A%60%60%60%0A%E5%AF%B9%E6%AF%94constrain%E8%AF%AD%E6%B3%95%EF%BC%9A%0A%60%60%60%0Aconstrain%20object_class_set%20perm_set%20expression%3B%0A%60%60%60%0A%E4%B8%80%E6%A0%B7%E5%95%8A%EF%BC%8C%E6%B2%A1%E6%9C%89%E5%8C%BA%E5%88%AB%E5%95%8A%EF%BC%81%E5%8C%BA%E5%88%AB%E5%9C%A8%E4%BA%8Eexpression%E3%80%82MLS%E7%9A%84expression%E5%A4%9A%E4%BA%86%E4%B8%8B%E9%9D%A2%E5%87%A0%E4%B8%AA%E4%B8%9C%E8%A5%BF%EF%BC%9A%0A%3E-%20l1%2C%20l2%EF%BC%9A%E5%B0%8F%E5%86%99%E7%9A%84L%E3%80%82l1%E8%A1%A8%E7%A4%BA%E6%BA%90%E7%9A%84low%20senstivity%20level%E3%80%82l2%E8%A1%A8%E7%A4%BAtarget%E7%9A%84low%20sensitivity%E3%80%82%0A%3E-%20h1%2C%20h2%EF%BC%9A%E5%B0%8F%E5%86%99%E7%9A%84H%E3%80%82h1%E8%A1%A8%E7%A4%BA%E6%BA%90%E7%9A%84high%20senstivity%20level%E3%80%82h2%E8%A1%A8%E7%A4%BAtarget%E7%9A%84high%20sensitivity%E3%80%82%0A%3E-%20l%E5%92%8Ch%E7%9A%84%E5%85%B3%E7%B3%BB%EF%BC%8C%E5%8C%85%E6%8B%ACdom%2Cdomby%2Ceq%E5%92%8Cincomp%E3%80%82%0A%0A%E4%B8%BE%E4%B8%AA%E5%AE%9E%E9%99%85%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%60%60%60bash%0A%20%23%20Datagram%20send%3A%20Sender%20must%20be%20dominated%20by%20receiver%20unless%20one%20of%20them%20is%20trusted.%0A%20mlsconstrain%20unix_dgram_socket%20%7B%20sendto%20%7D%0A%20%20%20%20%20%20%20%20%20%20(l1%20domby%20l2%20or%20t1%20%3D%3D%20mlstrustedsubject%20or%20t2%20%3D%3D%20mlstrustedsubject)%3B%0A%23%20mlstrustedsubject%20%E6%98%AFattribute%0A%60%60%60%0A%E5%8F%AA%E6%9C%89%E5%9C%A8%E4%BB%A5%E4%B8%8B3%E4%B8%AA%E6%9D%A1%E4%BB%B6%E4%B9%8B%E4%B8%80%E6%88%90%E7%AB%8B%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8Csubject%E6%89%8D%E8%83%BD%E8%B0%83%E7%94%A8unix_dgram_socket%20class%E7%9A%84object%E7%9A%84sendto%20permission%3A%0A-%20l1%20domby%20l2%2C%20l1%20sensitivity%E5%B0%8F%E4%BA%8El2%20sensitivity%0A-%20t1%E5%8C%B9%E9%85%8D%E6%88%96%E8%80%85t2%E5%8C%B9%E9%85%8D%E6%A0%87%E7%AD%BEmlstrustedsubject%0A%0A%23%23%20%E6%80%BB%E7%BB%93%0A%E5%BC%95%E7%94%A8%5B6%5D%E4%B8%AD%E7%9A%84%E5%87%A0%E5%BC%A0%E5%9B%BE%E5%81%9A%E4%B8%AA%E6%80%BB%E7%BB%93%E3%80%82%0A%23%23%23%20SELinux%20%E9%A1%B6%E5%B1%82%E6%9E%B6%E6%9E%84%0A!%5B07a76e86c5b555b9fb9070b609f2b0fe.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6230)%0A%23%23%23%20SELinux%20%E5%86%B3%E7%AD%96%E6%B5%81%E7%A8%8B%0A!%5B418b433aea761cc938884e966e8c76bf.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6231)%0A%23%23%23%20Show%20me%20the%20code%0A%E5%8F%82%E8%80%83%5B8%5D%2C%20%E4%B8%8B%E5%9B%BE%E6%98%AFMLS%E7%9A%84%E9%89%B4%E6%9D%83%E6%B5%81%E7%A8%8B%EF%BC%8C%E4%BD%86%E5%AE%9E%E9%99%85%E4%B8%8ASELinux%E7%9A%84TE%EF%BC%8CRABC%EF%BC%8CMLS%E9%83%BD%E6%98%AF%E9%80%9A%E8%BF%87secure%20context%E7%9A%84%E5%88%A4%E6%96%AD%E6%9D%A5%E9%89%B4%E6%9D%83%E7%9A%84%EF%BC%8C%E5%AE%83%E4%BB%AC%E7%9A%84%E5%AE%9E%E7%8E%B0%E4%BD%8D%E7%BD%AE%E5%BA%94%E8%AF%A5%E6%98%AF%E5%9C%A8%E4%B8%80%E8%B5%B7%E7%9A%84%E3%80%82%0A!%5B6ce0a26ebfc3e29766b25445ace8576d.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6232)%0A%0A%0A%23%23%20%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%0A1.%20%5B%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3SELinux%20SEAndroid%EF%BC%88%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86%EF%BC%89%5D(https%3A%2F%2Fblog.csdn.net%2FInnost%2Farticle%2Fdetails%2F19299937)%0A2.%20%5B%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3SELinux%20SEAndroid%E4%B9%8B%E4%BA%8C%5D(https%3A%2F%2Fblog.csdn.net%2FInnost%2Farticle%2Fdetails%2F19641487)%0A3.%20%5B%E4%BB%8E%E5%A4%B4%E5%BC%80%E5%A7%8B%E7%94%9F%E6%88%90%20SELinux%5D(https%3A%2F%2Fwww.ibm.com%2Fdeveloperworks%2Fcn%2Flinux%2Fl-selinux.html)%0A4.%20%5BSELinux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%5D(https%3A%2F%2Fm.open-open.com%2Fpdf%2Fe88821debd374d1cab7b4f54ae14161e.html)%0A5.%20%5BSELinux%E5%88%9D%E5%A7%8B%E5%8C%96%E7%99%BB%E5%BD%95%E7%94%A8%E6%88%B7%E5%AE%89%E5%85%A8%E4%B8%8A%E4%B8%8B%E6%96%87%E7%9A%84%E6%96%B9%E6%B3%95%5D(https%3A%2F%2Fblog.csdn.net%2Fkeheinash%2Farticle%2Fdetails%2F81047520)%0A6.%20%5BLinux%20%E5%9F%BA%E7%A1%80%20-%2013.%20SELinux%5D(https%3A%2F%2Flinotes.imliloli.com%2Flinux%2Fselinux%2F%23135-%25E5%25AF%25B9%25E7%2594%25A8%25E6%2588%25B7%25E7%259A%2584%25E9%2599%2590%25E5%2588%25B6)%0A7.%20Chad%20Hanson%2C%20%22SELinux%20and%20MLS%3A%20Putting%20the%20Pieces%20Together%22%2CTrusted%20Computer%20Solutions%2C%20Inc.%2C%202006%0A8.%20%5BLinux%E5%BC%BA%E5%88%B6%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6%E6%9C%BA%E5%88%B6%E6%A8%A1%E5%9D%97%E8%AF%A6%E7%BB%86%E6%8F%8F%E8%BF%B0%EF%BC%881%EF%BC%89%5D(http%3A%2F%2Fwww.sohu.com%2Fa%2F128175655_467784)

本文基于Go 1.13。
Golang runtime库有一套完全基于用户态的协程(goroutine)调度框架。为了配合协程调度框架,提升系统调用时的并发性能,Go对SYSCALL调用机制进行了封装。
通常一个系统调用,在类platform OS上都会进行地址空间的切换,这相当于一个大型的Context Switch,先不论具体是哪个SYSCALL,即使这样一次Context Switch的损耗也是很大的。所以Go的SYSCALL机制,利用了操作系统的并行计算(parallelism)来缓和这一开销,而将其对并发的损害降低。

1
2
3
4
5
6
TEXT ·Syscall(SB),NOSPLIT,$0-28
BL runtime·entersyscall(SB)
...
SWI $0
...
BL runtime·exitsyscall(SB)

Syscall总接口定义在操作系统相关的文件。Linux平台是go/src/syscall/asm_linux_arm.s
Go框架在真正的进内核调用系统调用前后进行接管,插入了配合调度的代码。

entersyscall

假设调用Syscall之前,GPM运行的状态如下图:
747549a28a7a627a3cbd98fffe728fad

Read more »

本文基于Go 1.13。
Golang runtime库有一套完全基于用户态的协程(goroutine)调度框架。为了配合协程调度框架,提升系统调用时的并发性能,Go对SYSCALL调用机制进行了封装。
通常一个系统调用,在类platform OS上都会进行地址空间的切换,这相当于一个大型的Context Switch,先不论具体是哪个SYSCALL,即使这样一次Context Switch的损耗也是很大的。所以Go的SYSCALL机制,利用了操作系统的并行计算(parallelism)来缓和这一开销,而将其对并发的损害降低。

TEXT ·Syscall(SB),NOSPLIT,$0-28
	BL	runtime·entersyscall(SB)
	...
	SWI	$0
	...
	BL	runtime·exitsyscall(SB)

Syscall总接口定义在操作系统相关的文件。Linux平台是go/src/syscall/asm_linux_arm.s
Go框架在真正的进内核调用系统调用前后进行接管,插入了配合调度的代码。

entersyscall

假设调用Syscall之前,GPM运行的状态如下图:

PM解绑

当调用了Syscall以后,进入entersyscall,P和M会解绑,变成下面这张图:

这张图不是很准确,当M1和P解绑时,M2并没有立即上位,P处于_Psyscall状态。P是否与新的M绑定由sysmon这个特殊M来完成。后面sysmon一节会专门介绍。

	pp := _g_.m.p.ptr()
	pp.m = 0
	_g_.m.oldp.set(pp)
	_g_.m.p = 0

此时原先的P被记入了m.oldp,未来会用到。

exitsyscall

当系统调用结束以后,调用Syscall的G需要归位

PHN2ZyBpZD0iZG1xZ2ppdWNrMXYiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDM0Mi44OTA2MjVweDsiIHZpZXdCb3g9IjAgMCAzNDIuODkwNjI1IDMyNy40MDYyNSI+PHN0eWxlPgoKCiNkbXFnaml1Y2sxdiAubGFiZWwgewogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgY29sb3I6ICMzMzM7IH0KCiNkbXFnaml1Y2sxdiAubm9kZSByZWN0LAojZG1xZ2ppdWNrMXYgLm5vZGUgY2lyY2xlLAojZG1xZ2ppdWNrMXYgLm5vZGUgZWxsaXBzZSwKI2RtcWdqaXVjazF2IC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMXB4OyB9CgojZG1xZ2ppdWNrMXYgLm5vZGUuY2xpY2thYmxlIHsKICBjdXJzb3I6IHBvaW50ZXI7IH0KCiNkbXFnaml1Y2sxdiAuYXJyb3doZWFkUGF0aCB7CiAgZmlsbDogIzMzMzMzMzsgfQoKI2RtcWdqaXVjazF2IC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMzMzMzMzOwogIHN0cm9rZS13aWR0aDogMS41cHg7IH0KCiNkbXFnaml1Y2sxdiAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZThlOGU4OyB9CgojZG1xZ2ppdWNrMXYgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI2ZmZmZkZSAhaW1wb3J0YW50OwogIHN0cm9rZTogI2FhYWEzMyAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7IH0KCiNkbXFnaml1Y2sxdiAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjMzMzOyB9CgojZG1xZ2ppdWNrMXYgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1heC13aWR0aDogMjAwcHg7CiAgcGFkZGluZzogMnB4OwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMnB4OwogIGJhY2tncm91bmQ6ICNmZmZmZGU7CiAgYm9yZGVyOiAxcHggc29saWQgI2FhYWEzMzsKICBib3JkZXItcmFkaXVzOiAycHg7CiAgcG9pbnRlci1ldmVudHM6IG5vbmU7CiAgei1pbmRleDogMTAwOyB9CgojZG1xZ2ppdWNrMXYgLmFjdG9yIHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RtcWdqaXVjazF2IHRleHQuYWN0b3IgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RtcWdqaXVjazF2IC5hY3Rvci1saW5lIHsKICBzdHJva2U6IGdyZXk7IH0KCiNkbXFnaml1Y2sxdiAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkbXFnaml1Y2sxdiAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkbXFnaml1Y2sxdiAjYXJyb3doZWFkIHsKICBmaWxsOiAjMzMzOyB9CgojZG1xZ2ppdWNrMXYgI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMzMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMzMzICFpbXBvcnRhbnQ7IH0KCiNkbXFnaml1Y2sxdiAubWVzc2FnZVRleHQgewogIGZpbGw6ICMzMzM7CiAgc3Ryb2tlOiBub25lOyB9CgojZG1xZ2ppdWNrMXYgLmxhYmVsQm94IHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RtcWdqaXVjazF2IC5sYWJlbFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RtcWdqaXVjazF2IC5sb29wVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZG1xZ2ppdWNrMXYgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOyB9CgojZG1xZ2ppdWNrMXYgLm5vdGUgewogIHN0cm9rZTogI2FhYWEzMzsKICBmaWxsOiAjZmZmNWFkOyB9CgojZG1xZ2ppdWNrMXYgLm5vdGVUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDE0cHg7IH0KCiNkbXFnaml1Y2sxdiAuYWN0aXZhdGlvbjAgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZG1xZ2ppdWNrMXYgLmFjdGl2YXRpb24xIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2RtcWdqaXVjazF2IC5hY3RpdmF0aW9uMiB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCgojZG1xZ2ppdWNrMXYgLnNlY3Rpb24gewogIHN0cm9rZTogbm9uZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkbXFnaml1Y2sxdiAuc2VjdGlvbjAgewogIGZpbGw6IHJnYmEoMTAyLCAxMDIsIDI1NSwgMC40OSk7IH0KCiNkbXFnaml1Y2sxdiAuc2VjdGlvbjIgewogIGZpbGw6ICNmZmY0MDA7IH0KCiNkbXFnaml1Y2sxdiAuc2VjdGlvbjEsCiNkbXFnaml1Y2sxdiAuc2VjdGlvbjMgewogIGZpbGw6IHdoaXRlOwogIG9wYWNpdHk6IDAuMjsgfQoKI2RtcWdqaXVjazF2IC5zZWN0aW9uVGl0bGUwIHsKICBmaWxsOiAjMzMzOyB9CgojZG1xZ2ppdWNrMXYgLnNlY3Rpb25UaXRsZTEgewogIGZpbGw6ICMzMzM7IH0KCiNkbXFnaml1Y2sxdiAuc2VjdGlvblRpdGxlMiB7CiAgZmlsbDogIzMzMzsgfQoKI2RtcWdqaXVjazF2IC5zZWN0aW9uVGl0bGUzIHsKICBmaWxsOiAjMzMzOyB9CgojZG1xZ2ppdWNrMXYgLnNlY3Rpb25UaXRsZSB7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsKICB0ZXh0LWhlaWdodDogMTRweDsgfQoKCiNkbXFnaml1Y2sxdiAuZ3JpZCAudGljayB7CiAgc3Ryb2tlOiBsaWdodGdyZXk7CiAgb3BhY2l0eTogMC4zOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2RtcWdqaXVjazF2IC5ncmlkIHBhdGggewogIHN0cm9rZS13aWR0aDogMDsgfQoKCiNkbXFnaml1Y2sxdiAudG9kYXkgewogIGZpbGw6IG5vbmU7CiAgc3Ryb2tlOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAycHg7IH0KCgoKI2RtcWdqaXVjazF2IC50YXNrIHsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkbXFnaml1Y2sxdiAudGFza1RleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZG1xZ2ppdWNrMXYgLnRhc2tUZXh0T3V0c2lkZVJpZ2h0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZG1xZ2ppdWNrMXYgLnRhc2tUZXh0T3V0c2lkZUxlZnQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBlbmQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgoKI2RtcWdqaXVjazF2IC50YXNrVGV4dDAsCiNkbXFnaml1Y2sxdiAudGFza1RleHQxLAojZG1xZ2ppdWNrMXYgLnRhc2tUZXh0MiwKI2RtcWdqaXVjazF2IC50YXNrVGV4dDMgewogIGZpbGw6IHdoaXRlOyB9CgojZG1xZ2ppdWNrMXYgLnRhc2swLAojZG1xZ2ppdWNrMXYgLnRhc2sxLAojZG1xZ2ppdWNrMXYgLnRhc2syLAojZG1xZ2ppdWNrMXYgLnRhc2szIHsKICBmaWxsOiAjOGE5MGRkOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2RtcWdqaXVjazF2IC50YXNrVGV4dE91dHNpZGUwLAojZG1xZ2ppdWNrMXYgLnRhc2tUZXh0T3V0c2lkZTIgewogIGZpbGw6IGJsYWNrOyB9CgojZG1xZ2ppdWNrMXYgLnRhc2tUZXh0T3V0c2lkZTEsCiNkbXFnaml1Y2sxdiAudGFza1RleHRPdXRzaWRlMyB7CiAgZmlsbDogYmxhY2s7IH0KCgojZG1xZ2ppdWNrMXYgLmFjdGl2ZTAsCiNkbXFnaml1Y2sxdiAuYWN0aXZlMSwKI2RtcWdqaXVjazF2IC5hY3RpdmUyLAojZG1xZ2ppdWNrMXYgLmFjdGl2ZTMgewogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZG1xZ2ppdWNrMXYgLmFjdGl2ZVRleHQwLAojZG1xZ2ppdWNrMXYgLmFjdGl2ZVRleHQxLAojZG1xZ2ppdWNrMXYgLmFjdGl2ZVRleHQyLAojZG1xZ2ppdWNrMXYgLmFjdGl2ZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RtcWdqaXVjazF2IC5kb25lMCwKI2RtcWdqaXVjazF2IC5kb25lMSwKI2RtcWdqaXVjazF2IC5kb25lMiwKI2RtcWdqaXVjazF2IC5kb25lMyB7CiAgc3Ryb2tlOiBncmV5OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkbXFnaml1Y2sxdiAuZG9uZVRleHQwLAojZG1xZ2ppdWNrMXYgLmRvbmVUZXh0MSwKI2RtcWdqaXVjazF2IC5kb25lVGV4dDIsCiNkbXFnaml1Y2sxdiAuZG9uZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RtcWdqaXVjazF2IC5jcml0MCwKI2RtcWdqaXVjazF2IC5jcml0MSwKI2RtcWdqaXVjazF2IC5jcml0MiwKI2RtcWdqaXVjazF2IC5jcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IHJlZDsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkbXFnaml1Y2sxdiAuYWN0aXZlQ3JpdDAsCiNkbXFnaml1Y2sxdiAuYWN0aXZlQ3JpdDEsCiNkbXFnaml1Y2sxdiAuYWN0aXZlQ3JpdDIsCiNkbXFnaml1Y2sxdiAuYWN0aXZlQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2RtcWdqaXVjazF2IC5kb25lQ3JpdDAsCiNkbXFnaml1Y2sxdiAuZG9uZUNyaXQxLAojZG1xZ2ppdWNrMXYgLmRvbmVDcml0MiwKI2RtcWdqaXVjazF2IC5kb25lQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIGN1cnNvcjogcG9pbnRlcjsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkbXFnaml1Y2sxdiAuZG9uZUNyaXRUZXh0MCwKI2RtcWdqaXVjazF2IC5kb25lQ3JpdFRleHQxLAojZG1xZ2ppdWNrMXYgLmRvbmVDcml0VGV4dDIsCiNkbXFnaml1Y2sxdiAuZG9uZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2RtcWdqaXVjazF2IC5hY3RpdmVDcml0VGV4dDAsCiNkbXFnaml1Y2sxdiAuYWN0aXZlQ3JpdFRleHQxLAojZG1xZ2ppdWNrMXYgLmFjdGl2ZUNyaXRUZXh0MiwKI2RtcWdqaXVjazF2IC5hY3RpdmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkbXFnaml1Y2sxdiAudGl0bGVUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMThweDsKICBmaWxsOiBibGFjazsgfQoKI2RtcWdqaXVjazF2IGcuY2xhc3NHcm91cCB0ZXh0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2RtcWdqaXVjazF2IGcuY2xhc3NHcm91cCByZWN0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsgfQoKI2RtcWdqaXVjazF2IGcuY2xhc3NHcm91cCBsaW5lIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZG1xZ2ppdWNrMXYgLmNsYXNzTGFiZWwgLmJveCB7CiAgc3Ryb2tlOiBub25lOwogIHN0cm9rZS13aWR0aDogMDsKICBmaWxsOiAjRUNFQ0ZGOwogIG9wYWNpdHk6IDAuNTsgfQoKI2RtcWdqaXVjazF2IC5jbGFzc0xhYmVsIC5sYWJlbCB7CiAgZmlsbDogIzkzNzBEQjsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkbXFnaml1Y2sxdiAucmVsYXRpb24gewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7CiAgZmlsbDogbm9uZTsgfQoKI2RtcWdqaXVjazF2ICNjb21wb3NpdGlvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkbXFnaml1Y2sxdiAjY29tcG9zaXRpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RtcWdqaXVjazF2ICNhZ2dyZWdhdGlvblN0YXJ0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkbXFnaml1Y2sxdiAjYWdncmVnYXRpb25FbmQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RtcWdqaXVjazF2ICNkZXBlbmRlbmN5U3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RtcWdqaXVjazF2ICNkZXBlbmRlbmN5RW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkbXFnaml1Y2sxdiAjZXh0ZW5zaW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RtcWdqaXVjazF2ICNleHRlbnNpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RtcWdqaXVjazF2IC5jb21taXQtaWQsCiNkbXFnaml1Y2sxdiAuY29tbWl0LW1zZywKI2RtcWdqaXVjazF2IC5icmFuY2gtbGFiZWwgewogIGZpbGw6IGxpZ2h0Z3JleTsKICBjb2xvcjogbGlnaHRncmV5OyB9CgoKCiNkbXFnaml1Y2sxdiAubGFiZWx7CiAgY29sb3I6IzE4QjE0RTsKfQojZG1xZ2ppdWNrMXYgLnRlLW1kLWNvbnRhaW5lci0tZGFyayAubm9kZSByZWN0IHsKICBmaWxsOiByZWQ7Cn0KCiNkbXFnaml1Y2sxdiAubm9kZSByZWN0LAojZG1xZ2ppdWNrMXYgLm5vZGUgY2lyY2xlLAojZG1xZ2ppdWNrMXYgLm5vZGUgZWxsaXBzZSwKI2RtcWdqaXVjazF2IC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNGOUZGRkI7OwogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDEuNXB4Owp9CiNkbXFnaml1Y2sxdiAuYXJyb3doZWFkUGF0aHsKICBmaWxsOiAjMkRCRDYwOwp9CiNkbXFnaml1Y2sxdiAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDFweDsKfQojZG1xZ2ppdWNrMXYgLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsKfQojZG1xZ2ppdWNrMXYgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI0Y5RkZGQiAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7Cn0KCiNkbXFnaml1Y2sxdiAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjRjlGRkZCOwp9CgojZG1xZ2ppdWNrMXYgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBiYWNrZ3JvdW5kOiAjRjlGRkZCOwogIGJvcmRlcjogMXB4IHNvbGlkICMyREJENjA7Cn0KCgojZG1xZ2ppdWNrMXYgLmFjdG9yIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RtcWdqaXVjazF2IHRleHQuYWN0b3IgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZG1xZ2ppdWNrMXYgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RtcWdqaXVjazF2IC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RtcWdqaXVjazF2IC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RtcWdqaXVjazF2ICNhcnJvd2hlYWQgewogIGZpbGw6ICMyREJENjA7Cn0KCiNkbXFnaml1Y2sxdiAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKfQoKI2RtcWdqaXVjazF2IC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkbXFnaml1Y2sxdiAubGFiZWxCb3ggewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZG1xZ2ppdWNrMXYgLmxhYmVsVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkbXFnaml1Y2sxdiAubG9vcFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZG1xZ2ppdWNrMXYgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZG1xZ2ppdWNrMXYgLm5vdGUgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZG1xZ2ppdWNrMXYgLm5vdGVUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKCiNkbXFnaml1Y2sxdiAuc2VjdGlvbnsKICBvcGFjaXR5OjE7Cn0KI2RtcWdqaXVjazF2IC5zZWN0aW9uMCwjZG1xZ2ppdWNrMXYgIC5zZWN0aW9uMiB7CiAgZmlsbDogI0VDRjdGMDsKfQoKI2RtcWdqaXVjazF2IC5zZWN0aW9uMSwKI2RtcWdqaXVjazF2IC5zZWN0aW9uMyB7CiAgZmlsbDogI0ZGRjsKfQojZG1xZ2ppdWNrMXYgLnRhc2tUZXh0MCwKI2RtcWdqaXVjazF2IC50YXNrVGV4dDEsCiNkbXFnaml1Y2sxdiAudGFza1RleHQyLAojZG1xZ2ppdWNrMXYgLnRhc2tUZXh0MyB7CiAgZmlsbDogI2ZmZjsKfQoKI2RtcWdqaXVjazF2IC50YXNrMCwKI2RtcWdqaXVjazF2IC50YXNrMSwKI2RtcWdqaXVjazF2IC50YXNrMiwKI2RtcWdqaXVjazF2IC50YXNrMyB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMzNTlGNUE7Cn0KPC9zdHlsZT48c3R5bGU+I2RtcWdqaXVjazF2IHsKICAgIGNvbG9yOiByZ2IoMjQ0LCAyNDQsIDI0NCk7CiAgICBmb250OiBub3JtYWwgbm9ybWFsIG5vcm1hbCBub3JtYWwgMTRweC8yMi4zOTk5OTk2MTg1MzAyNzNweCBtb25vc3BhY2U7CiAgfTwvc3R5bGU+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLCAtMTIpIj48ZyBjbGFzcz0ib3V0cHV0Ij48ZyBjbGFzcz0iY2x1c3RlcnMiPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGhzIj48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yMDguMTUyMzQzNzUsNTYuMjgxMjVMMjA4LjE1MjM0Mzc1LDgxLjI4MTI1TDIwOC4xNTIzNDM3NSwxMDYuMjgxMjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMTY1MykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMTY1MyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE3NC44MjEyOTQ0MTg0MTg2MywxNDIuNTYyNUwxMTMuOTI5Njg3NSwxNzUuNzAzMTI1TDExMy45Mjk2ODc1LDIwOC44NDM3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQxNjU0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQxNjU0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjQxLjQ4MzM5MzA4MTU4MTM3LDE0Mi41NjI1TDMwMi4zNzUsMTc1LjcwMzEyNUwzMDIuMzc1LDIwOC44NDM3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQxNjU1KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQxNjU1IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTEzLjkyOTY4NzUsMjQ1LjEyNUwxMTMuOTI5Njg3NSwyNzAuMTI1TDE3OS4yMTQ4NDM3NSwzMDAuMDE2MzUwNTA4ODkyNyIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQxNjU2KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQxNjU2IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMzAyLjM3NSwyNDUuMTI1TDMwMi4zNzUsMjcwLjEyNUwyMzcuMDg5ODQzNzUsMzAwLjAxNjM1MDUwODg5MjciIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMTY1NykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMTY1NyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVscyI+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEzLjkyOTY4NzUsMTc1LjcwMzEyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI4LjUwNzgxMjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iNDQuNDIxODc1IiBoZWlnaHQ9IjE2LjI5Njg3NSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+c3VjY2VzczwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzAyLjM3NSwxNzUuNzAzMTI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTYuMzU5Mzc1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjE5Ljc4MTI1IiBoZWlnaHQ9IjE2LjI5Njg3NSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+ZmFpbDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlcyI+PGcgY2xhc3M9Im5vZGUiIGlkPSJBIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDguMTUyMzQzNzUsMzguMTQwNjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii00MC45OTIxODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iODEuOTg0Mzc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzAuOTkyMTg3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+ZXhpdHN5c2NhbGw8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwOC4xNTIzNDM3NSwxMjQuNDIxODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii01Mi4yNjU2MjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxMDQuNTMxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00Mi4yNjU2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmV4aXRzeXNjYWxsZmFzdDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iQyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEzLjkyOTY4NzUsMjI2Ljk4NDM3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItOTMuOTI5Njg3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjE4Ny44NTkzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04My45Mjk2ODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5fZ186IF9Hc3lzY2FsbCA9Jmd0OyBfR3J1bm5pbmc8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMi4zNzUsMjI2Ljk4NDM3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNDQuNTE1NjI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iODkuMDMxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNC41MTU2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmV4aXRzeXNjYWxsMDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA4LjE1MjM0Mzc1LDMxMy4yNjU2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTI4LjkzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI1Ny44NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOC45Mzc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5yZXR1cm48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=

这其中涉及两个重要函数:

  • exitsyscallfast
  • exitsyscall0

exitsyscallfast

该函数会尝试先绑定oldp,如果不成功,会在尝试其他idlep。M绑定P使用wirep函数。
如果P,M绑定成功,那么G是不需要切换任何队列,G会继续运行。
如果无法绑定,则会停止M,并找到地方放置G。这一过程在exitsyscall0。

exitsyscall0

PHN2ZyBpZD0iZHF5emhzenN2N2giIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDMxNC4xNzE4NzVweDsiIHZpZXdCb3g9IjAgMCAzMTQuMTcxODc1IDU4Ni4yNSI+PHN0eWxlPgoKCiNkcXl6aHN6c3Y3aCAubGFiZWwgewogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgY29sb3I6ICMzMzM7IH0KCiNkcXl6aHN6c3Y3aCAubm9kZSByZWN0LAojZHF5emhzenN2N2ggLm5vZGUgY2lyY2xlLAojZHF5emhzenN2N2ggLm5vZGUgZWxsaXBzZSwKI2RxeXpoc3pzdjdoIC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMXB4OyB9CgojZHF5emhzenN2N2ggLm5vZGUuY2xpY2thYmxlIHsKICBjdXJzb3I6IHBvaW50ZXI7IH0KCiNkcXl6aHN6c3Y3aCAuYXJyb3doZWFkUGF0aCB7CiAgZmlsbDogIzMzMzMzMzsgfQoKI2RxeXpoc3pzdjdoIC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMzMzMzMzOwogIHN0cm9rZS13aWR0aDogMS41cHg7IH0KCiNkcXl6aHN6c3Y3aCAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZThlOGU4OyB9CgojZHF5emhzenN2N2ggLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI2ZmZmZkZSAhaW1wb3J0YW50OwogIHN0cm9rZTogI2FhYWEzMyAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7IH0KCiNkcXl6aHN6c3Y3aCAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjMzMzOyB9CgojZHF5emhzenN2N2ggZGl2Lm1lcm1haWRUb29sdGlwIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1heC13aWR0aDogMjAwcHg7CiAgcGFkZGluZzogMnB4OwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMnB4OwogIGJhY2tncm91bmQ6ICNmZmZmZGU7CiAgYm9yZGVyOiAxcHggc29saWQgI2FhYWEzMzsKICBib3JkZXItcmFkaXVzOiAycHg7CiAgcG9pbnRlci1ldmVudHM6IG5vbmU7CiAgei1pbmRleDogMTAwOyB9CgojZHF5emhzenN2N2ggLmFjdG9yIHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RxeXpoc3pzdjdoIHRleHQuYWN0b3IgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RxeXpoc3pzdjdoIC5hY3Rvci1saW5lIHsKICBzdHJva2U6IGdyZXk7IH0KCiNkcXl6aHN6c3Y3aCAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkcXl6aHN6c3Y3aCAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkcXl6aHN6c3Y3aCAjYXJyb3doZWFkIHsKICBmaWxsOiAjMzMzOyB9CgojZHF5emhzenN2N2ggI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMzMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMzMzICFpbXBvcnRhbnQ7IH0KCiNkcXl6aHN6c3Y3aCAubWVzc2FnZVRleHQgewogIGZpbGw6ICMzMzM7CiAgc3Ryb2tlOiBub25lOyB9CgojZHF5emhzenN2N2ggLmxhYmVsQm94IHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RxeXpoc3pzdjdoIC5sYWJlbFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RxeXpoc3pzdjdoIC5sb29wVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHF5emhzenN2N2ggLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOyB9CgojZHF5emhzenN2N2ggLm5vdGUgewogIHN0cm9rZTogI2FhYWEzMzsKICBmaWxsOiAjZmZmNWFkOyB9CgojZHF5emhzenN2N2ggLm5vdGVUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDE0cHg7IH0KCiNkcXl6aHN6c3Y3aCAuYWN0aXZhdGlvbjAgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZHF5emhzenN2N2ggLmFjdGl2YXRpb24xIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2RxeXpoc3pzdjdoIC5hY3RpdmF0aW9uMiB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCgojZHF5emhzenN2N2ggLnNlY3Rpb24gewogIHN0cm9rZTogbm9uZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkcXl6aHN6c3Y3aCAuc2VjdGlvbjAgewogIGZpbGw6IHJnYmEoMTAyLCAxMDIsIDI1NSwgMC40OSk7IH0KCiNkcXl6aHN6c3Y3aCAuc2VjdGlvbjIgewogIGZpbGw6ICNmZmY0MDA7IH0KCiNkcXl6aHN6c3Y3aCAuc2VjdGlvbjEsCiNkcXl6aHN6c3Y3aCAuc2VjdGlvbjMgewogIGZpbGw6IHdoaXRlOwogIG9wYWNpdHk6IDAuMjsgfQoKI2RxeXpoc3pzdjdoIC5zZWN0aW9uVGl0bGUwIHsKICBmaWxsOiAjMzMzOyB9CgojZHF5emhzenN2N2ggLnNlY3Rpb25UaXRsZTEgewogIGZpbGw6ICMzMzM7IH0KCiNkcXl6aHN6c3Y3aCAuc2VjdGlvblRpdGxlMiB7CiAgZmlsbDogIzMzMzsgfQoKI2RxeXpoc3pzdjdoIC5zZWN0aW9uVGl0bGUzIHsKICBmaWxsOiAjMzMzOyB9CgojZHF5emhzenN2N2ggLnNlY3Rpb25UaXRsZSB7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsKICB0ZXh0LWhlaWdodDogMTRweDsgfQoKCiNkcXl6aHN6c3Y3aCAuZ3JpZCAudGljayB7CiAgc3Ryb2tlOiBsaWdodGdyZXk7CiAgb3BhY2l0eTogMC4zOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2RxeXpoc3pzdjdoIC5ncmlkIHBhdGggewogIHN0cm9rZS13aWR0aDogMDsgfQoKCiNkcXl6aHN6c3Y3aCAudG9kYXkgewogIGZpbGw6IG5vbmU7CiAgc3Ryb2tlOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAycHg7IH0KCgoKI2RxeXpoc3pzdjdoIC50YXNrIHsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcXl6aHN6c3Y3aCAudGFza1RleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHF5emhzenN2N2ggLnRhc2tUZXh0T3V0c2lkZVJpZ2h0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHF5emhzenN2N2ggLnRhc2tUZXh0T3V0c2lkZUxlZnQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBlbmQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgoKI2RxeXpoc3pzdjdoIC50YXNrVGV4dDAsCiNkcXl6aHN6c3Y3aCAudGFza1RleHQxLAojZHF5emhzenN2N2ggLnRhc2tUZXh0MiwKI2RxeXpoc3pzdjdoIC50YXNrVGV4dDMgewogIGZpbGw6IHdoaXRlOyB9CgojZHF5emhzenN2N2ggLnRhc2swLAojZHF5emhzenN2N2ggLnRhc2sxLAojZHF5emhzenN2N2ggLnRhc2syLAojZHF5emhzenN2N2ggLnRhc2szIHsKICBmaWxsOiAjOGE5MGRkOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2RxeXpoc3pzdjdoIC50YXNrVGV4dE91dHNpZGUwLAojZHF5emhzenN2N2ggLnRhc2tUZXh0T3V0c2lkZTIgewogIGZpbGw6IGJsYWNrOyB9CgojZHF5emhzenN2N2ggLnRhc2tUZXh0T3V0c2lkZTEsCiNkcXl6aHN6c3Y3aCAudGFza1RleHRPdXRzaWRlMyB7CiAgZmlsbDogYmxhY2s7IH0KCgojZHF5emhzenN2N2ggLmFjdGl2ZTAsCiNkcXl6aHN6c3Y3aCAuYWN0aXZlMSwKI2RxeXpoc3pzdjdoIC5hY3RpdmUyLAojZHF5emhzenN2N2ggLmFjdGl2ZTMgewogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZHF5emhzenN2N2ggLmFjdGl2ZVRleHQwLAojZHF5emhzenN2N2ggLmFjdGl2ZVRleHQxLAojZHF5emhzenN2N2ggLmFjdGl2ZVRleHQyLAojZHF5emhzenN2N2ggLmFjdGl2ZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RxeXpoc3pzdjdoIC5kb25lMCwKI2RxeXpoc3pzdjdoIC5kb25lMSwKI2RxeXpoc3pzdjdoIC5kb25lMiwKI2RxeXpoc3pzdjdoIC5kb25lMyB7CiAgc3Ryb2tlOiBncmV5OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcXl6aHN6c3Y3aCAuZG9uZVRleHQwLAojZHF5emhzenN2N2ggLmRvbmVUZXh0MSwKI2RxeXpoc3pzdjdoIC5kb25lVGV4dDIsCiNkcXl6aHN6c3Y3aCAuZG9uZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RxeXpoc3pzdjdoIC5jcml0MCwKI2RxeXpoc3pzdjdoIC5jcml0MSwKI2RxeXpoc3pzdjdoIC5jcml0MiwKI2RxeXpoc3pzdjdoIC5jcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IHJlZDsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcXl6aHN6c3Y3aCAuYWN0aXZlQ3JpdDAsCiNkcXl6aHN6c3Y3aCAuYWN0aXZlQ3JpdDEsCiNkcXl6aHN6c3Y3aCAuYWN0aXZlQ3JpdDIsCiNkcXl6aHN6c3Y3aCAuYWN0aXZlQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2RxeXpoc3pzdjdoIC5kb25lQ3JpdDAsCiNkcXl6aHN6c3Y3aCAuZG9uZUNyaXQxLAojZHF5emhzenN2N2ggLmRvbmVDcml0MiwKI2RxeXpoc3pzdjdoIC5kb25lQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIGN1cnNvcjogcG9pbnRlcjsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkcXl6aHN6c3Y3aCAuZG9uZUNyaXRUZXh0MCwKI2RxeXpoc3pzdjdoIC5kb25lQ3JpdFRleHQxLAojZHF5emhzenN2N2ggLmRvbmVDcml0VGV4dDIsCiNkcXl6aHN6c3Y3aCAuZG9uZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2RxeXpoc3pzdjdoIC5hY3RpdmVDcml0VGV4dDAsCiNkcXl6aHN6c3Y3aCAuYWN0aXZlQ3JpdFRleHQxLAojZHF5emhzenN2N2ggLmFjdGl2ZUNyaXRUZXh0MiwKI2RxeXpoc3pzdjdoIC5hY3RpdmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkcXl6aHN6c3Y3aCAudGl0bGVUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMThweDsKICBmaWxsOiBibGFjazsgfQoKI2RxeXpoc3pzdjdoIGcuY2xhc3NHcm91cCB0ZXh0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2RxeXpoc3pzdjdoIGcuY2xhc3NHcm91cCByZWN0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsgfQoKI2RxeXpoc3pzdjdoIGcuY2xhc3NHcm91cCBsaW5lIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHF5emhzenN2N2ggLmNsYXNzTGFiZWwgLmJveCB7CiAgc3Ryb2tlOiBub25lOwogIHN0cm9rZS13aWR0aDogMDsKICBmaWxsOiAjRUNFQ0ZGOwogIG9wYWNpdHk6IDAuNTsgfQoKI2RxeXpoc3pzdjdoIC5jbGFzc0xhYmVsIC5sYWJlbCB7CiAgZmlsbDogIzkzNzBEQjsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkcXl6aHN6c3Y3aCAucmVsYXRpb24gewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7CiAgZmlsbDogbm9uZTsgfQoKI2RxeXpoc3pzdjdoICNjb21wb3NpdGlvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcXl6aHN6c3Y3aCAjY29tcG9zaXRpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxeXpoc3pzdjdoICNhZ2dyZWdhdGlvblN0YXJ0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcXl6aHN6c3Y3aCAjYWdncmVnYXRpb25FbmQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxeXpoc3pzdjdoICNkZXBlbmRlbmN5U3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxeXpoc3pzdjdoICNkZXBlbmRlbmN5RW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcXl6aHN6c3Y3aCAjZXh0ZW5zaW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxeXpoc3pzdjdoICNleHRlbnNpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxeXpoc3pzdjdoIC5jb21taXQtaWQsCiNkcXl6aHN6c3Y3aCAuY29tbWl0LW1zZywKI2RxeXpoc3pzdjdoIC5icmFuY2gtbGFiZWwgewogIGZpbGw6IGxpZ2h0Z3JleTsKICBjb2xvcjogbGlnaHRncmV5OyB9CgoKCiNkcXl6aHN6c3Y3aCAubGFiZWx7CiAgY29sb3I6IzE4QjE0RTsKfQojZHF5emhzenN2N2ggLnRlLW1kLWNvbnRhaW5lci0tZGFyayAubm9kZSByZWN0IHsKICBmaWxsOiByZWQ7Cn0KCiNkcXl6aHN6c3Y3aCAubm9kZSByZWN0LAojZHF5emhzenN2N2ggLm5vZGUgY2lyY2xlLAojZHF5emhzenN2N2ggLm5vZGUgZWxsaXBzZSwKI2RxeXpoc3pzdjdoIC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNGOUZGRkI7OwogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDEuNXB4Owp9CiNkcXl6aHN6c3Y3aCAuYXJyb3doZWFkUGF0aHsKICBmaWxsOiAjMkRCRDYwOwp9CiNkcXl6aHN6c3Y3aCAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDFweDsKfQojZHF5emhzenN2N2ggLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsKfQojZHF5emhzenN2N2ggLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI0Y5RkZGQiAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7Cn0KCiNkcXl6aHN6c3Y3aCAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHF5emhzenN2N2ggZGl2Lm1lcm1haWRUb29sdGlwIHsKICBiYWNrZ3JvdW5kOiAjRjlGRkZCOwogIGJvcmRlcjogMXB4IHNvbGlkICMyREJENjA7Cn0KCgojZHF5emhzenN2N2ggLmFjdG9yIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RxeXpoc3pzdjdoIHRleHQuYWN0b3IgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZHF5emhzenN2N2ggLmFjdG9yLWxpbmUgewogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxeXpoc3pzdjdoIC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxeXpoc3pzdjdoIC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxeXpoc3pzdjdoICNhcnJvd2hlYWQgewogIGZpbGw6ICMyREJENjA7Cn0KCiNkcXl6aHN6c3Y3aCAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKfQoKI2RxeXpoc3pzdjdoIC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkcXl6aHN6c3Y3aCAubGFiZWxCb3ggewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHF5emhzenN2N2ggLmxhYmVsVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkcXl6aHN6c3Y3aCAubG9vcFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHF5emhzenN2N2ggLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHF5emhzenN2N2ggLm5vdGUgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHF5emhzenN2N2ggLm5vdGVUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKCiNkcXl6aHN6c3Y3aCAuc2VjdGlvbnsKICBvcGFjaXR5OjE7Cn0KI2RxeXpoc3pzdjdoIC5zZWN0aW9uMCwjZHF5emhzenN2N2ggIC5zZWN0aW9uMiB7CiAgZmlsbDogI0VDRjdGMDsKfQoKI2RxeXpoc3pzdjdoIC5zZWN0aW9uMSwKI2RxeXpoc3pzdjdoIC5zZWN0aW9uMyB7CiAgZmlsbDogI0ZGRjsKfQojZHF5emhzenN2N2ggLnRhc2tUZXh0MCwKI2RxeXpoc3pzdjdoIC50YXNrVGV4dDEsCiNkcXl6aHN6c3Y3aCAudGFza1RleHQyLAojZHF5emhzenN2N2ggLnRhc2tUZXh0MyB7CiAgZmlsbDogI2ZmZjsKfQoKI2RxeXpoc3pzdjdoIC50YXNrMCwKI2RxeXpoc3pzdjdoIC50YXNrMSwKI2RxeXpoc3pzdjdoIC50YXNrMiwKI2RxeXpoc3pzdjdoIC50YXNrMyB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMzNTlGNUE7Cn0KPC9zdHlsZT48c3R5bGU+I2RxeXpoc3pzdjdoIHsKICAgIGNvbG9yOiByZ2IoMjQ0LCAyNDQsIDI0NCk7CiAgICBmb250OiBub3JtYWwgbm9ybWFsIG5vcm1hbCBub3JtYWwgMTRweC8yMi4zOTk5OTk2MTg1MzAyNzNweCBtb25vc3BhY2U7CiAgfTwvc3R5bGU+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLCAtMTIpIj48ZyBjbGFzcz0ib3V0cHV0Ij48ZyBjbGFzcz0iY2x1c3RlcnMiPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGhzIj48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xNTMuNTUwNzgxMjUsNTYuMjgxMjVMMTUzLjU1MDc4MTI1LDgxLjI4MTI1TDE1My41NTA3ODEyNSwxMDYuMjgxMjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMTY5MykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMTY5MyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE1My41NTA3ODEyNSwxNDIuNTYyNUwxNTMuNTUwNzgxMjUsMTY3LjU2MjVMMTUzLjU1MDc4MTI1LDE5Mi41NjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDE2OTQpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDE2OTQiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xNTMuNTUwNzgxMjUsMjI4Ljg0Mzc1TDE1My41NTA3ODEyNSwyNTMuODQzNzVMMTUzLjU1MDc4MTI1LDI3OC44NDM3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQxNjk1KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQxNjk1IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTIyLjc1OTUyOTk2NDU3OTUzLDMxNS4xMjVMNjYuNTA3ODEyNSwzNDguMjY1NjI1TDY2LjUwNzgxMjUsMzgxLjQwNjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDE2OTYpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDE2OTYiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xODQuMzQyMDMyNTM1NDIwNSwzMTUuMTI1TDI0MC41OTM3NSwzNDguMjY1NjI1TDI0MC41OTM3NSwzODEuNDA2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMTY5NykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMTY5NyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTY2LjUwNzgxMjUsNDE3LjY4NzVMNjYuNTA3ODEyNSw0NDIuNjg3NUw2Ni41MDc4MTI1LDQ2Ny42ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDE2OTgpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDE2OTgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik02Ni41MDc4MTI1LDUwMy45Njg3NUw2Ni41MDc4MTI1LDUyOC45Njg3NUw2Ni41MDc4MTI1LDU1My45Njg3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQxNjk5KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQxNjk5IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjQwLjU5Mzc1LDQxNy42ODc1TDI0MC41OTM3NSw0NDIuNjg3NUwyNDAuNTkzNzUsNDY3LjY4NzUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMTcwMCkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMTcwMCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVscyI+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjYuNTA3ODEyNSwzNDguMjY1NjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzYuNjA5Mzc1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjUyLjU5Mzc1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5ubyBpZGxlIFA8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0MC41OTM3NSwzNDguMjY1NjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDQuNzEwOTM3NSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI2MS40NTMxMjUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmZpbmQgaWRsZSBQPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGVzIj48ZyBjbGFzcz0ibm9kZSIgaWQ9IkEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE1My41NTA3ODEyNSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTQ0LjUxNTYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9Ijg5LjAzMTI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzQuNTE1NjI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5leGl0c3lzY2FsbDA8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE1My41NTA3ODEyNSwxMjQuNDIxODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii05NC42MDkzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxODkuMjE4NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04NC42MDkzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmdwOiBfR3N5c2NhbGwgPSZndDsgX0dydW5uYWJsZTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iQyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTUzLjU1MDc4MTI1LDIxMC43MDMxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTI3LjE5NTMxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI1NC4zOTA2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNy4xOTUzMTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5kcm9wZzwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTUzLjU1MDc4MTI1LDI5Ni45ODQzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTM0Ljc0MjE4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI2OS40ODQzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yNC43NDIxODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5waWRsZWdldDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjYuNTA3ODEyNSwzOTkuNTQ2ODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii00Ni41MDc4MTI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iOTMuMDE1NjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzYuNTA3ODEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+Z2xvYnJ1bnFwdXQ8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkYiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0MC41OTM3NSwzOTkuNTQ2ODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii03Ny41NzgxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxNTUuMTU2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02Ny41NzgxMjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmFxdWlyZXAgJmFtcDsgZXhlY3V0ZShncCk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDY2LjUwNzgxMjUsNDg1LjgyODEyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMjguNDc2NTYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjU2Ljk1MzEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE4LjQ3NjU2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnN0b3BtPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2Ni41MDc4MTI1LDU3Mi4xMDkzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTM2LjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI3MyIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI2LjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnNjaGVkdWxlPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJJIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNDAuNTkzNzUsNDg1LjgyODEyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNTYuOTc2NTYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjExMy45NTMxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00Ni45NzY1NjI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5uZXZlciByZXR1cm4gLi4uPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PC9zdmc+

exitsyscall0仍然会尝试获取P,如果能获取到,则会acquirep,acquirep会调用wirep完成P和M的绑定。之后调用execute函数,并且不会再返回。因为在execute G的时候,仍然会遇到调度点。
注:如果没有遇到调度点的情况没有想明白。

如果exitsyscall0仍然没有获取P,则会调用stopm来停止当前M,直到被唤醒。唤醒之后会直接进入调度。

sysmon

sysmon是一个由runtime启动的M,也叫监控线程,它无需P也可以运行,它每20us~10ms唤醒一次,主要执行:

  • 释放闲置超过5分钟的span物理内存;
  • 如果超过2分钟没有垃圾回收,强制执行;
  • 将长时间未处理的netpoll结果添加到任务队列;
  • 向长时间运行的G任务发出抢占调度;
  • 收回因syscall长时间阻塞的P;
    入口在src/runtime/proc.go:sysmon函数。
    因为我主要关注的是Go调度框架,所以sysmon中关于GC,CGO,trace等部分都忽略掉了。所以只剩下retake函数。retake会对syscall和长时间运行的G进行接管。

retake

retake会遍历所有的P,即allp数组,做两件事。

  1. 抢占运行过久的G
  2. handoff处于_Psyscall过久的P

preempt G

这里表示在某一个P上,即一个某个CPU核上运行的G运行时间过于久。
判断G运行过久的方法是:

  • retake传入的参数now = noontime()
  • retake会记录每次调用retake的时间点在_p_.sysmontick.schedwhen中
  • 如果schedwhen+forcePreemptNS <= now表示G运行过久,其中forcePreemptNS = 10ms

handoff P

与上一节类似,此处要判断P处于_Psyscall的时间过久。
每一次retake,记录时间到_p_.sysmontick.schedwhen。当发生下面的情况,则表示P处于_Psyscall时间太久:
syscallwhen+10*1000*1000 <= now
之后将P的状态切换为_Pidle,然后调用handoffp来绑定P和一个新的M。
实际上这里才完成了这幅图上M2与P的绑定:

参考文献

%E6%9C%AC%E6%96%87%E5%9F%BA%E4%BA%8EGo%201.13%E3%80%82%0AGolang%20runtime%E5%BA%93%E6%9C%89%E4%B8%80%E5%A5%97%E5%AE%8C%E5%85%A8%E5%9F%BA%E4%BA%8E%E7%94%A8%E6%88%B7%E6%80%81%E7%9A%84%E5%8D%8F%E7%A8%8B%EF%BC%88goroutine%EF%BC%89%E8%B0%83%E5%BA%A6%E6%A1%86%E6%9E%B6%E3%80%82%E4%B8%BA%E4%BA%86%E9%85%8D%E5%90%88%E5%8D%8F%E7%A8%8B%E8%B0%83%E5%BA%A6%E6%A1%86%E6%9E%B6%EF%BC%8C%E6%8F%90%E5%8D%87%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E6%97%B6%E7%9A%84%E5%B9%B6%E5%8F%91%E6%80%A7%E8%83%BD%EF%BC%8CGo%E5%AF%B9SYSCALL%E8%B0%83%E7%94%A8%E6%9C%BA%E5%88%B6%E8%BF%9B%E8%A1%8C%E4%BA%86%E5%B0%81%E8%A3%85%E3%80%82%0A%E9%80%9A%E5%B8%B8%E4%B8%80%E4%B8%AA%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%EF%BC%8C%E5%9C%A8%E7%B1%BBplatform%20OS%E4%B8%8A%E9%83%BD%E4%BC%9A%E8%BF%9B%E8%A1%8C%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E7%9A%84%E5%88%87%E6%8D%A2%EF%BC%8C%E8%BF%99%E7%9B%B8%E5%BD%93%E4%BA%8E%E4%B8%80%E4%B8%AA%E5%A4%A7%E5%9E%8B%E7%9A%84Context%20Switch%EF%BC%8C%E5%85%88%E4%B8%8D%E8%AE%BA%E5%85%B7%E4%BD%93%E6%98%AF%E5%93%AA%E4%B8%AASYSCALL%EF%BC%8C%E5%8D%B3%E4%BD%BF%E8%BF%99%E6%A0%B7%E4%B8%80%E6%AC%A1Context%20Switch%E7%9A%84%E6%8D%9F%E8%80%97%E4%B9%9F%E6%98%AF%E5%BE%88%E5%A4%A7%E7%9A%84%E3%80%82%E6%89%80%E4%BB%A5Go%E7%9A%84SYSCALL%E6%9C%BA%E5%88%B6%EF%BC%8C%E5%88%A9%E7%94%A8%E4%BA%86%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%B9%B6%E8%A1%8C%E8%AE%A1%E7%AE%97%EF%BC%88parallelism%EF%BC%89%E6%9D%A5%E7%BC%93%E5%92%8C%E8%BF%99%E4%B8%80%E5%BC%80%E9%94%80%EF%BC%8C%E8%80%8C%E5%B0%86%E5%85%B6%E5%AF%B9%E5%B9%B6%E5%8F%91%E7%9A%84%E6%8D%9F%E5%AE%B3%E9%99%8D%E4%BD%8E%E3%80%82%0A%0A%60%60%60go%0ATEXT%20%C2%B7Syscall(SB)%2CNOSPLIT%2C%240-28%0A%09BL%09runtime%C2%B7entersyscall(SB)%0A%09...%0A%09SWI%09%240%0A%09...%0A%09BL%09runtime%C2%B7exitsyscall(SB)%0A%60%60%60%0ASyscall%E6%80%BB%E6%8E%A5%E5%8F%A3%E5%AE%9A%E4%B9%89%E5%9C%A8%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9B%B8%E5%85%B3%E7%9A%84%E6%96%87%E4%BB%B6%E3%80%82Linux%E5%B9%B3%E5%8F%B0%E6%98%AFgo%2Fsrc%2Fsyscall%2Fasm_linux_arm.s%0AGo%E6%A1%86%E6%9E%B6%E5%9C%A8%E7%9C%9F%E6%AD%A3%E7%9A%84%E8%BF%9B%E5%86%85%E6%A0%B8%E8%B0%83%E7%94%A8%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E5%89%8D%E5%90%8E%E8%BF%9B%E8%A1%8C%E6%8E%A5%E7%AE%A1%EF%BC%8C%E6%8F%92%E5%85%A5%E4%BA%86%E9%85%8D%E5%90%88%E8%B0%83%E5%BA%A6%E7%9A%84%E4%BB%A3%E7%A0%81%E3%80%82%0A%0A%23%23%20entersyscall%0A%E5%81%87%E8%AE%BE%E8%B0%83%E7%94%A8Syscall%E4%B9%8B%E5%89%8D%EF%BC%8CGPM%E8%BF%90%E8%A1%8C%E7%9A%84%E7%8A%B6%E6%80%81%E5%A6%82%E4%B8%8B%E5%9B%BE%EF%BC%9A%0A!%5B747549a28a7a627a3cbd98fffe728fad.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6071)%0A%0A%23%23%23%20PM%E8%A7%A3%E7%BB%91%0A%E5%BD%93%E8%B0%83%E7%94%A8%E4%BA%86Syscall%E4%BB%A5%E5%90%8E%EF%BC%8C%E8%BF%9B%E5%85%A5entersyscall%EF%BC%8CP%E5%92%8CM%E4%BC%9A%E8%A7%A3%E7%BB%91%EF%BC%8C%E5%8F%98%E6%88%90%E4%B8%8B%E9%9D%A2%E8%BF%99%E5%BC%A0%E5%9B%BE%EF%BC%9A%0A!%5B96630c3dd34a06fbc5ed5f8b4c8bdfbc.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6072)%0A%0A%E8%BF%99%E5%BC%A0%E5%9B%BE%E4%B8%8D%E6%98%AF%E5%BE%88%E5%87%86%E7%A1%AE%EF%BC%8C%E5%BD%93M1%E5%92%8CP%E8%A7%A3%E7%BB%91%E6%97%B6%EF%BC%8CM2%E5%B9%B6%E6%B2%A1%E6%9C%89%E7%AB%8B%E5%8D%B3%E4%B8%8A%E4%BD%8D%EF%BC%8CP%E5%A4%84%E4%BA%8E_Psyscall%E7%8A%B6%E6%80%81%E3%80%82P%E6%98%AF%E5%90%A6%E4%B8%8E%E6%96%B0%E7%9A%84M%E7%BB%91%E5%AE%9A%E7%94%B1sysmon%E8%BF%99%E4%B8%AA%E7%89%B9%E6%AE%8AM%E6%9D%A5%E5%AE%8C%E6%88%90%E3%80%82%E5%90%8E%E9%9D%A2sysmon%E4%B8%80%E8%8A%82%E4%BC%9A%E4%B8%93%E9%97%A8%E4%BB%8B%E7%BB%8D%E3%80%82%0A%0A%60%60%60go%0A%09pp%20%3A%3D%20_g_.m.p.ptr()%0A%09pp.m%20%3D%200%0A%09_g_.m.oldp.set(pp)%0A%09_g_.m.p%20%3D%200%0A%60%60%60%0A%E6%AD%A4%E6%97%B6%E5%8E%9F%E5%85%88%E7%9A%84P%E8%A2%AB%E8%AE%B0%E5%85%A5%E4%BA%86m.oldp%EF%BC%8C%E6%9C%AA%E6%9D%A5%E4%BC%9A%E7%94%A8%E5%88%B0%E3%80%82%0A%0A%23%23%20exitsyscall%0A%E5%BD%93%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E7%BB%93%E6%9D%9F%E4%BB%A5%E5%90%8E%EF%BC%8C%E8%B0%83%E7%94%A8Syscall%E7%9A%84G%E9%9C%80%E8%A6%81%E5%BD%92%E4%BD%8D%0A!%5B5530edf8c481aee13a40ff0b55e8e1ed.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6073)%0A%E4%B8%8A%E5%9B%BE%E4%B8%ADG1%E8%A2%AB%E6%94%BE%E5%88%B0%E4%BA%86oldp%E7%9A%84%E9%98%9F%E5%88%97%E9%87%8C%EF%BC%8C%E5%AE%9E%E9%99%85%E5%B9%B6%E4%B8%8D%E4%B8%80%E5%AE%9A%E5%A6%82%E6%AD%A4%E3%80%82%0Aexitsyscall%E7%9A%84%E8%B0%83%E7%94%A8%E6%B5%81%E7%A8%8B%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%0A%60%60%60mermaid%0Agraph%20TD%0AA%5Bexitsyscall%5D%20--%3E%20B%5Bexitsyscallfast%5D%0AB%20--%3E%20%7Csuccess%7C%20C%5B_g_%3A%20_Gsyscall%20%3D%3E%20_Grunning%5D%0AB%20--%3E%20%7Cfail%7C%20D%5Bexitsyscall0%5D%0AC%20--%3E%20E%5Breturn%5D%0AD%20--%3E%20E%0A%60%60%60%0A%E8%BF%99%E5%85%B6%E4%B8%AD%E6%B6%89%E5%8F%8A%E4%B8%A4%E4%B8%AA%E9%87%8D%E8%A6%81%E5%87%BD%E6%95%B0%EF%BC%9A%0A-%20exitsyscallfast%0A-%20exitsyscall0%0A%0A%23%23%23%20exitsyscallfast%0A%E8%AF%A5%E5%87%BD%E6%95%B0%E4%BC%9A%E5%B0%9D%E8%AF%95%E5%85%88%E7%BB%91%E5%AE%9Aoldp%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%B8%8D%E6%88%90%E5%8A%9F%EF%BC%8C%E4%BC%9A%E5%9C%A8%E5%B0%9D%E8%AF%95%E5%85%B6%E4%BB%96idlep%E3%80%82M%E7%BB%91%E5%AE%9AP%E4%BD%BF%E7%94%A8wirep%E5%87%BD%E6%95%B0%E3%80%82%0A%E5%A6%82%E6%9E%9CP%EF%BC%8CM%E7%BB%91%E5%AE%9A%E6%88%90%E5%8A%9F%EF%BC%8C%E9%82%A3%E4%B9%88G%E6%98%AF%E4%B8%8D%E9%9C%80%E8%A6%81%E5%88%87%E6%8D%A2%E4%BB%BB%E4%BD%95%E9%98%9F%E5%88%97%EF%BC%8CG%E4%BC%9A%E7%BB%A7%E7%BB%AD%E8%BF%90%E8%A1%8C%E3%80%82%0A%E5%A6%82%E6%9E%9C%E6%97%A0%E6%B3%95%E7%BB%91%E5%AE%9A%EF%BC%8C%E5%88%99%E4%BC%9A%E5%81%9C%E6%AD%A2M%EF%BC%8C%E5%B9%B6%E6%89%BE%E5%88%B0%E5%9C%B0%E6%96%B9%E6%94%BE%E7%BD%AEG%E3%80%82%E8%BF%99%E4%B8%80%E8%BF%87%E7%A8%8B%E5%9C%A8exitsyscall0%E3%80%82%0A%0A%23%23%23%20exitsyscall0%0A%60%60%60mermaid%0Agraph%20TD%0AA%5Bexitsyscall0%5D%20--%3E%20B%5Bgp%3A%20_Gsyscall%20%3D%3E%20_Grunnable%5D%0AB%20--%3E%20C%5Bdropg%5D%0AC%20--%3E%20D%5Bpidleget%5D%0AD%20--%3E%20%7Cno%20idle%20P%7C%20E%5Bglobrunqput%5D%0AD%20--%3E%20%7Cfind%20idle%20P%7C%20F%5B%22aquirep%20%26%20execute(gp)%22%5D%0AE%20--%3E%20G%5Bstopm%5D%0AG%20--%3E%20H%5Bschedule%5D%0AF%20--%3E%20I%5Bnever%20return%20...%5D%0A%60%60%60%0Aexitsyscall0%E4%BB%8D%E7%84%B6%E4%BC%9A%E5%B0%9D%E8%AF%95%E8%8E%B7%E5%8F%96P%EF%BC%8C%E5%A6%82%E6%9E%9C%E8%83%BD%E8%8E%B7%E5%8F%96%E5%88%B0%EF%BC%8C%E5%88%99%E4%BC%9Aacquirep%EF%BC%8Cacquirep%E4%BC%9A%E8%B0%83%E7%94%A8wirep%E5%AE%8C%E6%88%90P%E5%92%8CM%E7%9A%84%E7%BB%91%E5%AE%9A%E3%80%82%E4%B9%8B%E5%90%8E%E8%B0%83%E7%94%A8execute%E5%87%BD%E6%95%B0%EF%BC%8C%E5%B9%B6%E4%B8%94%E4%B8%8D%E4%BC%9A%E5%86%8D%E8%BF%94%E5%9B%9E%E3%80%82%E5%9B%A0%E4%B8%BA%E5%9C%A8execute%20G%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E4%BB%8D%E7%84%B6%E4%BC%9A%E9%81%87%E5%88%B0%E8%B0%83%E5%BA%A6%E7%82%B9%E3%80%82%0A***%E6%B3%A8%EF%BC%9A%E5%A6%82%E6%9E%9C%E6%B2%A1%E6%9C%89%E9%81%87%E5%88%B0%E8%B0%83%E5%BA%A6%E7%82%B9%E7%9A%84%E6%83%85%E5%86%B5%E6%B2%A1%E6%9C%89%E6%83%B3%E6%98%8E%E7%99%BD%E3%80%82***%0A%0A%E5%A6%82%E6%9E%9Cexitsyscall0%E4%BB%8D%E7%84%B6%E6%B2%A1%E6%9C%89%E8%8E%B7%E5%8F%96P%EF%BC%8C%E5%88%99%E4%BC%9A%E8%B0%83%E7%94%A8stopm%E6%9D%A5%E5%81%9C%E6%AD%A2%E5%BD%93%E5%89%8DM%EF%BC%8C%E7%9B%B4%E5%88%B0%E8%A2%AB%E5%94%A4%E9%86%92%E3%80%82%E5%94%A4%E9%86%92%E4%B9%8B%E5%90%8E%E4%BC%9A%E7%9B%B4%E6%8E%A5%E8%BF%9B%E5%85%A5%E8%B0%83%E5%BA%A6%E3%80%82%0A%0A%23%23%20sysmon%0Asysmon%E6%98%AF%E4%B8%80%E4%B8%AA%E7%94%B1runtime%E5%90%AF%E5%8A%A8%E7%9A%84M%EF%BC%8C%E4%B9%9F%E5%8F%AB%E7%9B%91%E6%8E%A7%E7%BA%BF%E7%A8%8B%EF%BC%8C%E5%AE%83%E6%97%A0%E9%9C%80P%E4%B9%9F%E5%8F%AF%E4%BB%A5%E8%BF%90%E8%A1%8C%EF%BC%8C%E5%AE%83%E6%AF%8F20us~10ms%E5%94%A4%E9%86%92%E4%B8%80%E6%AC%A1%EF%BC%8C%E4%B8%BB%E8%A6%81%E6%89%A7%E8%A1%8C%3A%0A%0A-%20%E9%87%8A%E6%94%BE%E9%97%B2%E7%BD%AE%E8%B6%85%E8%BF%875%E5%88%86%E9%92%9F%E7%9A%84span%E7%89%A9%E7%90%86%E5%86%85%E5%AD%98%EF%BC%9B%0A-%20%E5%A6%82%E6%9E%9C%E8%B6%85%E8%BF%872%E5%88%86%E9%92%9F%E6%B2%A1%E6%9C%89%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%EF%BC%8C%E5%BC%BA%E5%88%B6%E6%89%A7%E8%A1%8C%EF%BC%9B%0A-%20%E5%B0%86%E9%95%BF%E6%97%B6%E9%97%B4%E6%9C%AA%E5%A4%84%E7%90%86%E7%9A%84netpoll%E7%BB%93%E6%9E%9C%E6%B7%BB%E5%8A%A0%E5%88%B0%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97%EF%BC%9B%0A-%20%E5%90%91%E9%95%BF%E6%97%B6%E9%97%B4%E8%BF%90%E8%A1%8C%E7%9A%84G%E4%BB%BB%E5%8A%A1%E5%8F%91%E5%87%BA%E6%8A%A2%E5%8D%A0%E8%B0%83%E5%BA%A6%EF%BC%9B%0A-%20%E6%94%B6%E5%9B%9E%E5%9B%A0syscall%E9%95%BF%E6%97%B6%E9%97%B4%E9%98%BB%E5%A1%9E%E7%9A%84P%EF%BC%9B%0A%E5%85%A5%E5%8F%A3%E5%9C%A8src%2Fruntime%2Fproc.go%3Asysmon%E5%87%BD%E6%95%B0%E3%80%82%0A%E5%9B%A0%E4%B8%BA%E6%88%91%E4%B8%BB%E8%A6%81%E5%85%B3%E6%B3%A8%E7%9A%84%E6%98%AFGo%E8%B0%83%E5%BA%A6%E6%A1%86%E6%9E%B6%EF%BC%8C%E6%89%80%E4%BB%A5sysmon%E4%B8%AD%E5%85%B3%E4%BA%8EGC%EF%BC%8CCGO%EF%BC%8Ctrace%E7%AD%89%E9%83%A8%E5%88%86%E9%83%BD%E5%BF%BD%E7%95%A5%E6%8E%89%E4%BA%86%E3%80%82%E6%89%80%E4%BB%A5%E5%8F%AA%E5%89%A9%E4%B8%8Bretake%E5%87%BD%E6%95%B0%E3%80%82retake%E4%BC%9A%E5%AF%B9syscall%E5%92%8C%E9%95%BF%E6%97%B6%E9%97%B4%E8%BF%90%E8%A1%8C%E7%9A%84G%E8%BF%9B%E8%A1%8C%E6%8E%A5%E7%AE%A1%E3%80%82%0A%0A%23%23%23%20retake%0Aretake%E4%BC%9A%E9%81%8D%E5%8E%86%E6%89%80%E6%9C%89%E7%9A%84P%EF%BC%8C%E5%8D%B3allp%E6%95%B0%E7%BB%84%EF%BC%8C%E5%81%9A%E4%B8%A4%E4%BB%B6%E4%BA%8B%E3%80%82%0A1.%20%E6%8A%A2%E5%8D%A0%E8%BF%90%E8%A1%8C%E8%BF%87%E4%B9%85%E7%9A%84G%0A2.%20handoff%E5%A4%84%E4%BA%8E_Psyscall%E8%BF%87%E4%B9%85%E7%9A%84P%0A%0A%23%23%23%23%20preempt%20G%0A%E8%BF%99%E9%87%8C%E8%A1%A8%E7%A4%BA%E5%9C%A8%E6%9F%90%E4%B8%80%E4%B8%AAP%E4%B8%8A%EF%BC%8C%E5%8D%B3%E4%B8%80%E4%B8%AA%E6%9F%90%E4%B8%AACPU%E6%A0%B8%E4%B8%8A%E8%BF%90%E8%A1%8C%E7%9A%84G%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4%E8%BF%87%E4%BA%8E%E4%B9%85%E3%80%82%0A%E5%88%A4%E6%96%ADG%E8%BF%90%E8%A1%8C%E8%BF%87%E4%B9%85%E7%9A%84%E6%96%B9%E6%B3%95%E6%98%AF%EF%BC%9A%0A-%20retake%E4%BC%A0%E5%85%A5%E7%9A%84%E5%8F%82%E6%95%B0now%20%3D%20noontime()%0A-%20retake%E4%BC%9A%E8%AE%B0%E5%BD%95%E6%AF%8F%E6%AC%A1%E8%B0%83%E7%94%A8retake%E7%9A%84%E6%97%B6%E9%97%B4%E7%82%B9%E5%9C%A8_p_.sysmontick.schedwhen%E4%B8%AD%20%0A-%20%E5%A6%82%E6%9E%9C%60schedwhen%2BforcePreemptNS%20%3C%3D%20now%60%E8%A1%A8%E7%A4%BAG%E8%BF%90%E8%A1%8C%E8%BF%87%E4%B9%85%EF%BC%8C%E5%85%B6%E4%B8%ADforcePreemptNS%20%3D%2010ms%0A%0A%23%23%23%23%20handoff%20P%0A%E4%B8%8E%E4%B8%8A%E4%B8%80%E8%8A%82%E7%B1%BB%E4%BC%BC%EF%BC%8C%E6%AD%A4%E5%A4%84%E8%A6%81%E5%88%A4%E6%96%ADP%E5%A4%84%E4%BA%8E_Psyscall%E7%9A%84%E6%97%B6%E9%97%B4%E8%BF%87%E4%B9%85%E3%80%82%0A%E6%AF%8F%E4%B8%80%E6%AC%A1retake%EF%BC%8C%E8%AE%B0%E5%BD%95%E6%97%B6%E9%97%B4%E5%88%B0_p_.sysmontick.schedwhen%E3%80%82%E5%BD%93%E5%8F%91%E7%94%9F%E4%B8%8B%E9%9D%A2%E7%9A%84%E6%83%85%E5%86%B5%EF%BC%8C%E5%88%99%E8%A1%A8%E7%A4%BAP%E5%A4%84%E4%BA%8E_Psyscall%E6%97%B6%E9%97%B4%E5%A4%AA%E4%B9%85%EF%BC%9A%0A%60syscallwhen%2B10*1000*1000%20%3C%3D%20now%20%60%0A%E4%B9%8B%E5%90%8E%E5%B0%86P%E7%9A%84%E7%8A%B6%E6%80%81%E5%88%87%E6%8D%A2%E4%B8%BA_Pidle%2C%E7%84%B6%E5%90%8E%E8%B0%83%E7%94%A8handoffp%E6%9D%A5%E7%BB%91%E5%AE%9AP%E5%92%8C%E4%B8%80%E4%B8%AA%E6%96%B0%E7%9A%84M%E3%80%82%0A%E5%AE%9E%E9%99%85%E4%B8%8A%E8%BF%99%E9%87%8C%E6%89%8D%E5%AE%8C%E6%88%90%E4%BA%86%E8%BF%99%E5%B9%85%E5%9B%BE%E4%B8%8AM2%E4%B8%8EP%E7%9A%84%E7%BB%91%E5%AE%9A%EF%BC%9A%0A!%5B96630c3dd34a06fbc5ed5f8b4c8bdfbc.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6072)%0A%0A%23%23%20%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%0A-%20%5BScheduling%20In%20Go%20%3A%20Part%20II%20-%20Go%20Scheduler%5D(https%3A%2F%2Fwww.ardanlabs.com%2Fblog%2F2018%2F08%2Fscheduling-in-go-part2.html)%0A-%20%5BGo%20%E8%B0%83%E5%BA%A6%E6%A8%A1%E5%9E%8B%5D(https%3A%2F%2Fwudaijun.com%2F2018%2F01%2Fgo-scheduler%2F)%0A%0A%0A

本文基于Go 1.13。
Go提供了一套runtime机制,来提供其协程调度特性。实际上就是完成一种类似JavaScript的event-driven编程或者异步编程的范式。其带来的特性是,大大增加了Go app的并发特性(可达百万级,甚至更多的并发)。特别适用于所有并发都是无差别的场景下。例如网络连接。但因为没有优先级概念,实际上Go的调度框架对实时性是有损害的。
本文专注于分析调度框架,以及一些框架的实现细节。文末会列举我在阅读时参考的网页链接。

GPM

Go基于GPM这三个object来组织调度框架。大致结构如下:

  • G: Gourtines, 每个Goroutine对应一个G结构体,G保存Goroutine的运行堆栈,即并发任务状态。
  • P: Processors, 理想状态下一个P对应一个CPU核。对M来说,P提供了相关的执行环境(Context),如内存分配状态(mcache),任务队列(G)等
  • M: Machine, OS线程抽象,当和某个P绑定,从P的runq中不断取出G,切换堆栈并执行,M本身不具备执行状态,在需要任务切换时,M将堆栈状态写回G,任何其它M都能据此恢复执行。

schedule

调度始于Go bootstrap过程的mstart,每一轮调度,实际就是一次schedule函数的调用。
该函数定义在go/src/runtime/proc.go中。
本文针对调度器进行分析,仍然忽略以下特性,包括但不限于:

  • garbage collection
  • C Go
  • Linux signal处理
  • Trace操作
  • 栈操作
    一次调度的流程如下:
PHN2ZyBpZD0iZGpmNnB4MDFtdW8iIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDMwMC4zOTg0Mzc1cHg7IiB2aWV3Qm94PSIwIDAgMzAwLjM5ODQzNzUgOTc4LjE5ODQyNTI5Mjk2ODgiPjxzdHlsZT4KCgojZGpmNnB4MDFtdW8gLmxhYmVsIHsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGNvbG9yOiAjMzMzOyB9CgojZGpmNnB4MDFtdW8gLm5vZGUgcmVjdCwKI2RqZjZweDAxbXVvIC5ub2RlIGNpcmNsZSwKI2RqZjZweDAxbXVvIC5ub2RlIGVsbGlwc2UsCiNkamY2cHgwMW11byAubm9kZSBwb2x5Z29uIHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDFweDsgfQoKI2RqZjZweDAxbXVvIC5ub2RlLmNsaWNrYWJsZSB7CiAgY3Vyc29yOiBwb2ludGVyOyB9CgojZGpmNnB4MDFtdW8gLmFycm93aGVhZFBhdGggewogIGZpbGw6ICMzMzMzMzM7IH0KCiNkamY2cHgwMW11byAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzMzMzMzMzsKICBzdHJva2Utd2lkdGg6IDEuNXB4OyB9CgojZGpmNnB4MDFtdW8gLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2U4ZThlODsgfQoKI2RqZjZweDAxbXVvIC5jbHVzdGVyIHJlY3QgewogIGZpbGw6ICNmZmZmZGUgIWltcG9ydGFudDsKICBzdHJva2U6ICNhYWFhMzMgIWltcG9ydGFudDsKICBzdHJva2Utd2lkdGg6IDFweCAhaW1wb3J0YW50OyB9CgojZGpmNnB4MDFtdW8gLmNsdXN0ZXIgdGV4dCB7CiAgZmlsbDogIzMzMzsgfQoKI2RqZjZweDAxbXVvIGRpdi5tZXJtYWlkVG9vbHRpcCB7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBtYXgtd2lkdGg6IDIwMHB4OwogIHBhZGRpbmc6IDJweDsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTJweDsKICBiYWNrZ3JvdW5kOiAjZmZmZmRlOwogIGJvcmRlcjogMXB4IHNvbGlkICNhYWFhMzM7CiAgYm9yZGVyLXJhZGl1czogMnB4OwogIHBvaW50ZXItZXZlbnRzOiBub25lOwogIHotaW5kZXg6IDEwMDsgfQoKI2RqZjZweDAxbXVvIC5hY3RvciB7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOwogIGZpbGw6ICNFQ0VDRkY7IH0KCiNkamY2cHgwMW11byB0ZXh0LmFjdG9yIHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkamY2cHgwMW11byAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiBncmV5OyB9CgojZGpmNnB4MDFtdW8gLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMzMzOyB9CgojZGpmNnB4MDFtdW8gLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMzMzOyB9CgojZGpmNnB4MDFtdW8gI2Fycm93aGVhZCB7CiAgZmlsbDogIzMzMzsgfQoKI2RqZjZweDAxbXVvICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzMzMyAhaW1wb3J0YW50OwogIHN0cm9rZTogIzMzMyAhaW1wb3J0YW50OyB9CgojZGpmNnB4MDFtdW8gLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMzMzOwogIHN0cm9rZTogbm9uZTsgfQoKI2RqZjZweDAxbXVvIC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOwogIGZpbGw6ICNFQ0VDRkY7IH0KCiNkamY2cHgwMW11byAubGFiZWxUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkamY2cHgwMW11byAubG9vcFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RqZjZweDAxbXVvIC5sb29wTGluZSB7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogI0NDQ0NGRjsgfQoKI2RqZjZweDAxbXVvIC5ub3RlIHsKICBzdHJva2U6ICNhYWFhMzM7CiAgZmlsbDogI2ZmZjVhZDsgfQoKI2RqZjZweDAxbXVvIC5ub3RlVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxNHB4OyB9CgojZGpmNnB4MDFtdW8gLmFjdGl2YXRpb24wIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2RqZjZweDAxbXVvIC5hY3RpdmF0aW9uMSB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNkamY2cHgwMW11byAuYWN0aXZhdGlvbjIgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgoKI2RqZjZweDAxbXVvIC5zZWN0aW9uIHsKICBzdHJva2U6IG5vbmU7CiAgb3BhY2l0eTogMC4yOyB9CgojZGpmNnB4MDFtdW8gLnNlY3Rpb24wIHsKICBmaWxsOiByZ2JhKDEwMiwgMTAyLCAyNTUsIDAuNDkpOyB9CgojZGpmNnB4MDFtdW8gLnNlY3Rpb24yIHsKICBmaWxsOiAjZmZmNDAwOyB9CgojZGpmNnB4MDFtdW8gLnNlY3Rpb24xLAojZGpmNnB4MDFtdW8gLnNlY3Rpb24zIHsKICBmaWxsOiB3aGl0ZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkamY2cHgwMW11byAuc2VjdGlvblRpdGxlMCB7CiAgZmlsbDogIzMzMzsgfQoKI2RqZjZweDAxbXVvIC5zZWN0aW9uVGl0bGUxIHsKICBmaWxsOiAjMzMzOyB9CgojZGpmNnB4MDFtdW8gLnNlY3Rpb25UaXRsZTIgewogIGZpbGw6ICMzMzM7IH0KCiNkamY2cHgwMW11byAuc2VjdGlvblRpdGxlMyB7CiAgZmlsbDogIzMzMzsgfQoKI2RqZjZweDAxbXVvIC5zZWN0aW9uVGl0bGUgewogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7CiAgdGV4dC1oZWlnaHQ6IDE0cHg7IH0KCgojZGpmNnB4MDFtdW8gLmdyaWQgLnRpY2sgewogIHN0cm9rZTogbGlnaHRncmV5OwogIG9wYWNpdHk6IDAuMzsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkamY2cHgwMW11byAuZ3JpZCBwYXRoIHsKICBzdHJva2Utd2lkdGg6IDA7IH0KCgojZGpmNnB4MDFtdW8gLnRvZGF5IHsKICBmaWxsOiBub25lOwogIHN0cm9rZTogcmVkOwogIHN0cm9rZS13aWR0aDogMnB4OyB9CgoKCiNkamY2cHgwMW11byAudGFzayB7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZGpmNnB4MDFtdW8gLnRhc2tUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMTFweDsgfQoKI2RqZjZweDAxbXVvIC50YXNrVGV4dE91dHNpZGVSaWdodCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsgfQoKI2RqZjZweDAxbXVvIC50YXNrVGV4dE91dHNpZGVMZWZ0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogZW5kOwogIGZvbnQtc2l6ZTogMTFweDsgfQoKCiNkamY2cHgwMW11byAudGFza1RleHQwLAojZGpmNnB4MDFtdW8gLnRhc2tUZXh0MSwKI2RqZjZweDAxbXVvIC50YXNrVGV4dDIsCiNkamY2cHgwMW11byAudGFza1RleHQzIHsKICBmaWxsOiB3aGl0ZTsgfQoKI2RqZjZweDAxbXVvIC50YXNrMCwKI2RqZjZweDAxbXVvIC50YXNrMSwKI2RqZjZweDAxbXVvIC50YXNrMiwKI2RqZjZweDAxbXVvIC50YXNrMyB7CiAgZmlsbDogIzhhOTBkZDsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNkamY2cHgwMW11byAudGFza1RleHRPdXRzaWRlMCwKI2RqZjZweDAxbXVvIC50YXNrVGV4dE91dHNpZGUyIHsKICBmaWxsOiBibGFjazsgfQoKI2RqZjZweDAxbXVvIC50YXNrVGV4dE91dHNpZGUxLAojZGpmNnB4MDFtdW8gLnRhc2tUZXh0T3V0c2lkZTMgewogIGZpbGw6IGJsYWNrOyB9CgoKI2RqZjZweDAxbXVvIC5hY3RpdmUwLAojZGpmNnB4MDFtdW8gLmFjdGl2ZTEsCiNkamY2cHgwMW11byAuYWN0aXZlMiwKI2RqZjZweDAxbXVvIC5hY3RpdmUzIHsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2RqZjZweDAxbXVvIC5hY3RpdmVUZXh0MCwKI2RqZjZweDAxbXVvIC5hY3RpdmVUZXh0MSwKI2RqZjZweDAxbXVvIC5hY3RpdmVUZXh0MiwKI2RqZjZweDAxbXVvIC5hY3RpdmVUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKCiNkamY2cHgwMW11byAuZG9uZTAsCiNkamY2cHgwMW11byAuZG9uZTEsCiNkamY2cHgwMW11byAuZG9uZTIsCiNkamY2cHgwMW11byAuZG9uZTMgewogIHN0cm9rZTogZ3JleTsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZGpmNnB4MDFtdW8gLmRvbmVUZXh0MCwKI2RqZjZweDAxbXVvIC5kb25lVGV4dDEsCiNkamY2cHgwMW11byAuZG9uZVRleHQyLAojZGpmNnB4MDFtdW8gLmRvbmVUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKCiNkamY2cHgwMW11byAuY3JpdDAsCiNkamY2cHgwMW11byAuY3JpdDEsCiNkamY2cHgwMW11byAuY3JpdDIsCiNkamY2cHgwMW11byAuY3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZGpmNnB4MDFtdW8gLmFjdGl2ZUNyaXQwLAojZGpmNnB4MDFtdW8gLmFjdGl2ZUNyaXQxLAojZGpmNnB4MDFtdW8gLmFjdGl2ZUNyaXQyLAojZGpmNnB4MDFtdW8gLmFjdGl2ZUNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkamY2cHgwMW11byAuZG9uZUNyaXQwLAojZGpmNnB4MDFtdW8gLmRvbmVDcml0MSwKI2RqZjZweDAxbXVvIC5kb25lQ3JpdDIsCiNkamY2cHgwMW11byAuZG9uZUNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsKICBjdXJzb3I6IHBvaW50ZXI7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZGpmNnB4MDFtdW8gLmRvbmVDcml0VGV4dDAsCiNkamY2cHgwMW11byAuZG9uZUNyaXRUZXh0MSwKI2RqZjZweDAxbXVvIC5kb25lQ3JpdFRleHQyLAojZGpmNnB4MDFtdW8gLmRvbmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkamY2cHgwMW11byAuYWN0aXZlQ3JpdFRleHQwLAojZGpmNnB4MDFtdW8gLmFjdGl2ZUNyaXRUZXh0MSwKI2RqZjZweDAxbXVvIC5hY3RpdmVDcml0VGV4dDIsCiNkamY2cHgwMW11byAuYWN0aXZlQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZGpmNnB4MDFtdW8gLnRpdGxlVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDE4cHg7CiAgZmlsbDogYmxhY2s7IH0KCiNkamY2cHgwMW11byBnLmNsYXNzR3JvdXAgdGV4dCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkamY2cHgwMW11byBnLmNsYXNzR3JvdXAgcmVjdCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7IH0KCiNkamY2cHgwMW11byBnLmNsYXNzR3JvdXAgbGluZSB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RqZjZweDAxbXVvIC5jbGFzc0xhYmVsIC5ib3ggewogIHN0cm9rZTogbm9uZTsKICBzdHJva2Utd2lkdGg6IDA7CiAgZmlsbDogI0VDRUNGRjsKICBvcGFjaXR5OiAwLjU7IH0KCiNkamY2cHgwMW11byAuY2xhc3NMYWJlbCAubGFiZWwgewogIGZpbGw6ICM5MzcwREI7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZGpmNnB4MDFtdW8gLnJlbGF0aW9uIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOwogIGZpbGw6IG5vbmU7IH0KCiNkamY2cHgwMW11byAjY29tcG9zaXRpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGpmNnB4MDFtdW8gI2NvbXBvc2l0aW9uRW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkamY2cHgwMW11byAjYWdncmVnYXRpb25TdGFydCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGpmNnB4MDFtdW8gI2FnZ3JlZ2F0aW9uRW5kIHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkamY2cHgwMW11byAjZGVwZW5kZW5jeVN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkamY2cHgwMW11byAjZGVwZW5kZW5jeUVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGpmNnB4MDFtdW8gI2V4dGVuc2lvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkamY2cHgwMW11byAjZXh0ZW5zaW9uRW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkamY2cHgwMW11byAuY29tbWl0LWlkLAojZGpmNnB4MDFtdW8gLmNvbW1pdC1tc2csCiNkamY2cHgwMW11byAuYnJhbmNoLWxhYmVsIHsKICBmaWxsOiBsaWdodGdyZXk7CiAgY29sb3I6IGxpZ2h0Z3JleTsgfQoKCgojZGpmNnB4MDFtdW8gLmxhYmVsewogIGNvbG9yOiMxOEIxNEU7Cn0KI2RqZjZweDAxbXVvIC50ZS1tZC1jb250YWluZXItLWRhcmsgLm5vZGUgcmVjdCB7CiAgZmlsbDogcmVkOwp9CgojZGpmNnB4MDFtdW8gLm5vZGUgcmVjdCwKI2RqZjZweDAxbXVvIC5ub2RlIGNpcmNsZSwKI2RqZjZweDAxbXVvIC5ub2RlIGVsbGlwc2UsCiNkamY2cHgwMW11byAubm9kZSBwb2x5Z29uIHsKICBmaWxsOiAjRjlGRkZCOzsKICBzdHJva2U6ICMyREJENjA7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsKfQojZGpmNnB4MDFtdW8gLmFycm93aGVhZFBhdGh7CiAgZmlsbDogIzJEQkQ2MDsKfQojZGpmNnB4MDFtdW8gLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMyREJENjA7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7Cn0KI2RqZjZweDAxbXVvIC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNmZmY7Cn0KI2RqZjZweDAxbXVvIC5jbHVzdGVyIHJlY3QgewogIGZpbGw6ICNGOUZGRkIgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2Utd2lkdGg6IDFweCAhaW1wb3J0YW50Owp9CgojZGpmNnB4MDFtdW8gLmNsdXN0ZXIgdGV4dCB7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RqZjZweDAxbXVvIGRpdi5tZXJtYWlkVG9vbHRpcCB7CiAgYmFja2dyb3VuZDogI0Y5RkZGQjsKICBib3JkZXI6IDFweCBzb2xpZCAjMkRCRDYwOwp9CgoKI2RqZjZweDAxbXVvIC5hY3RvciB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkamY2cHgwMW11byB0ZXh0LmFjdG9yIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2RqZjZweDAxbXVvIC5hY3Rvci1saW5lIHsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkamY2cHgwMW11byAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkamY2cHgwMW11byAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkamY2cHgwMW11byAjYXJyb3doZWFkIHsKICBmaWxsOiAjMkRCRDYwOwp9CgojZGpmNnB4MDFtdW8gI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7Cn0KCiNkamY2cHgwMW11byAubWVzc2FnZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZGpmNnB4MDFtdW8gLmxhYmVsQm94IHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RqZjZweDAxbXVvIC5sYWJlbFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZGpmNnB4MDFtdW8gLmxvb3BUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RqZjZweDAxbXVvIC5sb29wTGluZSB7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RqZjZweDAxbXVvIC5ub3RlIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RqZjZweDAxbXVvIC5ub3RlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCgojZGpmNnB4MDFtdW8gLnNlY3Rpb257CiAgb3BhY2l0eToxOwp9CiNkamY2cHgwMW11byAuc2VjdGlvbjAsI2RqZjZweDAxbXVvICAuc2VjdGlvbjIgewogIGZpbGw6ICNFQ0Y3RjA7Cn0KCiNkamY2cHgwMW11byAuc2VjdGlvbjEsCiNkamY2cHgwMW11byAuc2VjdGlvbjMgewogIGZpbGw6ICNGRkY7Cn0KI2RqZjZweDAxbXVvIC50YXNrVGV4dDAsCiNkamY2cHgwMW11byAudGFza1RleHQxLAojZGpmNnB4MDFtdW8gLnRhc2tUZXh0MiwKI2RqZjZweDAxbXVvIC50YXNrVGV4dDMgewogIGZpbGw6ICNmZmY7Cn0KCiNkamY2cHgwMW11byAudGFzazAsCiNkamY2cHgwMW11byAudGFzazEsCiNkamY2cHgwMW11byAudGFzazIsCiNkamY2cHgwMW11byAudGFzazMgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMzU5RjVBOwp9Cjwvc3R5bGU+PHN0eWxlPiNkamY2cHgwMW11byB7CiAgICBjb2xvcjogcmdiKDI0NCwgMjQ0LCAyNDQpOwogICAgZm9udDogbm9ybWFsIG5vcm1hbCBub3JtYWwgbm9ybWFsIDE0cHgvMjIuMzk5OTk5NjE4NTMwMjczcHggbW9ub3NwYWNlOwogIH08L3N0eWxlPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMiwgLTEyKSI+PGcgY2xhc3M9Im91dHB1dCI+PGcgY2xhc3M9ImNsdXN0ZXJzIj48L2c+PGcgY2xhc3M9ImVkZ2VQYXRocyI+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTcxLjI1LDU2LjI4MTI1TDE3MS4yNSw4MS4yODEyNUwxNzEuNzQ5OTk5OTk5OTk5OTcsMTA2Ljc4MTI1MzA1MTc1NzgiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTQ2MykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTQ2MyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE0MC4zODQyNDM0Mjg1NDM2LDIzOC4xNzQ4NjUzNzY3ODU4TDk5LjQyOTY4NzUsMzAyLjE4MTI0Mzg5NjQ4NDRMOTkuNDI5Njg3NSwzNTMuNDYyNDkzODk2NDg0NEw5OS40Mjk2ODc1LDQwNC43NDM3NDM4OTY0ODQ0TDExNC4xODQ5Mzk4NzA4ODY2NSw0MzcuODg0MzY4ODk2NDg0NCIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NDY0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NDY0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTk4Ljk2NDUwODcwOTc3MzA3LDI0Mi4zMjYxMTkzNDE5ODQ1N0wyMjguNzg5MDYyNSwzMDIuMTgxMjQzODk2NDg0NEwyMjguNzg5MDYyNSwzMzUuMzIxODY4ODk2NDg0NCIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NDY1KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NDY1IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjExLjQ1OTU2OTk1NTQzODc1LDM3MS42MDMxMTg4OTY0ODQ0TDE3OS44MDA3ODEyNSw0MDQuNzQzNzQzODk2NDg0NEwxNDIuNjE2MDMwNjIxNTcyMiw0MzcuODg0MzY4ODk2NDg0NCIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NDY2KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NDY2IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTAzLjE4MDA2OTU1NTUzMDE3LDQ3NC4xNjU2MTg4OTY0ODQ0TDY4LjMyMDMxMjUsNTA3LjMwNjI0Mzg5NjQ4NDRMNjguMzIwMzEyNSw1NDAuNDQ2ODY4ODk2NDg0NCIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NDY3KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NDY3IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNNjguMzIwMzEyNSw1NzYuNzI4MTE4ODk2NDg0NEw2OC4zMjAzMTI1LDYwMS43MjgxMTg4OTY0ODQ0TDEzNS4xMjk0Mjk1MDczNTQ0Nyw2NjguODAxODE3NDQwODg3NCIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NDY4KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NDY4IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTUxLjgwNzQyOTY2NDIwNjI0LDc2OC45NTg5ODMwMDg5MzI4TDEyNi41NzQyMTg3NSw4MjYuNDk1MzAwMjkyOTY4OEwxMjYuNTc0MjE4NzUsODU5LjYzNTkyNTI5Mjk2ODgiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTQ2OSkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTQ2OSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTEyNi41NzQyMTg3NSw4OTUuOTE3MTc1MjkyOTY4OEwxMjYuNTc0MjE4NzUsOTIwLjkxNzE3NTI5Mjk2ODhMMTU1LjMzNDE3ODkwOTM2MjU1LDk0NS45MTcxNzUyOTI5Njg4IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk0NzApIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk0NzAiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yMzYuODY1ODQxMzc5MTEzMzMsMzcxLjYwMzExODg5NjQ4NDRMMjUxLjYyMTA5Mzc1LDQwNC43NDM3NDM4OTY0ODQ0TDI1MS42MjEwOTM3NSw0NTYuMDI0OTkzODk2NDg0NEwyNTEuNjIxMDkzNzUsNTA3LjMwNjI0Mzg5NjQ4NDRMMjUxLjYyMTA5Mzc1LDU1OC41ODc0OTM4OTY0ODQ0TDI1MS42MjEwOTM3NSw2MDEuNzI4MTE4ODk2NDg0NEwyMTAuOTAxNTQ1NDk4MDc5NDYsNjYxLjQyNjUzNjM0MjgwNTkiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTQ3MSkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTQ3MSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE0MS4zNDMzNjc5NDQ0Njk4Myw0NzQuMTY1NjE4ODk2NDg0NEwxNzYuMjAzMTI1LDUwNy4zMDYyNDM4OTY0ODQ0TDE3Ni4yMDMxMjUsNTU4LjU4NzQ5Mzg5NjQ4NDRMMTc2LjIwMzEyNSw2MDEuNzI4MTE4ODk2NDg0NEwxNzYuNzAzMTI0OTk5OTk5OTcsNjI3LjIyODEyMTk0ODI0MjEiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTQ3MikiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTQ3MiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE5Ny44OTM0MDUzMjMwNzIsNzcyLjY2NDQwNDEyNTE3TDIxNS45MjU3ODEyNSw4MjYuNDk1MzAwMjkyOTY4OEwyMTUuOTI1NzgxMjUsODc3Ljc3NjU1MDI5Mjk2ODhMMjE1LjkyNTc4MTI1LDkyMC45MTcxNzUyOTI5Njg4TDE5Mi45MDY0OTQ3NTk1OTc5Niw5NDUuOTE3MTc1MjkyOTY4OCIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NDczKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NDczIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWxzIj48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg5OS40Mjk2ODc1LDM1My40NjI0OTM4OTY0ODQ0KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNC4yMDMxMjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iOC45Mzc1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5OPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjguNzg5MDYyNSwzMDIuMTgxMjQzODk2NDg0NCkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQuMjAzMTI1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjgiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPlk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE3OS44MDA3ODEyNSw0MDQuNzQzNzQzODk2NDg0NCkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM2LjYwOTM3NSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI1MS4zMjgxMjUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmdwID09IG5pbDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjguMzIwMzEyNSw1MDcuMzA2MjQzODk2NDg0NCkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM2LjYwOTM3NSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI1MS4zMjgxMjUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmdwID09IG5pbDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTI2LjU3NDIxODc1LDgyNi40OTUzMDAyOTI5Njg4KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNC4yMDMxMjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iOCIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+WTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjUxLjYyMTA5Mzc1LDUwNy4zMDYyNDM4OTY0ODQ0KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzYuNjA5Mzc1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjQ5LjE0MDYyNSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+Z3AgIT0gbmlsPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzYuMjAzMTI1LDU1OC41ODc0OTM4OTY0ODQ0KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzYuNjA5Mzc1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjQ5LjE0MDYyNSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+Z3AgIT0gbmlsPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMTUuOTI1NzgxMjUsODc3Ljc3NjU1MDI5Mjk2ODgpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI4LjkzNzUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPk48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZXMiPjxnIGNsYXNzPSJub2RlIiBpZD0iQSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTcxLjI1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMzYuNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjczIiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjYuNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+c2NoZWR1bGU8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE3MS4yNSwxODcuNjYwOTM0NDQ4MjQyMikiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBvbHlnb24gcG9pbnRzPSI4MS4zNzk2ODc1LDAgMTYyLjc1OTM3NSwtODEuMzc5Njg3NSA4MS4zNzk2ODc1LC0xNjIuNzU5Mzc1IDAsLTgxLjM3OTY4NzUiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTgxLjM3OTY4NzUsODEuMzc5Njg3NSkiPjwvcG9seWdvbj48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02Mi4yODEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+c2NoZWR0aWNrICUgNjEgPT0gMCA/PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJEIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjIuMjYxNzE4NzUsNDU2LjAyNDk5Mzg5NjQ4NDQpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTYyLjk3NjU2MjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxMjUuOTUzMTI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTIuOTc2NTYyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+cnVucWdldChfZ18ubS5wKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iQyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjI4Ljc4OTA2MjUsMzUzLjQ2MjQ5Mzg5NjQ4NDQpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTc1LjYwOTM3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjE1MS4yMTg3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTY1LjYwOTM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+Z2xvYnJ1bnFnZXQoX2dfLm0ucCk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDY4LjMyMDMxMjUsNTU4LjU4NzQ5Mzg5NjQ4NDQpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTQ4LjMyMDMxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI5Ni42NDA2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOC4zMjAzMTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5maW5kcnVubmFibGU8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE3Ni4yMDMxMjUsNzEwLjA0MTM5NzA5NDcyNjYpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwb2x5Z29uIHBvaW50cz0iODMuMzEzMjgxMjUsMCAxNjYuNjI2NTYyNSwtODMuMzEzMjgxMjUgODMuMzEzMjgxMjUsLTE2Ni42MjY1NjI1IDAsLTgzLjMxMzI4MTI1IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04My4zMTMyODEyNSw4My4zMTMyODEyNSkiPjwvcG9seWdvbj48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02NC40Mjk2ODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5fZ18ubS5zcGlubmluZyA9PSAxID88L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyNi41NzQyMTg3NSw4NzcuNzc2NTUwMjkyOTY4OCkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNDkuODgyODEyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9Ijk5Ljc2NTYyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM5Ljg4MjgxMjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnJlc2V0c3Bpbm5pbmc8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkYiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE3Ni4yMDMxMjUsOTY0LjA1NzgwMDI5Mjk2ODgpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTQ2LjA4NTkzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI5Mi4xNzE4NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNi4wODU5Mzc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5leGVjdXRlKGdwKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==

globrunqget & runqget

这两个函数非常类似,一个从全局队列中取,一个从本地队列中取。取的时机各有不同。

globrunqget

Go调度器为了全局队列中的G不被饿死,没61次调度都会检查一下全局队列中的G,并取出运行。

PHN2ZyBpZD0iZDh5bzYzNGNnYWMiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDM4Ni4zMTI1cHg7IiB2aWV3Qm94PSIwIDAgMzg2LjMxMjUgNTg2LjI1Ij48c3R5bGU+CgoKI2Q4eW82MzRjZ2FjIC5sYWJlbCB7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBjb2xvcjogIzMzMzsgfQoKI2Q4eW82MzRjZ2FjIC5ub2RlIHJlY3QsCiNkOHlvNjM0Y2dhYyAubm9kZSBjaXJjbGUsCiNkOHlvNjM0Y2dhYyAubm9kZSBlbGxpcHNlLAojZDh5bzYzNGNnYWMgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7IH0KCiNkOHlvNjM0Y2dhYyAubm9kZS5jbGlja2FibGUgewogIGN1cnNvcjogcG9pbnRlcjsgfQoKI2Q4eW82MzRjZ2FjIC5hcnJvd2hlYWRQYXRoIHsKICBmaWxsOiAjMzMzMzMzOyB9CgojZDh5bzYzNGNnYWMgLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMzMzMzMzM7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsgfQoKI2Q4eW82MzRjZ2FjIC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNlOGU4ZTg7IH0KCiNkOHlvNjM0Y2dhYyAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjZmZmZmRlICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjYWFhYTMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsgfQoKI2Q4eW82MzRjZ2FjIC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICMzMzM7IH0KCiNkOHlvNjM0Y2dhYyBkaXYubWVybWFpZFRvb2x0aXAgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWF4LXdpZHRoOiAyMDBweDsKICBwYWRkaW5nOiAycHg7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEycHg7CiAgYmFja2dyb3VuZDogI2ZmZmZkZTsKICBib3JkZXI6IDFweCBzb2xpZCAjYWFhYTMzOwogIGJvcmRlci1yYWRpdXM6IDJweDsKICBwb2ludGVyLWV2ZW50czogbm9uZTsKICB6LWluZGV4OiAxMDA7IH0KCiNkOHlvNjM0Y2dhYyAuYWN0b3IgewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZDh5bzYzNGNnYWMgdGV4dC5hY3RvciB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZDh5bzYzNGNnYWMgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogZ3JleTsgfQoKI2Q4eW82MzRjZ2FjIC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2Q4eW82MzRjZ2FjIC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2Q4eW82MzRjZ2FjICNhcnJvd2hlYWQgewogIGZpbGw6ICMzMzM7IH0KCiNkOHlvNjM0Y2dhYyAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMzMzMgIWltcG9ydGFudDsKICBzdHJva2U6ICMzMzMgIWltcG9ydGFudDsgfQoKI2Q4eW82MzRjZ2FjIC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzMzMzsKICBzdHJva2U6IG5vbmU7IH0KCiNkOHlvNjM0Y2dhYyAubGFiZWxCb3ggewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZDh5bzYzNGNnYWMgLmxhYmVsVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZDh5bzYzNGNnYWMgLmxvb3BUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkOHlvNjM0Y2dhYyAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICNDQ0NDRkY7IH0KCiNkOHlvNjM0Y2dhYyAubm90ZSB7CiAgc3Ryb2tlOiAjYWFhYTMzOwogIGZpbGw6ICNmZmY1YWQ7IH0KCiNkOHlvNjM0Y2dhYyAubm90ZVRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTRweDsgfQoKI2Q4eW82MzRjZ2FjIC5hY3RpdmF0aW9uMCB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNkOHlvNjM0Y2dhYyAuYWN0aXZhdGlvbjEgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZDh5bzYzNGNnYWMgLmFjdGl2YXRpb24yIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKCiNkOHlvNjM0Y2dhYyAuc2VjdGlvbiB7CiAgc3Ryb2tlOiBub25lOwogIG9wYWNpdHk6IDAuMjsgfQoKI2Q4eW82MzRjZ2FjIC5zZWN0aW9uMCB7CiAgZmlsbDogcmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KTsgfQoKI2Q4eW82MzRjZ2FjIC5zZWN0aW9uMiB7CiAgZmlsbDogI2ZmZjQwMDsgfQoKI2Q4eW82MzRjZ2FjIC5zZWN0aW9uMSwKI2Q4eW82MzRjZ2FjIC5zZWN0aW9uMyB7CiAgZmlsbDogd2hpdGU7CiAgb3BhY2l0eTogMC4yOyB9CgojZDh5bzYzNGNnYWMgLnNlY3Rpb25UaXRsZTAgewogIGZpbGw6ICMzMzM7IH0KCiNkOHlvNjM0Y2dhYyAuc2VjdGlvblRpdGxlMSB7CiAgZmlsbDogIzMzMzsgfQoKI2Q4eW82MzRjZ2FjIC5zZWN0aW9uVGl0bGUyIHsKICBmaWxsOiAjMzMzOyB9CgojZDh5bzYzNGNnYWMgLnNlY3Rpb25UaXRsZTMgewogIGZpbGw6ICMzMzM7IH0KCiNkOHlvNjM0Y2dhYyAuc2VjdGlvblRpdGxlIHsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OwogIHRleHQtaGVpZ2h0OiAxNHB4OyB9CgoKI2Q4eW82MzRjZ2FjIC5ncmlkIC50aWNrIHsKICBzdHJva2U6IGxpZ2h0Z3JleTsKICBvcGFjaXR5OiAwLjM7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZDh5bzYzNGNnYWMgLmdyaWQgcGF0aCB7CiAgc3Ryb2tlLXdpZHRoOiAwOyB9CgoKI2Q4eW82MzRjZ2FjIC50b2RheSB7CiAgZmlsbDogbm9uZTsKICBzdHJva2U6IHJlZDsKICBzdHJva2Utd2lkdGg6IDJweDsgfQoKCgojZDh5bzYzNGNnYWMgLnRhc2sgewogIHN0cm9rZS13aWR0aDogMjsgfQoKI2Q4eW82MzRjZ2FjIC50YXNrVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDExcHg7IH0KCiNkOHlvNjM0Y2dhYyAudGFza1RleHRPdXRzaWRlUmlnaHQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7IH0KCiNkOHlvNjM0Y2dhYyAudGFza1RleHRPdXRzaWRlTGVmdCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IGVuZDsKICBmb250LXNpemU6IDExcHg7IH0KCgojZDh5bzYzNGNnYWMgLnRhc2tUZXh0MCwKI2Q4eW82MzRjZ2FjIC50YXNrVGV4dDEsCiNkOHlvNjM0Y2dhYyAudGFza1RleHQyLAojZDh5bzYzNGNnYWMgLnRhc2tUZXh0MyB7CiAgZmlsbDogd2hpdGU7IH0KCiNkOHlvNjM0Y2dhYyAudGFzazAsCiNkOHlvNjM0Y2dhYyAudGFzazEsCiNkOHlvNjM0Y2dhYyAudGFzazIsCiNkOHlvNjM0Y2dhYyAudGFzazMgewogIGZpbGw6ICM4YTkwZGQ7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZDh5bzYzNGNnYWMgLnRhc2tUZXh0T3V0c2lkZTAsCiNkOHlvNjM0Y2dhYyAudGFza1RleHRPdXRzaWRlMiB7CiAgZmlsbDogYmxhY2s7IH0KCiNkOHlvNjM0Y2dhYyAudGFza1RleHRPdXRzaWRlMSwKI2Q4eW82MzRjZ2FjIC50YXNrVGV4dE91dHNpZGUzIHsKICBmaWxsOiBibGFjazsgfQoKCiNkOHlvNjM0Y2dhYyAuYWN0aXZlMCwKI2Q4eW82MzRjZ2FjIC5hY3RpdmUxLAojZDh5bzYzNGNnYWMgLmFjdGl2ZTIsCiNkOHlvNjM0Y2dhYyAuYWN0aXZlMyB7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNkOHlvNjM0Y2dhYyAuYWN0aXZlVGV4dDAsCiNkOHlvNjM0Y2dhYyAuYWN0aXZlVGV4dDEsCiNkOHlvNjM0Y2dhYyAuYWN0aXZlVGV4dDIsCiNkOHlvNjM0Y2dhYyAuYWN0aXZlVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZDh5bzYzNGNnYWMgLmRvbmUwLAojZDh5bzYzNGNnYWMgLmRvbmUxLAojZDh5bzYzNGNnYWMgLmRvbmUyLAojZDh5bzYzNGNnYWMgLmRvbmUzIHsKICBzdHJva2U6IGdyZXk7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2Q4eW82MzRjZ2FjIC5kb25lVGV4dDAsCiNkOHlvNjM0Y2dhYyAuZG9uZVRleHQxLAojZDh5bzYzNGNnYWMgLmRvbmVUZXh0MiwKI2Q4eW82MzRjZ2FjIC5kb25lVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZDh5bzYzNGNnYWMgLmNyaXQwLAojZDh5bzYzNGNnYWMgLmNyaXQxLAojZDh5bzYzNGNnYWMgLmNyaXQyLAojZDh5bzYzNGNnYWMgLmNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogcmVkOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2Q4eW82MzRjZ2FjIC5hY3RpdmVDcml0MCwKI2Q4eW82MzRjZ2FjIC5hY3RpdmVDcml0MSwKI2Q4eW82MzRjZ2FjIC5hY3RpdmVDcml0MiwKI2Q4eW82MzRjZ2FjIC5hY3RpdmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZDh5bzYzNGNnYWMgLmRvbmVDcml0MCwKI2Q4eW82MzRjZ2FjIC5kb25lQ3JpdDEsCiNkOHlvNjM0Y2dhYyAuZG9uZUNyaXQyLAojZDh5bzYzNGNnYWMgLmRvbmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7CiAgY3Vyc29yOiBwb2ludGVyOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2Q4eW82MzRjZ2FjIC5kb25lQ3JpdFRleHQwLAojZDh5bzYzNGNnYWMgLmRvbmVDcml0VGV4dDEsCiNkOHlvNjM0Y2dhYyAuZG9uZUNyaXRUZXh0MiwKI2Q4eW82MzRjZ2FjIC5kb25lQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZDh5bzYzNGNnYWMgLmFjdGl2ZUNyaXRUZXh0MCwKI2Q4eW82MzRjZ2FjIC5hY3RpdmVDcml0VGV4dDEsCiNkOHlvNjM0Y2dhYyAuYWN0aXZlQ3JpdFRleHQyLAojZDh5bzYzNGNnYWMgLmFjdGl2ZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2Q4eW82MzRjZ2FjIC50aXRsZVRleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxOHB4OwogIGZpbGw6IGJsYWNrOyB9CgojZDh5bzYzNGNnYWMgZy5jbGFzc0dyb3VwIHRleHQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZDh5bzYzNGNnYWMgZy5jbGFzc0dyb3VwIHJlY3QgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOyB9CgojZDh5bzYzNGNnYWMgZy5jbGFzc0dyb3VwIGxpbmUgewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkOHlvNjM0Y2dhYyAuY2xhc3NMYWJlbCAuYm94IHsKICBzdHJva2U6IG5vbmU7CiAgc3Ryb2tlLXdpZHRoOiAwOwogIGZpbGw6ICNFQ0VDRkY7CiAgb3BhY2l0eTogMC41OyB9CgojZDh5bzYzNGNnYWMgLmNsYXNzTGFiZWwgLmxhYmVsIHsKICBmaWxsOiAjOTM3MERCOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2Q4eW82MzRjZ2FjIC5yZWxhdGlvbiB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsKICBmaWxsOiBub25lOyB9CgojZDh5bzYzNGNnYWMgI2NvbXBvc2l0aW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2Q4eW82MzRjZ2FjICNjb21wb3NpdGlvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDh5bzYzNGNnYWMgI2FnZ3JlZ2F0aW9uU3RhcnQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2Q4eW82MzRjZ2FjICNhZ2dyZWdhdGlvbkVuZCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDh5bzYzNGNnYWMgI2RlcGVuZGVuY3lTdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDh5bzYzNGNnYWMgI2RlcGVuZGVuY3lFbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2Q4eW82MzRjZ2FjICNleHRlbnNpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDh5bzYzNGNnYWMgI2V4dGVuc2lvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDh5bzYzNGNnYWMgLmNvbW1pdC1pZCwKI2Q4eW82MzRjZ2FjIC5jb21taXQtbXNnLAojZDh5bzYzNGNnYWMgLmJyYW5jaC1sYWJlbCB7CiAgZmlsbDogbGlnaHRncmV5OwogIGNvbG9yOiBsaWdodGdyZXk7IH0KCgoKI2Q4eW82MzRjZ2FjIC5sYWJlbHsKICBjb2xvcjojMThCMTRFOwp9CiNkOHlvNjM0Y2dhYyAudGUtbWQtY29udGFpbmVyLS1kYXJrIC5ub2RlIHJlY3QgewogIGZpbGw6IHJlZDsKfQoKI2Q4eW82MzRjZ2FjIC5ub2RlIHJlY3QsCiNkOHlvNjM0Y2dhYyAubm9kZSBjaXJjbGUsCiNkOHlvNjM0Y2dhYyAubm9kZSBlbGxpcHNlLAojZDh5bzYzNGNnYWMgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0Y5RkZGQjs7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMS41cHg7Cn0KI2Q4eW82MzRjZ2FjIC5hcnJvd2hlYWRQYXRoewogIGZpbGw6ICMyREJENjA7Cn0KI2Q4eW82MzRjZ2FjIC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMXB4Owp9CiNkOHlvNjM0Y2dhYyAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOwp9CiNkOHlvNjM0Y2dhYyAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjRjlGRkZCICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsKfQoKI2Q4eW82MzRjZ2FjIC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkOHlvNjM0Y2dhYyBkaXYubWVybWFpZFRvb2x0aXAgewogIGJhY2tncm91bmQ6ICNGOUZGRkI7CiAgYm9yZGVyOiAxcHggc29saWQgIzJEQkQ2MDsKfQoKCiNkOHlvNjM0Y2dhYyAuYWN0b3IgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZDh5bzYzNGNnYWMgdGV4dC5hY3RvciB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkOHlvNjM0Y2dhYyAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZDh5bzYzNGNnYWMgLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZDh5bzYzNGNnYWMgLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZDh5bzYzNGNnYWMgI2Fycm93aGVhZCB7CiAgZmlsbDogIzJEQkQ2MDsKfQoKI2Q4eW82MzRjZ2FjICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50Owp9CgojZDh5bzYzNGNnYWMgLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2Q4eW82MzRjZ2FjIC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkOHlvNjM0Y2dhYyAubGFiZWxUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2Q4eW82MzRjZ2FjIC5sb29wVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkOHlvNjM0Y2dhYyAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkOHlvNjM0Y2dhYyAubm90ZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkOHlvNjM0Y2dhYyAubm90ZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgoKI2Q4eW82MzRjZ2FjIC5zZWN0aW9uewogIG9wYWNpdHk6MTsKfQojZDh5bzYzNGNnYWMgLnNlY3Rpb24wLCNkOHlvNjM0Y2dhYyAgLnNlY3Rpb24yIHsKICBmaWxsOiAjRUNGN0YwOwp9CgojZDh5bzYzNGNnYWMgLnNlY3Rpb24xLAojZDh5bzYzNGNnYWMgLnNlY3Rpb24zIHsKICBmaWxsOiAjRkZGOwp9CiNkOHlvNjM0Y2dhYyAudGFza1RleHQwLAojZDh5bzYzNGNnYWMgLnRhc2tUZXh0MSwKI2Q4eW82MzRjZ2FjIC50YXNrVGV4dDIsCiNkOHlvNjM0Y2dhYyAudGFza1RleHQzIHsKICBmaWxsOiAjZmZmOwp9CgojZDh5bzYzNGNnYWMgLnRhc2swLAojZDh5bzYzNGNnYWMgLnRhc2sxLAojZDh5bzYzNGNnYWMgLnRhc2syLAojZDh5bzYzNGNnYWMgLnRhc2szIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzM1OUY1QTsKfQo8L3N0eWxlPjxzdHlsZT4jZDh5bzYzNGNnYWMgewogICAgY29sb3I6IHJnYigyNDQsIDI0NCwgMjQ0KTsKICAgIGZvbnQ6IG5vcm1hbCBub3JtYWwgbm9ybWFsIG5vcm1hbCAxNHB4LzIyLjM5OTk5OTYxODUzMDI3M3B4IG1vbm9zcGFjZTsKICB9PC9zdHlsZT48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIsIC0xMikiPjxnIGNsYXNzPSJvdXRwdXQiPjxnIGNsYXNzPSJjbHVzdGVycyI+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aHMiPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTEyNC4xMjAzOTM5MDk5NjM0NCw1Ni4yODEyNUw1OS42NzE4NzUsODkuNDIxODc1TDU5LjY3MTg3NSwxMjIuNTYyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NTA4KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NTA4IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTk0LjY3NjQ4MTA5MDAzNjU2LDU2LjI4MTI1TDI1OS4xMjUsODkuNDIxODc1TDI1OS4xMjUsMTIyLjU2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTUwOSkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTUwOSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTI1OS4xMjUsMTU4Ljg0Mzc1TDI1OS4xMjUsMTgzLjg0Mzc1TDI1OS4xMjUsMjA4Ljg0Mzc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk1MTApIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk1MTAiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yNTkuMTI1LDI0NS4xMjVMMjU5LjEyNSwyNzAuMTI1TDI1OS4xMjUsMjk1LjEyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NTExKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NTExIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjU5LjEyNSwzMzEuNDA2MjVMMjU5LjEyNSwzNTYuNDA2MjVMMjU5LjEyNSwzODEuNDA2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTUxMikiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTUxMiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTI1OS4xMjUsNDE3LjY4NzVMMjU5LjEyNSw0NDIuNjg3NUwyNTkuMTI1LDQ2Ny42ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk1MTMpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk1MTMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yNTkuMTI1LDUwMy45Njg3NUwyNTkuMTI1LDUyOC45Njg3NUwyNTkuMTI1LDU1My45Njg3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NTE0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NTE0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWxzIj48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1OS42NzE4NzUsODkuNDIxODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTIuODEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI3OS4zOTA2MjUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnJ1bnFzaXplID09IDA8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1OS4xMjUsODkuNDIxODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTIuODEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI3Ny4xODc1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5ydW5xc2l6ZSAhPSAwPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGVzIj48ZyBjbGFzcz0ibm9kZSIgaWQ9IkEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE1OS4zOTg0Mzc1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNDYuMTE3MTg3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjkyLjIzNDM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM2LjExNzE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmdsb2JydW5xZ2V0PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1OS42NzE4NzUsMTQwLjcwMzEyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMzEuMjg5MDYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjYyLjU3ODEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIxLjI4OTA2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPui/lOWbnm5pbDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iQiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjU5LjEyNSwxNDAuNzAzMTI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0xMTguMTY0MDYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjIzNi4zMjgxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMDguMTY0MDYyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+biA6PSBzY2hlZC5ydW5xc2l6ZS9nb21heHByb2NzICsgMTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iQyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjU5LjEyNSwyMjYuOTg0Mzc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii01NC45Mjk2ODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTA5Ljg1OTM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ0LjkyOTY4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPuiuvue9ruWQiOmAgueahG7lgLw8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1OS4xMjUsMzEzLjI2NTYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNDguNzI2NTYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9Ijk3LjQ1MzEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM4LjcyNjU2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnJ1bnFzaXplIC09IG48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1OS4xMjUsMzk5LjU0Njg3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItOTkuNDQ1MzEyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjE5OC44OTA2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04OS40NDUzMTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj7ku45ydW5x5LitcG9wIEfvvIx65L2c5Li66L+U5Zue5YC8PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJGIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNTkuMTI1LDQ4NS44MjgxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTEzMS4xODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMjYyLjM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyMS4xODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj7ku45nbG9iYWwgcnVuceS4reWPluWHum7kuKpH77yM5pS+5YWlUOeahHJ1bnE8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1OS4xMjUsNTcyLjEwOTM3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMzguMDA3ODEyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9Ijc2LjAxNTYyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI4LjAwNzgxMjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnJldHVybiBncDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==

globrunqget的函数原型是:

func globrunqget(_p_ *p, max int32) *g

上图中n是要取出的G的个数。这里如果考虑max传入大于0的数,则n取值需要考虑:

  1. 不能超过runqsize,runqsize是此时global queue中G的个数
  2. 不能超过传入的max值
  3. 不能超过一个P的runqsize,该size定义在runtime2.go的type p声明中,当前值为256。
type p struct {
    ...
    runq     [256]guintptr
    ...
}

在schedule函数中globrunqget函数的max参数传入的是0,所以上述3个条件中的条件2就不用考虑了。

runqget

runqget会先查看P的runnext成员,如果有,则返回runnext指向的G
否则会取当前runqhead指向的runq数组的成员G。
runqhead和runqtail是两个int索引值。如果两值相等表示队列是空的。

findrunnable

findrunnable是一个阻塞型调用,来寻找runnable G。如果找不到,就会调用stopm,来休眠M。其基本流程如下:

PHN2ZyBpZD0iZDg1OXV1aGtkNnciIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDYxOC4zMDQ2ODc1cHg7IiB2aWV3Qm94PSIwIDAgNjE4LjMwNDY4NzUgODA3LjY1NjI1Ij48c3R5bGU+CgoKI2Q4NTl1dWhrZDZ3IC5sYWJlbCB7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBjb2xvcjogIzMzMzsgfQoKI2Q4NTl1dWhrZDZ3IC5ub2RlIHJlY3QsCiNkODU5dXVoa2Q2dyAubm9kZSBjaXJjbGUsCiNkODU5dXVoa2Q2dyAubm9kZSBlbGxpcHNlLAojZDg1OXV1aGtkNncgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7IH0KCiNkODU5dXVoa2Q2dyAubm9kZS5jbGlja2FibGUgewogIGN1cnNvcjogcG9pbnRlcjsgfQoKI2Q4NTl1dWhrZDZ3IC5hcnJvd2hlYWRQYXRoIHsKICBmaWxsOiAjMzMzMzMzOyB9CgojZDg1OXV1aGtkNncgLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMzMzMzMzM7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsgfQoKI2Q4NTl1dWhrZDZ3IC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNlOGU4ZTg7IH0KCiNkODU5dXVoa2Q2dyAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjZmZmZmRlICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjYWFhYTMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsgfQoKI2Q4NTl1dWhrZDZ3IC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICMzMzM7IH0KCiNkODU5dXVoa2Q2dyBkaXYubWVybWFpZFRvb2x0aXAgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWF4LXdpZHRoOiAyMDBweDsKICBwYWRkaW5nOiAycHg7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEycHg7CiAgYmFja2dyb3VuZDogI2ZmZmZkZTsKICBib3JkZXI6IDFweCBzb2xpZCAjYWFhYTMzOwogIGJvcmRlci1yYWRpdXM6IDJweDsKICBwb2ludGVyLWV2ZW50czogbm9uZTsKICB6LWluZGV4OiAxMDA7IH0KCiNkODU5dXVoa2Q2dyAuYWN0b3IgewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZDg1OXV1aGtkNncgdGV4dC5hY3RvciB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZDg1OXV1aGtkNncgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogZ3JleTsgfQoKI2Q4NTl1dWhrZDZ3IC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2Q4NTl1dWhrZDZ3IC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2Q4NTl1dWhrZDZ3ICNhcnJvd2hlYWQgewogIGZpbGw6ICMzMzM7IH0KCiNkODU5dXVoa2Q2dyAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMzMzMgIWltcG9ydGFudDsKICBzdHJva2U6ICMzMzMgIWltcG9ydGFudDsgfQoKI2Q4NTl1dWhrZDZ3IC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzMzMzsKICBzdHJva2U6IG5vbmU7IH0KCiNkODU5dXVoa2Q2dyAubGFiZWxCb3ggewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZDg1OXV1aGtkNncgLmxhYmVsVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZDg1OXV1aGtkNncgLmxvb3BUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkODU5dXVoa2Q2dyAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICNDQ0NDRkY7IH0KCiNkODU5dXVoa2Q2dyAubm90ZSB7CiAgc3Ryb2tlOiAjYWFhYTMzOwogIGZpbGw6ICNmZmY1YWQ7IH0KCiNkODU5dXVoa2Q2dyAubm90ZVRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTRweDsgfQoKI2Q4NTl1dWhrZDZ3IC5hY3RpdmF0aW9uMCB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNkODU5dXVoa2Q2dyAuYWN0aXZhdGlvbjEgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZDg1OXV1aGtkNncgLmFjdGl2YXRpb24yIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKCiNkODU5dXVoa2Q2dyAuc2VjdGlvbiB7CiAgc3Ryb2tlOiBub25lOwogIG9wYWNpdHk6IDAuMjsgfQoKI2Q4NTl1dWhrZDZ3IC5zZWN0aW9uMCB7CiAgZmlsbDogcmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KTsgfQoKI2Q4NTl1dWhrZDZ3IC5zZWN0aW9uMiB7CiAgZmlsbDogI2ZmZjQwMDsgfQoKI2Q4NTl1dWhrZDZ3IC5zZWN0aW9uMSwKI2Q4NTl1dWhrZDZ3IC5zZWN0aW9uMyB7CiAgZmlsbDogd2hpdGU7CiAgb3BhY2l0eTogMC4yOyB9CgojZDg1OXV1aGtkNncgLnNlY3Rpb25UaXRsZTAgewogIGZpbGw6ICMzMzM7IH0KCiNkODU5dXVoa2Q2dyAuc2VjdGlvblRpdGxlMSB7CiAgZmlsbDogIzMzMzsgfQoKI2Q4NTl1dWhrZDZ3IC5zZWN0aW9uVGl0bGUyIHsKICBmaWxsOiAjMzMzOyB9CgojZDg1OXV1aGtkNncgLnNlY3Rpb25UaXRsZTMgewogIGZpbGw6ICMzMzM7IH0KCiNkODU5dXVoa2Q2dyAuc2VjdGlvblRpdGxlIHsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OwogIHRleHQtaGVpZ2h0OiAxNHB4OyB9CgoKI2Q4NTl1dWhrZDZ3IC5ncmlkIC50aWNrIHsKICBzdHJva2U6IGxpZ2h0Z3JleTsKICBvcGFjaXR5OiAwLjM7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZDg1OXV1aGtkNncgLmdyaWQgcGF0aCB7CiAgc3Ryb2tlLXdpZHRoOiAwOyB9CgoKI2Q4NTl1dWhrZDZ3IC50b2RheSB7CiAgZmlsbDogbm9uZTsKICBzdHJva2U6IHJlZDsKICBzdHJva2Utd2lkdGg6IDJweDsgfQoKCgojZDg1OXV1aGtkNncgLnRhc2sgewogIHN0cm9rZS13aWR0aDogMjsgfQoKI2Q4NTl1dWhrZDZ3IC50YXNrVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDExcHg7IH0KCiNkODU5dXVoa2Q2dyAudGFza1RleHRPdXRzaWRlUmlnaHQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7IH0KCiNkODU5dXVoa2Q2dyAudGFza1RleHRPdXRzaWRlTGVmdCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IGVuZDsKICBmb250LXNpemU6IDExcHg7IH0KCgojZDg1OXV1aGtkNncgLnRhc2tUZXh0MCwKI2Q4NTl1dWhrZDZ3IC50YXNrVGV4dDEsCiNkODU5dXVoa2Q2dyAudGFza1RleHQyLAojZDg1OXV1aGtkNncgLnRhc2tUZXh0MyB7CiAgZmlsbDogd2hpdGU7IH0KCiNkODU5dXVoa2Q2dyAudGFzazAsCiNkODU5dXVoa2Q2dyAudGFzazEsCiNkODU5dXVoa2Q2dyAudGFzazIsCiNkODU5dXVoa2Q2dyAudGFzazMgewogIGZpbGw6ICM4YTkwZGQ7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZDg1OXV1aGtkNncgLnRhc2tUZXh0T3V0c2lkZTAsCiNkODU5dXVoa2Q2dyAudGFza1RleHRPdXRzaWRlMiB7CiAgZmlsbDogYmxhY2s7IH0KCiNkODU5dXVoa2Q2dyAudGFza1RleHRPdXRzaWRlMSwKI2Q4NTl1dWhrZDZ3IC50YXNrVGV4dE91dHNpZGUzIHsKICBmaWxsOiBibGFjazsgfQoKCiNkODU5dXVoa2Q2dyAuYWN0aXZlMCwKI2Q4NTl1dWhrZDZ3IC5hY3RpdmUxLAojZDg1OXV1aGtkNncgLmFjdGl2ZTIsCiNkODU5dXVoa2Q2dyAuYWN0aXZlMyB7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNkODU5dXVoa2Q2dyAuYWN0aXZlVGV4dDAsCiNkODU5dXVoa2Q2dyAuYWN0aXZlVGV4dDEsCiNkODU5dXVoa2Q2dyAuYWN0aXZlVGV4dDIsCiNkODU5dXVoa2Q2dyAuYWN0aXZlVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZDg1OXV1aGtkNncgLmRvbmUwLAojZDg1OXV1aGtkNncgLmRvbmUxLAojZDg1OXV1aGtkNncgLmRvbmUyLAojZDg1OXV1aGtkNncgLmRvbmUzIHsKICBzdHJva2U6IGdyZXk7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2Q4NTl1dWhrZDZ3IC5kb25lVGV4dDAsCiNkODU5dXVoa2Q2dyAuZG9uZVRleHQxLAojZDg1OXV1aGtkNncgLmRvbmVUZXh0MiwKI2Q4NTl1dWhrZDZ3IC5kb25lVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZDg1OXV1aGtkNncgLmNyaXQwLAojZDg1OXV1aGtkNncgLmNyaXQxLAojZDg1OXV1aGtkNncgLmNyaXQyLAojZDg1OXV1aGtkNncgLmNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogcmVkOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2Q4NTl1dWhrZDZ3IC5hY3RpdmVDcml0MCwKI2Q4NTl1dWhrZDZ3IC5hY3RpdmVDcml0MSwKI2Q4NTl1dWhrZDZ3IC5hY3RpdmVDcml0MiwKI2Q4NTl1dWhrZDZ3IC5hY3RpdmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZDg1OXV1aGtkNncgLmRvbmVDcml0MCwKI2Q4NTl1dWhrZDZ3IC5kb25lQ3JpdDEsCiNkODU5dXVoa2Q2dyAuZG9uZUNyaXQyLAojZDg1OXV1aGtkNncgLmRvbmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7CiAgY3Vyc29yOiBwb2ludGVyOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2Q4NTl1dWhrZDZ3IC5kb25lQ3JpdFRleHQwLAojZDg1OXV1aGtkNncgLmRvbmVDcml0VGV4dDEsCiNkODU5dXVoa2Q2dyAuZG9uZUNyaXRUZXh0MiwKI2Q4NTl1dWhrZDZ3IC5kb25lQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZDg1OXV1aGtkNncgLmFjdGl2ZUNyaXRUZXh0MCwKI2Q4NTl1dWhrZDZ3IC5hY3RpdmVDcml0VGV4dDEsCiNkODU5dXVoa2Q2dyAuYWN0aXZlQ3JpdFRleHQyLAojZDg1OXV1aGtkNncgLmFjdGl2ZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2Q4NTl1dWhrZDZ3IC50aXRsZVRleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxOHB4OwogIGZpbGw6IGJsYWNrOyB9CgojZDg1OXV1aGtkNncgZy5jbGFzc0dyb3VwIHRleHQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZDg1OXV1aGtkNncgZy5jbGFzc0dyb3VwIHJlY3QgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOyB9CgojZDg1OXV1aGtkNncgZy5jbGFzc0dyb3VwIGxpbmUgewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkODU5dXVoa2Q2dyAuY2xhc3NMYWJlbCAuYm94IHsKICBzdHJva2U6IG5vbmU7CiAgc3Ryb2tlLXdpZHRoOiAwOwogIGZpbGw6ICNFQ0VDRkY7CiAgb3BhY2l0eTogMC41OyB9CgojZDg1OXV1aGtkNncgLmNsYXNzTGFiZWwgLmxhYmVsIHsKICBmaWxsOiAjOTM3MERCOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2Q4NTl1dWhrZDZ3IC5yZWxhdGlvbiB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsKICBmaWxsOiBub25lOyB9CgojZDg1OXV1aGtkNncgI2NvbXBvc2l0aW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2Q4NTl1dWhrZDZ3ICNjb21wb3NpdGlvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDg1OXV1aGtkNncgI2FnZ3JlZ2F0aW9uU3RhcnQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2Q4NTl1dWhrZDZ3ICNhZ2dyZWdhdGlvbkVuZCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDg1OXV1aGtkNncgI2RlcGVuZGVuY3lTdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDg1OXV1aGtkNncgI2RlcGVuZGVuY3lFbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2Q4NTl1dWhrZDZ3ICNleHRlbnNpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDg1OXV1aGtkNncgI2V4dGVuc2lvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZDg1OXV1aGtkNncgLmNvbW1pdC1pZCwKI2Q4NTl1dWhrZDZ3IC5jb21taXQtbXNnLAojZDg1OXV1aGtkNncgLmJyYW5jaC1sYWJlbCB7CiAgZmlsbDogbGlnaHRncmV5OwogIGNvbG9yOiBsaWdodGdyZXk7IH0KCgoKI2Q4NTl1dWhrZDZ3IC5sYWJlbHsKICBjb2xvcjojMThCMTRFOwp9CiNkODU5dXVoa2Q2dyAudGUtbWQtY29udGFpbmVyLS1kYXJrIC5ub2RlIHJlY3QgewogIGZpbGw6IHJlZDsKfQoKI2Q4NTl1dWhrZDZ3IC5ub2RlIHJlY3QsCiNkODU5dXVoa2Q2dyAubm9kZSBjaXJjbGUsCiNkODU5dXVoa2Q2dyAubm9kZSBlbGxpcHNlLAojZDg1OXV1aGtkNncgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0Y5RkZGQjs7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMS41cHg7Cn0KI2Q4NTl1dWhrZDZ3IC5hcnJvd2hlYWRQYXRoewogIGZpbGw6ICMyREJENjA7Cn0KI2Q4NTl1dWhrZDZ3IC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMXB4Owp9CiNkODU5dXVoa2Q2dyAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOwp9CiNkODU5dXVoa2Q2dyAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjRjlGRkZCICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsKfQoKI2Q4NTl1dWhrZDZ3IC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkODU5dXVoa2Q2dyBkaXYubWVybWFpZFRvb2x0aXAgewogIGJhY2tncm91bmQ6ICNGOUZGRkI7CiAgYm9yZGVyOiAxcHggc29saWQgIzJEQkQ2MDsKfQoKCiNkODU5dXVoa2Q2dyAuYWN0b3IgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZDg1OXV1aGtkNncgdGV4dC5hY3RvciB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkODU5dXVoa2Q2dyAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZDg1OXV1aGtkNncgLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZDg1OXV1aGtkNncgLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZDg1OXV1aGtkNncgI2Fycm93aGVhZCB7CiAgZmlsbDogIzJEQkQ2MDsKfQoKI2Q4NTl1dWhrZDZ3ICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50Owp9CgojZDg1OXV1aGtkNncgLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2Q4NTl1dWhrZDZ3IC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkODU5dXVoa2Q2dyAubGFiZWxUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2Q4NTl1dWhrZDZ3IC5sb29wVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkODU5dXVoa2Q2dyAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkODU5dXVoa2Q2dyAubm90ZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkODU5dXVoa2Q2dyAubm90ZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgoKI2Q4NTl1dWhrZDZ3IC5zZWN0aW9uewogIG9wYWNpdHk6MTsKfQojZDg1OXV1aGtkNncgLnNlY3Rpb24wLCNkODU5dXVoa2Q2dyAgLnNlY3Rpb24yIHsKICBmaWxsOiAjRUNGN0YwOwp9CgojZDg1OXV1aGtkNncgLnNlY3Rpb24xLAojZDg1OXV1aGtkNncgLnNlY3Rpb24zIHsKICBmaWxsOiAjRkZGOwp9CiNkODU5dXVoa2Q2dyAudGFza1RleHQwLAojZDg1OXV1aGtkNncgLnRhc2tUZXh0MSwKI2Q4NTl1dWhrZDZ3IC50YXNrVGV4dDIsCiNkODU5dXVoa2Q2dyAudGFza1RleHQzIHsKICBmaWxsOiAjZmZmOwp9CgojZDg1OXV1aGtkNncgLnRhc2swLAojZDg1OXV1aGtkNncgLnRhc2sxLAojZDg1OXV1aGtkNncgLnRhc2syLAojZDg1OXV1aGtkNncgLnRhc2szIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzM1OUY1QTsKfQo8L3N0eWxlPjxzdHlsZT4jZDg1OXV1aGtkNncgewogICAgY29sb3I6IHJnYigyNDQsIDI0NCwgMjQ0KTsKICAgIGZvbnQ6IG5vcm1hbCBub3JtYWwgbm9ybWFsIG5vcm1hbCAxNHB4LzIyLjM5OTk5OTYxODUzMDI3M3B4IG1vbm9zcGFjZTsKICB9PC9zdHlsZT48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIsIC0xMikiPjxnIGNsYXNzPSJvdXRwdXQiPjxnIGNsYXNzPSJjbHVzdGVycyI+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aHMiPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTQwNC43MzgyODEyNSw1Ni4yODEyNUw0MDQuNzM4MjgxMjUsODEuMjgxMjVMNDA0LjczODI4MTI1LDEwNi4yODEyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NjA4KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NjA4IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMzU1LjYyODkwNjI1LDEzNS41ODM3MTQ5NDExMzU3MkwxNzkuMTEzMjgxMjUsMTc1LjcwMzEyNUwxNzkuMTEzMjgxMjUsMjA4Ljg0Mzc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MDkpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MDkiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0zNTUuNjI4OTA2MjUsMTMxLjI2MjQ5NDU5NTMxODY5TDM2LjU4NTkzNzUsMTc1LjcwMzEyNUwzNi41ODU5Mzc1LDIyNi45ODQzNzVMMzYuNTg1OTM3NSwyNzguMjY1NjI1TDM2LjU4NTkzNzUsMzI5LjU0Njg3NUwzNi41ODU5Mzc1LDM4MC44MjgxMjVMNDguNDA3ODEwMzU3NjMyNTQsNDEzLjk2ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MTApIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MTAiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yMDAuODI0NTQ3MjQ2MzQzNjgsMjQ1LjEyNUwyNDAuNDg4MjgxMjUsMjc4LjI2NTYyNUwyNDAuNDg4MjgxMjUsMzExLjQwNjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MTEpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MTEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yNTQuNzE0MTkwMzI3OTI1MDUsMzQ3LjY4NzVMMjgwLjcwMzEyNSwzODAuODI4MTI1TDI4MC43MDMxMjUsNDEzLjk2ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MTIpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MTIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yODAuNzAzMTI1LDQ1MC4yNUwyODAuNzAzMTI1LDQ4My4zOTA2MjVMMzMzLjc3NjU5MzkyMTM4OTQsNTE2LjUzMTI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MTMpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MTMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0zNjIuODI4MTI1LDU1Mi44MTI1TDM2Mi44MjgxMjUsNTc3LjgxMjVMMzYyLjgyODEyNSw2MDIuODEyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NjE0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NjE0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMzYyLjgyODEyNSw2MzkuMDkzNzVMMzYyLjgyODEyNSw2NjQuMDkzNzVMNDAzLjE0MTg3MDAxOTkyMDMsNjg5LjA5Mzc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MTUpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MTUiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik00MzIuMzk0NTMxMjUsNzI1LjM3NUw0MzIuMzk0NTMxMjUsNzUwLjM3NUw0NjYuMDc1NzE1NjAzNDk1MSw3NzUuMzc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MTYpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MTYiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik01MTguOTkyMTg3NSw3ODIuMjAxMjIxNjIzNjE0OUw1OTkuMDkzNzUsNzUwLjM3NUw1OTkuMDkzNzUsNzA3LjIzNDM3NUw1OTkuMDkzNzUsNjY0LjA5Mzc1TDU5OS4wOTM3NSw2MjAuOTUzMTI1TDU5OS4wOTM3NSw1NzcuODEyNUw1OTkuMDkzNzUsNTM0LjY3MTg3NUw1OTkuMDkzNzUsNDgzLjM5MDYyNUw1OTkuMDkzNzUsNDMyLjEwOTM3NUw1OTkuMDkzNzUsMzgwLjgyODEyNUw1OTkuMDkzNzUsMzI5LjU0Njg3NUw1OTkuMDkzNzUsMjc4LjI2NTYyNUw1OTkuMDkzNzUsMjI2Ljk4NDM3NUw1OTkuMDkzNzUsMTc1LjcwMzEyNUw0NTMuODQ3NjU2MjUsMTM3LjM3OTUyNDk4NDkyNjE1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MTcpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MTciIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0zNzcuNjUzNzQ3MDAwNjg1NTQsNTE2LjUzMTI1TDQwNC43MzgyODEyNSw0ODMuMzkwNjI1TDQwNC43MzgyODEyNSw0MzIuMTA5Mzc1TDQwNC43MzgyODEyNSwzODAuODI4MTI1TDQwNC43MzgyODEyNSwzMjkuNTQ2ODc1TDQwNC43MzgyODEyNSwyNzguMjY1NjI1TDQwNC43MzgyODEyNSwyMjYuOTg0Mzc1TDQwNC43MzgyODEyNSwxNzUuNzAzMTI1TDQwNC43MzgyODEyNSwxNDIuNTYyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NjE4KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NjE4IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNNDY2LjQzNTMwNTY1MjM5MDQsNjg5LjA5Mzc1TDUxMy4zNDc2NTYyNSw2NjQuMDkzNzVMNTEzLjM0NzY1NjI1LDYyMC45NTMxMjVMNTEzLjM0NzY1NjI1LDU3Ny44MTI1TDUxMy4zNDc2NTYyNSw1MzQuNjcxODc1TDUxMy4zNDc2NTYyNSw0ODMuMzkwNjI1TDUxMy4zNDc2NTYyNSw0MzIuMTA5Mzc1TDUxMy4zNDc2NTYyNSwzODAuODI4MTI1TDUxMy4zNDc2NTYyNSwzMjkuNTQ2ODc1TDUxMy4zNDc2NTYyNSwyNzguMjY1NjI1TDUxMy4zNDc2NTYyNSwyMjYuOTg0Mzc1TDUxMy4zNDc2NTYyNSwxNzUuNzAzMTI1TDQ0My4xNTg1OTk0NjI5Nzk5LDE0Mi41NjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MTkpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MTkiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xNTYuNTE2MjY0MTM5NjI1MjQsMjQ1LjEyNUwxMTUuMjM0Mzc1LDI3OC4yNjU2MjVMMTE1LjIzNDM3NSwzMjkuNTQ2ODc1TDExNS4yMzQzNzUsMzgwLjgyODEyNUw3Ni4yMjk1MTUzOTY0ODA4LDQxMy45Njg3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NjIwKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NjIwIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjI0LjM2MjM2MDAzMTk5MjcsMzQ3LjY4NzVMMTk0LjkwMjM0Mzc1LDM4MC44MjgxMjVMODMuODE2NDA2MjUsNDIxLjUxMTQ5Nzk3MDQ4NDg3IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2MjEpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2MjEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbHMiPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE3OS4xMTMyODEyNSwxNzUuNzAzMTI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTYuMzU5Mzc1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjI4LjE1NjI1IiBoZWlnaHQ9IjE2LjM5MDYyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+bm8gRzwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzYuNTg1OTM3NSwyNzguMjY1NjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjAuNDA2MjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMzMuNDA2MjUiIGhlaWdodD0iMTYuMzkwNjI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5oYXMgRzwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjQ4ODI4MTI1LDI3OC4yNjU2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNi4zNTkzNzUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMjguMTU2MjUiIGhlaWdodD0iMTYuMzkwNjI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5ubyBHPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODAuNzAzMTI1LDM4MC44MjgxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNi4zNTkzNzUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMjguMTU2MjUiIGhlaWdodD0iMTYuMzkwNjI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5ubyBHPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1OTkuMDkzNzUsNDgzLjM5MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI0LjQ2MDkzNzUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iNDYuNzY1NjI1IiBoZWlnaHQ9IjE2LjM5MDYyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+d2FrZXVwPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MDQuNzM4MjgxMjUsMzI5LjU0Njg3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTc3LjExNzE4NzUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMTE3LjAzMTI1IiBoZWlnaHQ9IjE2LjM5MDYyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+c2NoZWQucnVucXNpemUgIT0gMDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTEzLjM0NzY1NjI1LDQzMi4xMDkzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MC42NjQwNjI1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjcxLjAxNTYyNSIgaGVpZ2h0PSIxNi4zOTA2MjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPiFydW5xZW1wdHk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExNS4yMzQzNzUsMzI5LjU0Njg3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIwLjQwNjI1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjMzLjQwNjI1IiBoZWlnaHQ9IjE2LjM5MDYyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+aGFzIEc8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5NC45MDIzNDM3NSwzODAuODI4MTI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjAuNDA2MjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMzMuNDA2MjUiIGhlaWdodD0iMTYuMzkwNjI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5oYXMgRzwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlcyI+PGcgY2xhc3M9Im5vZGUiIGlkPSJBIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MDQuNzM4MjgxMjUsMzguMTQwNjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii00OC4zMjAzMTI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iOTYuNjQwNjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzguMzIwMzEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+ZmluZHJ1bm5hYmxlPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MDQuNzM4MjgxMjUsMTI0LjQyMTg3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNDkuMTA5Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iOTguMjE4NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOS4xMDkzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnJ1bnFnZXQoX3BfKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iQyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTc5LjExMzI4MTI1LDIyNi45ODQzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTg1LjcxMDkzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxNzEuNDIxODc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzUuNzEwOTM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+Z2xvYnJ1bnFnZXQoX3BfLCBtYXg9MCk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDU0Ljg3ODkwNjI1LDQzMi4xMDkzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTI4LjkzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI1Ny44NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOC45Mzc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5yZXR1cm48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0MC40ODgyODEyNSwzMjkuNTQ2ODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii03MS4xNjQwNjI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTQyLjMyODEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTYxLjE2NDA2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnN0ZWFsIEcgZnJvbSBvdGhlciBQPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJFIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODAuNzAzMTI1LDQzMi4xMDkzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTQ4LjgyMDMxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI5Ny42NDA2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOC44MjAzMTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5nb2luZyB0byBzdG9wPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJGIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjIuODI4MTI1LDUzNC42NzE4NzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTEwNC4xMzI4MTI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMjA4LjI2NTYyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTk0LjEzMjgxMjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmJlZm9yZSBzdG9wLCBjaGVjayBnbG9icnVucWdldDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzYyLjgyODEyNSw2MjAuOTUzMTI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii01MC43NjU2MjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxMDEuNTMxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MC43NjU2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnBpZGxlcHV0KF9wXyk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQzMi4zOTQ1MzEyNSw3MDcuMjM0Mzc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii04MS4yNDIxODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTYyLjQ4NDM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTcxLjI0MjE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmJlZm9yZSBzdG9wLCBjaGVjayBhbGwgUDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iSSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDkwLjUxNTYyNSw3OTMuNTE1NjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0yOC40NzY1NjI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iNTYuOTUzMTI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTguNDc2NTYyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+c3RvcG08L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=

这里忽略了net poller,这是用来处理异步系统调用的一种方式。
以上流程中除了常规的global q和local q操作,还有一段关于stealing G的算法,称为Go Stealing Scheduler,可以参考Go's work-stealing scheduler。具体代码如下:

for i := 0; i < 4; i++ {
    for enum := stealOrder.start(fastrand()); !enum.done(); enum.next() {
        if sched.gcwaiting != 0 {
            goto top
        }
        stealRunNextG := i > 2 // first look for ready queues with more than 1 g
        if gp := runqsteal(_p_, allp[enum.position()], stealRunNextG); gp != nil {
            return gp, false
        }
    }
}

说实话代码没有很看懂:

  • 这个i = [0..4]是怎么回事儿?
  • 第二个for循环似乎采用随机数来随机获得相应的P,来steal G,但是为啥有个stealRunNextG := i > 2

stealRunNextG根据代码理解,应该是bool变量,表示是否从P的runnext成员获取G。
runqsteal会从runnext偷取G,或者会偷取P的runq中一半的G

resetspinning

这个函数将原先为true的_g_.m.spinning设为false。当全局都没有spinning的M了,则要唤醒idle P。没有spinning M表示所有的M要么在工作(处理G),要么在休眠。如果此时有idle P,表示有CPU空闲,则此时是一个好的时机来唤醒M处理更多的工作。
实际上GPM三者都有自己的状态机,G和P比较清晰,M的状态就比较模糊,到底M有几种状态,特别的是M会在何时spinning。后文会介绍。

execute

简单来看,execute只做了两件事:

  1. 切换G status:_Grunnalbe --> _Grunning
  2. 调用gogo(&gp.sched)

ARM平台的gogo函数实现在:go/src/runtime/asm_arm.s,是一个汇编函数。主要做了以下几件事情:

  • 设置TLS中的G
  • 做context switch
  • 跳转到对应的PC取运行

GPM的状态变迁

GPM的状态变迁可以参考Golang 中 goroutine 的调度一文中关于GPM的一生的章节。

G & P

对G和P不做过多的解释,状态机还是很清晰的。
G由newproc函数创建,遵循下面的状态变化

P由bootstrap过程的procresize创建,遵循下面的状态机变迁:

M的状态

这里不讨论特殊的M,例如:sysmon或者finalizer
普通的M由startm函数创建。其大致流程如下:

PHN2ZyBpZD0iZHZia2ltbHVyZGsiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDM1Ny43MTA5Mzc1cHg7IiB2aWV3Qm94PSIwIDAgMzU3LjcxMDkzNzUgNTE2LjI1Ij48c3R5bGU+CgoKI2R2YmtpbWx1cmRrIC5sYWJlbCB7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBjb2xvcjogIzMzMzsgfQoKI2R2YmtpbWx1cmRrIC5ub2RlIHJlY3QsCiNkdmJraW1sdXJkayAubm9kZSBjaXJjbGUsCiNkdmJraW1sdXJkayAubm9kZSBlbGxpcHNlLAojZHZia2ltbHVyZGsgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7IH0KCiNkdmJraW1sdXJkayAubm9kZS5jbGlja2FibGUgewogIGN1cnNvcjogcG9pbnRlcjsgfQoKI2R2YmtpbWx1cmRrIC5hcnJvd2hlYWRQYXRoIHsKICBmaWxsOiAjMzMzMzMzOyB9CgojZHZia2ltbHVyZGsgLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMzMzMzMzM7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsgfQoKI2R2YmtpbWx1cmRrIC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNlOGU4ZTg7IH0KCiNkdmJraW1sdXJkayAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjZmZmZmRlICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjYWFhYTMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsgfQoKI2R2YmtpbWx1cmRrIC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICMzMzM7IH0KCiNkdmJraW1sdXJkayBkaXYubWVybWFpZFRvb2x0aXAgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWF4LXdpZHRoOiAyMDBweDsKICBwYWRkaW5nOiAycHg7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEycHg7CiAgYmFja2dyb3VuZDogI2ZmZmZkZTsKICBib3JkZXI6IDFweCBzb2xpZCAjYWFhYTMzOwogIGJvcmRlci1yYWRpdXM6IDJweDsKICBwb2ludGVyLWV2ZW50czogbm9uZTsKICB6LWluZGV4OiAxMDA7IH0KCiNkdmJraW1sdXJkayAuYWN0b3IgewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZHZia2ltbHVyZGsgdGV4dC5hY3RvciB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHZia2ltbHVyZGsgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogZ3JleTsgfQoKI2R2YmtpbWx1cmRrIC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2R2YmtpbWx1cmRrIC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2R2YmtpbWx1cmRrICNhcnJvd2hlYWQgewogIGZpbGw6ICMzMzM7IH0KCiNkdmJraW1sdXJkayAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMzMzMgIWltcG9ydGFudDsKICBzdHJva2U6ICMzMzMgIWltcG9ydGFudDsgfQoKI2R2YmtpbWx1cmRrIC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzMzMzsKICBzdHJva2U6IG5vbmU7IH0KCiNkdmJraW1sdXJkayAubGFiZWxCb3ggewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZHZia2ltbHVyZGsgLmxhYmVsVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHZia2ltbHVyZGsgLmxvb3BUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkdmJraW1sdXJkayAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICNDQ0NDRkY7IH0KCiNkdmJraW1sdXJkayAubm90ZSB7CiAgc3Ryb2tlOiAjYWFhYTMzOwogIGZpbGw6ICNmZmY1YWQ7IH0KCiNkdmJraW1sdXJkayAubm90ZVRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTRweDsgfQoKI2R2YmtpbWx1cmRrIC5hY3RpdmF0aW9uMCB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNkdmJraW1sdXJkayAuYWN0aXZhdGlvbjEgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZHZia2ltbHVyZGsgLmFjdGl2YXRpb24yIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKCiNkdmJraW1sdXJkayAuc2VjdGlvbiB7CiAgc3Ryb2tlOiBub25lOwogIG9wYWNpdHk6IDAuMjsgfQoKI2R2YmtpbWx1cmRrIC5zZWN0aW9uMCB7CiAgZmlsbDogcmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KTsgfQoKI2R2YmtpbWx1cmRrIC5zZWN0aW9uMiB7CiAgZmlsbDogI2ZmZjQwMDsgfQoKI2R2YmtpbWx1cmRrIC5zZWN0aW9uMSwKI2R2YmtpbWx1cmRrIC5zZWN0aW9uMyB7CiAgZmlsbDogd2hpdGU7CiAgb3BhY2l0eTogMC4yOyB9CgojZHZia2ltbHVyZGsgLnNlY3Rpb25UaXRsZTAgewogIGZpbGw6ICMzMzM7IH0KCiNkdmJraW1sdXJkayAuc2VjdGlvblRpdGxlMSB7CiAgZmlsbDogIzMzMzsgfQoKI2R2YmtpbWx1cmRrIC5zZWN0aW9uVGl0bGUyIHsKICBmaWxsOiAjMzMzOyB9CgojZHZia2ltbHVyZGsgLnNlY3Rpb25UaXRsZTMgewogIGZpbGw6ICMzMzM7IH0KCiNkdmJraW1sdXJkayAuc2VjdGlvblRpdGxlIHsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OwogIHRleHQtaGVpZ2h0OiAxNHB4OyB9CgoKI2R2YmtpbWx1cmRrIC5ncmlkIC50aWNrIHsKICBzdHJva2U6IGxpZ2h0Z3JleTsKICBvcGFjaXR5OiAwLjM7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZHZia2ltbHVyZGsgLmdyaWQgcGF0aCB7CiAgc3Ryb2tlLXdpZHRoOiAwOyB9CgoKI2R2YmtpbWx1cmRrIC50b2RheSB7CiAgZmlsbDogbm9uZTsKICBzdHJva2U6IHJlZDsKICBzdHJva2Utd2lkdGg6IDJweDsgfQoKCgojZHZia2ltbHVyZGsgLnRhc2sgewogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R2YmtpbWx1cmRrIC50YXNrVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDExcHg7IH0KCiNkdmJraW1sdXJkayAudGFza1RleHRPdXRzaWRlUmlnaHQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7IH0KCiNkdmJraW1sdXJkayAudGFza1RleHRPdXRzaWRlTGVmdCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IGVuZDsKICBmb250LXNpemU6IDExcHg7IH0KCgojZHZia2ltbHVyZGsgLnRhc2tUZXh0MCwKI2R2YmtpbWx1cmRrIC50YXNrVGV4dDEsCiNkdmJraW1sdXJkayAudGFza1RleHQyLAojZHZia2ltbHVyZGsgLnRhc2tUZXh0MyB7CiAgZmlsbDogd2hpdGU7IH0KCiNkdmJraW1sdXJkayAudGFzazAsCiNkdmJraW1sdXJkayAudGFzazEsCiNkdmJraW1sdXJkayAudGFzazIsCiNkdmJraW1sdXJkayAudGFzazMgewogIGZpbGw6ICM4YTkwZGQ7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZHZia2ltbHVyZGsgLnRhc2tUZXh0T3V0c2lkZTAsCiNkdmJraW1sdXJkayAudGFza1RleHRPdXRzaWRlMiB7CiAgZmlsbDogYmxhY2s7IH0KCiNkdmJraW1sdXJkayAudGFza1RleHRPdXRzaWRlMSwKI2R2YmtpbWx1cmRrIC50YXNrVGV4dE91dHNpZGUzIHsKICBmaWxsOiBibGFjazsgfQoKCiNkdmJraW1sdXJkayAuYWN0aXZlMCwKI2R2YmtpbWx1cmRrIC5hY3RpdmUxLAojZHZia2ltbHVyZGsgLmFjdGl2ZTIsCiNkdmJraW1sdXJkayAuYWN0aXZlMyB7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNkdmJraW1sdXJkayAuYWN0aXZlVGV4dDAsCiNkdmJraW1sdXJkayAuYWN0aXZlVGV4dDEsCiNkdmJraW1sdXJkayAuYWN0aXZlVGV4dDIsCiNkdmJraW1sdXJkayAuYWN0aXZlVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZHZia2ltbHVyZGsgLmRvbmUwLAojZHZia2ltbHVyZGsgLmRvbmUxLAojZHZia2ltbHVyZGsgLmRvbmUyLAojZHZia2ltbHVyZGsgLmRvbmUzIHsKICBzdHJva2U6IGdyZXk7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R2YmtpbWx1cmRrIC5kb25lVGV4dDAsCiNkdmJraW1sdXJkayAuZG9uZVRleHQxLAojZHZia2ltbHVyZGsgLmRvbmVUZXh0MiwKI2R2YmtpbWx1cmRrIC5kb25lVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZHZia2ltbHVyZGsgLmNyaXQwLAojZHZia2ltbHVyZGsgLmNyaXQxLAojZHZia2ltbHVyZGsgLmNyaXQyLAojZHZia2ltbHVyZGsgLmNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogcmVkOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R2YmtpbWx1cmRrIC5hY3RpdmVDcml0MCwKI2R2YmtpbWx1cmRrIC5hY3RpdmVDcml0MSwKI2R2YmtpbWx1cmRrIC5hY3RpdmVDcml0MiwKI2R2YmtpbWx1cmRrIC5hY3RpdmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZHZia2ltbHVyZGsgLmRvbmVDcml0MCwKI2R2YmtpbWx1cmRrIC5kb25lQ3JpdDEsCiNkdmJraW1sdXJkayAuZG9uZUNyaXQyLAojZHZia2ltbHVyZGsgLmRvbmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7CiAgY3Vyc29yOiBwb2ludGVyOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2R2YmtpbWx1cmRrIC5kb25lQ3JpdFRleHQwLAojZHZia2ltbHVyZGsgLmRvbmVDcml0VGV4dDEsCiNkdmJraW1sdXJkayAuZG9uZUNyaXRUZXh0MiwKI2R2YmtpbWx1cmRrIC5kb25lQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZHZia2ltbHVyZGsgLmFjdGl2ZUNyaXRUZXh0MCwKI2R2YmtpbWx1cmRrIC5hY3RpdmVDcml0VGV4dDEsCiNkdmJraW1sdXJkayAuYWN0aXZlQ3JpdFRleHQyLAojZHZia2ltbHVyZGsgLmFjdGl2ZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2R2YmtpbWx1cmRrIC50aXRsZVRleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxOHB4OwogIGZpbGw6IGJsYWNrOyB9CgojZHZia2ltbHVyZGsgZy5jbGFzc0dyb3VwIHRleHQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZHZia2ltbHVyZGsgZy5jbGFzc0dyb3VwIHJlY3QgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOyB9CgojZHZia2ltbHVyZGsgZy5jbGFzc0dyb3VwIGxpbmUgewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkdmJraW1sdXJkayAuY2xhc3NMYWJlbCAuYm94IHsKICBzdHJva2U6IG5vbmU7CiAgc3Ryb2tlLXdpZHRoOiAwOwogIGZpbGw6ICNFQ0VDRkY7CiAgb3BhY2l0eTogMC41OyB9CgojZHZia2ltbHVyZGsgLmNsYXNzTGFiZWwgLmxhYmVsIHsKICBmaWxsOiAjOTM3MERCOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2R2YmtpbWx1cmRrIC5yZWxhdGlvbiB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsKICBmaWxsOiBub25lOyB9CgojZHZia2ltbHVyZGsgI2NvbXBvc2l0aW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R2YmtpbWx1cmRrICNjb21wb3NpdGlvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHZia2ltbHVyZGsgI2FnZ3JlZ2F0aW9uU3RhcnQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R2YmtpbWx1cmRrICNhZ2dyZWdhdGlvbkVuZCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHZia2ltbHVyZGsgI2RlcGVuZGVuY3lTdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHZia2ltbHVyZGsgI2RlcGVuZGVuY3lFbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R2YmtpbWx1cmRrICNleHRlbnNpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHZia2ltbHVyZGsgI2V4dGVuc2lvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHZia2ltbHVyZGsgLmNvbW1pdC1pZCwKI2R2YmtpbWx1cmRrIC5jb21taXQtbXNnLAojZHZia2ltbHVyZGsgLmJyYW5jaC1sYWJlbCB7CiAgZmlsbDogbGlnaHRncmV5OwogIGNvbG9yOiBsaWdodGdyZXk7IH0KCgoKI2R2YmtpbWx1cmRrIC5sYWJlbHsKICBjb2xvcjojMThCMTRFOwp9CiNkdmJraW1sdXJkayAudGUtbWQtY29udGFpbmVyLS1kYXJrIC5ub2RlIHJlY3QgewogIGZpbGw6IHJlZDsKfQoKI2R2YmtpbWx1cmRrIC5ub2RlIHJlY3QsCiNkdmJraW1sdXJkayAubm9kZSBjaXJjbGUsCiNkdmJraW1sdXJkayAubm9kZSBlbGxpcHNlLAojZHZia2ltbHVyZGsgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0Y5RkZGQjs7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMS41cHg7Cn0KI2R2YmtpbWx1cmRrIC5hcnJvd2hlYWRQYXRoewogIGZpbGw6ICMyREJENjA7Cn0KI2R2YmtpbWx1cmRrIC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMXB4Owp9CiNkdmJraW1sdXJkayAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOwp9CiNkdmJraW1sdXJkayAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjRjlGRkZCICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsKfQoKI2R2YmtpbWx1cmRrIC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkdmJraW1sdXJkayBkaXYubWVybWFpZFRvb2x0aXAgewogIGJhY2tncm91bmQ6ICNGOUZGRkI7CiAgYm9yZGVyOiAxcHggc29saWQgIzJEQkQ2MDsKfQoKCiNkdmJraW1sdXJkayAuYWN0b3IgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHZia2ltbHVyZGsgdGV4dC5hY3RvciB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkdmJraW1sdXJkayAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHZia2ltbHVyZGsgLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHZia2ltbHVyZGsgLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHZia2ltbHVyZGsgI2Fycm93aGVhZCB7CiAgZmlsbDogIzJEQkQ2MDsKfQoKI2R2YmtpbWx1cmRrICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50Owp9CgojZHZia2ltbHVyZGsgLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2R2YmtpbWx1cmRrIC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkdmJraW1sdXJkayAubGFiZWxUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R2YmtpbWx1cmRrIC5sb29wVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkdmJraW1sdXJkayAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkdmJraW1sdXJkayAubm90ZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkdmJraW1sdXJkayAubm90ZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgoKI2R2YmtpbWx1cmRrIC5zZWN0aW9uewogIG9wYWNpdHk6MTsKfQojZHZia2ltbHVyZGsgLnNlY3Rpb24wLCNkdmJraW1sdXJkayAgLnNlY3Rpb24yIHsKICBmaWxsOiAjRUNGN0YwOwp9CgojZHZia2ltbHVyZGsgLnNlY3Rpb24xLAojZHZia2ltbHVyZGsgLnNlY3Rpb24zIHsKICBmaWxsOiAjRkZGOwp9CiNkdmJraW1sdXJkayAudGFza1RleHQwLAojZHZia2ltbHVyZGsgLnRhc2tUZXh0MSwKI2R2YmtpbWx1cmRrIC50YXNrVGV4dDIsCiNkdmJraW1sdXJkayAudGFza1RleHQzIHsKICBmaWxsOiAjZmZmOwp9CgojZHZia2ltbHVyZGsgLnRhc2swLAojZHZia2ltbHVyZGsgLnRhc2sxLAojZHZia2ltbHVyZGsgLnRhc2syLAojZHZia2ltbHVyZGsgLnRhc2szIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzM1OUY1QTsKfQo8L3N0eWxlPjxzdHlsZT4jZHZia2ltbHVyZGsgewogICAgY29sb3I6IHJnYigyNDQsIDI0NCwgMjQ0KTsKICAgIGZvbnQ6IG5vcm1hbCBub3JtYWwgbm9ybWFsIG5vcm1hbCAxNHB4LzIyLjM5OTk5OTYxODUzMDI3M3B4IG1vbm9zcGFjZTsKICB9PC9zdHlsZT48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIsIC0xMikiPjxnIGNsYXNzPSJvdXRwdXQiPjxnIGNsYXNzPSJjbHVzdGVycyI+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aHMiPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTEzMC44NDQ1MzU1MzQ3MzQ5Miw1Ni4yODEyNUw3MS42MzY3MTg3NSw4OS40MjE4NzVMNzEuNjM2NzE4NzUsMTIyLjU2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTY2NikiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTY2NiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTg0Ljc2ODIyMDgzNTIzNzY2LDE1OC44NDM3NUwxMDguNzU3ODEyNSwxOTEuOTg0Mzc1TDE3NC45MDYyNSwyMjkuMDA5OTAxMDI5Njc1MTIiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTY2NykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTY2NyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE4NS4zNTQ4NDc0NjM0MzY5Myw1Ni4yODEyNUwyMjUuNzMwNDY4NzUsODkuNDIxODc1TDIyNS43MzA0Njg3NSwxNDAuNzAzMTI1TDIyNS43MzA0Njg3NSwxOTEuOTg0Mzc1TDIwOS4zNDQ0MzkxMjgxOTkyNywyMjUuMTI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2NjgpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2NjgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik02Mi42NjcyNzk2MjE4MDA3MywxNTguODQzNzVMNDYuMjgxMjUsMTkxLjk4NDM3NUw0Ni4yODEyNSwyNDMuMjY1NjI1TDQ2LjI4MTI1LDI4Ni40MDYyNUw0Ni4yODEyNSwzMjkuNTQ2ODc1TDQ2LjI4MTI1LDM3Mi42ODc1TDQ2LjI4MTI1LDQxNS44MjgxMjVMNDYuMjgxMjUsNDU4Ljk2ODc1TDkxLjU4NTkzNzUsNDg1LjI5NDM4MjM2NjA5NDkiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTY2OSkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTY2OSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE3NC45MDYyNSwyNTcuMDI1Mzc4MjA0MTg3NDZMMTIwLjUyMzQzNzUsMjg2LjQwNjI1TDEyMC41MjM0Mzc1LDMyOS41NDY4NzVMMTIwLjUyMzQzNzUsMzcyLjY4NzVMMTIwLjUyMzQzNzUsMzk3LjY4NzUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTY3MCkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTY3MCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTEyMC41MjM0Mzc1LDQzMy45Njg3NUwxMjAuNTIzNDM3NSw0NTguOTY4NzVMMTIwLjUyMzQzNzUsNDgzLjk2ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2NzEpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2NzEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yMjUuODQzNzUsMjU3LjAyNTM3ODIwNDE4NzQ2TDI4MC4yMjY1NjI1LDI4Ni40MDYyNUwyODAuMjI2NTYyNSwzMTEuNDA2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTY3MikiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTY3MiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTI4MC4yMjY1NjI1LDM0Ny42ODc1TDI4MC4yMjY1NjI1LDM3Mi42ODc1TDI4MC4yMjY1NjI1LDM5Ny42ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk2NzMpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk2NzMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yODAuMjI2NTYyNSw0MzMuOTY4NzVMMjgwLjIyNjU2MjUsNDU4Ljk2ODc1TDE0OS40NjA5Mzc1LDQ5NC4yOTI0ODQ1Mjk0MDAyNyIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5Njc0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5Njc0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWxzIj48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3MS42MzY3MTg3NSw4OS40MjE4NzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MC42NjQwNjI1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjU4LjcwMzEyNSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+X3BfID09IG5pbDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTA4Ljc1NzgxMjUsMTkxLjk4NDM3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ0LjcxMDkzNzUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iNjEuNDUzMTI1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5maW5kIGlkbGUgUDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDYuMjgxMjUsMzI5LjU0Njg3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM2LjYwOTM3NSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI1Mi41OTM3NSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+bm8gaWRsZSBQPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjAuNTIzNDM3NSwzMjkuNTQ2ODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzYuNjA5Mzc1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjU1Ljk1MzEyNSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+bXAgPT0gbmlsPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGVzIj48ZyBjbGFzcz0ibm9kZSIgaWQ9IkEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE2My4yNTM5MDYyNSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTc0LjM3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjE0OC43NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTY0LjM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+c3RhcnRtKF9wXywgc3Bpbm5pbmcpPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3MS42MzY3MTg3NSwxNDAuNzAzMTI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0zNC43NDIxODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iNjkuNDg0Mzc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjQuNzQyMTg3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+cGlkbGVnZXQ8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwMC4zNzUsMjQzLjI2NTYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMjUuNDY4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI1MC45Mzc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTUuNDY4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPm1nZXQ8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMC41MjM0Mzc1LDUwMi4xMDkzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTI4LjkzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI1Ny44NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOC45Mzc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5yZXR1cm48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMC41MjM0Mzc1LDQxNS44MjgxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTI4LjIxODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iNTYuNDM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE4LjIxODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5uZXdtPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJFIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODAuMjI2NTYyNSwzMjkuNTQ2ODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii02Ni4wODU5Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTMyLjE3MTg3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU2LjA4NTkzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPm1wLm5leHRwLnNldChfcF8pPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJGIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODAuMjI2NTYyNSw0MTUuODI4MTI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii04MS40ODQzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxNjIuOTY4NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03MS40ODQzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPm5vdGV3YWtldXAoJmFtcDttcC5wYXJrKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==
M的创建

这里跟M状态有关的就是M的线程函数,但请注意下面这个fn并不是线程函数。

if spinning {
    // The caller incremented nmspinning, so set m.spinning in the new M.
    fn = mspinning
}

真正的线程函数在newosproc调用clone接口的时候传入。Linux平台的实现在os_linux.go中。如下:

func clone(flags int32, stk, mp, gp, fn unsafe.Pointer) int32

func newosproc(mp *m) {
    ...
	ret := clone(cloneFlags, stk, unsafe.Pointer(mp), unsafe.Pointer(mp.g0), unsafe.Pointer(funcPC(mstart)))
    ...
}

所以M的线程函数就是曾在bootstrap中出现过,运行M0的mstart函数。上面的mspinning函数在mstart1中被调用,它将线程设置为spinning状态。

idle M的管理

mget会去获取闲置的M。而所有的idle M并没有一个统一的保存位置,而是通过M.schedlink形成一个隐形的链表。看mput:

func mput(mp *m) {
	mp.schedlink = sched.midle
	sched.midle.set(mp)
	sched.nmidle++
    ...
}

假设调用了3次mput,那么此时的idle链表应该是这样的:

PHN2ZyBpZD0iZHU5dHBsMXdicDkiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDYxMS4xNDA2MjVweDsiIHZpZXdCb3g9IjAgMCA2MTEuMTQwNjI1IDUyLjI4MTI1Ij48c3R5bGU+CgoKI2R1OXRwbDF3YnA5IC5sYWJlbCB7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBjb2xvcjogIzMzMzsgfQoKI2R1OXRwbDF3YnA5IC5ub2RlIHJlY3QsCiNkdTl0cGwxd2JwOSAubm9kZSBjaXJjbGUsCiNkdTl0cGwxd2JwOSAubm9kZSBlbGxpcHNlLAojZHU5dHBsMXdicDkgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7IH0KCiNkdTl0cGwxd2JwOSAubm9kZS5jbGlja2FibGUgewogIGN1cnNvcjogcG9pbnRlcjsgfQoKI2R1OXRwbDF3YnA5IC5hcnJvd2hlYWRQYXRoIHsKICBmaWxsOiAjMzMzMzMzOyB9CgojZHU5dHBsMXdicDkgLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMzMzMzMzM7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsgfQoKI2R1OXRwbDF3YnA5IC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNlOGU4ZTg7IH0KCiNkdTl0cGwxd2JwOSAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjZmZmZmRlICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjYWFhYTMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsgfQoKI2R1OXRwbDF3YnA5IC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICMzMzM7IH0KCiNkdTl0cGwxd2JwOSBkaXYubWVybWFpZFRvb2x0aXAgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWF4LXdpZHRoOiAyMDBweDsKICBwYWRkaW5nOiAycHg7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEycHg7CiAgYmFja2dyb3VuZDogI2ZmZmZkZTsKICBib3JkZXI6IDFweCBzb2xpZCAjYWFhYTMzOwogIGJvcmRlci1yYWRpdXM6IDJweDsKICBwb2ludGVyLWV2ZW50czogbm9uZTsKICB6LWluZGV4OiAxMDA7IH0KCiNkdTl0cGwxd2JwOSAuYWN0b3IgewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZHU5dHBsMXdicDkgdGV4dC5hY3RvciB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHU5dHBsMXdicDkgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogZ3JleTsgfQoKI2R1OXRwbDF3YnA5IC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2R1OXRwbDF3YnA5IC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2R1OXRwbDF3YnA5ICNhcnJvd2hlYWQgewogIGZpbGw6ICMzMzM7IH0KCiNkdTl0cGwxd2JwOSAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMzMzMgIWltcG9ydGFudDsKICBzdHJva2U6ICMzMzMgIWltcG9ydGFudDsgfQoKI2R1OXRwbDF3YnA5IC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzMzMzsKICBzdHJva2U6IG5vbmU7IH0KCiNkdTl0cGwxd2JwOSAubGFiZWxCb3ggewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZHU5dHBsMXdicDkgLmxhYmVsVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHU5dHBsMXdicDkgLmxvb3BUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkdTl0cGwxd2JwOSAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICNDQ0NDRkY7IH0KCiNkdTl0cGwxd2JwOSAubm90ZSB7CiAgc3Ryb2tlOiAjYWFhYTMzOwogIGZpbGw6ICNmZmY1YWQ7IH0KCiNkdTl0cGwxd2JwOSAubm90ZVRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTRweDsgfQoKI2R1OXRwbDF3YnA5IC5hY3RpdmF0aW9uMCB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNkdTl0cGwxd2JwOSAuYWN0aXZhdGlvbjEgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZHU5dHBsMXdicDkgLmFjdGl2YXRpb24yIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKCiNkdTl0cGwxd2JwOSAuc2VjdGlvbiB7CiAgc3Ryb2tlOiBub25lOwogIG9wYWNpdHk6IDAuMjsgfQoKI2R1OXRwbDF3YnA5IC5zZWN0aW9uMCB7CiAgZmlsbDogcmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KTsgfQoKI2R1OXRwbDF3YnA5IC5zZWN0aW9uMiB7CiAgZmlsbDogI2ZmZjQwMDsgfQoKI2R1OXRwbDF3YnA5IC5zZWN0aW9uMSwKI2R1OXRwbDF3YnA5IC5zZWN0aW9uMyB7CiAgZmlsbDogd2hpdGU7CiAgb3BhY2l0eTogMC4yOyB9CgojZHU5dHBsMXdicDkgLnNlY3Rpb25UaXRsZTAgewogIGZpbGw6ICMzMzM7IH0KCiNkdTl0cGwxd2JwOSAuc2VjdGlvblRpdGxlMSB7CiAgZmlsbDogIzMzMzsgfQoKI2R1OXRwbDF3YnA5IC5zZWN0aW9uVGl0bGUyIHsKICBmaWxsOiAjMzMzOyB9CgojZHU5dHBsMXdicDkgLnNlY3Rpb25UaXRsZTMgewogIGZpbGw6ICMzMzM7IH0KCiNkdTl0cGwxd2JwOSAuc2VjdGlvblRpdGxlIHsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OwogIHRleHQtaGVpZ2h0OiAxNHB4OyB9CgoKI2R1OXRwbDF3YnA5IC5ncmlkIC50aWNrIHsKICBzdHJva2U6IGxpZ2h0Z3JleTsKICBvcGFjaXR5OiAwLjM7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZHU5dHBsMXdicDkgLmdyaWQgcGF0aCB7CiAgc3Ryb2tlLXdpZHRoOiAwOyB9CgoKI2R1OXRwbDF3YnA5IC50b2RheSB7CiAgZmlsbDogbm9uZTsKICBzdHJva2U6IHJlZDsKICBzdHJva2Utd2lkdGg6IDJweDsgfQoKCgojZHU5dHBsMXdicDkgLnRhc2sgewogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R1OXRwbDF3YnA5IC50YXNrVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDExcHg7IH0KCiNkdTl0cGwxd2JwOSAudGFza1RleHRPdXRzaWRlUmlnaHQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7IH0KCiNkdTl0cGwxd2JwOSAudGFza1RleHRPdXRzaWRlTGVmdCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IGVuZDsKICBmb250LXNpemU6IDExcHg7IH0KCgojZHU5dHBsMXdicDkgLnRhc2tUZXh0MCwKI2R1OXRwbDF3YnA5IC50YXNrVGV4dDEsCiNkdTl0cGwxd2JwOSAudGFza1RleHQyLAojZHU5dHBsMXdicDkgLnRhc2tUZXh0MyB7CiAgZmlsbDogd2hpdGU7IH0KCiNkdTl0cGwxd2JwOSAudGFzazAsCiNkdTl0cGwxd2JwOSAudGFzazEsCiNkdTl0cGwxd2JwOSAudGFzazIsCiNkdTl0cGwxd2JwOSAudGFzazMgewogIGZpbGw6ICM4YTkwZGQ7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZHU5dHBsMXdicDkgLnRhc2tUZXh0T3V0c2lkZTAsCiNkdTl0cGwxd2JwOSAudGFza1RleHRPdXRzaWRlMiB7CiAgZmlsbDogYmxhY2s7IH0KCiNkdTl0cGwxd2JwOSAudGFza1RleHRPdXRzaWRlMSwKI2R1OXRwbDF3YnA5IC50YXNrVGV4dE91dHNpZGUzIHsKICBmaWxsOiBibGFjazsgfQoKCiNkdTl0cGwxd2JwOSAuYWN0aXZlMCwKI2R1OXRwbDF3YnA5IC5hY3RpdmUxLAojZHU5dHBsMXdicDkgLmFjdGl2ZTIsCiNkdTl0cGwxd2JwOSAuYWN0aXZlMyB7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNkdTl0cGwxd2JwOSAuYWN0aXZlVGV4dDAsCiNkdTl0cGwxd2JwOSAuYWN0aXZlVGV4dDEsCiNkdTl0cGwxd2JwOSAuYWN0aXZlVGV4dDIsCiNkdTl0cGwxd2JwOSAuYWN0aXZlVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZHU5dHBsMXdicDkgLmRvbmUwLAojZHU5dHBsMXdicDkgLmRvbmUxLAojZHU5dHBsMXdicDkgLmRvbmUyLAojZHU5dHBsMXdicDkgLmRvbmUzIHsKICBzdHJva2U6IGdyZXk7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R1OXRwbDF3YnA5IC5kb25lVGV4dDAsCiNkdTl0cGwxd2JwOSAuZG9uZVRleHQxLAojZHU5dHBsMXdicDkgLmRvbmVUZXh0MiwKI2R1OXRwbDF3YnA5IC5kb25lVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZHU5dHBsMXdicDkgLmNyaXQwLAojZHU5dHBsMXdicDkgLmNyaXQxLAojZHU5dHBsMXdicDkgLmNyaXQyLAojZHU5dHBsMXdicDkgLmNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogcmVkOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R1OXRwbDF3YnA5IC5hY3RpdmVDcml0MCwKI2R1OXRwbDF3YnA5IC5hY3RpdmVDcml0MSwKI2R1OXRwbDF3YnA5IC5hY3RpdmVDcml0MiwKI2R1OXRwbDF3YnA5IC5hY3RpdmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZHU5dHBsMXdicDkgLmRvbmVDcml0MCwKI2R1OXRwbDF3YnA5IC5kb25lQ3JpdDEsCiNkdTl0cGwxd2JwOSAuZG9uZUNyaXQyLAojZHU5dHBsMXdicDkgLmRvbmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7CiAgY3Vyc29yOiBwb2ludGVyOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2R1OXRwbDF3YnA5IC5kb25lQ3JpdFRleHQwLAojZHU5dHBsMXdicDkgLmRvbmVDcml0VGV4dDEsCiNkdTl0cGwxd2JwOSAuZG9uZUNyaXRUZXh0MiwKI2R1OXRwbDF3YnA5IC5kb25lQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZHU5dHBsMXdicDkgLmFjdGl2ZUNyaXRUZXh0MCwKI2R1OXRwbDF3YnA5IC5hY3RpdmVDcml0VGV4dDEsCiNkdTl0cGwxd2JwOSAuYWN0aXZlQ3JpdFRleHQyLAojZHU5dHBsMXdicDkgLmFjdGl2ZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2R1OXRwbDF3YnA5IC50aXRsZVRleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxOHB4OwogIGZpbGw6IGJsYWNrOyB9CgojZHU5dHBsMXdicDkgZy5jbGFzc0dyb3VwIHRleHQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZHU5dHBsMXdicDkgZy5jbGFzc0dyb3VwIHJlY3QgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOyB9CgojZHU5dHBsMXdicDkgZy5jbGFzc0dyb3VwIGxpbmUgewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkdTl0cGwxd2JwOSAuY2xhc3NMYWJlbCAuYm94IHsKICBzdHJva2U6IG5vbmU7CiAgc3Ryb2tlLXdpZHRoOiAwOwogIGZpbGw6ICNFQ0VDRkY7CiAgb3BhY2l0eTogMC41OyB9CgojZHU5dHBsMXdicDkgLmNsYXNzTGFiZWwgLmxhYmVsIHsKICBmaWxsOiAjOTM3MERCOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2R1OXRwbDF3YnA5IC5yZWxhdGlvbiB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsKICBmaWxsOiBub25lOyB9CgojZHU5dHBsMXdicDkgI2NvbXBvc2l0aW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R1OXRwbDF3YnA5ICNjb21wb3NpdGlvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHU5dHBsMXdicDkgI2FnZ3JlZ2F0aW9uU3RhcnQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R1OXRwbDF3YnA5ICNhZ2dyZWdhdGlvbkVuZCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHU5dHBsMXdicDkgI2RlcGVuZGVuY3lTdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHU5dHBsMXdicDkgI2RlcGVuZGVuY3lFbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R1OXRwbDF3YnA5ICNleHRlbnNpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHU5dHBsMXdicDkgI2V4dGVuc2lvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHU5dHBsMXdicDkgLmNvbW1pdC1pZCwKI2R1OXRwbDF3YnA5IC5jb21taXQtbXNnLAojZHU5dHBsMXdicDkgLmJyYW5jaC1sYWJlbCB7CiAgZmlsbDogbGlnaHRncmV5OwogIGNvbG9yOiBsaWdodGdyZXk7IH0KCgoKI2R1OXRwbDF3YnA5IC5sYWJlbHsKICBjb2xvcjojMThCMTRFOwp9CiNkdTl0cGwxd2JwOSAudGUtbWQtY29udGFpbmVyLS1kYXJrIC5ub2RlIHJlY3QgewogIGZpbGw6IHJlZDsKfQoKI2R1OXRwbDF3YnA5IC5ub2RlIHJlY3QsCiNkdTl0cGwxd2JwOSAubm9kZSBjaXJjbGUsCiNkdTl0cGwxd2JwOSAubm9kZSBlbGxpcHNlLAojZHU5dHBsMXdicDkgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0Y5RkZGQjs7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMS41cHg7Cn0KI2R1OXRwbDF3YnA5IC5hcnJvd2hlYWRQYXRoewogIGZpbGw6ICMyREJENjA7Cn0KI2R1OXRwbDF3YnA5IC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMXB4Owp9CiNkdTl0cGwxd2JwOSAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOwp9CiNkdTl0cGwxd2JwOSAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjRjlGRkZCICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsKfQoKI2R1OXRwbDF3YnA5IC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkdTl0cGwxd2JwOSBkaXYubWVybWFpZFRvb2x0aXAgewogIGJhY2tncm91bmQ6ICNGOUZGRkI7CiAgYm9yZGVyOiAxcHggc29saWQgIzJEQkQ2MDsKfQoKCiNkdTl0cGwxd2JwOSAuYWN0b3IgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHU5dHBsMXdicDkgdGV4dC5hY3RvciB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkdTl0cGwxd2JwOSAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHU5dHBsMXdicDkgLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHU5dHBsMXdicDkgLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHU5dHBsMXdicDkgI2Fycm93aGVhZCB7CiAgZmlsbDogIzJEQkQ2MDsKfQoKI2R1OXRwbDF3YnA5ICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50Owp9CgojZHU5dHBsMXdicDkgLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2R1OXRwbDF3YnA5IC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkdTl0cGwxd2JwOSAubGFiZWxUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R1OXRwbDF3YnA5IC5sb29wVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkdTl0cGwxd2JwOSAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkdTl0cGwxd2JwOSAubm90ZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkdTl0cGwxd2JwOSAubm90ZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgoKI2R1OXRwbDF3YnA5IC5zZWN0aW9uewogIG9wYWNpdHk6MTsKfQojZHU5dHBsMXdicDkgLnNlY3Rpb24wLCNkdTl0cGwxd2JwOSAgLnNlY3Rpb24yIHsKICBmaWxsOiAjRUNGN0YwOwp9CgojZHU5dHBsMXdicDkgLnNlY3Rpb24xLAojZHU5dHBsMXdicDkgLnNlY3Rpb24zIHsKICBmaWxsOiAjRkZGOwp9CiNkdTl0cGwxd2JwOSAudGFza1RleHQwLAojZHU5dHBsMXdicDkgLnRhc2tUZXh0MSwKI2R1OXRwbDF3YnA5IC50YXNrVGV4dDIsCiNkdTl0cGwxd2JwOSAudGFza1RleHQzIHsKICBmaWxsOiAjZmZmOwp9CgojZHU5dHBsMXdicDkgLnRhc2swLAojZHU5dHBsMXdicDkgLnRhc2sxLAojZHU5dHBsMXdicDkgLnRhc2syLAojZHU5dHBsMXdicDkgLnRhc2szIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzM1OUY1QTsKfQo8L3N0eWxlPjxzdHlsZT4jZHU5dHBsMXdicDkgewogICAgY29sb3I6IHJnYigyNDQsIDI0NCwgMjQ0KTsKICAgIGZvbnQ6IG5vcm1hbCBub3JtYWwgbm9ybWFsIG5vcm1hbCAxNHB4LzIyLjM5OTk5OTYxODUzMDI3M3B4IG1vbm9zcGFjZTsKICB9PC9zdHlsZT48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIsIC0xMikiPjxnIGNsYXNzPSJvdXRwdXQiPjxnIGNsYXNzPSJjbHVzdGVycyI+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aHMiPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTc0LjQ4NDM3NSwzOC4xNDA2MjVMMTE2LjQ3NjU2MjUsMzguMTQwNjI1TDE1OC40Njg3NSwzOC4xNDA2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkOTcwMCkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkOTcwMCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE5NS40NTMxMjUsMzguMTQwNjI1TDI0OC41MTU2MjUsMzguMTQwNjI1TDMwMS41NzgxMjUsMzguMTQwNjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk3MDEpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk3MDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0zMzguNTYyNSwzOC4xNDA2MjVMMzkxLjYyNSwzOC4xNDA2MjVMNDQ0LjY4NzUsMzguMTQwNjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDk3MDIpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDk3MDIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik00ODEuNjcxODc1LDM4LjE0MDYyNUw1MzQuNzM0Mzc1LDM4LjE0MDYyNUw1ODcuNzk2ODc1LDM4LjE0MDYyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ5NzAzKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ5NzAzIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWxzIj48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMTYuNDc2NTYyNSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMC40MDYyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIzNC4xNzE4NzUiIGhlaWdodD0iMTYuMzU5Mzc1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5taWRsZTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ4LjUxNTYyNSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNi42MDkzNzUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iNTYuNDM3NSIgaGVpZ2h0PSIxNi4zNTkzNzUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnNjaGVkbGluazwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzkxLjYyNSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNi42MDkzNzUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iNTYuNDM3NSIgaGVpZ2h0PSIxNi4zNTkzNzUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnNjaGVkbGluazwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTM0LjczNDM3NSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNi42MDkzNzUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iNTYuNDM3NSIgaGVpZ2h0PSIxNi4zNTkzNzUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnNjaGVkbGluazwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlcyI+PGcgY2xhc3M9Im5vZGUiIGlkPSJBIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0Ny4yNDIxODc1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMjcuMjQyMTg3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjU0LjQ4NDM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE3LjI0MjE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnNjaGVkPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzYuOTYwOTM3NSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTE4LjQ5MjE4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIzNi45ODQzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04LjQ5MjE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPk0xPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJDIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMjAuMDcwMzEyNSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTE4LjQ5MjE4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIzNi45ODQzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04LjQ5MjE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPk0yPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJEIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NjMuMTc5Njg3NSwzOC4xNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTE4LjQ5MjE4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIzNi45ODQzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04LjQ5MjE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPk0zPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJFIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MDEuNDY4NzUsMzguMTQwNjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0xMy42NzE4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIyNy4zNDM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMuNjcxODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj4wPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PC9zdmc+
M的状态变迁

M在创建的时候会被设置成spinning状态。还有其他的spinning状态吗?
有:

  1. 当findrunnable准备进入stealing scheduler时,会先设置spinning
  2. 当findrunnable查找allp时,发现还有G,要重新回到循环来获取G

所以可以总结的是M的spinning是一种忙等的状态,而且它不是一个那么重要的状态,它可以看作一种系统的性能指标。如果spinning状态的M太多了,说明正常工作的M太少了。系统会组织M进入spinning状态。

// If number of spinning M's >= number of busy P's, block.
// This is necessary to prevent excessive CPU consumption
// when GOMAXPROCS>>1 but the program parallelism is low.
if !_g_.m.spinning && 2*atomic.Load(&sched.nmspinning) >= procs-atomic.Load(&sched.npidle) {
    goto stop
}

那么M什么时候离开spinning状态呢?有这几种情况:

  1. schedule中,M即将开始运行G,resetspinning将其spinning标志位设为false
  2. findrunnable没找到G,M即将调用stopm进入休眠状态

借用Golang 中 goroutine 的调度中的这张状态图:

这张图的状态变迁是正确的,但我觉得并不够贴切。因为对于M来说,没有很严格的状态变迁。只要知道M可以处于spinning状态,表示一种中间状态,在忙等待。而在正常工作和休眠的时候,都不是spinning。
M可以通过notesleep进入futexsleep状态,可以通过notewakeup唤醒休眠的M。

参考文献

%E6%9C%AC%E6%96%87%E5%9F%BA%E4%BA%8EGo%201.13%E3%80%82%0AGo%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%80%E5%A5%97runtime%E6%9C%BA%E5%88%B6%EF%BC%8C%E6%9D%A5%E6%8F%90%E4%BE%9B%E5%85%B6%E5%8D%8F%E7%A8%8B%E8%B0%83%E5%BA%A6%E7%89%B9%E6%80%A7%E3%80%82%E5%AE%9E%E9%99%85%E4%B8%8A%E5%B0%B1%E6%98%AF%E5%AE%8C%E6%88%90%E4%B8%80%E7%A7%8D%E7%B1%BB%E4%BC%BCJavaScript%E7%9A%84event-driven%E7%BC%96%E7%A8%8B%E6%88%96%E8%80%85%E5%BC%82%E6%AD%A5%E7%BC%96%E7%A8%8B%E7%9A%84%E8%8C%83%E5%BC%8F%E3%80%82%E5%85%B6%E5%B8%A6%E6%9D%A5%E7%9A%84%E7%89%B9%E6%80%A7%E6%98%AF%EF%BC%8C%E5%A4%A7%E5%A4%A7%E5%A2%9E%E5%8A%A0%E4%BA%86Go%20app%E7%9A%84%E5%B9%B6%E5%8F%91%E7%89%B9%E6%80%A7%EF%BC%88%E5%8F%AF%E8%BE%BE%E7%99%BE%E4%B8%87%E7%BA%A7%EF%BC%8C%E7%94%9A%E8%87%B3%E6%9B%B4%E5%A4%9A%E7%9A%84%E5%B9%B6%E5%8F%91%EF%BC%89%E3%80%82%E7%89%B9%E5%88%AB%E9%80%82%E7%94%A8%E4%BA%8E%E6%89%80%E6%9C%89%E5%B9%B6%E5%8F%91%E9%83%BD%E6%98%AF%E6%97%A0%E5%B7%AE%E5%88%AB%E7%9A%84%E5%9C%BA%E6%99%AF%E4%B8%8B%E3%80%82%E4%BE%8B%E5%A6%82%E7%BD%91%E7%BB%9C%E8%BF%9E%E6%8E%A5%E3%80%82%E4%BD%86%E5%9B%A0%E4%B8%BA%E6%B2%A1%E6%9C%89%E4%BC%98%E5%85%88%E7%BA%A7%E6%A6%82%E5%BF%B5%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8AGo%E7%9A%84%E8%B0%83%E5%BA%A6%E6%A1%86%E6%9E%B6%E5%AF%B9%E5%AE%9E%E6%97%B6%E6%80%A7%E6%98%AF%E6%9C%89%E6%8D%9F%E5%AE%B3%E7%9A%84%E3%80%82%0A%E6%9C%AC%E6%96%87%E4%B8%93%E6%B3%A8%E4%BA%8E%E5%88%86%E6%9E%90%E8%B0%83%E5%BA%A6%E6%A1%86%E6%9E%B6%EF%BC%8C%E4%BB%A5%E5%8F%8A%E4%B8%80%E4%BA%9B%E6%A1%86%E6%9E%B6%E7%9A%84%E5%AE%9E%E7%8E%B0%E7%BB%86%E8%8A%82%E3%80%82%E6%96%87%E6%9C%AB%E4%BC%9A%E5%88%97%E4%B8%BE%E6%88%91%E5%9C%A8%E9%98%85%E8%AF%BB%E6%97%B6%E5%8F%82%E8%80%83%E7%9A%84%E7%BD%91%E9%A1%B5%E9%93%BE%E6%8E%A5%E3%80%82%0A%5Btoc%5D%0A%23%23%20GPM%0AGo%E5%9F%BA%E4%BA%8EGPM%E8%BF%99%E4%B8%89%E4%B8%AAobject%E6%9D%A5%E7%BB%84%E7%BB%87%E8%B0%83%E5%BA%A6%E6%A1%86%E6%9E%B6%E3%80%82%E5%A4%A7%E8%87%B4%E7%BB%93%E6%9E%84%E5%A6%82%E4%B8%8B%EF%BC%9A%0A!%5B11413e494428c2540e349637f34bbec3.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6067)%0A%E5%85%B6%E4%B8%AD%EF%BC%9A%0A-%20G%3A%20Gourtines%2C%20%E6%AF%8F%E4%B8%AAGoroutine%E5%AF%B9%E5%BA%94%E4%B8%80%E4%B8%AAG%E7%BB%93%E6%9E%84%E4%BD%93%EF%BC%8CG%E4%BF%9D%E5%AD%98Goroutine%E7%9A%84%E8%BF%90%E8%A1%8C%E5%A0%86%E6%A0%88%EF%BC%8C%E5%8D%B3%E5%B9%B6%E5%8F%91%E4%BB%BB%E5%8A%A1%E7%8A%B6%E6%80%81%E3%80%82%0A-%20P%3A%20Processors%2C%20%E7%90%86%E6%83%B3%E7%8A%B6%E6%80%81%E4%B8%8B%E4%B8%80%E4%B8%AAP%E5%AF%B9%E5%BA%94%E4%B8%80%E4%B8%AACPU%E6%A0%B8%E3%80%82%E5%AF%B9M%E6%9D%A5%E8%AF%B4%EF%BC%8CP%E6%8F%90%E4%BE%9B%E4%BA%86%E7%9B%B8%E5%85%B3%E7%9A%84%E6%89%A7%E8%A1%8C%E7%8E%AF%E5%A2%83(Context)%EF%BC%8C%E5%A6%82%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%8A%B6%E6%80%81(mcache)%EF%BC%8C%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97(G)%E7%AD%89%0A-%20M%3A%20Machine%2C%20OS%E7%BA%BF%E7%A8%8B%E6%8A%BD%E8%B1%A1%EF%BC%8C%E5%BD%93%E5%92%8C%E6%9F%90%E4%B8%AAP%E7%BB%91%E5%AE%9A%EF%BC%8C%E4%BB%8EP%E7%9A%84runq%E4%B8%AD%E4%B8%8D%E6%96%AD%E5%8F%96%E5%87%BAG%EF%BC%8C%E5%88%87%E6%8D%A2%E5%A0%86%E6%A0%88%E5%B9%B6%E6%89%A7%E8%A1%8C%EF%BC%8CM%E6%9C%AC%E8%BA%AB%E4%B8%8D%E5%85%B7%E5%A4%87%E6%89%A7%E8%A1%8C%E7%8A%B6%E6%80%81%EF%BC%8C%E5%9C%A8%E9%9C%80%E8%A6%81%E4%BB%BB%E5%8A%A1%E5%88%87%E6%8D%A2%E6%97%B6%EF%BC%8CM%E5%B0%86%E5%A0%86%E6%A0%88%E7%8A%B6%E6%80%81%E5%86%99%E5%9B%9EG%EF%BC%8C%E4%BB%BB%E4%BD%95%E5%85%B6%E5%AE%83M%E9%83%BD%E8%83%BD%E6%8D%AE%E6%AD%A4%E6%81%A2%E5%A4%8D%E6%89%A7%E8%A1%8C%E3%80%82%0A%23%23%20schedule%0A%E8%B0%83%E5%BA%A6%E5%A7%8B%E4%BA%8EGo%20bootstrap%E8%BF%87%E7%A8%8B%E7%9A%84mstart%EF%BC%8C%E6%AF%8F%E4%B8%80%E8%BD%AE%E8%B0%83%E5%BA%A6%EF%BC%8C%E5%AE%9E%E9%99%85%E5%B0%B1%E6%98%AF%E4%B8%80%E6%AC%A1schedule%E5%87%BD%E6%95%B0%E7%9A%84%E8%B0%83%E7%94%A8%E3%80%82%0A%E8%AF%A5%E5%87%BD%E6%95%B0%E5%AE%9A%E4%B9%89%E5%9C%A8go%2Fsrc%2Fruntime%2Fproc.go%E4%B8%AD%E3%80%82%0A%E6%9C%AC%E6%96%87%E9%92%88%E5%AF%B9%E8%B0%83%E5%BA%A6%E5%99%A8%E8%BF%9B%E8%A1%8C%E5%88%86%E6%9E%90%EF%BC%8C%E4%BB%8D%E7%84%B6%E5%BF%BD%E7%95%A5%E4%BB%A5%E4%B8%8B%E7%89%B9%E6%80%A7%EF%BC%8C%E5%8C%85%E6%8B%AC%E4%BD%86%E4%B8%8D%E9%99%90%E4%BA%8E%EF%BC%9A%0A-%20garbage%20collection%0A-%20C%20Go%0A-%20Linux%20signal%E5%A4%84%E7%90%86%0A-%20Trace%E6%93%8D%E4%BD%9C%0A-%20%E6%A0%88%E6%93%8D%E4%BD%9C%0A%E4%B8%80%E6%AC%A1%E8%B0%83%E5%BA%A6%E7%9A%84%E6%B5%81%E7%A8%8B%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60mermaid%0Agraph%20TD%0AA%5Bschedule%5D%20--%3E%20B%7Bschedtick%20%25%2061%20%3D%3D%200%20%3F%7D%0AB%20--%3E%20%7CN%7C%20D%0AB%20--%3E%20%7CY%7C%20C%5B%22globrunqget(_g_.m.p)%22%5D%0AC%20--%3E%7Cgp%20%3D%3D%20nil%7C%20D%5B%22runqget(_g_.m.p)%22%5D%0AD%20--%3E%7Cgp%20%3D%3D%20nil%7C%20E%5Bfindrunnable%5D%0AE%20--%3E%20G%7B_g_.m.spinning%20%3D%3D%201%20%3F%7D%0AG%20--%3E%20%7CY%7C%20H%5Bresetspinning%5D%0AH%20--%3E%20F%5B%22execute(gp)%22%5D%0AC%20--%3E%7Cgp%20!%3D%20nil%7C%20G%0AD%20--%3E%7Cgp%20!%3D%20nil%7C%20G%0AG%20--%3E%20%7CN%7C%20F%0A%60%60%60%0A%23%23%23%20globrunqget%20%26%20runqget%0A%E8%BF%99%E4%B8%A4%E4%B8%AA%E5%87%BD%E6%95%B0%E9%9D%9E%E5%B8%B8%E7%B1%BB%E4%BC%BC%EF%BC%8C%E4%B8%80%E4%B8%AA%E4%BB%8E%E5%85%A8%E5%B1%80%E9%98%9F%E5%88%97%E4%B8%AD%E5%8F%96%EF%BC%8C%E4%B8%80%E4%B8%AA%E4%BB%8E%E6%9C%AC%E5%9C%B0%E9%98%9F%E5%88%97%E4%B8%AD%E5%8F%96%E3%80%82%E5%8F%96%E7%9A%84%E6%97%B6%E6%9C%BA%E5%90%84%E6%9C%89%E4%B8%8D%E5%90%8C%E3%80%82%0A%23%23%23%23%20globrunqget%0AGo%E8%B0%83%E5%BA%A6%E5%99%A8%E4%B8%BA%E4%BA%86%E5%85%A8%E5%B1%80%E9%98%9F%E5%88%97%E4%B8%AD%E7%9A%84G%E4%B8%8D%E8%A2%AB%E9%A5%BF%E6%AD%BB%EF%BC%8C%E6%B2%A161%E6%AC%A1%E8%B0%83%E5%BA%A6%E9%83%BD%E4%BC%9A%E6%A3%80%E6%9F%A5%E4%B8%80%E4%B8%8B%E5%85%A8%E5%B1%80%E9%98%9F%E5%88%97%E4%B8%AD%E7%9A%84G%EF%BC%8C%E5%B9%B6%E5%8F%96%E5%87%BA%E8%BF%90%E8%A1%8C%E3%80%82%0A%60%60%60mermaid%0Agraph%20TD%0AA%5Bglobrunqget%5D%20--%3E%20%7C%22runqsize%20%3D%3D%200%22%7C%20H%5B%E8%BF%94%E5%9B%9Enil%5D%0AA%20--%3E%20%7C%22runqsize%20!%3D%200%22%7C%20B%5Bn%20%3A%3D%20sched.runqsize%2Fgomaxprocs%20%2B%201%5D%0AB%20--%3E%20C%5B%E8%AE%BE%E7%BD%AE%E5%90%88%E9%80%82%E7%9A%84n%E5%80%BC%5D%0AC%20--%3E%20D%5Brunqsize%20-%3D%20n%5D%0AD%20--%3E%20E%5B%22%E4%BB%8Erunq%E4%B8%ADpop%20G%EF%BC%8Cz%E4%BD%9C%E4%B8%BA%E8%BF%94%E5%9B%9E%E5%80%BC%22%5D%0AE%20--%3E%20F%5B%22%E4%BB%8Eglobal%20runq%E4%B8%AD%E5%8F%96%E5%87%BAn%E4%B8%AAG%EF%BC%8C%E6%94%BE%E5%85%A5P%E7%9A%84runq%22%5D%0AF%20--%3E%20G%5Breturn%20gp%5D%0A%60%60%60%0Aglobrunqget%E7%9A%84%E5%87%BD%E6%95%B0%E5%8E%9F%E5%9E%8B%E6%98%AF%EF%BC%9A%0A%60%60%60go%0Afunc%20globrunqget(_p_%20*p%2C%20max%20int32)%20*g%0A%60%60%60%0A%E4%B8%8A%E5%9B%BE%E4%B8%ADn%E6%98%AF%E8%A6%81%E5%8F%96%E5%87%BA%E7%9A%84G%E7%9A%84%E4%B8%AA%E6%95%B0%E3%80%82%E8%BF%99%E9%87%8C%E5%A6%82%E6%9E%9C%E8%80%83%E8%99%91max%E4%BC%A0%E5%85%A5%E5%A4%A7%E4%BA%8E0%E7%9A%84%E6%95%B0%EF%BC%8C%E5%88%99n%E5%8F%96%E5%80%BC%E9%9C%80%E8%A6%81%E8%80%83%E8%99%91%EF%BC%9A%0A1.%20%E4%B8%8D%E8%83%BD%E8%B6%85%E8%BF%87runqsize%EF%BC%8Crunqsize%E6%98%AF%E6%AD%A4%E6%97%B6global%20queue%E4%B8%ADG%E7%9A%84%E4%B8%AA%E6%95%B0%0A2.%20%E4%B8%8D%E8%83%BD%E8%B6%85%E8%BF%87%E4%BC%A0%E5%85%A5%E7%9A%84max%E5%80%BC%0A3.%20%E4%B8%8D%E8%83%BD%E8%B6%85%E8%BF%87%E4%B8%80%E4%B8%AAP%E7%9A%84runqsize%EF%BC%8C%E8%AF%A5size%E5%AE%9A%E4%B9%89%E5%9C%A8runtime2.go%E7%9A%84type%20p%E5%A3%B0%E6%98%8E%E4%B8%AD%2C%E5%BD%93%E5%89%8D%E5%80%BC%E4%B8%BA256%E3%80%82%0A%60%60%60go%0Atype%20p%20struct%20%7B%0A%20%20%20%20...%0A%20%20%20%20runq%20%20%20%20%20%5B256%5Dguintptr%0A%20%20%20%20...%0A%7D%0A%60%60%60%0A%E5%9C%A8schedule%E5%87%BD%E6%95%B0%E4%B8%ADglobrunqget%E5%87%BD%E6%95%B0%E7%9A%84max%E5%8F%82%E6%95%B0%E4%BC%A0%E5%85%A5%E7%9A%84%E6%98%AF0%EF%BC%8C%E6%89%80%E4%BB%A5%E4%B8%8A%E8%BF%B03%E4%B8%AA%E6%9D%A1%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%9D%A1%E4%BB%B62%E5%B0%B1%E4%B8%8D%E7%94%A8%E8%80%83%E8%99%91%E4%BA%86%E3%80%82%0A%23%23%23%23%20runqget%0Arunqget%E4%BC%9A%E5%85%88%E6%9F%A5%E7%9C%8BP%E7%9A%84runnext%E6%88%90%E5%91%98%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%89%EF%BC%8C%E5%88%99%E8%BF%94%E5%9B%9Erunnext%E6%8C%87%E5%90%91%E7%9A%84G%0A%E5%90%A6%E5%88%99%E4%BC%9A%E5%8F%96%E5%BD%93%E5%89%8Drunqhead%E6%8C%87%E5%90%91%E7%9A%84runq%E6%95%B0%E7%BB%84%E7%9A%84%E6%88%90%E5%91%98G%E3%80%82%0Arunqhead%E5%92%8Crunqtail%E6%98%AF%E4%B8%A4%E4%B8%AAint%E7%B4%A2%E5%BC%95%E5%80%BC%E3%80%82%E5%A6%82%E6%9E%9C%E4%B8%A4%E5%80%BC%E7%9B%B8%E7%AD%89%E8%A1%A8%E7%A4%BA%E9%98%9F%E5%88%97%E6%98%AF%E7%A9%BA%E7%9A%84%E3%80%82%0A%0A%23%23%23%20findrunnable%0Afindrunnable%E6%98%AF%E4%B8%80%E4%B8%AA%E9%98%BB%E5%A1%9E%E5%9E%8B%E8%B0%83%E7%94%A8%EF%BC%8C%E6%9D%A5%E5%AF%BB%E6%89%BErunnable%20G%E3%80%82%E5%A6%82%E6%9E%9C%E6%89%BE%E4%B8%8D%E5%88%B0%EF%BC%8C%E5%B0%B1%E4%BC%9A%E8%B0%83%E7%94%A8stopm%EF%BC%8C%E6%9D%A5%E4%BC%91%E7%9C%A0M%E3%80%82%E5%85%B6%E5%9F%BA%E6%9C%AC%E6%B5%81%E7%A8%8B%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60mermaid%0Agraph%20TD%0AA%5Bfindrunnable%5D%20--%3E%20B%5B%22runqget(_p_)%22%5D%0AB%20--%3E%20%7Cno%20G%7C%20C%5B%22globrunqget(_p_%2C%20max%3D0)%22%5D%0AB%20--%3E%20%7Chas%20G%7C%20J%5Breturn%5D%0AC%20--%3E%20%7Cno%20G%7C%20D%5Bsteal%20G%20from%20other%20P%5D%0AD%20--%3E%20%7Cno%20G%7C%20E%5Bgoing%20to%20stop%5D%0AE%20--%3E%20F%5Bbefore%20stop%2C%20check%20globrunqget%5D%0AF%20--%3E%20G%5B%22pidleput(_p_)%22%5D%0AG%20--%3E%20H%5Bbefore%20stop%2C%20check%20all%20P%5D%0AH%20--%3E%20I%5Bstopm%5D%0AI%20--%3E%20%7Cwakeup%7C%20B%0AF%20--%3E%20%7Csched.runqsize%20!%3D%200%7C%20B%0AH%20--%3E%20%7C!runqempty%7C%20B%0A%0AC%20--%3E%20%7Chas%20G%7C%20J%0AD%20--%3E%20%7Chas%20G%7C%20J%0A%60%60%60%0A%E8%BF%99%E9%87%8C%E5%BF%BD%E7%95%A5%E4%BA%86net%20poller%EF%BC%8C%E8%BF%99%E6%98%AF%E7%94%A8%E6%9D%A5%E5%A4%84%E7%90%86%E5%BC%82%E6%AD%A5%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E7%9A%84%E4%B8%80%E7%A7%8D%E6%96%B9%E5%BC%8F%E3%80%82%0A%E4%BB%A5%E4%B8%8A%E6%B5%81%E7%A8%8B%E4%B8%AD%E9%99%A4%E4%BA%86%E5%B8%B8%E8%A7%84%E7%9A%84global%20q%E5%92%8Clocal%20q%E6%93%8D%E4%BD%9C%EF%BC%8C%E8%BF%98%E6%9C%89%E4%B8%80%E6%AE%B5%E5%85%B3%E4%BA%8Estealing%20G%E7%9A%84%E7%AE%97%E6%B3%95%EF%BC%8C%E7%A7%B0%E4%B8%BAGo%20Stealing%20Scheduler%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5BGo's%20work-stealing%20scheduler%5D(https%3A%2F%2Frakyll.org%2Fscheduler%2F)%E3%80%82%E5%85%B7%E4%BD%93%E4%BB%A3%E7%A0%81%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60go%0Afor%20i%20%3A%3D%200%3B%20i%20%3C%204%3B%20i%2B%2B%20%7B%0A%20%20%20%20for%20enum%20%3A%3D%20stealOrder.start(fastrand())%3B%20!enum.done()%3B%20enum.next()%20%7B%0A%20%20%20%20%20%20%20%20if%20sched.gcwaiting%20!%3D%200%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20goto%20top%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20stealRunNextG%20%3A%3D%20i%20%3E%202%20%2F%2F%20first%20look%20for%20ready%20queues%20with%20more%20than%201%20g%0A%20%20%20%20%20%20%20%20if%20gp%20%3A%3D%20runqsteal(_p_%2C%20allp%5Benum.position()%5D%2C%20stealRunNextG)%3B%20gp%20!%3D%20nil%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20gp%2C%20false%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%E8%AF%B4%E5%AE%9E%E8%AF%9D%E4%BB%A3%E7%A0%81%E6%B2%A1%E6%9C%89%E5%BE%88%E7%9C%8B%E6%87%82%EF%BC%9A%0A-%20%E8%BF%99%E4%B8%AAi%20%3D%20%5B0..4%5D%E6%98%AF%E6%80%8E%E4%B9%88%E5%9B%9E%E4%BA%8B%E5%84%BF%EF%BC%9F%0A-%20%E7%AC%AC%E4%BA%8C%E4%B8%AAfor%E5%BE%AA%E7%8E%AF%E4%BC%BC%E4%B9%8E%E9%87%87%E7%94%A8%E9%9A%8F%E6%9C%BA%E6%95%B0%E6%9D%A5%E9%9A%8F%E6%9C%BA%E8%8E%B7%E5%BE%97%E7%9B%B8%E5%BA%94%E7%9A%84P%EF%BC%8C%E6%9D%A5steal%20G%EF%BC%8C%E4%BD%86%E6%98%AF%E4%B8%BA%E5%95%A5%E6%9C%89%E4%B8%AA%60stealRunNextG%20%3A%3D%20i%20%3E%202%60%0A%0AstealRunNextG%E6%A0%B9%E6%8D%AE%E4%BB%A3%E7%A0%81%E7%90%86%E8%A7%A3%EF%BC%8C%E5%BA%94%E8%AF%A5%E6%98%AFbool%E5%8F%98%E9%87%8F%EF%BC%8C%E8%A1%A8%E7%A4%BA%E6%98%AF%E5%90%A6%E4%BB%8EP%E7%9A%84runnext%E6%88%90%E5%91%98%E8%8E%B7%E5%8F%96G%E3%80%82%0Arunqsteal%E4%BC%9A%E4%BB%8Erunnext%E5%81%B7%E5%8F%96G%EF%BC%8C%E6%88%96%E8%80%85%E4%BC%9A%E5%81%B7%E5%8F%96P%E7%9A%84runq%E4%B8%AD%E4%B8%80%E5%8D%8A%E7%9A%84G%0A%0A%23%23%23%20resetspinning%0A%E8%BF%99%E4%B8%AA%E5%87%BD%E6%95%B0%E5%B0%86%E5%8E%9F%E5%85%88%E4%B8%BAtrue%E7%9A%84_g_.m.spinning%E8%AE%BE%E4%B8%BAfalse%E3%80%82%E5%BD%93%E5%85%A8%E5%B1%80%E9%83%BD%E6%B2%A1%E6%9C%89spinning%E7%9A%84M%E4%BA%86%EF%BC%8C%E5%88%99%E8%A6%81%E5%94%A4%E9%86%92idle%20P%E3%80%82%E6%B2%A1%E6%9C%89spinning%20M%E8%A1%A8%E7%A4%BA%E6%89%80%E6%9C%89%E7%9A%84M%E8%A6%81%E4%B9%88%E5%9C%A8%E5%B7%A5%E4%BD%9C%EF%BC%88%E5%A4%84%E7%90%86G%EF%BC%89%EF%BC%8C%E8%A6%81%E4%B9%88%E5%9C%A8%E4%BC%91%E7%9C%A0%E3%80%82%E5%A6%82%E6%9E%9C%E6%AD%A4%E6%97%B6%E6%9C%89idle%20P%EF%BC%8C%E8%A1%A8%E7%A4%BA%E6%9C%89CPU%E7%A9%BA%E9%97%B2%EF%BC%8C%E5%88%99%E6%AD%A4%E6%97%B6%E6%98%AF%E4%B8%80%E4%B8%AA%E5%A5%BD%E7%9A%84%E6%97%B6%E6%9C%BA%E6%9D%A5%E5%94%A4%E9%86%92M%E5%A4%84%E7%90%86%E6%9B%B4%E5%A4%9A%E7%9A%84%E5%B7%A5%E4%BD%9C%E3%80%82%0A%E5%AE%9E%E9%99%85%E4%B8%8AGPM%E4%B8%89%E8%80%85%E9%83%BD%E6%9C%89%E8%87%AA%E5%B7%B1%E7%9A%84%E7%8A%B6%E6%80%81%E6%9C%BA%EF%BC%8CG%E5%92%8CP%E6%AF%94%E8%BE%83%E6%B8%85%E6%99%B0%EF%BC%8CM%E7%9A%84%E7%8A%B6%E6%80%81%E5%B0%B1%E6%AF%94%E8%BE%83%E6%A8%A1%E7%B3%8A%EF%BC%8C%E5%88%B0%E5%BA%95M%E6%9C%89%E5%87%A0%E7%A7%8D%E7%8A%B6%E6%80%81%EF%BC%8C%E7%89%B9%E5%88%AB%E7%9A%84%E6%98%AFM%E4%BC%9A%E5%9C%A8%E4%BD%95%E6%97%B6spinning%E3%80%82%E5%90%8E%E6%96%87%E4%BC%9A%E4%BB%8B%E7%BB%8D%E3%80%82%0A%0A%23%23%23%20execute%0A%E7%AE%80%E5%8D%95%E6%9D%A5%E7%9C%8B%EF%BC%8Cexecute%E5%8F%AA%E5%81%9A%E4%BA%86%E4%B8%A4%E4%BB%B6%E4%BA%8B%EF%BC%9A%0A1.%20%E5%88%87%E6%8D%A2G%20status%EF%BC%9A_Grunnalbe%20--%3E%20%5C_Grunning%0A2.%20%E8%B0%83%E7%94%A8%60gogo(%26gp.sched)%60%0A%0AARM%E5%B9%B3%E5%8F%B0%E7%9A%84gogo%E5%87%BD%E6%95%B0%E5%AE%9E%E7%8E%B0%E5%9C%A8%EF%BC%9Ago%2Fsrc%2Fruntime%2Fasm_arm.s%EF%BC%8C%E6%98%AF%E4%B8%80%E4%B8%AA%E6%B1%87%E7%BC%96%E5%87%BD%E6%95%B0%E3%80%82%E4%B8%BB%E8%A6%81%E5%81%9A%E4%BA%86%E4%BB%A5%E4%B8%8B%E5%87%A0%E4%BB%B6%E4%BA%8B%E6%83%85%EF%BC%9A%0A-%20%E8%AE%BE%E7%BD%AETLS%E4%B8%AD%E7%9A%84G%0A-%20%E5%81%9Acontext%20switch%0A-%20%E8%B7%B3%E8%BD%AC%E5%88%B0%E5%AF%B9%E5%BA%94%E7%9A%84PC%E5%8F%96%E8%BF%90%E8%A1%8C%0A%0A%23%23%23%20GPM%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81%0AGPM%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5BGolang%20%E4%B8%AD%20goroutine%20%E7%9A%84%E8%B0%83%E5%BA%A6%5D(https%3A%2F%2Fwww.ctolib.com%2Ftopics-133848.html)%E4%B8%80%E6%96%87%E4%B8%AD%E5%85%B3%E4%BA%8EGPM%E7%9A%84%E4%B8%80%E7%94%9F%E7%9A%84%E7%AB%A0%E8%8A%82%E3%80%82%0A%23%23%23%23%20G%20%26%20P%0A%E5%AF%B9G%E5%92%8CP%E4%B8%8D%E5%81%9A%E8%BF%87%E5%A4%9A%E7%9A%84%E8%A7%A3%E9%87%8A%EF%BC%8C%E7%8A%B6%E6%80%81%E6%9C%BA%E8%BF%98%E6%98%AF%E5%BE%88%E6%B8%85%E6%99%B0%E7%9A%84%E3%80%82%0AG%E7%94%B1newproc%E5%87%BD%E6%95%B0%E5%88%9B%E5%BB%BA%EF%BC%8C%E9%81%B5%E5%BE%AA%E4%B8%8B%E9%9D%A2%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E5%8C%96%0A!%5Bf2c48d2f55f7311e173548cc09458871.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6068)%0A%0AP%E7%94%B1bootstrap%E8%BF%87%E7%A8%8B%E7%9A%84procresize%E5%88%9B%E5%BB%BA%EF%BC%8C%E9%81%B5%E5%BE%AA%E4%B8%8B%E9%9D%A2%E7%9A%84%E7%8A%B6%E6%80%81%E6%9C%BA%E5%8F%98%E8%BF%81%EF%BC%9A%0A!%5B9e80b53de7666672eb5ce4e9174cdff6.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6069)%0A%0A%23%23%23%23%20M%E7%9A%84%E7%8A%B6%E6%80%81%0A%E8%BF%99%E9%87%8C%E4%B8%8D%E8%AE%A8%E8%AE%BA%E7%89%B9%E6%AE%8A%E7%9A%84M%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%9Asysmon%E6%88%96%E8%80%85finalizer%0A%E6%99%AE%E9%80%9A%E7%9A%84M%E7%94%B1startm%E5%87%BD%E6%95%B0%E5%88%9B%E5%BB%BA%E3%80%82%E5%85%B6%E5%A4%A7%E8%87%B4%E6%B5%81%E7%A8%8B%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60mermaid%0Agraph%20TD%0AA%5B%22startm(_p_%2C%20spinning)%22%5D%20--%3E%7C_p_%20%3D%3D%20nil%7C%20B%5Bpidleget%5D%0AB%20--%3E%20%7Cfind%20idle%20P%7C%20C%5Bmget%5D%0AA%20--%3E%20C%0AB%20--%3E%20%7Cno%20idle%20P%7C%20G%5Breturn%5D%0AC%20--%3E%20%7Cmp%20%3D%3D%20nil%7C%20D%5Bnewm%5D%0AD%20--%3E%20G%0AC%20--%3E%20E%5B%22mp.nextp.set(_p_)%22%5D%0AE%20--%3E%20F%5B%22notewakeup(%26mp.park)%22%5D%0AF%20--%3E%20G%0A%60%60%60%0A%0A%23%23%23%23%23%20M%E7%9A%84%E5%88%9B%E5%BB%BA%0A%E8%BF%99%E9%87%8C%E8%B7%9FM%E7%8A%B6%E6%80%81%E6%9C%89%E5%85%B3%E7%9A%84%E5%B0%B1%E6%98%AFM%E7%9A%84%E7%BA%BF%E7%A8%8B%E5%87%BD%E6%95%B0%2C%E4%BD%86%E8%AF%B7%E6%B3%A8%E6%84%8F%E4%B8%8B%E9%9D%A2%E8%BF%99%E4%B8%AAfn%E5%B9%B6%E4%B8%8D%E6%98%AF%E7%BA%BF%E7%A8%8B%E5%87%BD%E6%95%B0%E3%80%82%0A%60%60%60go%0Aif%20spinning%20%7B%0A%20%20%20%20%2F%2F%20The%20caller%20incremented%20nmspinning%2C%20so%20set%20m.spinning%20in%20the%20new%20M.%0A%20%20%20%20fn%20%3D%20mspinning%0A%7D%0A%60%60%60%0A%E7%9C%9F%E6%AD%A3%E7%9A%84%E7%BA%BF%E7%A8%8B%E5%87%BD%E6%95%B0%E5%9C%A8newosproc%E8%B0%83%E7%94%A8clone%E6%8E%A5%E5%8F%A3%E7%9A%84%E6%97%B6%E5%80%99%E4%BC%A0%E5%85%A5%E3%80%82Linux%E5%B9%B3%E5%8F%B0%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%9C%A8os_linux.go%E4%B8%AD%E3%80%82%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60go%0Afunc%20clone(flags%20int32%2C%20stk%2C%20mp%2C%20gp%2C%20fn%20unsafe.Pointer)%20int32%0A%0Afunc%20newosproc(mp%20*m)%20%7B%0A%20%20%20%20...%0A%09ret%20%3A%3D%20clone(cloneFlags%2C%20stk%2C%20unsafe.Pointer(mp)%2C%20unsafe.Pointer(mp.g0)%2C%20unsafe.Pointer(funcPC(mstart)))%0A%20%20%20%20...%0A%7D%0A%60%60%60%0A%E6%89%80%E4%BB%A5M%E7%9A%84%E7%BA%BF%E7%A8%8B%E5%87%BD%E6%95%B0%E5%B0%B1%E6%98%AF%E6%9B%BE%E5%9C%A8bootstrap%E4%B8%AD%E5%87%BA%E7%8E%B0%E8%BF%87%EF%BC%8C%E8%BF%90%E8%A1%8CM0%E7%9A%84mstart%E5%87%BD%E6%95%B0%E3%80%82%E4%B8%8A%E9%9D%A2%E7%9A%84mspinning%E5%87%BD%E6%95%B0%E5%9C%A8mstart1%E4%B8%AD%E8%A2%AB%E8%B0%83%E7%94%A8%EF%BC%8C%E5%AE%83%E5%B0%86%E7%BA%BF%E7%A8%8B%E8%AE%BE%E7%BD%AE%E4%B8%BAspinning%E7%8A%B6%E6%80%81%E3%80%82%0A%0A%23%23%23%23%23%20idle%20M%E7%9A%84%E7%AE%A1%E7%90%86%0Amget%E4%BC%9A%E5%8E%BB%E8%8E%B7%E5%8F%96%E9%97%B2%E7%BD%AE%E7%9A%84M%E3%80%82%E8%80%8C%E6%89%80%E6%9C%89%E7%9A%84idle%20M%E5%B9%B6%E6%B2%A1%E6%9C%89%E4%B8%80%E4%B8%AA%E7%BB%9F%E4%B8%80%E7%9A%84%E4%BF%9D%E5%AD%98%E4%BD%8D%E7%BD%AE%EF%BC%8C%E8%80%8C%E6%98%AF%E9%80%9A%E8%BF%87M.schedlink%E5%BD%A2%E6%88%90%E4%B8%80%E4%B8%AA%E9%9A%90%E5%BD%A2%E7%9A%84%E9%93%BE%E8%A1%A8%E3%80%82%E7%9C%8Bmput%EF%BC%9A%0A%60%60%60go%0Afunc%20mput(mp%20*m)%20%7B%0A%09mp.schedlink%20%3D%20sched.midle%0A%09sched.midle.set(mp)%0A%09sched.nmidle%2B%2B%0A%20%20%20%20...%0A%7D%0A%60%60%60%0A%E5%81%87%E8%AE%BE%E8%B0%83%E7%94%A8%E4%BA%863%E6%AC%A1mput%EF%BC%8C%E9%82%A3%E4%B9%88%E6%AD%A4%E6%97%B6%E7%9A%84idle%E9%93%BE%E8%A1%A8%E5%BA%94%E8%AF%A5%E6%98%AF%E8%BF%99%E6%A0%B7%E7%9A%84%EF%BC%9A%0A%60%60%60mermaid%0Agraph%20LR%0AA%5Bsched%5D%20--%3E%7Cmidle%7C%20B%5BM1%5D%0AB%20--%3E%20%7Cschedlink%7C%20C%5BM2%5D%0AC%20--%3E%20%7Cschedlink%7C%20D%5BM3%5D%0AD%20--%3E%20%7Cschedlink%7C%20E%5B0%5D%0A%60%60%60%0A%0A%23%23%23%23%23%20M%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81%0AM%E5%9C%A8%E5%88%9B%E5%BB%BA%E7%9A%84%E6%97%B6%E5%80%99%E4%BC%9A%E8%A2%AB%E8%AE%BE%E7%BD%AE%E6%88%90spinning%E7%8A%B6%E6%80%81%E3%80%82%E8%BF%98%E6%9C%89%E5%85%B6%E4%BB%96%E7%9A%84spinning%E7%8A%B6%E6%80%81%E5%90%97%EF%BC%9F%0A%E6%9C%89%EF%BC%9A%0A1.%20%E5%BD%93findrunnable%E5%87%86%E5%A4%87%E8%BF%9B%E5%85%A5stealing%20scheduler%E6%97%B6%EF%BC%8C%E4%BC%9A%E5%85%88%E8%AE%BE%E7%BD%AEspinning%0A2.%20%E5%BD%93findrunnable%E6%9F%A5%E6%89%BEallp%E6%97%B6%EF%BC%8C%E5%8F%91%E7%8E%B0%E8%BF%98%E6%9C%89G%EF%BC%8C%E8%A6%81%E9%87%8D%E6%96%B0%E5%9B%9E%E5%88%B0%E5%BE%AA%E7%8E%AF%E6%9D%A5%E8%8E%B7%E5%8F%96G%0A%0A%E6%89%80%E4%BB%A5%E5%8F%AF%E4%BB%A5%E6%80%BB%E7%BB%93%E7%9A%84%E6%98%AFM%E7%9A%84spinning%E6%98%AF%E4%B8%80%E7%A7%8D%E5%BF%99%E7%AD%89%E7%9A%84%E7%8A%B6%E6%80%81%EF%BC%8C%E8%80%8C%E4%B8%94%E5%AE%83%E4%B8%8D%E6%98%AF%E4%B8%80%E4%B8%AA%E9%82%A3%E4%B9%88%E9%87%8D%E8%A6%81%E7%9A%84%E7%8A%B6%E6%80%81%EF%BC%8C%E5%AE%83%E5%8F%AF%E4%BB%A5%E7%9C%8B%E4%BD%9C%E4%B8%80%E7%A7%8D%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87%E3%80%82%E5%A6%82%E6%9E%9Cspinning%E7%8A%B6%E6%80%81%E7%9A%84M%E5%A4%AA%E5%A4%9A%E4%BA%86%EF%BC%8C%E8%AF%B4%E6%98%8E%E6%AD%A3%E5%B8%B8%E5%B7%A5%E4%BD%9C%E7%9A%84M%E5%A4%AA%E5%B0%91%E4%BA%86%E3%80%82%E7%B3%BB%E7%BB%9F%E4%BC%9A%E7%BB%84%E7%BB%87M%E8%BF%9B%E5%85%A5spinning%E7%8A%B6%E6%80%81%E3%80%82%0A%60%60%60go%0A%2F%2F%20If%20number%20of%20spinning%20M's%20%3E%3D%20number%20of%20busy%20P's%2C%20block.%0A%2F%2F%20This%20is%20necessary%20to%20prevent%20excessive%20CPU%20consumption%0A%2F%2F%20when%20GOMAXPROCS%3E%3E1%20but%20the%20program%20parallelism%20is%20low.%0Aif%20!_g_.m.spinning%20%26%26%202*atomic.Load(%26sched.nmspinning)%20%3E%3D%20procs-atomic.Load(%26sched.npidle)%20%7B%0A%20%20%20%20goto%20stop%0A%7D%0A%60%60%60%0A%0A%E9%82%A3%E4%B9%88M%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E7%A6%BB%E5%BC%80spinning%E7%8A%B6%E6%80%81%E5%91%A2%EF%BC%9F%E6%9C%89%E8%BF%99%E5%87%A0%E7%A7%8D%E6%83%85%E5%86%B5%EF%BC%9A%0A1.%20schedule%E4%B8%AD%EF%BC%8CM%E5%8D%B3%E5%B0%86%E5%BC%80%E5%A7%8B%E8%BF%90%E8%A1%8CG%EF%BC%8Cresetspinning%E5%B0%86%E5%85%B6spinning%E6%A0%87%E5%BF%97%E4%BD%8D%E8%AE%BE%E4%B8%BAfalse%0A2.%20findrunnable%E6%B2%A1%E6%89%BE%E5%88%B0G%EF%BC%8CM%E5%8D%B3%E5%B0%86%E8%B0%83%E7%94%A8stopm%E8%BF%9B%E5%85%A5%E4%BC%91%E7%9C%A0%E7%8A%B6%E6%80%81%0A%0A%E5%80%9F%E7%94%A8%5BGolang%20%E4%B8%AD%20goroutine%20%E7%9A%84%E8%B0%83%E5%BA%A6%5D(https%3A%2F%2Fwww.ctolib.com%2Ftopics-133848.html)%E4%B8%AD%E7%9A%84%E8%BF%99%E5%BC%A0%E7%8A%B6%E6%80%81%E5%9B%BE%EF%BC%9A%0A!%5B55d559f0bfd46d4bfecb35a969213c1c.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6070)%0A%0A%E8%BF%99%E5%BC%A0%E5%9B%BE%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81%E6%98%AF%E6%AD%A3%E7%A1%AE%E7%9A%84%EF%BC%8C%E4%BD%86%E6%88%91%E8%A7%89%E5%BE%97%E5%B9%B6%E4%B8%8D%E5%A4%9F%E8%B4%B4%E5%88%87%E3%80%82%E5%9B%A0%E4%B8%BA%E5%AF%B9%E4%BA%8EM%E6%9D%A5%E8%AF%B4%EF%BC%8C%E6%B2%A1%E6%9C%89%E5%BE%88%E4%B8%A5%E6%A0%BC%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81%E3%80%82%E5%8F%AA%E8%A6%81%E7%9F%A5%E9%81%93M%E5%8F%AF%E4%BB%A5%E5%A4%84%E4%BA%8Espinning%E7%8A%B6%E6%80%81%EF%BC%8C%E8%A1%A8%E7%A4%BA%E4%B8%80%E7%A7%8D%E4%B8%AD%E9%97%B4%E7%8A%B6%E6%80%81%EF%BC%8C%E5%9C%A8%E5%BF%99%E7%AD%89%E5%BE%85%E3%80%82%E8%80%8C%E5%9C%A8%E6%AD%A3%E5%B8%B8%E5%B7%A5%E4%BD%9C%E5%92%8C%E4%BC%91%E7%9C%A0%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E9%83%BD%E4%B8%8D%E6%98%AFspinning%E3%80%82%0AM%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87notesleep%E8%BF%9B%E5%85%A5futexsleep%E7%8A%B6%E6%80%81%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87notewakeup%E5%94%A4%E9%86%92%E4%BC%91%E7%9C%A0%E7%9A%84M%E3%80%82%0A%0A%23%23%20%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%0A-%20%5BScheduling%20In%20Go%20%3A%20Part%20II%20-%20Go%20Scheduler%5D(https%3A%2F%2Fwww.ardanlabs.com%2Fblog%2F2018%2F08%2Fscheduling-in-go-part2.html)%0A-%20%5BGo%20%E8%B0%83%E5%BA%A6%E6%A8%A1%E5%9E%8B%5D(https%3A%2F%2Fwudaijun.com%2F2018%2F01%2Fgo-scheduler%2F)%0A-%20%5BGo's%20work-stealing%20scheduler%5D(https%3A%2F%2Frakyll.org%2Fscheduler%2F)%0A-%20%5BGolang%20%E4%B8%AD%20goroutine%20%E7%9A%84%E8%B0%83%E5%BA%A6%5D(https%3A%2F%2Fwww.ctolib.com%2Ftopics-133848.html)

本文基于Go 1.13。
本人首次接触golang,也不是gopher,主要想研究一下go的用户态调度框架。因为看到m0,g0和schedinit,所以顺带着也把bootstrap过程看了一下。既然看了,就记一点笔记吧。另外本文紧扣与调度相关的主题,一些go的其他特性,虽然非常棒但是不在本文讨论范围。包括但不限于:

  • garbage collection
  • C Go
  • Linux signal处理
  • Trace操作
  • 栈操作

golang和其他语言一样,用户代码的入口是用户定义的main函数。那么go程序从启动到main函数运行之间的过程就是所谓的bootstrap过程。网上也有大把的资料介绍这一流程。本文以阅读Go源码为主,所以暂且不列参考文献了。

Go程序的入口定义在rt0_<os>_<arch>.s,例如rt0_linux_arm.s。入口函数是:_rt0_arm_linux。Go的汇编语法不同于常见的语法格式,具体可以参考Go官方网页:A Quick Guide to Go's Assembler。本文不做过多牵涉具体语法的解释。

_rt0_arm_linux通过以下调用,进入runtime库的rt0_go函数。_rt0_arm_linux --> _rt0_arm_linux1 --> runtime·rt0_go

rt0_go

该函数做了以下这些事情:

  1. 绑定m0, g0
	// set up g register
	// g is R10
	MOVW	$runtime·g0(SB), g
	MOVW	$runtime·m0(SB), R8

	// save m->g0 = g0
	MOVW	g, m_g0(R8)
	// save g->m = m0
	MOVW	R8, g_m(g)
  1. 设置g0的stackguard0和stackguard1
  2. runtime.emptyfunc
  3. runtime._initcgo
  4. runtime.check
  5. runtime.args
  6. runtime.checkgoarm
  7. runtime.osinit
  8. runtime.shcedinit
    10.runtime.newproc创建G来运行runtime.main
    11.runtime.mstart来运行M0,M0获得第一个G(注意不是g0),来运行runtime.main

以上这一堆,最终让runtime.main运行起来,runtime.main会调用用户的main函数,即main_main或者叫main.main。
另外大多数的代码都是为了做一些检查,以及操作系统级别的初始化。特别值得关注的是runtime.schedinit, runtime.newproc以及runtime.mstart。
创建G的newproc和运行M的mstart都是通用函数,不光是在bootstrap过程中使用。在调度器运行时创建G和运行M都是使用这两个函数。
rto_go是bootstrap的总纲。它调用各个函数,最终进入用户的main函数运行。

schedinit

schedinit对调度器做了基本的初始化,摘出两个可能与调度相关的函数:

  • mcommoninit
  • procresize

前者其实也没做啥事儿,调用了mpreinit分配了与signal相关的栈参数gsignal,与调度实没多大关系,暂时略过。后者就比较重要了。

procresize

本函数其实是对整个app里的P做了初始化。先看调用:

procs := ncpu // ncpu在osinit中赋值,ncpu = getncpu()
if n, ok := atoi32(gogetenv("GOMAXPROCS")); ok && n > 0 {
    procs = n
}
if procresize(procs) != nil {
    throw("unknown runnable goroutine during bootstrap")
}

这里根据环境变量GOMAXPROCS对ncpu进行了更新。procs逻辑上就对应了P的个数。

PHN2ZyBpZD0iZHQ5azRrbzFjcjIiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDU2Ni45ODQzNzVweDsiIHZpZXdCb3g9IjAgMCA1NjYuOTg0Mzc1IDExMzEuODk4NDM3NSI+PHN0eWxlPgoKCiNkdDlrNGtvMWNyMiAubGFiZWwgewogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgY29sb3I6ICMzMzM7IH0KCiNkdDlrNGtvMWNyMiAubm9kZSByZWN0LAojZHQ5azRrbzFjcjIgLm5vZGUgY2lyY2xlLAojZHQ5azRrbzFjcjIgLm5vZGUgZWxsaXBzZSwKI2R0OWs0a28xY3IyIC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMXB4OyB9CgojZHQ5azRrbzFjcjIgLm5vZGUuY2xpY2thYmxlIHsKICBjdXJzb3I6IHBvaW50ZXI7IH0KCiNkdDlrNGtvMWNyMiAuYXJyb3doZWFkUGF0aCB7CiAgZmlsbDogIzMzMzMzMzsgfQoKI2R0OWs0a28xY3IyIC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMzMzMzMzOwogIHN0cm9rZS13aWR0aDogMS41cHg7IH0KCiNkdDlrNGtvMWNyMiAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZThlOGU4OyB9CgojZHQ5azRrbzFjcjIgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI2ZmZmZkZSAhaW1wb3J0YW50OwogIHN0cm9rZTogI2FhYWEzMyAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7IH0KCiNkdDlrNGtvMWNyMiAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjMzMzOyB9CgojZHQ5azRrbzFjcjIgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1heC13aWR0aDogMjAwcHg7CiAgcGFkZGluZzogMnB4OwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMnB4OwogIGJhY2tncm91bmQ6ICNmZmZmZGU7CiAgYm9yZGVyOiAxcHggc29saWQgI2FhYWEzMzsKICBib3JkZXItcmFkaXVzOiAycHg7CiAgcG9pbnRlci1ldmVudHM6IG5vbmU7CiAgei1pbmRleDogMTAwOyB9CgojZHQ5azRrbzFjcjIgLmFjdG9yIHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2R0OWs0a28xY3IyIHRleHQuYWN0b3IgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2R0OWs0a28xY3IyIC5hY3Rvci1saW5lIHsKICBzdHJva2U6IGdyZXk7IH0KCiNkdDlrNGtvMWNyMiAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkdDlrNGtvMWNyMiAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkdDlrNGtvMWNyMiAjYXJyb3doZWFkIHsKICBmaWxsOiAjMzMzOyB9CgojZHQ5azRrbzFjcjIgI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMzMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMzMzICFpbXBvcnRhbnQ7IH0KCiNkdDlrNGtvMWNyMiAubWVzc2FnZVRleHQgewogIGZpbGw6ICMzMzM7CiAgc3Ryb2tlOiBub25lOyB9CgojZHQ5azRrbzFjcjIgLmxhYmVsQm94IHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2R0OWs0a28xY3IyIC5sYWJlbFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2R0OWs0a28xY3IyIC5sb29wVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHQ5azRrbzFjcjIgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOyB9CgojZHQ5azRrbzFjcjIgLm5vdGUgewogIHN0cm9rZTogI2FhYWEzMzsKICBmaWxsOiAjZmZmNWFkOyB9CgojZHQ5azRrbzFjcjIgLm5vdGVUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDE0cHg7IH0KCiNkdDlrNGtvMWNyMiAuYWN0aXZhdGlvbjAgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZHQ5azRrbzFjcjIgLmFjdGl2YXRpb24xIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2R0OWs0a28xY3IyIC5hY3RpdmF0aW9uMiB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCgojZHQ5azRrbzFjcjIgLnNlY3Rpb24gewogIHN0cm9rZTogbm9uZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkdDlrNGtvMWNyMiAuc2VjdGlvbjAgewogIGZpbGw6IHJnYmEoMTAyLCAxMDIsIDI1NSwgMC40OSk7IH0KCiNkdDlrNGtvMWNyMiAuc2VjdGlvbjIgewogIGZpbGw6ICNmZmY0MDA7IH0KCiNkdDlrNGtvMWNyMiAuc2VjdGlvbjEsCiNkdDlrNGtvMWNyMiAuc2VjdGlvbjMgewogIGZpbGw6IHdoaXRlOwogIG9wYWNpdHk6IDAuMjsgfQoKI2R0OWs0a28xY3IyIC5zZWN0aW9uVGl0bGUwIHsKICBmaWxsOiAjMzMzOyB9CgojZHQ5azRrbzFjcjIgLnNlY3Rpb25UaXRsZTEgewogIGZpbGw6ICMzMzM7IH0KCiNkdDlrNGtvMWNyMiAuc2VjdGlvblRpdGxlMiB7CiAgZmlsbDogIzMzMzsgfQoKI2R0OWs0a28xY3IyIC5zZWN0aW9uVGl0bGUzIHsKICBmaWxsOiAjMzMzOyB9CgojZHQ5azRrbzFjcjIgLnNlY3Rpb25UaXRsZSB7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsKICB0ZXh0LWhlaWdodDogMTRweDsgfQoKCiNkdDlrNGtvMWNyMiAuZ3JpZCAudGljayB7CiAgc3Ryb2tlOiBsaWdodGdyZXk7CiAgb3BhY2l0eTogMC4zOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2R0OWs0a28xY3IyIC5ncmlkIHBhdGggewogIHN0cm9rZS13aWR0aDogMDsgfQoKCiNkdDlrNGtvMWNyMiAudG9kYXkgewogIGZpbGw6IG5vbmU7CiAgc3Ryb2tlOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAycHg7IH0KCgoKI2R0OWs0a28xY3IyIC50YXNrIHsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkdDlrNGtvMWNyMiAudGFza1RleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHQ5azRrbzFjcjIgLnRhc2tUZXh0T3V0c2lkZVJpZ2h0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHQ5azRrbzFjcjIgLnRhc2tUZXh0T3V0c2lkZUxlZnQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBlbmQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgoKI2R0OWs0a28xY3IyIC50YXNrVGV4dDAsCiNkdDlrNGtvMWNyMiAudGFza1RleHQxLAojZHQ5azRrbzFjcjIgLnRhc2tUZXh0MiwKI2R0OWs0a28xY3IyIC50YXNrVGV4dDMgewogIGZpbGw6IHdoaXRlOyB9CgojZHQ5azRrbzFjcjIgLnRhc2swLAojZHQ5azRrbzFjcjIgLnRhc2sxLAojZHQ5azRrbzFjcjIgLnRhc2syLAojZHQ5azRrbzFjcjIgLnRhc2szIHsKICBmaWxsOiAjOGE5MGRkOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2R0OWs0a28xY3IyIC50YXNrVGV4dE91dHNpZGUwLAojZHQ5azRrbzFjcjIgLnRhc2tUZXh0T3V0c2lkZTIgewogIGZpbGw6IGJsYWNrOyB9CgojZHQ5azRrbzFjcjIgLnRhc2tUZXh0T3V0c2lkZTEsCiNkdDlrNGtvMWNyMiAudGFza1RleHRPdXRzaWRlMyB7CiAgZmlsbDogYmxhY2s7IH0KCgojZHQ5azRrbzFjcjIgLmFjdGl2ZTAsCiNkdDlrNGtvMWNyMiAuYWN0aXZlMSwKI2R0OWs0a28xY3IyIC5hY3RpdmUyLAojZHQ5azRrbzFjcjIgLmFjdGl2ZTMgewogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZHQ5azRrbzFjcjIgLmFjdGl2ZVRleHQwLAojZHQ5azRrbzFjcjIgLmFjdGl2ZVRleHQxLAojZHQ5azRrbzFjcjIgLmFjdGl2ZVRleHQyLAojZHQ5azRrbzFjcjIgLmFjdGl2ZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2R0OWs0a28xY3IyIC5kb25lMCwKI2R0OWs0a28xY3IyIC5kb25lMSwKI2R0OWs0a28xY3IyIC5kb25lMiwKI2R0OWs0a28xY3IyIC5kb25lMyB7CiAgc3Ryb2tlOiBncmV5OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkdDlrNGtvMWNyMiAuZG9uZVRleHQwLAojZHQ5azRrbzFjcjIgLmRvbmVUZXh0MSwKI2R0OWs0a28xY3IyIC5kb25lVGV4dDIsCiNkdDlrNGtvMWNyMiAuZG9uZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2R0OWs0a28xY3IyIC5jcml0MCwKI2R0OWs0a28xY3IyIC5jcml0MSwKI2R0OWs0a28xY3IyIC5jcml0MiwKI2R0OWs0a28xY3IyIC5jcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IHJlZDsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkdDlrNGtvMWNyMiAuYWN0aXZlQ3JpdDAsCiNkdDlrNGtvMWNyMiAuYWN0aXZlQ3JpdDEsCiNkdDlrNGtvMWNyMiAuYWN0aXZlQ3JpdDIsCiNkdDlrNGtvMWNyMiAuYWN0aXZlQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R0OWs0a28xY3IyIC5kb25lQ3JpdDAsCiNkdDlrNGtvMWNyMiAuZG9uZUNyaXQxLAojZHQ5azRrbzFjcjIgLmRvbmVDcml0MiwKI2R0OWs0a28xY3IyIC5kb25lQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIGN1cnNvcjogcG9pbnRlcjsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkdDlrNGtvMWNyMiAuZG9uZUNyaXRUZXh0MCwKI2R0OWs0a28xY3IyIC5kb25lQ3JpdFRleHQxLAojZHQ5azRrbzFjcjIgLmRvbmVDcml0VGV4dDIsCiNkdDlrNGtvMWNyMiAuZG9uZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2R0OWs0a28xY3IyIC5hY3RpdmVDcml0VGV4dDAsCiNkdDlrNGtvMWNyMiAuYWN0aXZlQ3JpdFRleHQxLAojZHQ5azRrbzFjcjIgLmFjdGl2ZUNyaXRUZXh0MiwKI2R0OWs0a28xY3IyIC5hY3RpdmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkdDlrNGtvMWNyMiAudGl0bGVUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMThweDsKICBmaWxsOiBibGFjazsgfQoKI2R0OWs0a28xY3IyIGcuY2xhc3NHcm91cCB0ZXh0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2R0OWs0a28xY3IyIGcuY2xhc3NHcm91cCByZWN0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsgfQoKI2R0OWs0a28xY3IyIGcuY2xhc3NHcm91cCBsaW5lIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHQ5azRrbzFjcjIgLmNsYXNzTGFiZWwgLmJveCB7CiAgc3Ryb2tlOiBub25lOwogIHN0cm9rZS13aWR0aDogMDsKICBmaWxsOiAjRUNFQ0ZGOwogIG9wYWNpdHk6IDAuNTsgfQoKI2R0OWs0a28xY3IyIC5jbGFzc0xhYmVsIC5sYWJlbCB7CiAgZmlsbDogIzkzNzBEQjsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkdDlrNGtvMWNyMiAucmVsYXRpb24gewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7CiAgZmlsbDogbm9uZTsgfQoKI2R0OWs0a28xY3IyICNjb21wb3NpdGlvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkdDlrNGtvMWNyMiAjY29tcG9zaXRpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R0OWs0a28xY3IyICNhZ2dyZWdhdGlvblN0YXJ0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkdDlrNGtvMWNyMiAjYWdncmVnYXRpb25FbmQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R0OWs0a28xY3IyICNkZXBlbmRlbmN5U3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R0OWs0a28xY3IyICNkZXBlbmRlbmN5RW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkdDlrNGtvMWNyMiAjZXh0ZW5zaW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R0OWs0a28xY3IyICNleHRlbnNpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R0OWs0a28xY3IyIC5jb21taXQtaWQsCiNkdDlrNGtvMWNyMiAuY29tbWl0LW1zZywKI2R0OWs0a28xY3IyIC5icmFuY2gtbGFiZWwgewogIGZpbGw6IGxpZ2h0Z3JleTsKICBjb2xvcjogbGlnaHRncmV5OyB9CgoKCiNkdDlrNGtvMWNyMiAubGFiZWx7CiAgY29sb3I6IzE4QjE0RTsKfQojZHQ5azRrbzFjcjIgLnRlLW1kLWNvbnRhaW5lci0tZGFyayAubm9kZSByZWN0IHsKICBmaWxsOiByZWQ7Cn0KCiNkdDlrNGtvMWNyMiAubm9kZSByZWN0LAojZHQ5azRrbzFjcjIgLm5vZGUgY2lyY2xlLAojZHQ5azRrbzFjcjIgLm5vZGUgZWxsaXBzZSwKI2R0OWs0a28xY3IyIC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNGOUZGRkI7OwogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDEuNXB4Owp9CiNkdDlrNGtvMWNyMiAuYXJyb3doZWFkUGF0aHsKICBmaWxsOiAjMkRCRDYwOwp9CiNkdDlrNGtvMWNyMiAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDFweDsKfQojZHQ5azRrbzFjcjIgLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsKfQojZHQ5azRrbzFjcjIgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI0Y5RkZGQiAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7Cn0KCiNkdDlrNGtvMWNyMiAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHQ5azRrbzFjcjIgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBiYWNrZ3JvdW5kOiAjRjlGRkZCOwogIGJvcmRlcjogMXB4IHNvbGlkICMyREJENjA7Cn0KCgojZHQ5azRrbzFjcjIgLmFjdG9yIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2R0OWs0a28xY3IyIHRleHQuYWN0b3IgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZHQ5azRrbzFjcjIgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R0OWs0a28xY3IyIC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R0OWs0a28xY3IyIC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R0OWs0a28xY3IyICNhcnJvd2hlYWQgewogIGZpbGw6ICMyREJENjA7Cn0KCiNkdDlrNGtvMWNyMiAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKfQoKI2R0OWs0a28xY3IyIC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkdDlrNGtvMWNyMiAubGFiZWxCb3ggewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHQ5azRrbzFjcjIgLmxhYmVsVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkdDlrNGtvMWNyMiAubG9vcFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHQ5azRrbzFjcjIgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHQ5azRrbzFjcjIgLm5vdGUgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHQ5azRrbzFjcjIgLm5vdGVUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKCiNkdDlrNGtvMWNyMiAuc2VjdGlvbnsKICBvcGFjaXR5OjE7Cn0KI2R0OWs0a28xY3IyIC5zZWN0aW9uMCwjZHQ5azRrbzFjcjIgIC5zZWN0aW9uMiB7CiAgZmlsbDogI0VDRjdGMDsKfQoKI2R0OWs0a28xY3IyIC5zZWN0aW9uMSwKI2R0OWs0a28xY3IyIC5zZWN0aW9uMyB7CiAgZmlsbDogI0ZGRjsKfQojZHQ5azRrbzFjcjIgLnRhc2tUZXh0MCwKI2R0OWs0a28xY3IyIC50YXNrVGV4dDEsCiNkdDlrNGtvMWNyMiAudGFza1RleHQyLAojZHQ5azRrbzFjcjIgLnRhc2tUZXh0MyB7CiAgZmlsbDogI2ZmZjsKfQoKI2R0OWs0a28xY3IyIC50YXNrMCwKI2R0OWs0a28xY3IyIC50YXNrMSwKI2R0OWs0a28xY3IyIC50YXNrMiwKI2R0OWs0a28xY3IyIC50YXNrMyB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMzNTlGNUE7Cn0KPC9zdHlsZT48c3R5bGU+I2R0OWs0a28xY3IyIHsKICAgIGNvbG9yOiByZ2IoMjQ0LCAyNDQsIDI0NCk7CiAgICBmb250OiBub3JtYWwgbm9ybWFsIG5vcm1hbCBub3JtYWwgMTRweC8yMi4zOTk5OTk2MTg1MzAyNzNweCBtb25vc3BhY2U7CiAgfTwvc3R5bGU+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLCAtMTIpIj48ZyBjbGFzcz0ib3V0cHV0Ij48ZyBjbGFzcz0iY2x1c3RlcnMiPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGhzIj48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yNDYuOTg0Mzc1LDU2LjI4MTI1TDI0Ni45ODQzNzUsODEuMjgxMjVMMjQ3LjQ4NDM3NSwxMDYuNzgxMjUzMDUxNzU3ODIiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzE5MikiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzE5MiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTI3NS4xNTI3ODE4ODY3MDU1LDIyOC40NDI1MzM2NjUwNTI0TDMxMC40NTMxMjUsMjg4Ljc1MTU1NjM5NjQ4NDRMMzEwLjk1MzEyNDk5OTk5OTk0LDMyMi4zOTIxODQ0NDgyNDIyIiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMxOTMpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMxOTMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yNjcuMjYyNjQ1Mjg0MTU0ODcsNDQwLjI5Mzg5MjIzMjM5NzA3TDE3Ni4yOTY4NzUsNTE2LjYyNUwxNzYuMjk2ODc1LDU0OS43NjU2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzE5NCkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzE5NCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTM1NC42NDM2MDE0MTUzNjk4LDQ0MC4yOTM4ODk0MjkzNTY5N0w0NDQuNjA5Mzc1LDUxNi42MjVMNDQ0LjYwOTM3NSw1NDkuNzY1NjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMxOTUpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMxOTUiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xOTkuMTczNDEyNTkzNjc2MjYsMjA3Ljc5OTk3MjA0MTkxODM4TDQ5LjM1OTM3NSwyODguNzUxNTU2Mzk2NDg0NEw0OS4zNTkzNzUsNDAyLjY4ODI3ODE5ODI0MjJMNDkuMzU5Mzc1LDUxNi42MjVMNDkuMzU5Mzc1LDU2Ny45MDYyNUw0OS4zNTkzNzUsNjExLjA0Njg3NUwxMjIuOTE5Njc5MjM3NTk1MDgsNjM2LjA0Njg3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMTk2KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMTk2IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTc2LjI5Njg3NSw1ODYuMDQ2ODc1TDE3Ni4yOTY4NzUsNjExLjA0Njg3NUwxNzYuMjk2ODc1LDYzNi4wNDY4NzUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzE5NykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzE5NyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTQ0NC42MDkzNzUsNTg2LjA0Njg3NUw0NDQuNjA5Mzc1LDYxMS4wNDY4NzVMMjUzLjM5ODQzNzUsNjQxLjc5MDcyNTM2MzIzNjciIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzE5OCkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzE5OCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE3Ni4yOTY4NzUsNjcyLjMyODEyNUwxNzYuMjk2ODc1LDY5Ny4zMjgxMjVMMTc2Ljc5Njg3NSw3MjIuODI4MTI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMxOTkpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMxOTkiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yMTMuMDk2MTQ2OTA5MDg3NjIsODI0Ljk3NDE2NTU5MDkxMjRMMjg5LjE1NjI1LDg5My45MTQwNjI1TDI4OS4xNTYyNSw5MjcuMDU0Njg3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjAwKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjAwIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTUwLjMwMzM0NzU5OTEwOTYsODM0Ljc3OTkxMDA5OTEwOTdMMTEyLjgyODEyNSw4OTMuOTE0MDYyNUwxMTIuODI4MTI1LDkyNy4wNTQ2ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMyMDEpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMyMDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xMTIuODI4MTI1LDk2My4zMzU5Mzc1TDExMi44MjgxMjUsOTg4LjMzNTkzNzVMMTQ5LjYwODI3NzExODc5NzUzLDEwMTMuMzM1OTM3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjAyKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjAyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjg5LjE1NjI1LDk2My4zMzU5Mzc1TDI4OS4xNTYyNSw5ODguMzM1OTM3NUwyMjMuNzU0MjIxNzQ5MzY2MTcsMTAxMy4zMzU5Mzc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMyMDMpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMyMDMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xNzYuMjk2ODc1LDEwNDkuNjE3MTg3NUwxNzYuMjk2ODc1LDEwNzQuNjE3MTg3NUwxNzYuMjk2ODc1LDEwOTkuNjE3MTg3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjA0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjA0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWxzIj48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMTAuNDUzMTI1LDI4OC43NTE1NTYzOTY0ODQ0KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNC4yMDMxMjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iNy45ODQzNzUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPlk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE3Ni4yOTY4NzUsNTE2LjYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQuMjAzMTI1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjcuOTg0Mzc1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5ZPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NDQuNjA5Mzc1LDUxNi42MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI4LjkzNzUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPk48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ5LjM1OTM3NSw1MTYuNjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNC4yMDMxMjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iOC45Mzc1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5OPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODkuMTU2MjUsODkzLjkxNDA2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI3Ljk4NDM3NSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+WTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEyLjgyODEyNSw4OTMuOTE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQuMjAzMTI1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjguOTM3NSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+TjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlcyI+PGcgY2xhc3M9Im5vZGUiIGlkPSJBIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNDYuOTg0Mzc1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjUiIHJ5PSI1IiB4PSItMTA1Ljc4MTI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMjExLjU2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC05NS43ODEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+ZnVuYyBwcm9jcmVzaXplKG5wcm9jcyBpbnQzMikgKnA8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0Ni45ODQzNzUsMTgwLjk0NjA5MDY5ODI0MjIpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwb2x5Z29uIHBvaW50cz0iNzQuNjY0ODQzNzUsMCAxNDkuMzI5Njg3NSwtNzQuNjY0ODQzNzUgNzQuNjY0ODQzNzUsLTE0OS4zMjk2ODc1IDAsLTc0LjY2NDg0Mzc1IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03NC42NjQ4NDM3NSw3NC42NjQ4NDM3NSkiPjwvcG9seWdvbj48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01NC44MjAzMTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5ucHJvY3MgJmd0OyBsZW4oYWxscCk/PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJDIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMTAuNDUzMTI1LDQwMi42ODgyNzgxOTgyNDIyKSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cG9seWdvbiBwb2ludHM9IjgwLjc5NjA5Mzc1LDAgMTYxLjU5MjE4NzUsLTgwLjc5NjA5Mzc1IDgwLjc5NjA5Mzc1LC0xNjEuNTkyMTg3NSAwLC04MC43OTYwOTM3NSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtODAuNzk2MDkzNzUsODAuNzk2MDkzNzUpIj48L3BvbHlnb24+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjEuNjMyODEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+bnByb2NzICZsdDs9IGNhcFthbGxwXSA/PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJEIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzYuMjk2ODc1LDU2Ny45MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItOTEuOTM3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjE4My44NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04MS45Mzc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5hbGxw5aSf5aSnLCBhbGxwPWFsbHBbOm5wcm9jc108L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0NC42MDkzNzUsNTY3LjkwNjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0xMjYuMzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMjUyLjc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTE2LjM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+YWxscOS4jeWkn+WkpyznlKhtYWtl5p2l55Sz6K+35paw55qEYWxscOaVsOe7hDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTc2LjI5Njg3NSw2NTQuMTg3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNzcuMTAxNTYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjE1NC4yMDMxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02Ny4xMDE1NjI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5sb29wIGFsbHAgYW5kIGluaXQgZWFjaDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTc2LjI5Njg3NSw3OTEuNTUwNzgxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwb2x5Z29uIHBvaW50cz0iNjkuMjIyNjU2MjUsMCAxMzguNDQ1MzEyNSwtNjkuMjIyNjU2MjUgNjkuMjIyNjU2MjUsLTEzOC40NDUzMTI1IDAsLTY5LjIyMjY1NjI1IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02OS4yMjI2NTYyNSw2OS4yMjI2NTYyNSkiPjwvcG9seWdvbj48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00OC43NzM0Mzc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5jdXJyZW50IEcgaGFzIFA/PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODkuMTU2MjUsOTQ1LjE5NTMxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTcxLjM0Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTQyLjY4NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MS4zNDM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+UC5zdGF0dXMgPSBfUHJ1bm5pbmc8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExMi44MjgxMjUsOTQ1LjE5NTMxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTU0Ljk4NDM3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjEwOS45Njg3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ0Ljk4NDM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+TeS4jmFsbHBbMF3nu5Hlrpo8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE3Ni4yOTY4NzUsMTAzMS40NzY1NjI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0xMDYuMjY1NjI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMjEyLjUzMTI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtOTYuMjY1NjI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj7ph4rmlL5hbGxw5LitbnByb2Nz5Lul5ZCO55So5LiN552A55qEUDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iSyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTc2LjI5Njg3NSwxMTE3Ljc1NzgxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTE1Ni4yOTY4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIzMTIuNTkzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuMjk2ODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj7lpoLmnpwhcnVucWVtcHR5KHApLOWImeS4jk3nu5HlrprvvIzlkKbliJlwaWRsZXB1dChwKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==
  • type p,m,g都定义在runtime/runtime2.go中,allp数组也定义在该文件中
  • len表示当前slice的长度,cap表示该slice所在数组能容纳的最多的成员数
  • pp->init(id)也是定义在proc.go中,对P做初始化
  • P与M在这里完成了绑定,为之后mstart做好了准备

runtime.newproc

这里瞄准的是bootstrap阶段的newproc。
newproc的调用如下:

	// create a new goroutine to start program
	MOVW	$runtime·mainPC(SB), R0
	MOVW.W	R0, -4(R13)
	MOVW	$8, R0
	MOVW.W	R0, -4(R13)
	MOVW	$0, R0
	MOVW.W	R0, -4(R13)	// push $0 as guard
	BL	runtime·newproc(SB)

mainPC是指向runtime.main函数的指针。所以newproc是为这个函数创建G,并挂在到一个P上运行。
newproc是newproc1的wrapper,为newproc1准备了callergp和callerpc。newproc1在systemstack上运行。

systemstack

systemstack的语意是在系统栈上运行函数fn。

  • 如果当前栈指针是在g0栈或者gsignal栈上,则直接调用fn函数然后返回。
  • 否则,systemstack将切换到g0栈上调用 fn然后切换回来。
// func systemstack(fn func())
TEXT runtime·systemstack(SB),NOSPLIT,$0-4
	MOVW	fn+0(FP), R0	// R0 = fn
	MOVW	g_m(g), R1	// R1 = m

	MOVW	m_gsignal(R1), R2	// R2 = gsignal
	CMP	g, R2
	B.EQ	noswitch

	MOVW	m_g0(R1), R2	// R2 = g0
	CMP	g, R2
	B.EQ	noswitch

	MOVW	m_curg(R1), R3
	CMP	g, R3
	B.EQ	switch

这一段就是在判断当前g栈指针的位置,只在最后一种情况下才switch。switch即将栈指针切换到g0栈。
此处g, g_m, m_curg,都是变量的表示方法,下划线表示'.'。即:

  • g表示当前g,bootstrap阶段就是g0
  • g_m表示g.m
  • m_curg表示m.curg

上面这段snip中,g实际上就是g的栈指针,因为栈指针是g的第一个参数,可以参考runtime2.go中type g的定义。参看:

type g struct {
	// Stack parameters.
	// stack describes the actual stack memory: [stack.lo, stack.hi).
	// stackguard0 is the stack pointer compared in the Go stack growth prologue.
	// It is stack.lo+StackGuard normally, but can be StackPreempt to trigger a preemption.
	// stackguard1 is the stack pointer compared in the C stack growth prologue.
	// It is stack.lo+StackGuard on g0 and gsignal stacks.
	// It is ~0 on other goroutine stacks, to trigger a call to morestackc (and crash).
	stack       stack   // offset known to runtime/cgo
	stackguard0 uintptr // offset known to liblink
	stackguard1 uintptr // offset known to liblink
...
}

newproc1

PHN2ZyBpZD0iZGgxNmdkNjhyN2EiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDIyMy43OTYwOTY4MDE3NTc4cHg7IiB2aWV3Qm94PSIwIDAgMjIzLjc5NjA5NjgwMTc1NzggMTAyNS4wMDYyNTYxMDM1MTU2Ij48c3R5bGU+CgoKI2RoMTZnZDY4cjdhIC5sYWJlbCB7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBjb2xvcjogIzMzMzsgfQoKI2RoMTZnZDY4cjdhIC5ub2RlIHJlY3QsCiNkaDE2Z2Q2OHI3YSAubm9kZSBjaXJjbGUsCiNkaDE2Z2Q2OHI3YSAubm9kZSBlbGxpcHNlLAojZGgxNmdkNjhyN2EgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7IH0KCiNkaDE2Z2Q2OHI3YSAubm9kZS5jbGlja2FibGUgewogIGN1cnNvcjogcG9pbnRlcjsgfQoKI2RoMTZnZDY4cjdhIC5hcnJvd2hlYWRQYXRoIHsKICBmaWxsOiAjMzMzMzMzOyB9CgojZGgxNmdkNjhyN2EgLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMzMzMzMzM7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsgfQoKI2RoMTZnZDY4cjdhIC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNlOGU4ZTg7IH0KCiNkaDE2Z2Q2OHI3YSAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjZmZmZmRlICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjYWFhYTMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsgfQoKI2RoMTZnZDY4cjdhIC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICMzMzM7IH0KCiNkaDE2Z2Q2OHI3YSBkaXYubWVybWFpZFRvb2x0aXAgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWF4LXdpZHRoOiAyMDBweDsKICBwYWRkaW5nOiAycHg7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEycHg7CiAgYmFja2dyb3VuZDogI2ZmZmZkZTsKICBib3JkZXI6IDFweCBzb2xpZCAjYWFhYTMzOwogIGJvcmRlci1yYWRpdXM6IDJweDsKICBwb2ludGVyLWV2ZW50czogbm9uZTsKICB6LWluZGV4OiAxMDA7IH0KCiNkaDE2Z2Q2OHI3YSAuYWN0b3IgewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZGgxNmdkNjhyN2EgdGV4dC5hY3RvciB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZGgxNmdkNjhyN2EgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogZ3JleTsgfQoKI2RoMTZnZDY4cjdhIC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2RoMTZnZDY4cjdhIC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzMzMzsgfQoKI2RoMTZnZDY4cjdhICNhcnJvd2hlYWQgewogIGZpbGw6ICMzMzM7IH0KCiNkaDE2Z2Q2OHI3YSAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMzMzMgIWltcG9ydGFudDsKICBzdHJva2U6ICMzMzMgIWltcG9ydGFudDsgfQoKI2RoMTZnZDY4cjdhIC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzMzMzsKICBzdHJva2U6IG5vbmU7IH0KCiNkaDE2Z2Q2OHI3YSAubGFiZWxCb3ggewogIHN0cm9rZTogI0NDQ0NGRjsKICBmaWxsOiAjRUNFQ0ZGOyB9CgojZGgxNmdkNjhyN2EgLmxhYmVsVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZGgxNmdkNjhyN2EgLmxvb3BUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNkaDE2Z2Q2OHI3YSAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICNDQ0NDRkY7IH0KCiNkaDE2Z2Q2OHI3YSAubm90ZSB7CiAgc3Ryb2tlOiAjYWFhYTMzOwogIGZpbGw6ICNmZmY1YWQ7IH0KCiNkaDE2Z2Q2OHI3YSAubm90ZVRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTRweDsgfQoKI2RoMTZnZDY4cjdhIC5hY3RpdmF0aW9uMCB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNkaDE2Z2Q2OHI3YSAuYWN0aXZhdGlvbjEgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZGgxNmdkNjhyN2EgLmFjdGl2YXRpb24yIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKCiNkaDE2Z2Q2OHI3YSAuc2VjdGlvbiB7CiAgc3Ryb2tlOiBub25lOwogIG9wYWNpdHk6IDAuMjsgfQoKI2RoMTZnZDY4cjdhIC5zZWN0aW9uMCB7CiAgZmlsbDogcmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KTsgfQoKI2RoMTZnZDY4cjdhIC5zZWN0aW9uMiB7CiAgZmlsbDogI2ZmZjQwMDsgfQoKI2RoMTZnZDY4cjdhIC5zZWN0aW9uMSwKI2RoMTZnZDY4cjdhIC5zZWN0aW9uMyB7CiAgZmlsbDogd2hpdGU7CiAgb3BhY2l0eTogMC4yOyB9CgojZGgxNmdkNjhyN2EgLnNlY3Rpb25UaXRsZTAgewogIGZpbGw6ICMzMzM7IH0KCiNkaDE2Z2Q2OHI3YSAuc2VjdGlvblRpdGxlMSB7CiAgZmlsbDogIzMzMzsgfQoKI2RoMTZnZDY4cjdhIC5zZWN0aW9uVGl0bGUyIHsKICBmaWxsOiAjMzMzOyB9CgojZGgxNmdkNjhyN2EgLnNlY3Rpb25UaXRsZTMgewogIGZpbGw6ICMzMzM7IH0KCiNkaDE2Z2Q2OHI3YSAuc2VjdGlvblRpdGxlIHsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OwogIHRleHQtaGVpZ2h0OiAxNHB4OyB9CgoKI2RoMTZnZDY4cjdhIC5ncmlkIC50aWNrIHsKICBzdHJva2U6IGxpZ2h0Z3JleTsKICBvcGFjaXR5OiAwLjM7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZGgxNmdkNjhyN2EgLmdyaWQgcGF0aCB7CiAgc3Ryb2tlLXdpZHRoOiAwOyB9CgoKI2RoMTZnZDY4cjdhIC50b2RheSB7CiAgZmlsbDogbm9uZTsKICBzdHJva2U6IHJlZDsKICBzdHJva2Utd2lkdGg6IDJweDsgfQoKCgojZGgxNmdkNjhyN2EgLnRhc2sgewogIHN0cm9rZS13aWR0aDogMjsgfQoKI2RoMTZnZDY4cjdhIC50YXNrVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDExcHg7IH0KCiNkaDE2Z2Q2OHI3YSAudGFza1RleHRPdXRzaWRlUmlnaHQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7IH0KCiNkaDE2Z2Q2OHI3YSAudGFza1RleHRPdXRzaWRlTGVmdCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IGVuZDsKICBmb250LXNpemU6IDExcHg7IH0KCgojZGgxNmdkNjhyN2EgLnRhc2tUZXh0MCwKI2RoMTZnZDY4cjdhIC50YXNrVGV4dDEsCiNkaDE2Z2Q2OHI3YSAudGFza1RleHQyLAojZGgxNmdkNjhyN2EgLnRhc2tUZXh0MyB7CiAgZmlsbDogd2hpdGU7IH0KCiNkaDE2Z2Q2OHI3YSAudGFzazAsCiNkaDE2Z2Q2OHI3YSAudGFzazEsCiNkaDE2Z2Q2OHI3YSAudGFzazIsCiNkaDE2Z2Q2OHI3YSAudGFzazMgewogIGZpbGw6ICM4YTkwZGQ7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZGgxNmdkNjhyN2EgLnRhc2tUZXh0T3V0c2lkZTAsCiNkaDE2Z2Q2OHI3YSAudGFza1RleHRPdXRzaWRlMiB7CiAgZmlsbDogYmxhY2s7IH0KCiNkaDE2Z2Q2OHI3YSAudGFza1RleHRPdXRzaWRlMSwKI2RoMTZnZDY4cjdhIC50YXNrVGV4dE91dHNpZGUzIHsKICBmaWxsOiBibGFjazsgfQoKCiNkaDE2Z2Q2OHI3YSAuYWN0aXZlMCwKI2RoMTZnZDY4cjdhIC5hY3RpdmUxLAojZGgxNmdkNjhyN2EgLmFjdGl2ZTIsCiNkaDE2Z2Q2OHI3YSAuYWN0aXZlMyB7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNkaDE2Z2Q2OHI3YSAuYWN0aXZlVGV4dDAsCiNkaDE2Z2Q2OHI3YSAuYWN0aXZlVGV4dDEsCiNkaDE2Z2Q2OHI3YSAuYWN0aXZlVGV4dDIsCiNkaDE2Z2Q2OHI3YSAuYWN0aXZlVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZGgxNmdkNjhyN2EgLmRvbmUwLAojZGgxNmdkNjhyN2EgLmRvbmUxLAojZGgxNmdkNjhyN2EgLmRvbmUyLAojZGgxNmdkNjhyN2EgLmRvbmUzIHsKICBzdHJva2U6IGdyZXk7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2RoMTZnZDY4cjdhIC5kb25lVGV4dDAsCiNkaDE2Z2Q2OHI3YSAuZG9uZVRleHQxLAojZGgxNmdkNjhyN2EgLmRvbmVUZXh0MiwKI2RoMTZnZDY4cjdhIC5kb25lVGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCgojZGgxNmdkNjhyN2EgLmNyaXQwLAojZGgxNmdkNjhyN2EgLmNyaXQxLAojZGgxNmdkNjhyN2EgLmNyaXQyLAojZGgxNmdkNjhyN2EgLmNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogcmVkOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2RoMTZnZDY4cjdhIC5hY3RpdmVDcml0MCwKI2RoMTZnZDY4cjdhIC5hY3RpdmVDcml0MSwKI2RoMTZnZDY4cjdhIC5hY3RpdmVDcml0MiwKI2RoMTZnZDY4cjdhIC5hY3RpdmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZGgxNmdkNjhyN2EgLmRvbmVDcml0MCwKI2RoMTZnZDY4cjdhIC5kb25lQ3JpdDEsCiNkaDE2Z2Q2OHI3YSAuZG9uZUNyaXQyLAojZGgxNmdkNjhyN2EgLmRvbmVDcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7CiAgY3Vyc29yOiBwb2ludGVyOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2RoMTZnZDY4cjdhIC5kb25lQ3JpdFRleHQwLAojZGgxNmdkNjhyN2EgLmRvbmVDcml0VGV4dDEsCiNkaDE2Z2Q2OHI3YSAuZG9uZUNyaXRUZXh0MiwKI2RoMTZnZDY4cjdhIC5kb25lQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZGgxNmdkNjhyN2EgLmFjdGl2ZUNyaXRUZXh0MCwKI2RoMTZnZDY4cjdhIC5hY3RpdmVDcml0VGV4dDEsCiNkaDE2Z2Q2OHI3YSAuYWN0aXZlQ3JpdFRleHQyLAojZGgxNmdkNjhyN2EgLmFjdGl2ZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2RoMTZnZDY4cjdhIC50aXRsZVRleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxOHB4OwogIGZpbGw6IGJsYWNrOyB9CgojZGgxNmdkNjhyN2EgZy5jbGFzc0dyb3VwIHRleHQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZGgxNmdkNjhyN2EgZy5jbGFzc0dyb3VwIHJlY3QgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOyB9CgojZGgxNmdkNjhyN2EgZy5jbGFzc0dyb3VwIGxpbmUgewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkaDE2Z2Q2OHI3YSAuY2xhc3NMYWJlbCAuYm94IHsKICBzdHJva2U6IG5vbmU7CiAgc3Ryb2tlLXdpZHRoOiAwOwogIGZpbGw6ICNFQ0VDRkY7CiAgb3BhY2l0eTogMC41OyB9CgojZGgxNmdkNjhyN2EgLmNsYXNzTGFiZWwgLmxhYmVsIHsKICBmaWxsOiAjOTM3MERCOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2RoMTZnZDY4cjdhIC5yZWxhdGlvbiB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsKICBmaWxsOiBub25lOyB9CgojZGgxNmdkNjhyN2EgI2NvbXBvc2l0aW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RoMTZnZDY4cjdhICNjb21wb3NpdGlvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGgxNmdkNjhyN2EgI2FnZ3JlZ2F0aW9uU3RhcnQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RoMTZnZDY4cjdhICNhZ2dyZWdhdGlvbkVuZCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGgxNmdkNjhyN2EgI2RlcGVuZGVuY3lTdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGgxNmdkNjhyN2EgI2RlcGVuZGVuY3lFbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RoMTZnZDY4cjdhICNleHRlbnNpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGgxNmdkNjhyN2EgI2V4dGVuc2lvbkVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGgxNmdkNjhyN2EgLmNvbW1pdC1pZCwKI2RoMTZnZDY4cjdhIC5jb21taXQtbXNnLAojZGgxNmdkNjhyN2EgLmJyYW5jaC1sYWJlbCB7CiAgZmlsbDogbGlnaHRncmV5OwogIGNvbG9yOiBsaWdodGdyZXk7IH0KCgoKI2RoMTZnZDY4cjdhIC5sYWJlbHsKICBjb2xvcjojMThCMTRFOwp9CiNkaDE2Z2Q2OHI3YSAudGUtbWQtY29udGFpbmVyLS1kYXJrIC5ub2RlIHJlY3QgewogIGZpbGw6IHJlZDsKfQoKI2RoMTZnZDY4cjdhIC5ub2RlIHJlY3QsCiNkaDE2Z2Q2OHI3YSAubm9kZSBjaXJjbGUsCiNkaDE2Z2Q2OHI3YSAubm9kZSBlbGxpcHNlLAojZGgxNmdkNjhyN2EgLm5vZGUgcG9seWdvbiB7CiAgZmlsbDogI0Y5RkZGQjs7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMS41cHg7Cn0KI2RoMTZnZDY4cjdhIC5hcnJvd2hlYWRQYXRoewogIGZpbGw6ICMyREJENjA7Cn0KI2RoMTZnZDY4cjdhIC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIHN0cm9rZS13aWR0aDogMXB4Owp9CiNkaDE2Z2Q2OHI3YSAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOwp9CiNkaDE2Z2Q2OHI3YSAuY2x1c3RlciByZWN0IHsKICBmaWxsOiAjRjlGRkZCICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlLXdpZHRoOiAxcHggIWltcG9ydGFudDsKfQoKI2RoMTZnZDY4cjdhIC5jbHVzdGVyIHRleHQgewogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkaDE2Z2Q2OHI3YSBkaXYubWVybWFpZFRvb2x0aXAgewogIGJhY2tncm91bmQ6ICNGOUZGRkI7CiAgYm9yZGVyOiAxcHggc29saWQgIzJEQkQ2MDsKfQoKCiNkaDE2Z2Q2OHI3YSAuYWN0b3IgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZGgxNmdkNjhyN2EgdGV4dC5hY3RvciB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkaDE2Z2Q2OHI3YSAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZGgxNmdkNjhyN2EgLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZGgxNmdkNjhyN2EgLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZGgxNmdkNjhyN2EgI2Fycm93aGVhZCB7CiAgZmlsbDogIzJEQkQ2MDsKfQoKI2RoMTZnZDY4cjdhICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50Owp9CgojZGgxNmdkNjhyN2EgLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2RoMTZnZDY4cjdhIC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkaDE2Z2Q2OHI3YSAubGFiZWxUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RoMTZnZDY4cjdhIC5sb29wVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkaDE2Z2Q2OHI3YSAubG9vcExpbmUgewogIHN0cm9rZS13aWR0aDogMjsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkaDE2Z2Q2OHI3YSAubm90ZSB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNkaDE2Z2Q2OHI3YSAubm90ZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgoKI2RoMTZnZDY4cjdhIC5zZWN0aW9uewogIG9wYWNpdHk6MTsKfQojZGgxNmdkNjhyN2EgLnNlY3Rpb24wLCNkaDE2Z2Q2OHI3YSAgLnNlY3Rpb24yIHsKICBmaWxsOiAjRUNGN0YwOwp9CgojZGgxNmdkNjhyN2EgLnNlY3Rpb24xLAojZGgxNmdkNjhyN2EgLnNlY3Rpb24zIHsKICBmaWxsOiAjRkZGOwp9CiNkaDE2Z2Q2OHI3YSAudGFza1RleHQwLAojZGgxNmdkNjhyN2EgLnRhc2tUZXh0MSwKI2RoMTZnZDY4cjdhIC50YXNrVGV4dDIsCiNkaDE2Z2Q2OHI3YSAudGFza1RleHQzIHsKICBmaWxsOiAjZmZmOwp9CgojZGgxNmdkNjhyN2EgLnRhc2swLAojZGgxNmdkNjhyN2EgLnRhc2sxLAojZGgxNmdkNjhyN2EgLnRhc2syLAojZGgxNmdkNjhyN2EgLnRhc2szIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzM1OUY1QTsKfQo8L3N0eWxlPjxzdHlsZT4jZGgxNmdkNjhyN2EgewogICAgY29sb3I6IHJnYigyNDQsIDI0NCwgMjQ0KTsKICAgIGZvbnQ6IG5vcm1hbCBub3JtYWwgbm9ybWFsIG5vcm1hbCAxNHB4LzIyLjM5OTk5OTYxODUzMDI3M3B4IG1vbm9zcGFjZTsKICB9PC9zdHlsZT48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIsIC0xMikiPjxnIGNsYXNzPSJvdXRwdXQiPjxnIGNsYXNzPSJjbHVzdGVycyI+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aHMiPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTExOS45NTYyNTMwNTE3NTc4MSw1Ni4yODEyNUwxMTkuOTU2MjUzMDUxNzU3ODEsODEuMjgxMjVMMTE5Ljk1NjI1MzA1MTc1NzgxLDEwNi4yODEyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjU5KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjU5IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTE5Ljk1NjI1MzA1MTc1NzgxLDE0Mi41NjI1TDExOS45NTYyNTMwNTE3NTc4MSwxNjcuNTYyNUwxMTkuOTU2MjUzMDUxNzU3ODEsMTkyLjU2MjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzI2MCkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzI2MCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTEzNi43OTkzNDI0ODg0NTgsMjI4Ljg0Mzc1TDE2Ny41Njk1MzQzMDE3NTc4LDI2MS45ODQzNzVMMTY3LjU2OTUzNDMwMTc1NzgsMjk1LjEyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjYxKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjYxIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTAzLjExMzE2MzYxNTA1NzYzLDIyOC44NDM3NUw3Mi4zNDI5NzE4MDE3NTc4MSwyNjEuOTg0Mzc1TDcyLjM0Mjk3MTgwMTc1NzgxLDMxMy4yNjU2MjVMNzIuMzQyOTcxODAxNzU3ODEsMzU2LjQwNjI1TDk5LjkzNDg3NjkwODYwMzE2LDM4MS40MDYyNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjYyKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjYyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTY3LjU2OTUzNDMwMTc1NzgsMzMxLjQwNjI1TDE2Ny41Njk1MzQzMDE3NTc4LDM1Ni40MDYyNUwxMzkuOTc3NjI5MTk0OTEyNDgsMzgxLjQwNjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMyNjMpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMyNjMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xMTkuOTU2MjUzMDUxNzU3ODEsNDE3LjY4NzVMMTE5Ljk1NjI1MzA1MTc1NzgxLDQ0Mi42ODc1TDExOS45NTYyNTMwNTE3NTc4MSw0NjcuNjg3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjY0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjY0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTE5Ljk1NjI1MzA1MTc1NzgxLDUwMy45Njg3NUwxMTkuOTU2MjUzMDUxNzU3ODEsNTI4Ljk2ODc1TDExOS45NTYyNTMwNTE3NTc4MSw1NTMuOTY4NzUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzI2NSkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzI2NSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTExOS45NTYyNTMwNTE3NTc4MSw1OTAuMjVMMTE5Ljk1NjI1MzA1MTc1NzgxLDYxNS4yNUwxMjAuNDU2MjUzMDUxNzU3OCw2NDAuNzUwMDAzMDUxNzU3NyIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjY2KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjY2IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNODkuOTI2ODQ2MzM3Mzg1Niw4MTAuMTMzMDk2MzM3Mzg1Nkw2MS40Mjg5MDkzMDE3NTc4MSw4NzMuMzAzMTMxMTAzNTE1Nkw2MS40Mjg5MDkzMDE3NTc4MSw5MDYuNDQzNzU2MTAzNTE1NiIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjY3KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjY3IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTUwLjk4NTY1NzkwMTk0NzM4LDgxMC4xMzMwOTIwOTgwNTI4TDE3OC40ODM1OTY4MDE3NTc4LDg3My4zMDMxMzExMDM1MTU2TDE3OC40ODM1OTY4MDE3NTc4LDkwNi40NDM3NTYxMDM1MTU2IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMyNjgpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMyNjgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik02MS40Mjg5MDkzMDE3NTc4MSw5NDIuNzI1MDA2MTAzNTE1Nkw2MS40Mjg5MDkzMDE3NTc4MSw5NjcuNzI1MDA2MTAzNTE1Nkw5NS4zNDU1MTU2MDM4MjIyOCw5OTIuNzI1MDA2MTAzNTE1NiIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMjY5KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMjY5IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTc4LjQ4MzU5NjgwMTc1NzgsOTQyLjcyNTAwNjEwMzUxNTZMMTc4LjQ4MzU5NjgwMTc1NzgsOTY3LjcyNTAwNjEwMzUxNTZMMTQ0LjU2Njk5MDQ5OTY5MzMzLDk5Mi43MjUwMDYxMDM1MTU2IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMyNzApIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMyNzAiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbHMiPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE2Ny41Njk1MzQzMDE3NTc4LDI2MS45ODQzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00NC43MTA5Mzc1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjY4LjYyNSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+bmV3ZyA9PSBuaWw8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYxLjQyODkwOTMwMTc1NzgxLDg3My4zMDMxMzExMDM1MTU2KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNC4yMDMxMjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iOCIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+WTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTc4LjQ4MzU5NjgwMTc1NzgsODczLjMwMzEzMTEwMzUxNTYpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI4LjkzNzUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPk48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZXMiPjxnIGNsYXNzPSJub2RlIiBpZD0iQSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTE5Ljk1NjI1MzA1MTc1NzgxLDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMzkuMzIwMzEyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9Ijc4LjY0MDYyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI5LjMyMDMxMjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPm5ld3Byb2MxPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMTkuOTU2MjUzMDUxNzU3ODEsMTI0LjQyMTg3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjUiIHJ5PSI1IiB4PSItMzQuODUxNTYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjY5LjcwMzEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI0Ljg1MTU2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmFxdWlyZW08L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExOS45NTYyNTMwNTE3NTc4MSwyMTAuNzAzMTI1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii00MS4yNDIxODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iODIuNDg0Mzc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzEuMjQyMTg3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+Z2ZnZXQoX3BfKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTY3LjU2OTUzNDMwMTc1NzgsMzEzLjI2NTYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNjAuMjI2NTYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjEyMC40NTMxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01MC4yMjY1NjI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5tYWxnKF9TdGFja21pbik8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExOS45NTYyNTMwNTE3NTc4MSwzOTkuNTQ2ODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0zNy44NjcxODc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iNzUuNzM0Mzc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjcuODY3MTg3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+aW5pdCBuZXdnPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJGIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMTkuOTU2MjUzMDUxNzU3ODEsNDg1LjgyODEyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNzAuODgyODEyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjE0MS43NjU2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MC44ODI4MTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5fR2RlYWQ9Jmd0O19HcnVuYWJsZTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTE5Ljk1NjI1MzA1MTc1NzgxLDU3Mi4xMDkzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTg2LjU3MDMxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxNzMuMTQwNjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzYuNTcwMzEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+cnVucXB1dChfcF8sIG5ld2csIHRydWUpPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMTkuOTU2MjUzMDUxNzU3ODEsNzQwLjIwNjI1MzA1MTc1NzgpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwb2x5Z29uIHBvaW50cz0iOTkuOTU2MjUsMCAxOTkuOTEyNSwtOTkuOTU2MjUgOTkuOTU2MjUsLTE5OS45MTI1IDAsLTk5Ljk1NjI1IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC05OS45NTYyNSw5OS45NTYyNSkiPjwvcG9seWdvbj48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04Mi45MjE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmhhcyBpZGxlIFAgJmFtcDsmYW1wOyBubyBzcGlubmluZyBNPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJJIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MS40Mjg5MDkzMDE3NTc4MSw5MjQuNTg0MzgxMTAzNTE1NikiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMjkuNTM5MDYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjU5LjA3ODEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5LjUzOTA2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPndha2VwPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJKIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNzguNDgzNTk2ODAxNzU3OCw5MjQuNTg0MzgxMTAzNTE1NikiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMzcuNTE1NjI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iNzUuMDMxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yNy41MTU2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnJlbGVhc2VtPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJLIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMTkuOTU2MjUzMDUxNzU3ODEsMTAxMC44NjU2MzExMDM1MTU2KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iNSIgcnk9IjUiIHg9Ii0yOC45Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iNTcuODc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTguOTM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+cmV0dXJuPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PC9zdmc+

以上的流程还是比较清楚的。在有free G的时候获取之,否则malg创建一个G。G在创建出来的时候,状态为_Gdead,初始化以后是_Grunnable。
aquirem和releasem的意义没看明白。按照注释的意思是,阻止抢占。

aquirem: disable preemption because it can be holding p in a local var

有点引用计数的感觉。

runtime.mstart

mstart负责运行M,在bootstrap阶段这里start的实际上是M0。
与newproc类似,mstart是mstart1的封装。mstart为运行mstart1做一些准备,主要是m.g0栈区数据的初始化。当进入mstart1运行后,函数再也不会返回,因为这里面会调用调度器的schedule函数。如果函数返回到这里,说明再也没有东西需要运行,也就是程序到达main函数结尾,程序要退出。这也是mexit的语意。在Linux的实现就是调用SYS_exit系统调用来退出程序。
mstart --> mexit --> exitThread
Linux平台的exitThread定义在runtime/sys_linux_arm.s中,是一个汇编函数。

// func exitThread(wait *uint32)
TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-4
	MOVW	wait+0(FP), R0
	// We're done using the stack.
	// Alas, there's no reliable way to make this write atomic
	// without potentially using the stack. So it goes.
	MOVW	$0, R1
	MOVW	R1, (R0)
	MOVW	$0, R0	// exit code
	MOVW	$SYS_exit, R7
	SWI	$0

可见最终调用的SYS_exit,并且设置了返回值。

mstart1

PHN2ZyBpZD0iZGJidnhveDV1N3oiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDE3MC4wNDY4NzVweDsiIHZpZXdCb3g9IjAgMCAxNzAuMDQ2ODc1IDY3Mi41MzEyNSI+PHN0eWxlPgoKCiNkYmJ2eG94NXU3eiAubGFiZWwgewogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgY29sb3I6ICMzMzM7IH0KCiNkYmJ2eG94NXU3eiAubm9kZSByZWN0LAojZGJidnhveDV1N3ogLm5vZGUgY2lyY2xlLAojZGJidnhveDV1N3ogLm5vZGUgZWxsaXBzZSwKI2RiYnZ4b3g1dTd6IC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMXB4OyB9CgojZGJidnhveDV1N3ogLm5vZGUuY2xpY2thYmxlIHsKICBjdXJzb3I6IHBvaW50ZXI7IH0KCiNkYmJ2eG94NXU3eiAuYXJyb3doZWFkUGF0aCB7CiAgZmlsbDogIzMzMzMzMzsgfQoKI2RiYnZ4b3g1dTd6IC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMzMzMzMzOwogIHN0cm9rZS13aWR0aDogMS41cHg7IH0KCiNkYmJ2eG94NXU3eiAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZThlOGU4OyB9CgojZGJidnhveDV1N3ogLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI2ZmZmZkZSAhaW1wb3J0YW50OwogIHN0cm9rZTogI2FhYWEzMyAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7IH0KCiNkYmJ2eG94NXU3eiAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjMzMzOyB9CgojZGJidnhveDV1N3ogZGl2Lm1lcm1haWRUb29sdGlwIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1heC13aWR0aDogMjAwcHg7CiAgcGFkZGluZzogMnB4OwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMnB4OwogIGJhY2tncm91bmQ6ICNmZmZmZGU7CiAgYm9yZGVyOiAxcHggc29saWQgI2FhYWEzMzsKICBib3JkZXItcmFkaXVzOiAycHg7CiAgcG9pbnRlci1ldmVudHM6IG5vbmU7CiAgei1pbmRleDogMTAwOyB9CgojZGJidnhveDV1N3ogLmFjdG9yIHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RiYnZ4b3g1dTd6IHRleHQuYWN0b3IgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RiYnZ4b3g1dTd6IC5hY3Rvci1saW5lIHsKICBzdHJva2U6IGdyZXk7IH0KCiNkYmJ2eG94NXU3eiAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkYmJ2eG94NXU3eiAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkYmJ2eG94NXU3eiAjYXJyb3doZWFkIHsKICBmaWxsOiAjMzMzOyB9CgojZGJidnhveDV1N3ogI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMzMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMzMzICFpbXBvcnRhbnQ7IH0KCiNkYmJ2eG94NXU3eiAubWVzc2FnZVRleHQgewogIGZpbGw6ICMzMzM7CiAgc3Ryb2tlOiBub25lOyB9CgojZGJidnhveDV1N3ogLmxhYmVsQm94IHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RiYnZ4b3g1dTd6IC5sYWJlbFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RiYnZ4b3g1dTd6IC5sb29wVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZGJidnhveDV1N3ogLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOyB9CgojZGJidnhveDV1N3ogLm5vdGUgewogIHN0cm9rZTogI2FhYWEzMzsKICBmaWxsOiAjZmZmNWFkOyB9CgojZGJidnhveDV1N3ogLm5vdGVUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDE0cHg7IH0KCiNkYmJ2eG94NXU3eiAuYWN0aXZhdGlvbjAgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZGJidnhveDV1N3ogLmFjdGl2YXRpb24xIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2RiYnZ4b3g1dTd6IC5hY3RpdmF0aW9uMiB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCgojZGJidnhveDV1N3ogLnNlY3Rpb24gewogIHN0cm9rZTogbm9uZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkYmJ2eG94NXU3eiAuc2VjdGlvbjAgewogIGZpbGw6IHJnYmEoMTAyLCAxMDIsIDI1NSwgMC40OSk7IH0KCiNkYmJ2eG94NXU3eiAuc2VjdGlvbjIgewogIGZpbGw6ICNmZmY0MDA7IH0KCiNkYmJ2eG94NXU3eiAuc2VjdGlvbjEsCiNkYmJ2eG94NXU3eiAuc2VjdGlvbjMgewogIGZpbGw6IHdoaXRlOwogIG9wYWNpdHk6IDAuMjsgfQoKI2RiYnZ4b3g1dTd6IC5zZWN0aW9uVGl0bGUwIHsKICBmaWxsOiAjMzMzOyB9CgojZGJidnhveDV1N3ogLnNlY3Rpb25UaXRsZTEgewogIGZpbGw6ICMzMzM7IH0KCiNkYmJ2eG94NXU3eiAuc2VjdGlvblRpdGxlMiB7CiAgZmlsbDogIzMzMzsgfQoKI2RiYnZ4b3g1dTd6IC5zZWN0aW9uVGl0bGUzIHsKICBmaWxsOiAjMzMzOyB9CgojZGJidnhveDV1N3ogLnNlY3Rpb25UaXRsZSB7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsKICB0ZXh0LWhlaWdodDogMTRweDsgfQoKCiNkYmJ2eG94NXU3eiAuZ3JpZCAudGljayB7CiAgc3Ryb2tlOiBsaWdodGdyZXk7CiAgb3BhY2l0eTogMC4zOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2RiYnZ4b3g1dTd6IC5ncmlkIHBhdGggewogIHN0cm9rZS13aWR0aDogMDsgfQoKCiNkYmJ2eG94NXU3eiAudG9kYXkgewogIGZpbGw6IG5vbmU7CiAgc3Ryb2tlOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAycHg7IH0KCgoKI2RiYnZ4b3g1dTd6IC50YXNrIHsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkYmJ2eG94NXU3eiAudGFza1RleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZGJidnhveDV1N3ogLnRhc2tUZXh0T3V0c2lkZVJpZ2h0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZGJidnhveDV1N3ogLnRhc2tUZXh0T3V0c2lkZUxlZnQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBlbmQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgoKI2RiYnZ4b3g1dTd6IC50YXNrVGV4dDAsCiNkYmJ2eG94NXU3eiAudGFza1RleHQxLAojZGJidnhveDV1N3ogLnRhc2tUZXh0MiwKI2RiYnZ4b3g1dTd6IC50YXNrVGV4dDMgewogIGZpbGw6IHdoaXRlOyB9CgojZGJidnhveDV1N3ogLnRhc2swLAojZGJidnhveDV1N3ogLnRhc2sxLAojZGJidnhveDV1N3ogLnRhc2syLAojZGJidnhveDV1N3ogLnRhc2szIHsKICBmaWxsOiAjOGE5MGRkOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2RiYnZ4b3g1dTd6IC50YXNrVGV4dE91dHNpZGUwLAojZGJidnhveDV1N3ogLnRhc2tUZXh0T3V0c2lkZTIgewogIGZpbGw6IGJsYWNrOyB9CgojZGJidnhveDV1N3ogLnRhc2tUZXh0T3V0c2lkZTEsCiNkYmJ2eG94NXU3eiAudGFza1RleHRPdXRzaWRlMyB7CiAgZmlsbDogYmxhY2s7IH0KCgojZGJidnhveDV1N3ogLmFjdGl2ZTAsCiNkYmJ2eG94NXU3eiAuYWN0aXZlMSwKI2RiYnZ4b3g1dTd6IC5hY3RpdmUyLAojZGJidnhveDV1N3ogLmFjdGl2ZTMgewogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZGJidnhveDV1N3ogLmFjdGl2ZVRleHQwLAojZGJidnhveDV1N3ogLmFjdGl2ZVRleHQxLAojZGJidnhveDV1N3ogLmFjdGl2ZVRleHQyLAojZGJidnhveDV1N3ogLmFjdGl2ZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RiYnZ4b3g1dTd6IC5kb25lMCwKI2RiYnZ4b3g1dTd6IC5kb25lMSwKI2RiYnZ4b3g1dTd6IC5kb25lMiwKI2RiYnZ4b3g1dTd6IC5kb25lMyB7CiAgc3Ryb2tlOiBncmV5OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkYmJ2eG94NXU3eiAuZG9uZVRleHQwLAojZGJidnhveDV1N3ogLmRvbmVUZXh0MSwKI2RiYnZ4b3g1dTd6IC5kb25lVGV4dDIsCiNkYmJ2eG94NXU3eiAuZG9uZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RiYnZ4b3g1dTd6IC5jcml0MCwKI2RiYnZ4b3g1dTd6IC5jcml0MSwKI2RiYnZ4b3g1dTd6IC5jcml0MiwKI2RiYnZ4b3g1dTd6IC5jcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IHJlZDsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkYmJ2eG94NXU3eiAuYWN0aXZlQ3JpdDAsCiNkYmJ2eG94NXU3eiAuYWN0aXZlQ3JpdDEsCiNkYmJ2eG94NXU3eiAuYWN0aXZlQ3JpdDIsCiNkYmJ2eG94NXU3eiAuYWN0aXZlQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2RiYnZ4b3g1dTd6IC5kb25lQ3JpdDAsCiNkYmJ2eG94NXU3eiAuZG9uZUNyaXQxLAojZGJidnhveDV1N3ogLmRvbmVDcml0MiwKI2RiYnZ4b3g1dTd6IC5kb25lQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIGN1cnNvcjogcG9pbnRlcjsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkYmJ2eG94NXU3eiAuZG9uZUNyaXRUZXh0MCwKI2RiYnZ4b3g1dTd6IC5kb25lQ3JpdFRleHQxLAojZGJidnhveDV1N3ogLmRvbmVDcml0VGV4dDIsCiNkYmJ2eG94NXU3eiAuZG9uZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2RiYnZ4b3g1dTd6IC5hY3RpdmVDcml0VGV4dDAsCiNkYmJ2eG94NXU3eiAuYWN0aXZlQ3JpdFRleHQxLAojZGJidnhveDV1N3ogLmFjdGl2ZUNyaXRUZXh0MiwKI2RiYnZ4b3g1dTd6IC5hY3RpdmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkYmJ2eG94NXU3eiAudGl0bGVUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMThweDsKICBmaWxsOiBibGFjazsgfQoKI2RiYnZ4b3g1dTd6IGcuY2xhc3NHcm91cCB0ZXh0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2RiYnZ4b3g1dTd6IGcuY2xhc3NHcm91cCByZWN0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsgfQoKI2RiYnZ4b3g1dTd6IGcuY2xhc3NHcm91cCBsaW5lIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGJidnhveDV1N3ogLmNsYXNzTGFiZWwgLmJveCB7CiAgc3Ryb2tlOiBub25lOwogIHN0cm9rZS13aWR0aDogMDsKICBmaWxsOiAjRUNFQ0ZGOwogIG9wYWNpdHk6IDAuNTsgfQoKI2RiYnZ4b3g1dTd6IC5jbGFzc0xhYmVsIC5sYWJlbCB7CiAgZmlsbDogIzkzNzBEQjsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkYmJ2eG94NXU3eiAucmVsYXRpb24gewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7CiAgZmlsbDogbm9uZTsgfQoKI2RiYnZ4b3g1dTd6ICNjb21wb3NpdGlvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkYmJ2eG94NXU3eiAjY29tcG9zaXRpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RiYnZ4b3g1dTd6ICNhZ2dyZWdhdGlvblN0YXJ0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkYmJ2eG94NXU3eiAjYWdncmVnYXRpb25FbmQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RiYnZ4b3g1dTd6ICNkZXBlbmRlbmN5U3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RiYnZ4b3g1dTd6ICNkZXBlbmRlbmN5RW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkYmJ2eG94NXU3eiAjZXh0ZW5zaW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RiYnZ4b3g1dTd6ICNleHRlbnNpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RiYnZ4b3g1dTd6IC5jb21taXQtaWQsCiNkYmJ2eG94NXU3eiAuY29tbWl0LW1zZywKI2RiYnZ4b3g1dTd6IC5icmFuY2gtbGFiZWwgewogIGZpbGw6IGxpZ2h0Z3JleTsKICBjb2xvcjogbGlnaHRncmV5OyB9CgoKCiNkYmJ2eG94NXU3eiAubGFiZWx7CiAgY29sb3I6IzE4QjE0RTsKfQojZGJidnhveDV1N3ogLnRlLW1kLWNvbnRhaW5lci0tZGFyayAubm9kZSByZWN0IHsKICBmaWxsOiByZWQ7Cn0KCiNkYmJ2eG94NXU3eiAubm9kZSByZWN0LAojZGJidnhveDV1N3ogLm5vZGUgY2lyY2xlLAojZGJidnhveDV1N3ogLm5vZGUgZWxsaXBzZSwKI2RiYnZ4b3g1dTd6IC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNGOUZGRkI7OwogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDEuNXB4Owp9CiNkYmJ2eG94NXU3eiAuYXJyb3doZWFkUGF0aHsKICBmaWxsOiAjMkRCRDYwOwp9CiNkYmJ2eG94NXU3eiAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDFweDsKfQojZGJidnhveDV1N3ogLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsKfQojZGJidnhveDV1N3ogLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI0Y5RkZGQiAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7Cn0KCiNkYmJ2eG94NXU3eiAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjRjlGRkZCOwp9CgojZGJidnhveDV1N3ogZGl2Lm1lcm1haWRUb29sdGlwIHsKICBiYWNrZ3JvdW5kOiAjRjlGRkZCOwogIGJvcmRlcjogMXB4IHNvbGlkICMyREJENjA7Cn0KCgojZGJidnhveDV1N3ogLmFjdG9yIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RiYnZ4b3g1dTd6IHRleHQuYWN0b3IgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZGJidnhveDV1N3ogLmFjdG9yLWxpbmUgewogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RiYnZ4b3g1dTd6IC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RiYnZ4b3g1dTd6IC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RiYnZ4b3g1dTd6ICNhcnJvd2hlYWQgewogIGZpbGw6ICMyREJENjA7Cn0KCiNkYmJ2eG94NXU3eiAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKfQoKI2RiYnZ4b3g1dTd6IC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkYmJ2eG94NXU3eiAubGFiZWxCb3ggewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZGJidnhveDV1N3ogLmxhYmVsVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkYmJ2eG94NXU3eiAubG9vcFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZGJidnhveDV1N3ogLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZGJidnhveDV1N3ogLm5vdGUgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZGJidnhveDV1N3ogLm5vdGVUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKCiNkYmJ2eG94NXU3eiAuc2VjdGlvbnsKICBvcGFjaXR5OjE7Cn0KI2RiYnZ4b3g1dTd6IC5zZWN0aW9uMCwjZGJidnhveDV1N3ogIC5zZWN0aW9uMiB7CiAgZmlsbDogI0VDRjdGMDsKfQoKI2RiYnZ4b3g1dTd6IC5zZWN0aW9uMSwKI2RiYnZ4b3g1dTd6IC5zZWN0aW9uMyB7CiAgZmlsbDogI0ZGRjsKfQojZGJidnhveDV1N3ogLnRhc2tUZXh0MCwKI2RiYnZ4b3g1dTd6IC50YXNrVGV4dDEsCiNkYmJ2eG94NXU3eiAudGFza1RleHQyLAojZGJidnhveDV1N3ogLnRhc2tUZXh0MyB7CiAgZmlsbDogI2ZmZjsKfQoKI2RiYnZ4b3g1dTd6IC50YXNrMCwKI2RiYnZ4b3g1dTd6IC50YXNrMSwKI2RiYnZ4b3g1dTd6IC50YXNrMiwKI2RiYnZ4b3g1dTd6IC50YXNrMyB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMzNTlGNUE7Cn0KPC9zdHlsZT48c3R5bGU+I2RiYnZ4b3g1dTd6IHsKICAgIGNvbG9yOiByZ2IoMjQ0LCAyNDQsIDI0NCk7CiAgICBmb250OiBub3JtYWwgbm9ybWFsIG5vcm1hbCBub3JtYWwgMTRweC8yMi4zOTk5OTk2MTg1MzAyNzNweCBtb25vc3BhY2U7CiAgfTwvc3R5bGU+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLCAtMTIpIj48ZyBjbGFzcz0ib3V0cHV0Ij48ZyBjbGFzcz0iY2x1c3RlcnMiPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGhzIj48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik05NS43NjU2MjUsNTYuMjgxMjVMOTUuNzY1NjI1LDgxLjI4MTI1TDk1Ljc2NTYyNSwxMDYuMjgxMjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzMxMikiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzMxMiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTk1Ljc2NTYyNSwxNDIuNTYyNUw5NS43NjU2MjUsMTY3LjU2MjVMOTUuNzY1NjI1LDE5Mi41NjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMzMTMpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMzMTMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik05NS43NjU2MjUsMjI4Ljg0Mzc1TDk1Ljc2NTYyNSwyNTMuODQzNzVMOTUuNzY1NjI1LDI3OC44NDM3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMzE0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMzE0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTA5LjY1MDIyMjgwNjIxNTcyLDMxNS4xMjVMMTM1LjAxNTYyNSwzNDguMjY1NjI1TDEzNS4wMTU2MjUsMzgxLjQwNjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMzMTUpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMzMTUiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik04MS44ODEwMjcxOTM3ODQyOCwzMTUuMTI1TDU2LjUxNTYyNSwzNDguMjY1NjI1TDU2LjUxNTYyNSwzOTkuNTQ2ODc1TDU2LjUxNTYyNSw0NDIuNjg3NUw3OS4yNjEwMDcxMDc5MzE5LDQ2Ny42ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMzMTYpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMzMTYiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik05NS43NjU2MjUsNTAzLjk2ODc1TDk1Ljc2NTYyNSw1MjguOTY4NzVMOTUuNzY1NjI1LDU1My45Njg3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMzE3KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMzE3IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMTM1LjAxNTYyNSw0MTcuNjg3NUwxMzUuMDE1NjI1LDQ0Mi42ODc1TDExMi4yNzAyNDI4OTIwNjgxLDQ2Ny42ODc1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMzMTgpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMzMTgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik05NS43NjU2MjUsNTkwLjI1TDk1Ljc2NTYyNSw2MTUuMjVMOTUuNzY1NjI1LDY0MC4yNSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMzE5KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMzE5IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWxzIj48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09IiIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMzUuMDE1NjI1LDM0OC4yNjU2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI3Ljk4NDM3NSIgaGVpZ2h0PSIxNi4yODEyNSIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+WTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTYuNTE1NjI1LDM5OS41NDY4NzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI4LjkzNzUiIGhlaWdodD0iMTYuMjgxMjUiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPk48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWwiIHRyYW5zZm9ybT0iIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj48L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZXMiPjxnIGNsYXNzPSJub2RlIiBpZD0iQSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOTUuNzY1NjI1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMzMuMzY3MTg3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjY2LjczNDM3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIzLjM2NzE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPm1zdGFydDE8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDk1Ljc2NTYyNSwxMjQuNDIxODc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii0zMi4wMTU2MjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI2NC4wMzEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIyLjAxNTYyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+YXNtaW5pdDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iQyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOTUuNzY1NjI1LDIxMC43MDMxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTI1LjgwNDY4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI1MS42MDkzNzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNS44MDQ2ODc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5taW5pdDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOTUuNzY1NjI1LDI5Ni45ODQzNzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTQwLjc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iODEuNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMwLjc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5tID09ICZhbXA7bTA8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEzNS4wMTU2MjUsMzk5LjU0Njg3NSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMzkuMDMxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI3OC4wNjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjkuMDMxMjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPm1zdGFydG0wPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJGIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg5NS43NjU2MjUsNDg1LjgyODEyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMjEuMTA5Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iNDIuMjE4NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMS4xMDkzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmZuKCk8L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgaWQ9IkciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDk1Ljc2NTYyNSw1NzIuMTA5Mzc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii03NS43NjU2MjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxNTEuNTMxMjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02NS43NjU2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmFxdWlyZXAoX2dfLm0ubmV4dHApPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg5NS43NjU2MjUsNjU4LjM5MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMTQuNTg1OTM3NSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjI5LjE3MTg3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQuNTg1OTM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+SDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==

bootstrap阶段是左边的分支,也就是说会执行mstartm0,之后进入调度

  • asminit:调用runtime.goarm来初始化汇编的运行环境,不关系主逻辑,没有关注
  • minit:Linux平台,该函数是对信号处理的一些初始化

mstartm0

在Linux平台上,这个函数会对signal处理做一些初始化,和调度本身没啥关系,所以不予关注。

fn

对于M0,其线程函数是什么?fn即runtime.main。参看runtime.rt0_go

	// create a new goroutine to start program
	MOVW	$runtime·mainPC(SB), R0

runtime.main

PHN2ZyBpZD0iZHFkZmVmbGswcnYiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDEyMy41NDY4NzVweDsiIHZpZXdCb3g9IjAgMCAxMjMuNTQ2ODc1IDM5Ny40MDYyNSI+PHN0eWxlPgoKCiNkcWRmZWZsazBydiAubGFiZWwgewogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgY29sb3I6ICMzMzM7IH0KCiNkcWRmZWZsazBydiAubm9kZSByZWN0LAojZHFkZmVmbGswcnYgLm5vZGUgY2lyY2xlLAojZHFkZmVmbGswcnYgLm5vZGUgZWxsaXBzZSwKI2RxZGZlZmxrMHJ2IC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMXB4OyB9CgojZHFkZmVmbGswcnYgLm5vZGUuY2xpY2thYmxlIHsKICBjdXJzb3I6IHBvaW50ZXI7IH0KCiNkcWRmZWZsazBydiAuYXJyb3doZWFkUGF0aCB7CiAgZmlsbDogIzMzMzMzMzsgfQoKI2RxZGZlZmxrMHJ2IC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMzMzMzMzOwogIHN0cm9rZS13aWR0aDogMS41cHg7IH0KCiNkcWRmZWZsazBydiAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZThlOGU4OyB9CgojZHFkZmVmbGswcnYgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI2ZmZmZkZSAhaW1wb3J0YW50OwogIHN0cm9rZTogI2FhYWEzMyAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7IH0KCiNkcWRmZWZsazBydiAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjMzMzOyB9CgojZHFkZmVmbGswcnYgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1heC13aWR0aDogMjAwcHg7CiAgcGFkZGluZzogMnB4OwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMnB4OwogIGJhY2tncm91bmQ6ICNmZmZmZGU7CiAgYm9yZGVyOiAxcHggc29saWQgI2FhYWEzMzsKICBib3JkZXItcmFkaXVzOiAycHg7CiAgcG9pbnRlci1ldmVudHM6IG5vbmU7CiAgei1pbmRleDogMTAwOyB9CgojZHFkZmVmbGswcnYgLmFjdG9yIHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RxZGZlZmxrMHJ2IHRleHQuYWN0b3IgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RxZGZlZmxrMHJ2IC5hY3Rvci1saW5lIHsKICBzdHJva2U6IGdyZXk7IH0KCiNkcWRmZWZsazBydiAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkcWRmZWZsazBydiAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkcWRmZWZsazBydiAjYXJyb3doZWFkIHsKICBmaWxsOiAjMzMzOyB9CgojZHFkZmVmbGswcnYgI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMzMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMzMzICFpbXBvcnRhbnQ7IH0KCiNkcWRmZWZsazBydiAubWVzc2FnZVRleHQgewogIGZpbGw6ICMzMzM7CiAgc3Ryb2tlOiBub25lOyB9CgojZHFkZmVmbGswcnYgLmxhYmVsQm94IHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2RxZGZlZmxrMHJ2IC5sYWJlbFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RxZGZlZmxrMHJ2IC5sb29wVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHFkZmVmbGswcnYgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOyB9CgojZHFkZmVmbGswcnYgLm5vdGUgewogIHN0cm9rZTogI2FhYWEzMzsKICBmaWxsOiAjZmZmNWFkOyB9CgojZHFkZmVmbGswcnYgLm5vdGVUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDE0cHg7IH0KCiNkcWRmZWZsazBydiAuYWN0aXZhdGlvbjAgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZHFkZmVmbGswcnYgLmFjdGl2YXRpb24xIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2RxZGZlZmxrMHJ2IC5hY3RpdmF0aW9uMiB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCgojZHFkZmVmbGswcnYgLnNlY3Rpb24gewogIHN0cm9rZTogbm9uZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkcWRmZWZsazBydiAuc2VjdGlvbjAgewogIGZpbGw6IHJnYmEoMTAyLCAxMDIsIDI1NSwgMC40OSk7IH0KCiNkcWRmZWZsazBydiAuc2VjdGlvbjIgewogIGZpbGw6ICNmZmY0MDA7IH0KCiNkcWRmZWZsazBydiAuc2VjdGlvbjEsCiNkcWRmZWZsazBydiAuc2VjdGlvbjMgewogIGZpbGw6IHdoaXRlOwogIG9wYWNpdHk6IDAuMjsgfQoKI2RxZGZlZmxrMHJ2IC5zZWN0aW9uVGl0bGUwIHsKICBmaWxsOiAjMzMzOyB9CgojZHFkZmVmbGswcnYgLnNlY3Rpb25UaXRsZTEgewogIGZpbGw6ICMzMzM7IH0KCiNkcWRmZWZsazBydiAuc2VjdGlvblRpdGxlMiB7CiAgZmlsbDogIzMzMzsgfQoKI2RxZGZlZmxrMHJ2IC5zZWN0aW9uVGl0bGUzIHsKICBmaWxsOiAjMzMzOyB9CgojZHFkZmVmbGswcnYgLnNlY3Rpb25UaXRsZSB7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsKICB0ZXh0LWhlaWdodDogMTRweDsgfQoKCiNkcWRmZWZsazBydiAuZ3JpZCAudGljayB7CiAgc3Ryb2tlOiBsaWdodGdyZXk7CiAgb3BhY2l0eTogMC4zOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2RxZGZlZmxrMHJ2IC5ncmlkIHBhdGggewogIHN0cm9rZS13aWR0aDogMDsgfQoKCiNkcWRmZWZsazBydiAudG9kYXkgewogIGZpbGw6IG5vbmU7CiAgc3Ryb2tlOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAycHg7IH0KCgoKI2RxZGZlZmxrMHJ2IC50YXNrIHsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcWRmZWZsazBydiAudGFza1RleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHFkZmVmbGswcnYgLnRhc2tUZXh0T3V0c2lkZVJpZ2h0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHFkZmVmbGswcnYgLnRhc2tUZXh0T3V0c2lkZUxlZnQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBlbmQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgoKI2RxZGZlZmxrMHJ2IC50YXNrVGV4dDAsCiNkcWRmZWZsazBydiAudGFza1RleHQxLAojZHFkZmVmbGswcnYgLnRhc2tUZXh0MiwKI2RxZGZlZmxrMHJ2IC50YXNrVGV4dDMgewogIGZpbGw6IHdoaXRlOyB9CgojZHFkZmVmbGswcnYgLnRhc2swLAojZHFkZmVmbGswcnYgLnRhc2sxLAojZHFkZmVmbGswcnYgLnRhc2syLAojZHFkZmVmbGswcnYgLnRhc2szIHsKICBmaWxsOiAjOGE5MGRkOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2RxZGZlZmxrMHJ2IC50YXNrVGV4dE91dHNpZGUwLAojZHFkZmVmbGswcnYgLnRhc2tUZXh0T3V0c2lkZTIgewogIGZpbGw6IGJsYWNrOyB9CgojZHFkZmVmbGswcnYgLnRhc2tUZXh0T3V0c2lkZTEsCiNkcWRmZWZsazBydiAudGFza1RleHRPdXRzaWRlMyB7CiAgZmlsbDogYmxhY2s7IH0KCgojZHFkZmVmbGswcnYgLmFjdGl2ZTAsCiNkcWRmZWZsazBydiAuYWN0aXZlMSwKI2RxZGZlZmxrMHJ2IC5hY3RpdmUyLAojZHFkZmVmbGswcnYgLmFjdGl2ZTMgewogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZHFkZmVmbGswcnYgLmFjdGl2ZVRleHQwLAojZHFkZmVmbGswcnYgLmFjdGl2ZVRleHQxLAojZHFkZmVmbGswcnYgLmFjdGl2ZVRleHQyLAojZHFkZmVmbGswcnYgLmFjdGl2ZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RxZGZlZmxrMHJ2IC5kb25lMCwKI2RxZGZlZmxrMHJ2IC5kb25lMSwKI2RxZGZlZmxrMHJ2IC5kb25lMiwKI2RxZGZlZmxrMHJ2IC5kb25lMyB7CiAgc3Ryb2tlOiBncmV5OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcWRmZWZsazBydiAuZG9uZVRleHQwLAojZHFkZmVmbGswcnYgLmRvbmVUZXh0MSwKI2RxZGZlZmxrMHJ2IC5kb25lVGV4dDIsCiNkcWRmZWZsazBydiAuZG9uZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2RxZGZlZmxrMHJ2IC5jcml0MCwKI2RxZGZlZmxrMHJ2IC5jcml0MSwKI2RxZGZlZmxrMHJ2IC5jcml0MiwKI2RxZGZlZmxrMHJ2IC5jcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IHJlZDsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkcWRmZWZsazBydiAuYWN0aXZlQ3JpdDAsCiNkcWRmZWZsazBydiAuYWN0aXZlQ3JpdDEsCiNkcWRmZWZsazBydiAuYWN0aXZlQ3JpdDIsCiNkcWRmZWZsazBydiAuYWN0aXZlQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2RxZGZlZmxrMHJ2IC5kb25lQ3JpdDAsCiNkcWRmZWZsazBydiAuZG9uZUNyaXQxLAojZHFkZmVmbGswcnYgLmRvbmVDcml0MiwKI2RxZGZlZmxrMHJ2IC5kb25lQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIGN1cnNvcjogcG9pbnRlcjsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkcWRmZWZsazBydiAuZG9uZUNyaXRUZXh0MCwKI2RxZGZlZmxrMHJ2IC5kb25lQ3JpdFRleHQxLAojZHFkZmVmbGswcnYgLmRvbmVDcml0VGV4dDIsCiNkcWRmZWZsazBydiAuZG9uZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2RxZGZlZmxrMHJ2IC5hY3RpdmVDcml0VGV4dDAsCiNkcWRmZWZsazBydiAuYWN0aXZlQ3JpdFRleHQxLAojZHFkZmVmbGswcnYgLmFjdGl2ZUNyaXRUZXh0MiwKI2RxZGZlZmxrMHJ2IC5hY3RpdmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkcWRmZWZsazBydiAudGl0bGVUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMThweDsKICBmaWxsOiBibGFjazsgfQoKI2RxZGZlZmxrMHJ2IGcuY2xhc3NHcm91cCB0ZXh0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2RxZGZlZmxrMHJ2IGcuY2xhc3NHcm91cCByZWN0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsgfQoKI2RxZGZlZmxrMHJ2IGcuY2xhc3NHcm91cCBsaW5lIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHFkZmVmbGswcnYgLmNsYXNzTGFiZWwgLmJveCB7CiAgc3Ryb2tlOiBub25lOwogIHN0cm9rZS13aWR0aDogMDsKICBmaWxsOiAjRUNFQ0ZGOwogIG9wYWNpdHk6IDAuNTsgfQoKI2RxZGZlZmxrMHJ2IC5jbGFzc0xhYmVsIC5sYWJlbCB7CiAgZmlsbDogIzkzNzBEQjsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkcWRmZWZsazBydiAucmVsYXRpb24gewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7CiAgZmlsbDogbm9uZTsgfQoKI2RxZGZlZmxrMHJ2ICNjb21wb3NpdGlvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcWRmZWZsazBydiAjY29tcG9zaXRpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxZGZlZmxrMHJ2ICNhZ2dyZWdhdGlvblN0YXJ0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcWRmZWZsazBydiAjYWdncmVnYXRpb25FbmQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxZGZlZmxrMHJ2ICNkZXBlbmRlbmN5U3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxZGZlZmxrMHJ2ICNkZXBlbmRlbmN5RW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkcWRmZWZsazBydiAjZXh0ZW5zaW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxZGZlZmxrMHJ2ICNleHRlbnNpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RxZGZlZmxrMHJ2IC5jb21taXQtaWQsCiNkcWRmZWZsazBydiAuY29tbWl0LW1zZywKI2RxZGZlZmxrMHJ2IC5icmFuY2gtbGFiZWwgewogIGZpbGw6IGxpZ2h0Z3JleTsKICBjb2xvcjogbGlnaHRncmV5OyB9CgoKCiNkcWRmZWZsazBydiAubGFiZWx7CiAgY29sb3I6IzE4QjE0RTsKfQojZHFkZmVmbGswcnYgLnRlLW1kLWNvbnRhaW5lci0tZGFyayAubm9kZSByZWN0IHsKICBmaWxsOiByZWQ7Cn0KCiNkcWRmZWZsazBydiAubm9kZSByZWN0LAojZHFkZmVmbGswcnYgLm5vZGUgY2lyY2xlLAojZHFkZmVmbGswcnYgLm5vZGUgZWxsaXBzZSwKI2RxZGZlZmxrMHJ2IC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNGOUZGRkI7OwogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDEuNXB4Owp9CiNkcWRmZWZsazBydiAuYXJyb3doZWFkUGF0aHsKICBmaWxsOiAjMkRCRDYwOwp9CiNkcWRmZWZsazBydiAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDFweDsKfQojZHFkZmVmbGswcnYgLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsKfQojZHFkZmVmbGswcnYgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI0Y5RkZGQiAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7Cn0KCiNkcWRmZWZsazBydiAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHFkZmVmbGswcnYgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBiYWNrZ3JvdW5kOiAjRjlGRkZCOwogIGJvcmRlcjogMXB4IHNvbGlkICMyREJENjA7Cn0KCgojZHFkZmVmbGswcnYgLmFjdG9yIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RxZGZlZmxrMHJ2IHRleHQuYWN0b3IgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZHFkZmVmbGswcnYgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxZGZlZmxrMHJ2IC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxZGZlZmxrMHJ2IC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RxZGZlZmxrMHJ2ICNhcnJvd2hlYWQgewogIGZpbGw6ICMyREJENjA7Cn0KCiNkcWRmZWZsazBydiAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKfQoKI2RxZGZlZmxrMHJ2IC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkcWRmZWZsazBydiAubGFiZWxCb3ggewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHFkZmVmbGswcnYgLmxhYmVsVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkcWRmZWZsazBydiAubG9vcFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHFkZmVmbGswcnYgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHFkZmVmbGswcnYgLm5vdGUgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHFkZmVmbGswcnYgLm5vdGVUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKCiNkcWRmZWZsazBydiAuc2VjdGlvbnsKICBvcGFjaXR5OjE7Cn0KI2RxZGZlZmxrMHJ2IC5zZWN0aW9uMCwjZHFkZmVmbGswcnYgIC5zZWN0aW9uMiB7CiAgZmlsbDogI0VDRjdGMDsKfQoKI2RxZGZlZmxrMHJ2IC5zZWN0aW9uMSwKI2RxZGZlZmxrMHJ2IC5zZWN0aW9uMyB7CiAgZmlsbDogI0ZGRjsKfQojZHFkZmVmbGswcnYgLnRhc2tUZXh0MCwKI2RxZGZlZmxrMHJ2IC50YXNrVGV4dDEsCiNkcWRmZWZsazBydiAudGFza1RleHQyLAojZHFkZmVmbGswcnYgLnRhc2tUZXh0MyB7CiAgZmlsbDogI2ZmZjsKfQoKI2RxZGZlZmxrMHJ2IC50YXNrMCwKI2RxZGZlZmxrMHJ2IC50YXNrMSwKI2RxZGZlZmxrMHJ2IC50YXNrMiwKI2RxZGZlZmxrMHJ2IC50YXNrMyB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMzNTlGNUE7Cn0KPC9zdHlsZT48c3R5bGU+I2RxZGZlZmxrMHJ2IHsKICAgIGNvbG9yOiByZ2IoMjQ0LCAyNDQsIDI0NCk7CiAgICBmb250OiBub3JtYWwgbm9ybWFsIG5vcm1hbCBub3JtYWwgMTRweC8yMi4zOTk5OTk2MTg1MzAyNzNweCBtb25vc3BhY2U7CiAgfTwvc3R5bGU+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLCAtMTIpIj48ZyBjbGFzcz0ib3V0cHV0Ij48ZyBjbGFzcz0iY2x1c3RlcnMiPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGhzIj48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik03My43NzM0Mzc1LDU2LjI4MTI1TDczLjc3MzQzNzUsODEuMjgxMjVMNzMuNzczNDM3NSwxMDYuMjgxMjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzM0MSkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzM0MSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTczLjc3MzQzNzUsMTQyLjU2MjVMNzMuNzczNDM3NSwxNjcuNTYyNUw3My43NzM0Mzc1LDE5Mi41NjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDMzNDIpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDMzNDIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik03My43NzM0Mzc1LDIyOC44NDM3NUw3My43NzM0Mzc1LDI1My44NDM3NUw3My43NzM0Mzc1LDI3OC44NDM3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQzMzQzKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQzMzQzIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNNzMuNzczNDM3NSwzMTUuMTI1TDczLjc3MzQzNzUsMzQwLjEyNUw3My43NzM0Mzc1LDM2NS4xMjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkMzM0NCkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkMzM0NCIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVscyI+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PGcgY2xhc3M9ImVkZ2VMYWJlbCIgdHJhbnNmb3JtPSIiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiIHN0eWxlPSJmaWxsOiNlOGU4ZTg7Ij48L3JlY3Q+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPjwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlcyI+PGcgY2xhc3M9Im5vZGUiIGlkPSJBIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3My43NzM0Mzc1LDM4LjE0MDYyNSkiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNTEiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxMDIiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+cnVudGltZS5tYWluPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3My43NzM0Mzc1LDEyNC40MjE4NzUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTUzLjc3MzQzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxMDcuNTQ2ODc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDMuNzczNDM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+aW5pdCBldmVyeXRoaW5nPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJDIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3My43NzM0Mzc1LDIxMC43MDMxMjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTQ2LjgzNTkzNzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI5My42NzE4NzUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNi44MzU5Mzc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5tYWluLm1haW4oKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBpZD0iRCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzMuNzczNDM3NSwyOTYuOTg0Mzc1KSIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii00OC40Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iOTYuODc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzguNDM3NSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+aGFuZGxlIHBhbmljPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIGlkPSJFIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3My43NzM0Mzc1LDM4My4yNjU2MjUpIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTMwLjAwNzgxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSI2MC4wMTU2MjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMC4wMDc4MTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5leGl0KDApPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PC9zdmc+

这里并没有涉及调度的代码,只是调用了用户定义的main函数。
main函数调用采用间接调用。猜测因为编译runtime的时候还不知道main.main的地址,只能放一个符号在这里,链接的时候再做替换。

	fn := main_main // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime
	fn()

用户main函数退出时,调用exit退出整个程序。

总结

整个bootstrap过程始于rt0_go,终止于runtime.main。至此,用户main函数得到调用,Go的用户态调度器也开始运行了

%E6%9C%AC%E6%96%87%E5%9F%BA%E4%BA%8EGo%201.13%E3%80%82%0A%E6%9C%AC%E4%BA%BA%E9%A6%96%E6%AC%A1%E6%8E%A5%E8%A7%A6golang%EF%BC%8C%E4%B9%9F%E4%B8%8D%E6%98%AFgopher%EF%BC%8C%E4%B8%BB%E8%A6%81%E6%83%B3%E7%A0%94%E7%A9%B6%E4%B8%80%E4%B8%8Bgo%E7%9A%84%E7%94%A8%E6%88%B7%E6%80%81%E8%B0%83%E5%BA%A6%E6%A1%86%E6%9E%B6%E3%80%82%E5%9B%A0%E4%B8%BA%E7%9C%8B%E5%88%B0m0%EF%BC%8Cg0%E5%92%8Cschedinit%EF%BC%8C%E6%89%80%E4%BB%A5%E9%A1%BA%E5%B8%A6%E7%9D%80%E4%B9%9F%E6%8A%8Abootstrap%E8%BF%87%E7%A8%8B%E7%9C%8B%E4%BA%86%E4%B8%80%E4%B8%8B%E3%80%82%E6%97%A2%E7%84%B6%E7%9C%8B%E4%BA%86%EF%BC%8C%E5%B0%B1%E8%AE%B0%E4%B8%80%E7%82%B9%E7%AC%94%E8%AE%B0%E5%90%A7%E3%80%82%E5%8F%A6%E5%A4%96%E6%9C%AC%E6%96%87%E7%B4%A7%E6%89%A3%E4%B8%8E%E8%B0%83%E5%BA%A6%E7%9B%B8%E5%85%B3%E7%9A%84%E4%B8%BB%E9%A2%98%EF%BC%8C%E4%B8%80%E4%BA%9Bgo%E7%9A%84%E5%85%B6%E4%BB%96%E7%89%B9%E6%80%A7%EF%BC%8C%E8%99%BD%E7%84%B6%E9%9D%9E%E5%B8%B8%E6%A3%92%E4%BD%86%E6%98%AF%E4%B8%8D%E5%9C%A8%E6%9C%AC%E6%96%87%E8%AE%A8%E8%AE%BA%E8%8C%83%E5%9B%B4%E3%80%82%E5%8C%85%E6%8B%AC%E4%BD%86%E4%B8%8D%E9%99%90%E4%BA%8E%EF%BC%9A%0A-%20garbage%20collection%0A-%20C%20Go%0A-%20Linux%20signal%E5%A4%84%E7%90%86%0A-%20Trace%E6%93%8D%E4%BD%9C%0A-%20%E6%A0%88%E6%93%8D%E4%BD%9C%0A%0Agolang%E5%92%8C%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E4%B8%80%E6%A0%B7%EF%BC%8C%E7%94%A8%E6%88%B7%E4%BB%A3%E7%A0%81%E7%9A%84%E5%85%A5%E5%8F%A3%E6%98%AF%E7%94%A8%E6%88%B7%E5%AE%9A%E4%B9%89%E7%9A%84main%E5%87%BD%E6%95%B0%E3%80%82%E9%82%A3%E4%B9%88go%E7%A8%8B%E5%BA%8F%E4%BB%8E%E5%90%AF%E5%8A%A8%E5%88%B0main%E5%87%BD%E6%95%B0%E8%BF%90%E8%A1%8C%E4%B9%8B%E9%97%B4%E7%9A%84%E8%BF%87%E7%A8%8B%E5%B0%B1%E6%98%AF%E6%89%80%E8%B0%93%E7%9A%84bootstrap%E8%BF%87%E7%A8%8B%E3%80%82%E7%BD%91%E4%B8%8A%E4%B9%9F%E6%9C%89%E5%A4%A7%E6%8A%8A%E7%9A%84%E8%B5%84%E6%96%99%E4%BB%8B%E7%BB%8D%E8%BF%99%E4%B8%80%E6%B5%81%E7%A8%8B%E3%80%82%E6%9C%AC%E6%96%87%E4%BB%A5%E9%98%85%E8%AF%BBGo%E6%BA%90%E7%A0%81%E4%B8%BA%E4%B8%BB%EF%BC%8C%E6%89%80%E4%BB%A5%E6%9A%82%E4%B8%94%E4%B8%8D%E5%88%97%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%E4%BA%86%E3%80%82%0A%0AGo%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%85%A5%E5%8F%A3%E5%AE%9A%E4%B9%89%E5%9C%A8%60rt0_%3Cos%3E_%3Carch%3E.s%60%2C%E4%BE%8B%E5%A6%82%60rt0_linux_arm.s%60%E3%80%82%E5%85%A5%E5%8F%A3%E5%87%BD%E6%95%B0%E6%98%AF%EF%BC%9A%60_rt0_arm_linux%60%E3%80%82Go%E7%9A%84%E6%B1%87%E7%BC%96%E8%AF%AD%E6%B3%95%E4%B8%8D%E5%90%8C%E4%BA%8E%E5%B8%B8%E8%A7%81%E7%9A%84%E8%AF%AD%E6%B3%95%E6%A0%BC%E5%BC%8F%EF%BC%8C%E5%85%B7%E4%BD%93%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83Go%E5%AE%98%E6%96%B9%E7%BD%91%E9%A1%B5%EF%BC%9A%5BA%20Quick%20Guide%20to%20Go's%20Assembler%5D(https%3A%2F%2Fgolang.org%2Fdoc%2Fasm)%E3%80%82%E6%9C%AC%E6%96%87%E4%B8%8D%E5%81%9A%E8%BF%87%E5%A4%9A%E7%89%B5%E6%B6%89%E5%85%B7%E4%BD%93%E8%AF%AD%E6%B3%95%E7%9A%84%E8%A7%A3%E9%87%8A%E3%80%82%0A%0A%60_rt0_arm_linux%60%E9%80%9A%E8%BF%87%E4%BB%A5%E4%B8%8B%E8%B0%83%E7%94%A8%EF%BC%8C%E8%BF%9B%E5%85%A5runtime%E5%BA%93%E7%9A%84rt0_go%E5%87%BD%E6%95%B0%E3%80%82%60_rt0_arm_linux%60%20--%3E%20%60_rt0_arm_linux1%60%20--%3E%20%60runtime%C2%B7rt0_go%60%0A%0A%23%23%20rt0_go%0A%E8%AF%A5%E5%87%BD%E6%95%B0%E5%81%9A%E4%BA%86%E4%BB%A5%E4%B8%8B%E8%BF%99%E4%BA%9B%E4%BA%8B%E6%83%85%EF%BC%9A%0A1.%20%E7%BB%91%E5%AE%9Am0%2C%20g0%0A%60%60%60asm%0A%09%2F%2F%20set%20up%20g%20register%0A%09%2F%2F%20g%20is%20R10%0A%09MOVW%09%24runtime%C2%B7g0(SB)%2C%20g%0A%09MOVW%09%24runtime%C2%B7m0(SB)%2C%20R8%0A%0A%09%2F%2F%20save%20m-%3Eg0%20%3D%20g0%0A%09MOVW%09g%2C%20m_g0(R8)%0A%09%2F%2F%20save%20g-%3Em%20%3D%20m0%0A%09MOVW%09R8%2C%20g_m(g)%0A%60%60%60%0A2.%20%E8%AE%BE%E7%BD%AEg0%E7%9A%84stackguard0%E5%92%8Cstackguard1%0A3.%20runtime.emptyfunc%0A4.%20runtime.%5C_initcgo%0A5.%20runtime.check%0A6.%20runtime.args%0A7.%20runtime.checkgoarm%0A8.%20runtime.osinit%0A9.%20runtime.shcedinit%0A10.runtime.newproc%E5%88%9B%E5%BB%BAG%E6%9D%A5%E8%BF%90%E8%A1%8Cruntime.main%0A11.runtime.mstart%E6%9D%A5%E8%BF%90%E8%A1%8CM0%EF%BC%8CM0%E8%8E%B7%E5%BE%97%E7%AC%AC%E4%B8%80%E4%B8%AAG%EF%BC%88%E6%B3%A8%E6%84%8F%E4%B8%8D%E6%98%AFg0%EF%BC%89%EF%BC%8C%E6%9D%A5%E8%BF%90%E8%A1%8Cruntime.main%0A%0A%E4%BB%A5%E4%B8%8A%E8%BF%99%E4%B8%80%E5%A0%86%EF%BC%8C%E6%9C%80%E7%BB%88%E8%AE%A9runtime.main%E8%BF%90%E8%A1%8C%E8%B5%B7%E6%9D%A5%EF%BC%8Cruntime.main%E4%BC%9A%E8%B0%83%E7%94%A8%E7%94%A8%E6%88%B7%E7%9A%84main%E5%87%BD%E6%95%B0%EF%BC%8C%E5%8D%B3main%5C_main%E6%88%96%E8%80%85%E5%8F%ABmain.main%E3%80%82%0A%E5%8F%A6%E5%A4%96%E5%A4%A7%E5%A4%9A%E6%95%B0%E7%9A%84%E4%BB%A3%E7%A0%81%E9%83%BD%E6%98%AF%E4%B8%BA%E4%BA%86%E5%81%9A%E4%B8%80%E4%BA%9B%E6%A3%80%E6%9F%A5%EF%BC%8C%E4%BB%A5%E5%8F%8A%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%BA%A7%E5%88%AB%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%82%E7%89%B9%E5%88%AB%E5%80%BC%E5%BE%97%E5%85%B3%E6%B3%A8%E7%9A%84%E6%98%AFruntime.schedinit%2C%20runtime.newproc%E4%BB%A5%E5%8F%8Aruntime.mstart%E3%80%82%0A%E5%88%9B%E5%BB%BAG%E7%9A%84newproc%E5%92%8C%E8%BF%90%E8%A1%8CM%E7%9A%84mstart%E9%83%BD%E6%98%AF%E9%80%9A%E7%94%A8%E5%87%BD%E6%95%B0%EF%BC%8C%E4%B8%8D%E5%85%89%E6%98%AF%E5%9C%A8bootstrap%E8%BF%87%E7%A8%8B%E4%B8%AD%E4%BD%BF%E7%94%A8%E3%80%82%E5%9C%A8%E8%B0%83%E5%BA%A6%E5%99%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E5%88%9B%E5%BB%BAG%E5%92%8C%E8%BF%90%E8%A1%8CM%E9%83%BD%E6%98%AF%E4%BD%BF%E7%94%A8%E8%BF%99%E4%B8%A4%E4%B8%AA%E5%87%BD%E6%95%B0%E3%80%82%0Arto_go%E6%98%AFbootstrap%E7%9A%84%E6%80%BB%E7%BA%B2%E3%80%82%E5%AE%83%E8%B0%83%E7%94%A8%E5%90%84%E4%B8%AA%E5%87%BD%E6%95%B0%EF%BC%8C%E6%9C%80%E7%BB%88%E8%BF%9B%E5%85%A5%E7%94%A8%E6%88%B7%E7%9A%84main%E5%87%BD%E6%95%B0%E8%BF%90%E8%A1%8C%E3%80%82%0A%0A%23%23%20schedinit%0Aschedinit%E5%AF%B9%E8%B0%83%E5%BA%A6%E5%99%A8%E5%81%9A%E4%BA%86%E5%9F%BA%E6%9C%AC%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%2C%E6%91%98%E5%87%BA%E4%B8%A4%E4%B8%AA%E5%8F%AF%E8%83%BD%E4%B8%8E%E8%B0%83%E5%BA%A6%E7%9B%B8%E5%85%B3%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%9A%0A-%20mcommoninit%0A-%20procresize%0A%0A%E5%89%8D%E8%80%85%E5%85%B6%E5%AE%9E%E4%B9%9F%E6%B2%A1%E5%81%9A%E5%95%A5%E4%BA%8B%E5%84%BF%EF%BC%8C%E8%B0%83%E7%94%A8%E4%BA%86mpreinit%E5%88%86%E9%85%8D%E4%BA%86%E4%B8%8Esignal%E7%9B%B8%E5%85%B3%E7%9A%84%E6%A0%88%E5%8F%82%E6%95%B0gsignal%EF%BC%8C%E4%B8%8E%E8%B0%83%E5%BA%A6%E5%AE%9E%E6%B2%A1%E5%A4%9A%E5%A4%A7%E5%85%B3%E7%B3%BB%EF%BC%8C%E6%9A%82%E6%97%B6%E7%95%A5%E8%BF%87%E3%80%82%E5%90%8E%E8%80%85%E5%B0%B1%E6%AF%94%E8%BE%83%E9%87%8D%E8%A6%81%E4%BA%86%E3%80%82%0A%23%23%23%20procresize%0A%E6%9C%AC%E5%87%BD%E6%95%B0%E5%85%B6%E5%AE%9E%E6%98%AF%E5%AF%B9%E6%95%B4%E4%B8%AAapp%E9%87%8C%E7%9A%84P%E5%81%9A%E4%BA%86%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%82%E5%85%88%E7%9C%8B%E8%B0%83%E7%94%A8%EF%BC%9A%0A%60%60%60go%0Aprocs%20%3A%3D%20ncpu%20%2F%2F%20ncpu%E5%9C%A8osinit%E4%B8%AD%E8%B5%8B%E5%80%BC%EF%BC%8Cncpu%20%3D%20getncpu()%0Aif%20n%2C%20ok%20%3A%3D%20atoi32(gogetenv(%22GOMAXPROCS%22))%3B%20ok%20%26%26%20n%20%3E%200%20%7B%0A%20%20%20%20procs%20%3D%20n%0A%7D%0Aif%20procresize(procs)%20!%3D%20nil%20%7B%0A%20%20%20%20throw(%22unknown%20runnable%20goroutine%20during%20bootstrap%22)%0A%7D%0A%60%60%60%0A%E8%BF%99%E9%87%8C%E6%A0%B9%E6%8D%AE%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%60GOMAXPROCS%60%E5%AF%B9ncpu%E8%BF%9B%E8%A1%8C%E4%BA%86%E6%9B%B4%E6%96%B0%E3%80%82procs%E9%80%BB%E8%BE%91%E4%B8%8A%E5%B0%B1%E5%AF%B9%E5%BA%94%E4%BA%86P%E7%9A%84%E4%B8%AA%E6%95%B0%E3%80%82%0A%60%60%60mermaid%0Agraph%20TD%0AA(%22func%20procresize(nprocs%20int32)%20*p%22)%20--%3E%7C%20%7C%20B%7B%22nprocs%20%3E%20len(allp)%3F%22%7D%0AB%20--%3E%20%7CY%7C%20C%7B%22nprocs%20%3C%3D%20cap%5Ballp%5D%20%3F%22%7D%0AC%20--%3E%7CY%7C%20D%5B%22allp%E5%A4%9F%E5%A4%A7%2C%20allp%3Dallp%5B%3Anprocs%5D%22%5D%0AC%20--%3E%7CN%7C%20E%5Ballp%E4%B8%8D%E5%A4%9F%E5%A4%A7%2C%E7%94%A8make%E6%9D%A5%E7%94%B3%E8%AF%B7%E6%96%B0%E7%9A%84allp%E6%95%B0%E7%BB%84%5D%0AB%20--%3E%20%7CN%7C%20F%5Bloop%20allp%20and%20init%20each%5D%0AD%20--%3E%20F%0AE%20--%3E%20F%0AF%20--%3E%20%7C%20%7C%20G%7Bcurrent%20G%20has%20P%3F%7D%0AG%20--%3E%20%7CY%7C%20H%5BP.status%20%3D%20_Prunning%5D%0AG%20--%3E%20%7CN%7C%20I%5B%22M%E4%B8%8Eallp%5B0%5D%E7%BB%91%E5%AE%9A%22%5D%0AI%20--%3E%20J%5B%E9%87%8A%E6%94%BEallp%E4%B8%ADnprocs%E4%BB%A5%E5%90%8E%E7%94%A8%E4%B8%8D%E7%9D%80%E7%9A%84P%5D%0AH%20--%3E%20J%0AJ%20--%3E%20K%5B%22%E5%A6%82%E6%9E%9C!runqempty(p)%2C%E5%88%99%E4%B8%8EM%E7%BB%91%E5%AE%9A%EF%BC%8C%E5%90%A6%E5%88%99pidleput(p)%22%5D%0A%60%60%60%0A%0A-%20type%20p%2Cm%2Cg%E9%83%BD%E5%AE%9A%E4%B9%89%E5%9C%A8runtime%2Fruntime2.go%E4%B8%AD%EF%BC%8Callp%E6%95%B0%E7%BB%84%E4%B9%9F%E5%AE%9A%E4%B9%89%E5%9C%A8%E8%AF%A5%E6%96%87%E4%BB%B6%E4%B8%AD%0A-%20len%E8%A1%A8%E7%A4%BA%E5%BD%93%E5%89%8Dslice%E7%9A%84%E9%95%BF%E5%BA%A6%EF%BC%8Ccap%E8%A1%A8%E7%A4%BA%E8%AF%A5slice%E6%89%80%E5%9C%A8%E6%95%B0%E7%BB%84%E8%83%BD%E5%AE%B9%E7%BA%B3%E7%9A%84%E6%9C%80%E5%A4%9A%E7%9A%84%E6%88%90%E5%91%98%E6%95%B0%0A-%20pp-%3Einit(id)%E4%B9%9F%E6%98%AF%E5%AE%9A%E4%B9%89%E5%9C%A8proc.go%E4%B8%AD%EF%BC%8C%E5%AF%B9P%E5%81%9A%E5%88%9D%E5%A7%8B%E5%8C%96%0A-%20P%E4%B8%8EM%E5%9C%A8%E8%BF%99%E9%87%8C%E5%AE%8C%E6%88%90%E4%BA%86%E7%BB%91%E5%AE%9A%EF%BC%8C%E4%B8%BA%E4%B9%8B%E5%90%8Emstart%E5%81%9A%E5%A5%BD%E4%BA%86%E5%87%86%E5%A4%87%0A%0A%23%23%20runtime.newproc%0A%E8%BF%99%E9%87%8C%E7%9E%84%E5%87%86%E7%9A%84%E6%98%AFbootstrap%E9%98%B6%E6%AE%B5%E7%9A%84newproc%E3%80%82%0Anewproc%E7%9A%84%E8%B0%83%E7%94%A8%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60asm%0A%09%2F%2F%20create%20a%20new%20goroutine%20to%20start%20program%0A%09MOVW%09%24runtime%C2%B7mainPC(SB)%2C%20R0%0A%09MOVW.W%09R0%2C%20-4(R13)%0A%09MOVW%09%248%2C%20R0%0A%09MOVW.W%09R0%2C%20-4(R13)%0A%09MOVW%09%240%2C%20R0%0A%09MOVW.W%09R0%2C%20-4(R13)%09%2F%2F%20push%20%240%20as%20guard%0A%09BL%09runtime%C2%B7newproc(SB)%0A%60%60%60%0AmainPC%E6%98%AF%E6%8C%87%E5%90%91runtime.main%E5%87%BD%E6%95%B0%E7%9A%84%E6%8C%87%E9%92%88%E3%80%82%E6%89%80%E4%BB%A5newproc%E6%98%AF%E4%B8%BA%E8%BF%99%E4%B8%AA%E5%87%BD%E6%95%B0%E5%88%9B%E5%BB%BAG%EF%BC%8C%E5%B9%B6%E6%8C%82%E5%9C%A8%E5%88%B0%E4%B8%80%E4%B8%AAP%E4%B8%8A%E8%BF%90%E8%A1%8C%E3%80%82%0Anewproc%E6%98%AFnewproc1%E7%9A%84wrapper%EF%BC%8C%E4%B8%BAnewproc1%E5%87%86%E5%A4%87%E4%BA%86callergp%E5%92%8Ccallerpc%E3%80%82newproc1%E5%9C%A8systemstack%E4%B8%8A%E8%BF%90%E8%A1%8C%E3%80%82%0A%23%23%23%20systemstack%0Asystemstack%E7%9A%84%E8%AF%AD%E6%84%8F%E6%98%AF%E5%9C%A8%E7%B3%BB%E7%BB%9F%E6%A0%88%E4%B8%8A%E8%BF%90%E8%A1%8C%E5%87%BD%E6%95%B0fn%E3%80%82%0A-%20%E5%A6%82%E6%9E%9C%E5%BD%93%E5%89%8D%E6%A0%88%E6%8C%87%E9%92%88%E6%98%AF%E5%9C%A8g0%E6%A0%88%E6%88%96%E8%80%85gsignal%E6%A0%88%E4%B8%8A%EF%BC%8C%E5%88%99%E7%9B%B4%E6%8E%A5%E8%B0%83%E7%94%A8fn%E5%87%BD%E6%95%B0%E7%84%B6%E5%90%8E%E8%BF%94%E5%9B%9E%E3%80%82%0A-%20%E5%90%A6%E5%88%99%EF%BC%8Csystemstack%E5%B0%86%E5%88%87%E6%8D%A2%E5%88%B0g0%E6%A0%88%E4%B8%8A%E8%B0%83%E7%94%A8%20fn%E7%84%B6%E5%90%8E%E5%88%87%E6%8D%A2%E5%9B%9E%E6%9D%A5%E3%80%82%0A%60%60%60asm%0A%2F%2F%20func%20systemstack(fn%20func())%0ATEXT%20runtime%C2%B7systemstack(SB)%2CNOSPLIT%2C%240-4%0A%09MOVW%09fn%2B0(FP)%2C%20R0%09%2F%2F%20R0%20%3D%20fn%0A%09MOVW%09g_m(g)%2C%20R1%09%2F%2F%20R1%20%3D%20m%0A%0A%09MOVW%09m_gsignal(R1)%2C%20R2%09%2F%2F%20R2%20%3D%20gsignal%0A%09CMP%09g%2C%20R2%0A%09B.EQ%09noswitch%0A%0A%09MOVW%09m_g0(R1)%2C%20R2%09%2F%2F%20R2%20%3D%20g0%0A%09CMP%09g%2C%20R2%0A%09B.EQ%09noswitch%0A%0A%09MOVW%09m_curg(R1)%2C%20R3%0A%09CMP%09g%2C%20R3%0A%09B.EQ%09switch%0A%60%60%60%0A%E8%BF%99%E4%B8%80%E6%AE%B5%E5%B0%B1%E6%98%AF%E5%9C%A8%E5%88%A4%E6%96%AD%E5%BD%93%E5%89%8Dg%E6%A0%88%E6%8C%87%E9%92%88%E7%9A%84%E4%BD%8D%E7%BD%AE%EF%BC%8C%E5%8F%AA%E5%9C%A8%E6%9C%80%E5%90%8E%E4%B8%80%E7%A7%8D%E6%83%85%E5%86%B5%E4%B8%8B%E6%89%8Dswitch%E3%80%82switch%E5%8D%B3%E5%B0%86%E6%A0%88%E6%8C%87%E9%92%88%E5%88%87%E6%8D%A2%E5%88%B0g0%E6%A0%88%E3%80%82%0A%E6%AD%A4%E5%A4%84g%2C%20g_m%2C%20m_curg%EF%BC%8C%E9%83%BD%E6%98%AF%E5%8F%98%E9%87%8F%E7%9A%84%E8%A1%A8%E7%A4%BA%E6%96%B9%E6%B3%95%EF%BC%8C%E4%B8%8B%E5%88%92%E7%BA%BF%E8%A1%A8%E7%A4%BA'.'%E3%80%82%E5%8D%B3%EF%BC%9A%0A-%20g%E8%A1%A8%E7%A4%BA%E5%BD%93%E5%89%8Dg%EF%BC%8Cbootstrap%E9%98%B6%E6%AE%B5%E5%B0%B1%E6%98%AFg0%0A-%20g_m%E8%A1%A8%E7%A4%BAg.m%0A-%20m_curg%E8%A1%A8%E7%A4%BAm.curg%0A%0A%E4%B8%8A%E9%9D%A2%E8%BF%99%E6%AE%B5snip%E4%B8%AD%EF%BC%8Cg%E5%AE%9E%E9%99%85%E4%B8%8A%E5%B0%B1%E6%98%AFg%E7%9A%84%E6%A0%88%E6%8C%87%E9%92%88%EF%BC%8C%E5%9B%A0%E4%B8%BA%E6%A0%88%E6%8C%87%E9%92%88%E6%98%AFg%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%8F%82%E6%95%B0%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83runtime2.go%E4%B8%ADtype%20g%E7%9A%84%E5%AE%9A%E4%B9%89%E3%80%82%E5%8F%82%E7%9C%8B%EF%BC%9A%0A%60%60%60go%0Atype%20g%20struct%20%7B%0A%09%2F%2F%20Stack%20parameters.%0A%09%2F%2F%20stack%20describes%20the%20actual%20stack%20memory%3A%20%5Bstack.lo%2C%20stack.hi).%0A%09%2F%2F%20stackguard0%20is%20the%20stack%20pointer%20compared%20in%20the%20Go%20stack%20growth%20prologue.%0A%09%2F%2F%20It%20is%20stack.lo%2BStackGuard%20normally%2C%20but%20can%20be%20StackPreempt%20to%20trigger%20a%20preemption.%0A%09%2F%2F%20stackguard1%20is%20the%20stack%20pointer%20compared%20in%20the%20C%20stack%20growth%20prologue.%0A%09%2F%2F%20It%20is%20stack.lo%2BStackGuard%20on%20g0%20and%20gsignal%20stacks.%0A%09%2F%2F%20It%20is%20~0%20on%20other%20goroutine%20stacks%2C%20to%20trigger%20a%20call%20to%20morestackc%20(and%20crash).%0A%09stack%20%20%20%20%20%20%20stack%20%20%20%2F%2F%20offset%20known%20to%20runtime%2Fcgo%0A%09stackguard0%20uintptr%20%2F%2F%20offset%20known%20to%20liblink%0A%09stackguard1%20uintptr%20%2F%2F%20offset%20known%20to%20liblink%0A...%0A%7D%0A%60%60%60%0A%0A%23%23%23%20newproc1%0A%60%60%60mermaid%0Agraph%20TD%0AA%5Bnewproc1%5D%20--%3E%20B(aquirem)%0AB%20--%3E%20C%5B%22gfget(_p_)%22%5D%0AC%20--%3E%7Cnewg%20%3D%3D%20nil%7C%20D%5B%22malg(_Stackmin)%22%5D%0AC%20--%3E%20E%5Binit%20newg%5D%0AD%20--%3E%20E%0AE%20--%3E%20F%5B_Gdead%3D%3E_Grunable%5D%0AF%20--%3E%20G%5B%22runqput(_p_%2C%20newg%2C%20true)%22%5D%0AG%20--%3E%20H%7Bhas%20idle%20P%20%26%26%20no%20spinning%20M%7D%0AH%20--%3E%20%7CY%7C%20I%5Bwakep%5D%0AH%20--%3E%20%7CN%7C%20J%5Breleasem%5D%0AI%20--%3E%20K(return)%0AJ%20--%3E%20K%0A%60%60%60%0A%E4%BB%A5%E4%B8%8A%E7%9A%84%E6%B5%81%E7%A8%8B%E8%BF%98%E6%98%AF%E6%AF%94%E8%BE%83%E6%B8%85%E6%A5%9A%E7%9A%84%E3%80%82%E5%9C%A8%E6%9C%89free%20G%E7%9A%84%E6%97%B6%E5%80%99%E8%8E%B7%E5%8F%96%E4%B9%8B%EF%BC%8C%E5%90%A6%E5%88%99malg%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AAG%E3%80%82G%E5%9C%A8%E5%88%9B%E5%BB%BA%E5%87%BA%E6%9D%A5%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E7%8A%B6%E6%80%81%E4%B8%BA_Gdead%2C%E5%88%9D%E5%A7%8B%E5%8C%96%E4%BB%A5%E5%90%8E%E6%98%AF_Grunnable%E3%80%82%0Aaquirem%E5%92%8Creleasem%E7%9A%84%E6%84%8F%E4%B9%89%E6%B2%A1%E7%9C%8B%E6%98%8E%E7%99%BD%E3%80%82%E6%8C%89%E7%85%A7%E6%B3%A8%E9%87%8A%E7%9A%84%E6%84%8F%E6%80%9D%E6%98%AF%EF%BC%8C%E9%98%BB%E6%AD%A2%E6%8A%A2%E5%8D%A0%E3%80%82%0A%3E**aquirem**%3A%20disable%20preemption%20because%20it%20can%20be%20holding%20p%20in%20a%20local%20var%0A%0A%E6%9C%89%E7%82%B9%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0%E7%9A%84%E6%84%9F%E8%A7%89%E3%80%82%0A%0A%23%23%20runtime.mstart%0Amstart%E8%B4%9F%E8%B4%A3%E8%BF%90%E8%A1%8CM%EF%BC%8C%E5%9C%A8bootstrap%E9%98%B6%E6%AE%B5%E8%BF%99%E9%87%8Cstart%E7%9A%84%E5%AE%9E%E9%99%85%E4%B8%8A%E6%98%AFM0%E3%80%82%0A%E4%B8%8Enewproc%E7%B1%BB%E4%BC%BC%EF%BC%8Cmstart%E6%98%AFmstart1%E7%9A%84%E5%B0%81%E8%A3%85%E3%80%82mstart%E4%B8%BA%E8%BF%90%E8%A1%8Cmstart1%E5%81%9A%E4%B8%80%E4%BA%9B%E5%87%86%E5%A4%87%EF%BC%8C%E4%B8%BB%E8%A6%81%E6%98%AFm.g0%E6%A0%88%E5%8C%BA%E6%95%B0%E6%8D%AE%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%82%E5%BD%93%E8%BF%9B%E5%85%A5mstart1%E8%BF%90%E8%A1%8C%E5%90%8E%EF%BC%8C%E5%87%BD%E6%95%B0%E5%86%8D%E4%B9%9F%E4%B8%8D%E4%BC%9A%E8%BF%94%E5%9B%9E%EF%BC%8C%E5%9B%A0%E4%B8%BA%E8%BF%99%E9%87%8C%E9%9D%A2%E4%BC%9A%E8%B0%83%E7%94%A8%E8%B0%83%E5%BA%A6%E5%99%A8%E7%9A%84schedule%E5%87%BD%E6%95%B0%E3%80%82%E5%A6%82%E6%9E%9C%E5%87%BD%E6%95%B0%E8%BF%94%E5%9B%9E%E5%88%B0%E8%BF%99%E9%87%8C%EF%BC%8C%E8%AF%B4%E6%98%8E%E5%86%8D%E4%B9%9F%E6%B2%A1%E6%9C%89%E4%B8%9C%E8%A5%BF%E9%9C%80%E8%A6%81%E8%BF%90%E8%A1%8C%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%88%B0%E8%BE%BEmain%E5%87%BD%E6%95%B0%E7%BB%93%E5%B0%BE%EF%BC%8C%E7%A8%8B%E5%BA%8F%E8%A6%81%E9%80%80%E5%87%BA%E3%80%82%E8%BF%99%E4%B9%9F%E6%98%AFmexit%E7%9A%84%E8%AF%AD%E6%84%8F%E3%80%82%E5%9C%A8Linux%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%B0%B1%E6%98%AF%E8%B0%83%E7%94%A8SYS_exit%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E6%9D%A5%E9%80%80%E5%87%BA%E7%A8%8B%E5%BA%8F%E3%80%82%0Amstart%20--%3E%20mexit%20--%3E%20exitThread%0ALinux%E5%B9%B3%E5%8F%B0%E7%9A%84exitThread%E5%AE%9A%E4%B9%89%E5%9C%A8runtime%2Fsys_linux_arm.s%E4%B8%AD%EF%BC%8C%E6%98%AF%E4%B8%80%E4%B8%AA%E6%B1%87%E7%BC%96%E5%87%BD%E6%95%B0%E3%80%82%0A%60%60%60asm%0A%2F%2F%20func%20exitThread(wait%20*uint32)%0ATEXT%20runtime%C2%B7exitThread(SB)%2CNOSPLIT%7CNOFRAME%2C%240-4%0A%09MOVW%09wait%2B0(FP)%2C%20R0%0A%09%2F%2F%20We're%20done%20using%20the%20stack.%0A%09%2F%2F%20Alas%2C%20there's%20no%20reliable%20way%20to%20make%20this%20write%20atomic%0A%09%2F%2F%20without%20potentially%20using%20the%20stack.%20So%20it%20goes.%0A%09MOVW%09%240%2C%20R1%0A%09MOVW%09R1%2C%20(R0)%0A%09MOVW%09%240%2C%20R0%09%2F%2F%20exit%20code%0A%09MOVW%09%24SYS_exit%2C%20R7%0A%09SWI%09%240%0A%60%60%60%0A%E5%8F%AF%E8%A7%81%E6%9C%80%E7%BB%88%E8%B0%83%E7%94%A8%E7%9A%84SYS_exit%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%AE%BE%E7%BD%AE%E4%BA%86%E8%BF%94%E5%9B%9E%E5%80%BC%E3%80%82%0A%0A%23%23%23%20mstart1%0A%60%60%60mermaid%0Agraph%20TD%0AA%5Bmstart1%5D%20--%3E%20B%5Basminit%5D%0AB%20--%3E%20C%5Bminit%5D%0AC%20--%3E%20D%5Bm%20%3D%3D%20%26m0%5D%0AD%20--%3E%7CY%7C%20E%5Bmstartm0%5D%0AD%20--%3E%7CN%7C%20F%5B%22fn()%22%5D%0AF%20--%3E%20G%5B%22aquirep(_g_.m.nextp)%22%5D%0AE%20--%3E%20F%0AG%20--%3E%20H%0A%60%60%60%0Abootstrap%E9%98%B6%E6%AE%B5%E6%98%AF%E5%B7%A6%E8%BE%B9%E7%9A%84%E5%88%86%E6%94%AF%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AF%E8%AF%B4%E4%BC%9A%E6%89%A7%E8%A1%8Cmstartm0%EF%BC%8C%E4%B9%8B%E5%90%8E%E8%BF%9B%E5%85%A5%E8%B0%83%E5%BA%A6%0A%0A-%20asminit%EF%BC%9A%E8%B0%83%E7%94%A8runtime.goarm%E6%9D%A5%E5%88%9D%E5%A7%8B%E5%8C%96%E6%B1%87%E7%BC%96%E7%9A%84%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83%EF%BC%8C%E4%B8%8D%E5%85%B3%E7%B3%BB%E4%B8%BB%E9%80%BB%E8%BE%91%EF%BC%8C%E6%B2%A1%E6%9C%89%E5%85%B3%E6%B3%A8%0A-%20minit%EF%BC%9ALinux%E5%B9%B3%E5%8F%B0%EF%BC%8C%E8%AF%A5%E5%87%BD%E6%95%B0%E6%98%AF%E5%AF%B9%E4%BF%A1%E5%8F%B7%E5%A4%84%E7%90%86%E7%9A%84%E4%B8%80%E4%BA%9B%E5%88%9D%E5%A7%8B%E5%8C%96%0A%0A%23%23%23%20mstartm0%0A%E5%9C%A8Linux%E5%B9%B3%E5%8F%B0%E4%B8%8A%EF%BC%8C%E8%BF%99%E4%B8%AA%E5%87%BD%E6%95%B0%E4%BC%9A%E5%AF%B9signal%E5%A4%84%E7%90%86%E5%81%9A%E4%B8%80%E4%BA%9B%E5%88%9D%E5%A7%8B%E5%8C%96%EF%BC%8C%E5%92%8C%E8%B0%83%E5%BA%A6%E6%9C%AC%E8%BA%AB%E6%B2%A1%E5%95%A5%E5%85%B3%E7%B3%BB%EF%BC%8C%E6%89%80%E4%BB%A5%E4%B8%8D%E4%BA%88%E5%85%B3%E6%B3%A8%E3%80%82%0A%0A%23%23%23%20fn%0A%E5%AF%B9%E4%BA%8EM0%EF%BC%8C%E5%85%B6%E7%BA%BF%E7%A8%8B%E5%87%BD%E6%95%B0%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9Ffn%E5%8D%B3runtime.main%E3%80%82%E5%8F%82%E7%9C%8Bruntime.rt0_go%0A%60%60%60asm%0A%09%2F%2F%20create%20a%20new%20goroutine%20to%20start%20program%0A%09MOVW%09%24runtime%C2%B7mainPC(SB)%2C%20R0%0A%60%60%60%0A%0A%23%23%20runtime.main%0A%60%60%60mermaid%0Agraph%20TD%0AA%5Bruntime.main%5D%20--%3E%20B%5Binit%20everything%5D%0AB%20--%3E%20C%5B%22main.main()%22%5D%0AC%20--%3E%20D%5Bhandle%20panic%5D%0AD%20--%3E%20E%5B%22exit(0)%22%5D%0A%60%60%60%0A%E8%BF%99%E9%87%8C%E5%B9%B6%E6%B2%A1%E6%9C%89%E6%B6%89%E5%8F%8A%E8%B0%83%E5%BA%A6%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%8F%AA%E6%98%AF%E8%B0%83%E7%94%A8%E4%BA%86%E7%94%A8%E6%88%B7%E5%AE%9A%E4%B9%89%E7%9A%84main%E5%87%BD%E6%95%B0%E3%80%82%0Amain%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E9%87%87%E7%94%A8%E9%97%B4%E6%8E%A5%E8%B0%83%E7%94%A8%E3%80%82%E7%8C%9C%E6%B5%8B%E5%9B%A0%E4%B8%BA%E7%BC%96%E8%AF%91runtime%E7%9A%84%E6%97%B6%E5%80%99%E8%BF%98%E4%B8%8D%E7%9F%A5%E9%81%93main.main%E7%9A%84%E5%9C%B0%E5%9D%80%EF%BC%8C%E5%8F%AA%E8%83%BD%E6%94%BE%E4%B8%80%E4%B8%AA%E7%AC%A6%E5%8F%B7%E5%9C%A8%E8%BF%99%E9%87%8C%EF%BC%8C%E9%93%BE%E6%8E%A5%E7%9A%84%E6%97%B6%E5%80%99%E5%86%8D%E5%81%9A%E6%9B%BF%E6%8D%A2%E3%80%82%0A%60%60%60go%0A%09fn%20%3A%3D%20main_main%20%2F%2F%20make%20an%20indirect%20call%2C%20as%20the%20linker%20doesn't%20know%20the%20address%20of%20the%20main%20package%20when%20laying%20down%20the%20runtime%0A%09fn()%0A%60%60%60%0A%E7%94%A8%E6%88%B7main%E5%87%BD%E6%95%B0%E9%80%80%E5%87%BA%E6%97%B6%EF%BC%8C%E8%B0%83%E7%94%A8exit%E9%80%80%E5%87%BA%E6%95%B4%E4%B8%AA%E7%A8%8B%E5%BA%8F%E3%80%82%0A%0A%23%23%20%E6%80%BB%E7%BB%93%0A%E6%95%B4%E4%B8%AAbootstrap%E8%BF%87%E7%A8%8B%E5%A7%8B%E4%BA%8Ert0_go%EF%BC%8C%E7%BB%88%E6%AD%A2%E4%BA%8Eruntime.main%E3%80%82%E8%87%B3%E6%AD%A4%EF%BC%8C%E7%94%A8%E6%88%B7main%E5%87%BD%E6%95%B0%E5%BE%97%E5%88%B0%E8%B0%83%E7%94%A8%EF%BC%8CGo%E7%9A%84%E7%94%A8%E6%88%B7%E6%80%81%E8%B0%83%E5%BA%A6%E5%99%A8%E4%B9%9F%E5%BC%80%E5%A7%8B%E8%BF%90%E8%A1%8C%E4%BA%86%0A%0A%0A

曾经看过一种说法,写代码最难的是命名,当时不能理解。这么多年写下来,发现真的是这样,一个好的变量名或者函数名,要简短,又要反应足够的逻辑。确实很难,并不是一句玩笑话。
与此类似的是,如何写好一个函数,也不是那么简单的。曾经我们认为不管代码写成什么样,只要能做到最后的功能,它们就都是一样的。真的是这样吗?
就好比,围棋的布局阶段。你可以说,不管布局怎么下,只要最后赢棋就可以了。但如果布局阶段失败,会让你的中盘官子处处被动。败局从一开始就注定了的。
写代码也是这样,虽然函数可以想怎么写就怎么写,虽然最后的功能可以实现,但是后续的阅读,扩展,重构会越来越困难。最终积重难返,败局也是从一开始就注定了的。
那么如何真正的写好一个函数呢?Uncle Bob用他的经验,给了我们很多操作性很高的指导。

什么样是一个好的函数?

本文完全是Clean Code一书Function一章的摘录。有些加入了我一些自己的认识。本文可以作为文摘阅读,具体可以查阅原文。

small!

Functions should hardly ever be 20 lines long.

Uncle Bob心目中理想的函数的样子:

Every function in this program was just two, or three, or four lines long.

  • Each was transparently obvious. Each told a story.
  • And each led you to the next in a compelling order.

That’s how short your functions should be!

实际上,我们很难做到一个函数只有2~4行,尤其像C语言这样强类型的非OO语言。如果刻意的为了短而短,牺牲了可读性,倒是没什么必要。但以我的经验做到不超过20行还是可以做到的。而且应该做到。

Blocks and Indenting

这个是说应该有一个良好且统一的编程格式风格。这个在我经历的公司已经都达成了共识了。所以不再赘述。

Do One Thing

我们知道设计模式中有一个SRP(Single Response Principle)原则。函数也应该符合SRP原则。

FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY.

但其实这句话说起来简单,做起来还是很不容易的。

If a function does only those steps that are one level below the stated name of the function, then the function is doing one thing. After all, the reason we write functions is to decompose a larger concept (in other words, the name of the function) into a set of steps at the next level of abstraction.

也就是说,一个函数只对其名称描述的功能做一层分解。
例如:

void handle_command(unsigned char *buf, size_t size)
{
    if (0 = strcmp(buf, "cmd1")) {
        int i = sizeof(struct header);
        buf[i] = 1;
        buf[i+1] = 2;
    }
}

这里应该当判断到命令是cmd1时,不应当在内联命令处理的代码,因为这已经是2级抽象了,应当是:

void handle_command(unsigned char *buf, size_t size)
{
    if (0 = strcmp(buf, "cmd1")) {
        handle_cmd1(buf, size);
    }
}

这就是所谓的一级抽象。特别是你想写这样的分段注释的时候:

public static int[] generatePrimes(int maxValue)
{
    if (maxValue >= 2) // the only valid case
    {
        // declarations
        int s = maxValue + 1;
        
        // size of array
        boolean[] f = new boolean[s];
        int i;
        // initialize array to true.
        for (i = 0; i < s; i++)
            f[i] = true;

        // get rid of known non-primes
        f[0] = f[1] = false;
        ...
    }
}

每一个section就可以提炼成一个函数。当你想用注释把一个函数分成一段一段的,每一段是一个步骤,那么就是机会提炼函数,提供抽象层级。

Switch Statements

这里是说switch泛滥,到处都是长长的对类型switch的语句。而这种情况通常可以由面向对象来解决。

The solution to this problem (see Listing 3-5) is to bury the switch statement in the basement of an ABSTRACT FACTORY, 9 and never let anyone see it.

对于C语言这种弱OO的语言,就要就事论事了。但通常C也是可以应用OO的一些思想来重构这种switch的问题。

My general rule for switch statements is that they can be tolerated if they appear only once, are used to create polymorphic objects, and are hidden behind an inheritance

Use Descriptive Names

这个不再赘述,它有多重要,应该已经得到共识。

Function Arguments

我们现实的编程生活中,函数参数也是非常容易忽视的地方。很多时候,我们为了信息传递的方便,参数一下4,5个,非常常见。却不自知,这样的代码味道很不好。

The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway.

在看Uncle Bob的Clean Code之前,其实我也没有过多的关注函数参数的个数,只是偶尔隐隐的觉得调用参数多的函数时,有一种很茫然不知从何开始的感觉。要么翻阅文档,要么查看源码,总归是不那么直接,要费点力气。你看这里作者就明确指出了,参数越少越好(当然这我们也知道),超过3个就要慎重考虑了,尽量避免使用3个及以上个数的参数(作者说的优点夸张,shouldn’t be used anyway,绝对不许使用)。
参数个数多,代表代码有一些坏味道(代码坏味道由Martin Fowler在他的Refactoring一书里提出,即指虽然代码功能没问题,但却在向不好的方向发展,越来越坏,最后就可能出问题了)。

  • They take a lot of conceptual power.
    因为参数不属于函数名表达的抽象层次,所以要知道参数是什么意思,只能看调用时是怎么传入的。然后在阅读函数的时候要时时记得。
  • Arguments are even harder from a testing point of view. Imagine the difficulty of writing all the test cases to ensure that all the various combinations of arguments work properly.
  • Output arguments are harder to understand than input arguments. When we read a function, we are used to the idea of information going in to the function through arguments and out through the return value. We don’t usually expect information to be going out through the arguments.

一个参数的函数(Monadic Function)

有两种情况,很适合使用单参数函数:

  • transformation,做转换或者映射,把参数集映射到输出集
  • event:The overall program is meant to interpret the function call as an event and use the argument to alter the state of the system

标志位参数

Passing a boolean into a function is a truly terrible practice. It immediately complicates the signature of the method, loudly proclaiming that this function does more than one thing.
这时候应该做的是,用不同的函数名来阐述标志位想区分的情况。

两个参数的函数(Dydadic Function)

两个参数要比一个参数难理解的多,因为你需要理解参数的顺序是怎么回事儿。但作者也说了:

Dyads aren’t evil, and you will certainly have to write them. However, you should be aware that they come at a cost and should take advantage of what mechanims may be available to you to convert them into monads.

有两个参数的时候,就要慎重了。总是要尝试找机会转换成单参数的函数。实践来看,想转总是容易的。但是转完之后要符合逻辑语意,有时候就没那么容易了。但总归还是要去尝试,能让函数调用变得更加clean。

三个参数的函数(Triads)

Functions that take three arguments are significantly harder to understand than dyads. The issues of ordering, pausing, and ignoring are more than doubled. I suggest you think very carefully before creating a triad.

没啥好说的,三个参数比两个参数引入的额外effort翻倍都不止。所以尽量避免。
作者也提到了一个好的三个参数的例子:assertEquals(1.0, amount, .001)。对float变量的判断,第三个参数引入精度值,这样让调用者返回查看函数原型时,能够得到提醒,对于浮点数来说,相等总是相对的。

Argument Objects

When a function seems to need more than two or three arguments, it is likely that some of those arguments ought to be wrapped into a class of their own.

Reducing the number of arguments by creating objects out of them may seem like cheating, but it’s not. When groups of variables are passed together, they are likely part of a concept that deserves a name of its own.

Verbs and Keywords

这里作者想提醒的是为函数起一个好名字。最好就是用动词+名词的搭配,能阐述的更加清楚。例如:
assertEquals就没有assertExpectedEqualsActual(expected, actual)好。后者体现了参数顺序。
write(name)没有writeField(name)好。因为前者不知道name修饰的是什么,后者告诉我们name是一个field name。

Have No Side Effects

Side effects are lies. Your function promises to do one thing, but it also does other hidden things.
If you must have a temporal coupling, you should make it clear in the name of the function.

函数不要有side effect,也就是focus一件事情。我觉得这里的side effect应该不包括更新全局变量或者类对象的成员变量。

Command Query Separation

Functions should either do something or answer something, but not both. Either your function should change the state of an object, or it should return some information about that object.

这里的意思还是保持SRP,函数要么反应某个object的状态,要么对object做一些操作。对比下面两种写法:

if (setAndCheckIfExists("username", "unclebob"))...

if (attributeExists("username")) {
    setAttribute("username", "unclebob");
    ...
}

Don’t Repeat Yourself

DRY原则,这个也无需赘述

Duplication may be the root of all evil in software.

Prefer Exceptions to Returning Error Codes

使用exception便于在同一个地方处理错误情况。如果用return error code的方式,只能在error发生的地方处理。坏处是,正常逻辑的代码和错误代码会混合在一起。

Thus, a function that handles errors should do nothing else. This implies (as in the example above) that if the keyword try exists in a function, it should be the very first word in the function and that there should be nothing after the catch/finally blocks.

处理error的所有代码应该放在一起。不过这里的建议不适用于纯C编程,因为我们没有try-catch。

总结

写好一个函数看似简单,但其实难度不亚于起一个优雅又清晰的名字。Clean Code一书给了不少建议,其实可以反复参阅,勤加重构。
这些建议中,目前我认为重要的是篇首的几个,特别是Function Arguments特别发人警醒。

  • Small!
  • Do one thing
  • One Level of Abstraction per Function
  • Use Descriptive Names
  • Function Arguments
%0A%E6%9B%BE%E7%BB%8F%E7%9C%8B%E8%BF%87%E4%B8%80%E7%A7%8D%E8%AF%B4%E6%B3%95%EF%BC%8C%E5%86%99%E4%BB%A3%E7%A0%81%E6%9C%80%E9%9A%BE%E7%9A%84%E6%98%AF%E5%91%BD%E5%90%8D%EF%BC%8C%E5%BD%93%E6%97%B6%E4%B8%8D%E8%83%BD%E7%90%86%E8%A7%A3%E3%80%82%E8%BF%99%E4%B9%88%E5%A4%9A%E5%B9%B4%E5%86%99%E4%B8%8B%E6%9D%A5%EF%BC%8C%E5%8F%91%E7%8E%B0%E7%9C%9F%E7%9A%84%E6%98%AF%E8%BF%99%E6%A0%B7%EF%BC%8C%E4%B8%80%E4%B8%AA%E5%A5%BD%E7%9A%84%E5%8F%98%E9%87%8F%E5%90%8D%E6%88%96%E8%80%85%E5%87%BD%E6%95%B0%E5%90%8D%EF%BC%8C%E8%A6%81%E7%AE%80%E7%9F%AD%EF%BC%8C%E5%8F%88%E8%A6%81%E5%8F%8D%E5%BA%94%E8%B6%B3%E5%A4%9F%E7%9A%84%E9%80%BB%E8%BE%91%E3%80%82%E7%A1%AE%E5%AE%9E%E5%BE%88%E9%9A%BE%EF%BC%8C%E5%B9%B6%E4%B8%8D%E6%98%AF%E4%B8%80%E5%8F%A5%E7%8E%A9%E7%AC%91%E8%AF%9D%E3%80%82%0A%E4%B8%8E%E6%AD%A4%E7%B1%BB%E4%BC%BC%E7%9A%84%E6%98%AF%EF%BC%8C%E5%A6%82%E4%BD%95%E5%86%99%E5%A5%BD%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%EF%BC%8C%E4%B9%9F%E4%B8%8D%E6%98%AF%E9%82%A3%E4%B9%88%E7%AE%80%E5%8D%95%E7%9A%84%E3%80%82%E6%9B%BE%E7%BB%8F%E6%88%91%E4%BB%AC%E8%AE%A4%E4%B8%BA%E4%B8%8D%E7%AE%A1%E4%BB%A3%E7%A0%81%E5%86%99%E6%88%90%E4%BB%80%E4%B9%88%E6%A0%B7%EF%BC%8C%E5%8F%AA%E8%A6%81%E8%83%BD%E5%81%9A%E5%88%B0%E6%9C%80%E5%90%8E%E7%9A%84%E5%8A%9F%E8%83%BD%EF%BC%8C%E5%AE%83%E4%BB%AC%E5%B0%B1%E9%83%BD%E6%98%AF%E4%B8%80%E6%A0%B7%E7%9A%84%E3%80%82%E7%9C%9F%E7%9A%84%E6%98%AF%E8%BF%99%E6%A0%B7%E5%90%97%EF%BC%9F%0A%E5%B0%B1%E5%A5%BD%E6%AF%94%EF%BC%8C%E5%9B%B4%E6%A3%8B%E7%9A%84%E5%B8%83%E5%B1%80%E9%98%B6%E6%AE%B5%E3%80%82%E4%BD%A0%E5%8F%AF%E4%BB%A5%E8%AF%B4%EF%BC%8C%E4%B8%8D%E7%AE%A1%E5%B8%83%E5%B1%80%E6%80%8E%E4%B9%88%E4%B8%8B%EF%BC%8C%E5%8F%AA%E8%A6%81%E6%9C%80%E5%90%8E%E8%B5%A2%E6%A3%8B%E5%B0%B1%E5%8F%AF%E4%BB%A5%E4%BA%86%E3%80%82%E4%BD%86%E5%A6%82%E6%9E%9C%E5%B8%83%E5%B1%80%E9%98%B6%E6%AE%B5%E5%A4%B1%E8%B4%A5%EF%BC%8C%E4%BC%9A%E8%AE%A9%E4%BD%A0%E7%9A%84%E4%B8%AD%E7%9B%98%E5%AE%98%E5%AD%90%E5%A4%84%E5%A4%84%E8%A2%AB%E5%8A%A8%E3%80%82%E8%B4%A5%E5%B1%80%E4%BB%8E%E4%B8%80%E5%BC%80%E5%A7%8B%E5%B0%B1%E6%B3%A8%E5%AE%9A%E4%BA%86%E7%9A%84%E3%80%82%0A%E5%86%99%E4%BB%A3%E7%A0%81%E4%B9%9F%E6%98%AF%E8%BF%99%E6%A0%B7%EF%BC%8C%E8%99%BD%E7%84%B6%E5%87%BD%E6%95%B0%E5%8F%AF%E4%BB%A5%E6%83%B3%E6%80%8E%E4%B9%88%E5%86%99%E5%B0%B1%E6%80%8E%E4%B9%88%E5%86%99%EF%BC%8C%E8%99%BD%E7%84%B6%E6%9C%80%E5%90%8E%E7%9A%84%E5%8A%9F%E8%83%BD%E5%8F%AF%E4%BB%A5%E5%AE%9E%E7%8E%B0%EF%BC%8C%E4%BD%86%E6%98%AF%E5%90%8E%E7%BB%AD%E7%9A%84%E9%98%85%E8%AF%BB%EF%BC%8C%E6%89%A9%E5%B1%95%EF%BC%8C%E9%87%8D%E6%9E%84%E4%BC%9A%E8%B6%8A%E6%9D%A5%E8%B6%8A%E5%9B%B0%E9%9A%BE%E3%80%82%E6%9C%80%E7%BB%88%E7%A7%AF%E9%87%8D%E9%9A%BE%E8%BF%94%EF%BC%8C%E8%B4%A5%E5%B1%80%E4%B9%9F%E6%98%AF%E4%BB%8E%E4%B8%80%E5%BC%80%E5%A7%8B%E5%B0%B1%E6%B3%A8%E5%AE%9A%E4%BA%86%E7%9A%84%E3%80%82%0A%E9%82%A3%E4%B9%88%E5%A6%82%E4%BD%95%E7%9C%9F%E6%AD%A3%E7%9A%84%E5%86%99%E5%A5%BD%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E5%91%A2%EF%BC%9FUncle%20Bob%E7%94%A8%E4%BB%96%E7%9A%84%E7%BB%8F%E9%AA%8C%EF%BC%8C%E7%BB%99%E4%BA%86%E6%88%91%E4%BB%AC%E5%BE%88%E5%A4%9A%E6%93%8D%E4%BD%9C%E6%80%A7%E5%BE%88%E9%AB%98%E7%9A%84%E6%8C%87%E5%AF%BC%E3%80%82%0A%0A%23%23%20%E4%BB%80%E4%B9%88%E6%A0%B7%E6%98%AF%E4%B8%80%E4%B8%AA%E5%A5%BD%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%9F%0A%E6%9C%AC%E6%96%87%E5%AE%8C%E5%85%A8%E6%98%AFClean%20Code%E4%B8%80%E4%B9%A6Function%E4%B8%80%E7%AB%A0%E7%9A%84%E6%91%98%E5%BD%95%E3%80%82%E6%9C%89%E4%BA%9B%E5%8A%A0%E5%85%A5%E4%BA%86%E6%88%91%E4%B8%80%E4%BA%9B%E8%87%AA%E5%B7%B1%E7%9A%84%E8%AE%A4%E8%AF%86%E3%80%82%E6%9C%AC%E6%96%87%E5%8F%AF%E4%BB%A5%E4%BD%9C%E4%B8%BA%E6%96%87%E6%91%98%E9%98%85%E8%AF%BB%EF%BC%8C%E5%85%B7%E4%BD%93%E5%8F%AF%E4%BB%A5%E6%9F%A5%E9%98%85%E5%8E%9F%E6%96%87%E3%80%82%0A%23%23%23%20small%EF%BC%81%0A%3E%20Functions%20should%20hardly%20ever%20be%2020%20lines%20long.%0A%0AUncle%20Bob%E5%BF%83%E7%9B%AE%E4%B8%AD%E7%90%86%E6%83%B3%E7%9A%84%E5%87%BD%E6%95%B0%E7%9A%84%E6%A0%B7%E5%AD%90%EF%BC%9A%0A%3E%20Every%20function%20in%20this%20program%20was%20just%20two%2C%20or%20three%2C%20or%20four%20lines%20long.%20%0A%3E%20-%20**Each%20was%20transparently%20obvious.%20Each%20told%20a%20story.**%0A%3E%20-%20**And%20each%20led%20you%20to%20the%20next%20in%20a%20compelling%20order.**%0A%3E%20%0A%3E%20That%E2%80%99s%20how%20short%20your%20functions%20should%20be!%0A%0A%0A%E5%AE%9E%E9%99%85%E4%B8%8A%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BE%88%E9%9A%BE%E5%81%9A%E5%88%B0%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E5%8F%AA%E6%9C%892%EF%BD%9E4%E8%A1%8C%EF%BC%8C%E5%B0%A4%E5%85%B6%E5%83%8FC%E8%AF%AD%E8%A8%80%E8%BF%99%E6%A0%B7%E5%BC%BA%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%9D%9EOO%E8%AF%AD%E8%A8%80%E3%80%82%E5%A6%82%E6%9E%9C%E5%88%BB%E6%84%8F%E7%9A%84%E4%B8%BA%E4%BA%86%E7%9F%AD%E8%80%8C%E7%9F%AD%EF%BC%8C%E7%89%BA%E7%89%B2%E4%BA%86%E5%8F%AF%E8%AF%BB%E6%80%A7%EF%BC%8C%E5%80%92%E6%98%AF%E6%B2%A1%E4%BB%80%E4%B9%88%E5%BF%85%E8%A6%81%E3%80%82%E4%BD%86%E4%BB%A5%E6%88%91%E7%9A%84%E7%BB%8F%E9%AA%8C%E5%81%9A%E5%88%B0%E4%B8%8D%E8%B6%85%E8%BF%8720%E8%A1%8C%E8%BF%98%E6%98%AF%E5%8F%AF%E4%BB%A5%E5%81%9A%E5%88%B0%E7%9A%84%E3%80%82%E8%80%8C%E4%B8%94%E5%BA%94%E8%AF%A5%E5%81%9A%E5%88%B0%E3%80%82%0A%0A%23%23%23%20Blocks%20and%20Indenting%0A%E8%BF%99%E4%B8%AA%E6%98%AF%E8%AF%B4%E5%BA%94%E8%AF%A5%E6%9C%89%E4%B8%80%E4%B8%AA%E8%89%AF%E5%A5%BD%E4%B8%94%E7%BB%9F%E4%B8%80%E7%9A%84%E7%BC%96%E7%A8%8B%E6%A0%BC%E5%BC%8F%E9%A3%8E%E6%A0%BC%E3%80%82%E8%BF%99%E4%B8%AA%E5%9C%A8%E6%88%91%E7%BB%8F%E5%8E%86%E7%9A%84%E5%85%AC%E5%8F%B8%E5%B7%B2%E7%BB%8F%E9%83%BD%E8%BE%BE%E6%88%90%E4%BA%86%E5%85%B1%E8%AF%86%E4%BA%86%E3%80%82%E6%89%80%E4%BB%A5%E4%B8%8D%E5%86%8D%E8%B5%98%E8%BF%B0%E3%80%82%0A%0A%23%23%23%20Do%20One%20Thing%0A%E6%88%91%E4%BB%AC%E7%9F%A5%E9%81%93%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%AD%E6%9C%89%E4%B8%80%E4%B8%AASRP%EF%BC%88Single%20Response%20Principle%EF%BC%89%E5%8E%9F%E5%88%99%E3%80%82%E5%87%BD%E6%95%B0%E4%B9%9F%E5%BA%94%E8%AF%A5%E7%AC%A6%E5%90%88SRP%E5%8E%9F%E5%88%99%E3%80%82%0A%3E%20**FUNCTIONS%20SHOULD%20DO%20ONE%20THING.%20THEY%20SHOULD%20DO%20IT%20WELL.%20THEY%20SHOULD%20DO%20IT%20ONLY.**%0A%0A%E4%BD%86%E5%85%B6%E5%AE%9E%E8%BF%99%E5%8F%A5%E8%AF%9D%E8%AF%B4%E8%B5%B7%E6%9D%A5%E7%AE%80%E5%8D%95%EF%BC%8C%E5%81%9A%E8%B5%B7%E6%9D%A5%E8%BF%98%E6%98%AF%E5%BE%88%E4%B8%8D%E5%AE%B9%E6%98%93%E7%9A%84%E3%80%82%0A%3E**If%20a%20function%20does%20only%20those%20steps%20that%20are%20one%20level%20below%20the%20stated%20name%20of%20the%20function%2C%20then%20the%20function%20is%20doing%20one%20thing.**%20After%20all%2C%20the%20reason%20we%20write%20functions%20is%20to%20decompose%20a%20larger%20concept%20(in%20other%20words%2C%20the%20name%20of%20the%20function)%20into%20a%20set%20of%20steps%20at%20the%20next%20level%20of%20abstraction.%0A%0A%E4%B9%9F%E5%B0%B1%E6%98%AF%E8%AF%B4%EF%BC%8C%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E5%8F%AA%E5%AF%B9%E5%85%B6%E5%90%8D%E7%A7%B0%E6%8F%8F%E8%BF%B0%E7%9A%84%E5%8A%9F%E8%83%BD%E5%81%9A%E4%B8%80%E5%B1%82%E5%88%86%E8%A7%A3%E3%80%82%0A%E4%BE%8B%E5%A6%82%EF%BC%9A%0A%60%60%60c%0Avoid%20handle_command(unsigned%20char%20*buf%2C%20size_t%20size)%0A%7B%0A%20%20%20%20if%20(0%20%3D%20strcmp(buf%2C%20%22cmd1%22))%20%7B%0A%20%20%20%20%20%20%20%20int%20i%20%3D%20sizeof(struct%20header)%3B%0A%20%20%20%20%20%20%20%20buf%5Bi%5D%20%3D%201%3B%0A%20%20%20%20%20%20%20%20buf%5Bi%2B1%5D%20%3D%202%3B%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%E8%BF%99%E9%87%8C%E5%BA%94%E8%AF%A5%E5%BD%93%E5%88%A4%E6%96%AD%E5%88%B0%E5%91%BD%E4%BB%A4%E6%98%AFcmd1%E6%97%B6%EF%BC%8C%E4%B8%8D%E5%BA%94%E5%BD%93%E5%9C%A8%E5%86%85%E8%81%94%E5%91%BD%E4%BB%A4%E5%A4%84%E7%90%86%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%9B%A0%E4%B8%BA%E8%BF%99%E5%B7%B2%E7%BB%8F%E6%98%AF2%E7%BA%A7%E6%8A%BD%E8%B1%A1%E4%BA%86%EF%BC%8C%E5%BA%94%E5%BD%93%E6%98%AF%EF%BC%9A%0A%60%60%60c%0Avoid%20handle_command(unsigned%20char%20*buf%2C%20size_t%20size)%0A%7B%0A%20%20%20%20if%20(0%20%3D%20strcmp(buf%2C%20%22cmd1%22))%20%7B%0A%20%20%20%20%20%20%20%20handle_cmd1(buf%2C%20size)%3B%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%E8%BF%99%E5%B0%B1%E6%98%AF%E6%89%80%E8%B0%93%E7%9A%84%E4%B8%80%E7%BA%A7%E6%8A%BD%E8%B1%A1%E3%80%82%E7%89%B9%E5%88%AB%E6%98%AF%E4%BD%A0%E6%83%B3%E5%86%99%E8%BF%99%E6%A0%B7%E7%9A%84%E5%88%86%E6%AE%B5%E6%B3%A8%E9%87%8A%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%9A%0A%60%60%60java%0Apublic%20static%20int%5B%5D%20generatePrimes(int%20maxValue)%0A%7B%0A%20%20%20%20if%20(maxValue%20%3E%3D%202)%20%2F%2F%20the%20only%20valid%20case%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20declarations%0A%20%20%20%20%20%20%20%20int%20s%20%3D%20maxValue%20%2B%201%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20size%20of%20array%0A%20%20%20%20%20%20%20%20boolean%5B%5D%20f%20%3D%20new%20boolean%5Bs%5D%3B%0A%20%20%20%20%20%20%20%20int%20i%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20initialize%20array%20to%20true.%0A%20%20%20%20%20%20%20%20for%20(i%20%3D%200%3B%20i%20%3C%20s%3B%20i%2B%2B)%0A%20%20%20%20%20%20%20%20%20%20%20%20f%5Bi%5D%20%3D%20true%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20get%20rid%20of%20known%20non-primes%0A%20%20%20%20%20%20%20%20f%5B0%5D%20%3D%20f%5B1%5D%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20...%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%E6%AF%8F%E4%B8%80%E4%B8%AAsection%E5%B0%B1%E5%8F%AF%E4%BB%A5%E6%8F%90%E7%82%BC%E6%88%90%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E3%80%82%E5%BD%93%E4%BD%A0%E6%83%B3%E7%94%A8%E6%B3%A8%E9%87%8A%E6%8A%8A%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E5%88%86%E6%88%90%E4%B8%80%E6%AE%B5%E4%B8%80%E6%AE%B5%E7%9A%84%EF%BC%8C%E6%AF%8F%E4%B8%80%E6%AE%B5%E6%98%AF%E4%B8%80%E4%B8%AA%E6%AD%A5%E9%AA%A4%EF%BC%8C%E9%82%A3%E4%B9%88%E5%B0%B1%E6%98%AF%E6%9C%BA%E4%BC%9A%E6%8F%90%E7%82%BC%E5%87%BD%E6%95%B0%EF%BC%8C%E6%8F%90%E4%BE%9B%E6%8A%BD%E8%B1%A1%E5%B1%82%E7%BA%A7%E3%80%82%0A%0A%23%23%23%20Switch%20Statements%0A%E8%BF%99%E9%87%8C%E6%98%AF%E8%AF%B4switch%E6%B3%9B%E6%BB%A5%EF%BC%8C%E5%88%B0%E5%A4%84%E9%83%BD%E6%98%AF%E9%95%BF%E9%95%BF%E7%9A%84%E5%AF%B9%E7%B1%BB%E5%9E%8Bswitch%E7%9A%84%E8%AF%AD%E5%8F%A5%E3%80%82%E8%80%8C%E8%BF%99%E7%A7%8D%E6%83%85%E5%86%B5%E9%80%9A%E5%B8%B8%E5%8F%AF%E4%BB%A5%E7%94%B1%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E6%9D%A5%E8%A7%A3%E5%86%B3%E3%80%82%0A%3E%20The%20solution%20to%20this%20problem%20(see%20Listing%203-5)%20is%20to%20bury%20the%20switch%20statement%20in%20the%20basement%20of%20an%20**ABSTRACT%20FACTORY**%2C%209%20and%20never%20let%20anyone%20see%20it.%0A%0A%E5%AF%B9%E4%BA%8EC%E8%AF%AD%E8%A8%80%E8%BF%99%E7%A7%8D%E5%BC%B1OO%E7%9A%84%E8%AF%AD%E8%A8%80%EF%BC%8C%E5%B0%B1%E8%A6%81%E5%B0%B1%E4%BA%8B%E8%AE%BA%E4%BA%8B%E4%BA%86%E3%80%82%E4%BD%86%E9%80%9A%E5%B8%B8C%E4%B9%9F%E6%98%AF%E5%8F%AF%E4%BB%A5%E5%BA%94%E7%94%A8OO%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%9D%E6%83%B3%E6%9D%A5%E9%87%8D%E6%9E%84%E8%BF%99%E7%A7%8Dswitch%E7%9A%84%E9%97%AE%E9%A2%98%E3%80%82%0A%3EMy%20general%20rule%20for%20switch%20statements%20is%20that%20they%20can%20be%20tolerated%20if%20they%20**appear%20only%20once**%2C%20are%20used%20to%20**create%20polymorphic%20objects**%2C%20and%20are%20hidden%20behind%20an%20**inheritance**%0A%0A%23%23%23%20Use%20Descriptive%20Names%0A%E8%BF%99%E4%B8%AA%E4%B8%8D%E5%86%8D%E8%B5%98%E8%BF%B0%EF%BC%8C%E5%AE%83%E6%9C%89%E5%A4%9A%E9%87%8D%E8%A6%81%EF%BC%8C%E5%BA%94%E8%AF%A5%E5%B7%B2%E7%BB%8F%E5%BE%97%E5%88%B0%E5%85%B1%E8%AF%86%E3%80%82%0A%0A%23%23%23%20Function%20Arguments%0A%E6%88%91%E4%BB%AC%E7%8E%B0%E5%AE%9E%E7%9A%84%E7%BC%96%E7%A8%8B%E7%94%9F%E6%B4%BB%E4%B8%AD%EF%BC%8C%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E4%B9%9F%E6%98%AF%E9%9D%9E%E5%B8%B8%E5%AE%B9%E6%98%93%E5%BF%BD%E8%A7%86%E7%9A%84%E5%9C%B0%E6%96%B9%E3%80%82%E5%BE%88%E5%A4%9A%E6%97%B6%E5%80%99%EF%BC%8C%E6%88%91%E4%BB%AC%E4%B8%BA%E4%BA%86%E4%BF%A1%E6%81%AF%E4%BC%A0%E9%80%92%E7%9A%84%E6%96%B9%E4%BE%BF%EF%BC%8C%E5%8F%82%E6%95%B0%E4%B8%80%E4%B8%8B4%EF%BC%8C5%E4%B8%AA%EF%BC%8C%E9%9D%9E%E5%B8%B8%E5%B8%B8%E8%A7%81%E3%80%82%E5%8D%B4%E4%B8%8D%E8%87%AA%E7%9F%A5%EF%BC%8C%E8%BF%99%E6%A0%B7%E7%9A%84%E4%BB%A3%E7%A0%81%E5%91%B3%E9%81%93%E5%BE%88%E4%B8%8D%E5%A5%BD%E3%80%82%0A%3E%20The%20ideal%20number%20of%20arguments%20for%20a%20function%20is%20zero%20(niladic).%20Next%20comes%20one%20(monadic)%2C%20followed%20closely%20by%20two%20(dyadic).%20Three%20arguments%20(triadic)%20should%20be%20avoided%20where%20possible.%20More%20than%20three%20(polyadic)%20requires%20very%20special%20justi%EF%AC%81cation%E2%80%94and%20then%20shouldn%E2%80%99t%20be%20used%20anyway.%0A%0A%E5%9C%A8%E7%9C%8BUncle%20Bob%E7%9A%84Clean%20Code%E4%B9%8B%E5%89%8D%EF%BC%8C%E5%85%B6%E5%AE%9E%E6%88%91%E4%B9%9F%E6%B2%A1%E6%9C%89%E8%BF%87%E5%A4%9A%E7%9A%84%E5%85%B3%E6%B3%A8%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E7%9A%84%E4%B8%AA%E6%95%B0%EF%BC%8C%E5%8F%AA%E6%98%AF%E5%81%B6%E5%B0%94%E9%9A%90%E9%9A%90%E7%9A%84%E8%A7%89%E5%BE%97%E8%B0%83%E7%94%A8%E5%8F%82%E6%95%B0%E5%A4%9A%E7%9A%84%E5%87%BD%E6%95%B0%E6%97%B6%EF%BC%8C%E6%9C%89%E4%B8%80%E7%A7%8D%E5%BE%88%E8%8C%AB%E7%84%B6%E4%B8%8D%E7%9F%A5%E4%BB%8E%E4%BD%95%E5%BC%80%E5%A7%8B%E7%9A%84%E6%84%9F%E8%A7%89%E3%80%82%E8%A6%81%E4%B9%88%E7%BF%BB%E9%98%85%E6%96%87%E6%A1%A3%EF%BC%8C%E8%A6%81%E4%B9%88%E6%9F%A5%E7%9C%8B%E6%BA%90%E7%A0%81%EF%BC%8C%E6%80%BB%E5%BD%92%E6%98%AF%E4%B8%8D%E9%82%A3%E4%B9%88%E7%9B%B4%E6%8E%A5%EF%BC%8C%E8%A6%81%E8%B4%B9%E7%82%B9%E5%8A%9B%E6%B0%94%E3%80%82%E4%BD%A0%E7%9C%8B%E8%BF%99%E9%87%8C%E4%BD%9C%E8%80%85%E5%B0%B1%E6%98%8E%E7%A1%AE%E6%8C%87%E5%87%BA%E4%BA%86%EF%BC%8C%E5%8F%82%E6%95%B0%E8%B6%8A%E5%B0%91%E8%B6%8A%E5%A5%BD%EF%BC%88%E5%BD%93%E7%84%B6%E8%BF%99%E6%88%91%E4%BB%AC%E4%B9%9F%E7%9F%A5%E9%81%93%EF%BC%89%EF%BC%8C%E8%B6%85%E8%BF%873%E4%B8%AA%E5%B0%B1%E8%A6%81%E6%85%8E%E9%87%8D%E8%80%83%E8%99%91%E4%BA%86%EF%BC%8C%E5%B0%BD%E9%87%8F%E9%81%BF%E5%85%8D%E4%BD%BF%E7%94%A83%E4%B8%AA%E5%8F%8A%E4%BB%A5%E4%B8%8A%E4%B8%AA%E6%95%B0%E7%9A%84%E5%8F%82%E6%95%B0%EF%BC%88%E4%BD%9C%E8%80%85%E8%AF%B4%E7%9A%84%E4%BC%98%E7%82%B9%E5%A4%B8%E5%BC%A0%EF%BC%8Cshouldn%E2%80%99t%20be%20used%20anyway%EF%BC%8C%E7%BB%9D%E5%AF%B9%E4%B8%8D%E8%AE%B8%E4%BD%BF%E7%94%A8%EF%BC%89%E3%80%82%0A%E5%8F%82%E6%95%B0%E4%B8%AA%E6%95%B0%E5%A4%9A%EF%BC%8C%E4%BB%A3%E8%A1%A8%E4%BB%A3%E7%A0%81%E6%9C%89%E4%B8%80%E4%BA%9B%E5%9D%8F%E5%91%B3%E9%81%93%EF%BC%88%E4%BB%A3%E7%A0%81%E5%9D%8F%E5%91%B3%E9%81%93%E7%94%B1Martin%20Fowler%E5%9C%A8%E4%BB%96%E7%9A%84Refactoring%E4%B8%80%E4%B9%A6%E9%87%8C%E6%8F%90%E5%87%BA%EF%BC%8C%E5%8D%B3%E6%8C%87%E8%99%BD%E7%84%B6%E4%BB%A3%E7%A0%81%E5%8A%9F%E8%83%BD%E6%B2%A1%E9%97%AE%E9%A2%98%EF%BC%8C%E4%BD%86%E5%8D%B4%E5%9C%A8%E5%90%91%E4%B8%8D%E5%A5%BD%E7%9A%84%E6%96%B9%E5%90%91%E5%8F%91%E5%B1%95%EF%BC%8C%E8%B6%8A%E6%9D%A5%E8%B6%8A%E5%9D%8F%EF%BC%8C%E6%9C%80%E5%90%8E%E5%B0%B1%E5%8F%AF%E8%83%BD%E5%87%BA%E9%97%AE%E9%A2%98%E4%BA%86%EF%BC%89%E3%80%82%0A-%20They%20take%20a%20lot%20of%20conceptual%20power.%0A%20%20%20%20%E5%9B%A0%E4%B8%BA%E5%8F%82%E6%95%B0%E4%B8%8D%E5%B1%9E%E4%BA%8E%E5%87%BD%E6%95%B0%E5%90%8D%E8%A1%A8%E8%BE%BE%E7%9A%84%E6%8A%BD%E8%B1%A1%E5%B1%82%E6%AC%A1%EF%BC%8C%E6%89%80%E4%BB%A5%E8%A6%81%E7%9F%A5%E9%81%93%E5%8F%82%E6%95%B0%E6%98%AF%E4%BB%80%E4%B9%88%E6%84%8F%E6%80%9D%EF%BC%8C%E5%8F%AA%E8%83%BD%E7%9C%8B%E8%B0%83%E7%94%A8%E6%97%B6%E6%98%AF%E6%80%8E%E4%B9%88%E4%BC%A0%E5%85%A5%E7%9A%84%E3%80%82%E7%84%B6%E5%90%8E%E5%9C%A8%E9%98%85%E8%AF%BB%E5%87%BD%E6%95%B0%E7%9A%84%E6%97%B6%E5%80%99%E8%A6%81%E6%97%B6%E6%97%B6%E8%AE%B0%E5%BE%97%E3%80%82%0A-%20Arguments%20are%20even%20harder%20from%20a%20**testing%20point%20of%20view**.%20Imagine%20the%20dif%EF%AC%81culty%20of%20writing%20all%20the%20test%20cases%20to%20ensure%20that%20all%20the%20various%20combinations%20of%20arguments%20work%20properly.%0A-%20**Output%20arguments**%20are%20harder%20to%20understand%20than%20input%20arguments.%20When%20we%20read%20a%20function%2C%20we%20are%20used%20to%20the%20idea%20of%20information%20going%20in%20to%20the%20function%20through%20arguments%20and%20out%20through%20the%20return%20value.%20We%20don%E2%80%99t%20usually%20expect%20information%20to%20be%20going%20out%20through%20the%20arguments.%0A%0A%23%23%23%23%20%E4%B8%80%E4%B8%AA%E5%8F%82%E6%95%B0%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%88Monadic%20Function%EF%BC%89%0A%E6%9C%89%E4%B8%A4%E7%A7%8D%E6%83%85%E5%86%B5%EF%BC%8C%E5%BE%88%E9%80%82%E5%90%88%E4%BD%BF%E7%94%A8%E5%8D%95%E5%8F%82%E6%95%B0%E5%87%BD%E6%95%B0%EF%BC%9A%0A-%20transformation%EF%BC%8C%E5%81%9A%E8%BD%AC%E6%8D%A2%E6%88%96%E8%80%85%E6%98%A0%E5%B0%84%EF%BC%8C%E6%8A%8A%E5%8F%82%E6%95%B0%E9%9B%86%E6%98%A0%E5%B0%84%E5%88%B0%E8%BE%93%E5%87%BA%E9%9B%86%0A-%20event%EF%BC%9AThe%20overall%20program%20is%20meant%20to%20interpret%20the%20function%20call%20as%20an%20event%20and%20use%20the%20argument%20to%20alter%20the%20state%20of%20the%20system%0A%0A%23%23%23%23%20%E6%A0%87%E5%BF%97%E4%BD%8D%E5%8F%82%E6%95%B0%0APassing%20a%20boolean%20into%20a%20function%20is%20a%20truly%20terrible%20practice.%20It%20immediately%20complicates%20the%20signature%20of%20the%20method%2C%20***loudly%20proclaiming%20that%20this%20function%20does%20more%20than%20one%20thing***.%0A%E8%BF%99%E6%97%B6%E5%80%99%E5%BA%94%E8%AF%A5%E5%81%9A%E7%9A%84%E6%98%AF%EF%BC%8C%E7%94%A8%E4%B8%8D%E5%90%8C%E7%9A%84%E5%87%BD%E6%95%B0%E5%90%8D%E6%9D%A5%E9%98%90%E8%BF%B0%E6%A0%87%E5%BF%97%E4%BD%8D%E6%83%B3%E5%8C%BA%E5%88%86%E7%9A%84%E6%83%85%E5%86%B5%E3%80%82%0A%0A%23%23%23%23%20%E4%B8%A4%E4%B8%AA%E5%8F%82%E6%95%B0%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%88Dydadic%20Function%EF%BC%89%0A%E4%B8%A4%E4%B8%AA%E5%8F%82%E6%95%B0%E8%A6%81%E6%AF%94%E4%B8%80%E4%B8%AA%E5%8F%82%E6%95%B0%E9%9A%BE%E7%90%86%E8%A7%A3%E7%9A%84%E5%A4%9A%EF%BC%8C%E5%9B%A0%E4%B8%BA%E4%BD%A0%E9%9C%80%E8%A6%81%E7%90%86%E8%A7%A3%E5%8F%82%E6%95%B0%E7%9A%84%E9%A1%BA%E5%BA%8F%E6%98%AF%E6%80%8E%E4%B9%88%E5%9B%9E%E4%BA%8B%E5%84%BF%E3%80%82%E4%BD%86%E4%BD%9C%E8%80%85%E4%B9%9F%E8%AF%B4%E4%BA%86%EF%BC%9A%0A%3E%20Dyads%20aren%E2%80%99t%20evil%2C%20and%20you%20will%20certainly%20have%20to%20write%20them.%20However%2C%20you%20should%20be%20aware%20that%20they%20come%20at%20a%20cost%20and%20should%20take%20advantage%20of%20what%20mechanims%20may%20be%20available%20to%20you%20to%20convert%20them%20into%20monads.%0A%0A%E6%9C%89%E4%B8%A4%E4%B8%AA%E5%8F%82%E6%95%B0%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E5%B0%B1%E8%A6%81%E6%85%8E%E9%87%8D%E4%BA%86%E3%80%82%E6%80%BB%E6%98%AF%E8%A6%81%E5%B0%9D%E8%AF%95%E6%89%BE%E6%9C%BA%E4%BC%9A%E8%BD%AC%E6%8D%A2%E6%88%90%E5%8D%95%E5%8F%82%E6%95%B0%E7%9A%84%E5%87%BD%E6%95%B0%E3%80%82%E5%AE%9E%E8%B7%B5%E6%9D%A5%E7%9C%8B%EF%BC%8C%E6%83%B3%E8%BD%AC%E6%80%BB%E6%98%AF%E5%AE%B9%E6%98%93%E7%9A%84%E3%80%82%E4%BD%86%E6%98%AF%E8%BD%AC%E5%AE%8C%E4%B9%8B%E5%90%8E%E8%A6%81%E7%AC%A6%E5%90%88%E9%80%BB%E8%BE%91%E8%AF%AD%E6%84%8F%EF%BC%8C%E6%9C%89%E6%97%B6%E5%80%99%E5%B0%B1%E6%B2%A1%E9%82%A3%E4%B9%88%E5%AE%B9%E6%98%93%E4%BA%86%E3%80%82%E4%BD%86%E6%80%BB%E5%BD%92%E8%BF%98%E6%98%AF%E8%A6%81%E5%8E%BB%E5%B0%9D%E8%AF%95%EF%BC%8C%E8%83%BD%E8%AE%A9%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E5%8F%98%E5%BE%97%E6%9B%B4%E5%8A%A0clean%E3%80%82%0A%0A%23%23%23%23%20%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%88Triads%EF%BC%89%0A%3EFunctions%20that%20take%20three%20arguments%20are%20signi%EF%AC%81cantly%20harder%20to%20understand%20than%20dyads.%20The%20issues%20of%20ordering%2C%20pausing%2C%20and%20ignoring%20are%20more%20than%20**doubled**.%20I%20suggest%20you%20think%20very%20carefully%20before%20creating%20a%20triad.%0A%0A%E6%B2%A1%E5%95%A5%E5%A5%BD%E8%AF%B4%E7%9A%84%EF%BC%8C%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0%E6%AF%94%E4%B8%A4%E4%B8%AA%E5%8F%82%E6%95%B0%E5%BC%95%E5%85%A5%E7%9A%84%E9%A2%9D%E5%A4%96effort%E7%BF%BB%E5%80%8D%E9%83%BD%E4%B8%8D%E6%AD%A2%E3%80%82%E6%89%80%E4%BB%A5%E5%B0%BD%E9%87%8F%E9%81%BF%E5%85%8D%E3%80%82%0A%E4%BD%9C%E8%80%85%E4%B9%9F%E6%8F%90%E5%88%B0%E4%BA%86%E4%B8%80%E4%B8%AA%E5%A5%BD%E7%9A%84%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%9A%60assertEquals(1.0%2C%20amount%2C%20.001)%60%E3%80%82%E5%AF%B9float%E5%8F%98%E9%87%8F%E7%9A%84%E5%88%A4%E6%96%AD%EF%BC%8C%E7%AC%AC%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0%E5%BC%95%E5%85%A5%E7%B2%BE%E5%BA%A6%E5%80%BC%EF%BC%8C%E8%BF%99%E6%A0%B7%E8%AE%A9%E8%B0%83%E7%94%A8%E8%80%85%E8%BF%94%E5%9B%9E%E6%9F%A5%E7%9C%8B%E5%87%BD%E6%95%B0%E5%8E%9F%E5%9E%8B%E6%97%B6%EF%BC%8C%E8%83%BD%E5%A4%9F%E5%BE%97%E5%88%B0%E6%8F%90%E9%86%92%EF%BC%8C%E5%AF%B9%E4%BA%8E%E6%B5%AE%E7%82%B9%E6%95%B0%E6%9D%A5%E8%AF%B4%EF%BC%8C%E7%9B%B8%E7%AD%89%E6%80%BB%E6%98%AF%E7%9B%B8%E5%AF%B9%E7%9A%84%E3%80%82%0A%0A%23%23%23%23%20Argument%20Objects%0A%3EWhen%20a%20function%20seems%20to%20need%20more%20than%20two%20or%20three%20arguments%2C%20it%20is%20likely%20that%20some%20of%20those%20arguments%20ought%20to%20be%20wrapped%20into%20a%20class%20of%20their%20own.%0A%0A%3EReducing%20the%20number%20of%20arguments%20by%20creating%20objects%20out%20of%20them%20may%20**seem%20like%20cheating%2C%20but%20it%E2%80%99s%20not**.%20When%20groups%20of%20variables%20are%20passed%20together%2C%20**they%20are%20likely%20part%20of%20a%20concept%20that%20deserves%20a%20name%20of%20its%20own**.%0A%0A%23%23%23%23%20Verbs%20and%20Keywords%0A%E8%BF%99%E9%87%8C%E4%BD%9C%E8%80%85%E6%83%B3%E6%8F%90%E9%86%92%E7%9A%84%E6%98%AF%E4%B8%BA%E5%87%BD%E6%95%B0%E8%B5%B7%E4%B8%80%E4%B8%AA%E5%A5%BD%E5%90%8D%E5%AD%97%E3%80%82%E6%9C%80%E5%A5%BD%E5%B0%B1%E6%98%AF%E7%94%A8%E5%8A%A8%E8%AF%8D%2B%E5%90%8D%E8%AF%8D%E7%9A%84%E6%90%AD%E9%85%8D%EF%BC%8C%E8%83%BD%E9%98%90%E8%BF%B0%E7%9A%84%E6%9B%B4%E5%8A%A0%E6%B8%85%E6%A5%9A%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%9A%0A%60assertEquals%60%E5%B0%B1%E6%B2%A1%E6%9C%89%60assertExpectedEqualsActual(expected%2C%20actual)%60%E5%A5%BD%E3%80%82%E5%90%8E%E8%80%85%E4%BD%93%E7%8E%B0%E4%BA%86%E5%8F%82%E6%95%B0%E9%A1%BA%E5%BA%8F%E3%80%82%0A%60write(name)%60%E6%B2%A1%E6%9C%89%60writeField(name)%60%E5%A5%BD%E3%80%82%E5%9B%A0%E4%B8%BA%E5%89%8D%E8%80%85%E4%B8%8D%E7%9F%A5%E9%81%93name%E4%BF%AE%E9%A5%B0%E7%9A%84%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%8C%E5%90%8E%E8%80%85%E5%91%8A%E8%AF%89%E6%88%91%E4%BB%ACname%E6%98%AF%E4%B8%80%E4%B8%AAfield%20name%E3%80%82%0A%0A%23%23%23%20Have%20No%20Side%20Effects%0A%3ESide%20effects%20are%20lies.%20Your%20function%20promises%20to%20do%20one%20thing%2C%20but%20it%20also%20does%20other%20hidden%20things.%0A%3EIf%20you%20must%20have%20a%20temporal%20coupling%2C%20you%20should%20make%20it%20clear%20in%20the%20name%20of%20the%20function.%0A%0A%E5%87%BD%E6%95%B0%E4%B8%8D%E8%A6%81%E6%9C%89side%20effect%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AFfocus%E4%B8%80%E4%BB%B6%E4%BA%8B%E6%83%85%E3%80%82%E6%88%91%E8%A7%89%E5%BE%97%E8%BF%99%E9%87%8C%E7%9A%84side%20effect%E5%BA%94%E8%AF%A5%E4%B8%8D%E5%8C%85%E6%8B%AC%E6%9B%B4%E6%96%B0%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E6%88%96%E8%80%85%E7%B1%BB%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E3%80%82%0A%0A%23%23%23%20Command%20Query%20Separation%0A%3EFunctions%20should%20either%20do%20something%20or%20answer%20something%2C%20but%20not%20both.%20Either%20your%20function%20should%20change%20the%20state%20of%20an%20object%2C%20or%20it%20should%20return%20some%20information%20about%20that%20object.%0A%0A%E8%BF%99%E9%87%8C%E7%9A%84%E6%84%8F%E6%80%9D%E8%BF%98%E6%98%AF%E4%BF%9D%E6%8C%81SRP%EF%BC%8C%E5%87%BD%E6%95%B0%E8%A6%81%E4%B9%88%E5%8F%8D%E5%BA%94%E6%9F%90%E4%B8%AAobject%E7%9A%84%E7%8A%B6%E6%80%81%EF%BC%8C%E8%A6%81%E4%B9%88%E5%AF%B9object%E5%81%9A%E4%B8%80%E4%BA%9B%E6%93%8D%E4%BD%9C%E3%80%82%E5%AF%B9%E6%AF%94%E4%B8%8B%E9%9D%A2%E4%B8%A4%E7%A7%8D%E5%86%99%E6%B3%95%EF%BC%9A%0A%60%60%60java%0Aif%20(setAndCheckIfExists(%22username%22%2C%20%22unclebob%22))...%0A%0Aif%20(attributeExists(%22username%22))%20%7B%0A%20%20%20%20setAttribute(%22username%22%2C%20%22unclebob%22)%3B%0A%20%20%20%20...%0A%7D%0A%60%60%60%0A%0A%23%23%23%20Don%E2%80%99t%20Repeat%20Yourself%0ADRY%E5%8E%9F%E5%88%99%EF%BC%8C%E8%BF%99%E4%B8%AA%E4%B9%9F%E6%97%A0%E9%9C%80%E8%B5%98%E8%BF%B0%0A%3E%20Duplication%20may%20be%20the%20root%20of%20all%20evil%20in%20software.%0A%0A%23%23%23%20Prefer%20Exceptions%20to%20Returning%20Error%20Codes%0A%E4%BD%BF%E7%94%A8exception%E4%BE%BF%E4%BA%8E%E5%9C%A8%E5%90%8C%E4%B8%80%E4%B8%AA%E5%9C%B0%E6%96%B9%E5%A4%84%E7%90%86%E9%94%99%E8%AF%AF%E6%83%85%E5%86%B5%E3%80%82%E5%A6%82%E6%9E%9C%E7%94%A8return%20error%20code%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%8C%E5%8F%AA%E8%83%BD%E5%9C%A8error%E5%8F%91%E7%94%9F%E7%9A%84%E5%9C%B0%E6%96%B9%E5%A4%84%E7%90%86%E3%80%82%E5%9D%8F%E5%A4%84%E6%98%AF%EF%BC%8C%E6%AD%A3%E5%B8%B8%E9%80%BB%E8%BE%91%E7%9A%84%E4%BB%A3%E7%A0%81%E5%92%8C%E9%94%99%E8%AF%AF%E4%BB%A3%E7%A0%81%E4%BC%9A%E6%B7%B7%E5%90%88%E5%9C%A8%E4%B8%80%E8%B5%B7%E3%80%82%0A%3EThus%2C%20a%20function%20that%20handles%20errors%20should%20do%20nothing%20else.%20This%20implies%20(as%20in%20the%20example%20above)%20that%20if%20the%20keyword%20try%20exists%20in%20a%20function%2C%20it%20should%20be%20the%20very%20%EF%AC%81rst%20word%20in%20the%20function%20and%20that%20there%20should%20be%20nothing%20after%20the%20catch%2Ffinally%20blocks.%0A%0A%E5%A4%84%E7%90%86error%E7%9A%84%E6%89%80%E6%9C%89%E4%BB%A3%E7%A0%81%E5%BA%94%E8%AF%A5%E6%94%BE%E5%9C%A8%E4%B8%80%E8%B5%B7%E3%80%82%E4%B8%8D%E8%BF%87%E8%BF%99%E9%87%8C%E7%9A%84%E5%BB%BA%E8%AE%AE%E4%B8%8D%E9%80%82%E7%94%A8%E4%BA%8E%E7%BA%AFC%E7%BC%96%E7%A8%8B%EF%BC%8C%E5%9B%A0%E4%B8%BA%E6%88%91%E4%BB%AC%E6%B2%A1%E6%9C%89try-catch%E3%80%82%0A%0A%23%23%20%E6%80%BB%E7%BB%93%0A%E5%86%99%E5%A5%BD%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E7%9C%8B%E4%BC%BC%E7%AE%80%E5%8D%95%EF%BC%8C%E4%BD%86%E5%85%B6%E5%AE%9E%E9%9A%BE%E5%BA%A6%E4%B8%8D%E4%BA%9A%E4%BA%8E%E8%B5%B7%E4%B8%80%E4%B8%AA%E4%BC%98%E9%9B%85%E5%8F%88%E6%B8%85%E6%99%B0%E7%9A%84%E5%90%8D%E5%AD%97%E3%80%82Clean%20Code%E4%B8%80%E4%B9%A6%E7%BB%99%E4%BA%86%E4%B8%8D%E5%B0%91%E5%BB%BA%E8%AE%AE%EF%BC%8C%E5%85%B6%E5%AE%9E%E5%8F%AF%E4%BB%A5%E5%8F%8D%E5%A4%8D%E5%8F%82%E9%98%85%EF%BC%8C%E5%8B%A4%E5%8A%A0%E9%87%8D%E6%9E%84%E3%80%82%0A%E8%BF%99%E4%BA%9B%E5%BB%BA%E8%AE%AE%E4%B8%AD%EF%BC%8C%E7%9B%AE%E5%89%8D%E6%88%91%E8%AE%A4%E4%B8%BA%E9%87%8D%E8%A6%81%E7%9A%84%E6%98%AF%E7%AF%87%E9%A6%96%E7%9A%84%E5%87%A0%E4%B8%AA%EF%BC%8C%E7%89%B9%E5%88%AB%E6%98%AFFunction%20Arguments%E7%89%B9%E5%88%AB%E5%8F%91%E4%BA%BA%E8%AD%A6%E9%86%92%E3%80%82%0A-%20Small!%0A-%20Do%20one%20thing%0A-%20One%20Level%20of%20Abstraction%20per%20Function%0A-%20Use%20Descriptive%20Names%0A-%20Function%20Arguments

代码注释问题是最容易被讨论的。我们常常听到这种说法,一份好的代码有一份完备的注释。又有一种说法,好的代码是自注释的。
说前者的,往往忽视了代码维护的难度。或者干脆就是外行,因为外行怎么能简单粗暴的评价一份代码的好坏呢?最简单的方法就是,注释多就是好代码,没注释就是烂代码。
说后者的往往是经过一些专业的训练,并有一些对维护代码自身的认识的。不过很多情况下,自注释是理想状态。注释有时是难免的。
我认为,通常情况下,当你想注释一段代码的时候,往往应该考虑怎么重构它,而让它更加semantic,如果实在做不到,或者重构的effort非常大,那么可以加一段注释,或者放一个TODO。但起码注释是一种提醒,你的代码或多或少有一点点坏味道了。

Good comments

有一些情况的comment避免不了,本书称之为good comment,暂且罗列,具体也可以参考Uncle Bob的书

  • Legal Comments
  • Informative Comments:注释里放一些逻辑抽象信息,而不要简单机械的重复具体的实现代码
  • Explanation of Intent
  • Clarification
  • Warning of Consequences
  • TODO Comments
  • Amplification
  • Javadocs in Public APIs

即便是这些所谓的good comment,在添加的时候,也不应当是心安理得的。看作者的告诫:

If you are writing a public API, then you should certainly write good javadocs for it. But keep in mind the rest of the advice in this chapter. Javadocs can be just as misleading, nonlocal, and dishonest as any other kind of comment.

即便我们认为的绝对正义的java doc,作者也在警醒我们,这些注释仍然会年久失修,或者传递错误信息。
诚然!这也是我的经验。

Bad comments

在我的经验里,仍然有很多人仍然抱着注释即正义的思路。所以还是想着重指出什么样的注释是不应该的,实际上要么是无用的重复,要么是偷懒的表现。Clean Code一书给出的18个例子可以成为一份checklist来检验我们的代码。本文选取我经常遇到的几种

Mumbling

这种comment指的是,有时候,代码作者在写代码的时候,想要解释或者记录一些信息,便于后续查阅。但这时候通常都是以当时开发时的心境,写下的注释,往往缺乏很多隐含信息的描述。而这样的信息,在经过一段时间后,并不能提供很多有用的信息,而且如果当初的代码逻辑稍作变更,而注释没跟上的话,往往就会造成很多困扰。
例如文中的这个例子:

public void loadProperties() {
    try {
        String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE;       
        FileInputStream propertiesStream = new FileInputStream(propertiesPath);       
        loadedProperties.load(propertiesStream);
    } catch(IOException e) {
        // No properties files means all defaults are loaded
    }
}

这样的例子在我们的代码中非常常见,我猜这也是作者把这种类型的comment放到第一个的原因吧。在写代码时,我们往往都会有这样的冲动,而且往往这时候我们都自我感觉良好——看,我在做注释了,以后的人(有可能就是几天或者几周后的我)肯定会感激我。
Uncle Bob针对这段注释,发出了灵魂拷问:

Apparently, if we get an IOException, it means that there was no properties file; and in that case all the defaults are loaded.

  • But who loads all the defaults?
  • Were they loaded before the call to loadProperties.load?
  • Or did loadProperties.load catch the exception, load the defaults, and then pass the exception on for us to ignore?
  • Or did loadProperties.load load all the defaults before attempting to load the file?

Was the author trying to comfort himself about the fact that he was leaving the catch block empty? Or—and this is the scary possibility was the author trying to tell himself to come back here later and write the code that would load the defaults?

我认为这样的注释可以出现在最开始的版本里,像作者说的

  • 你可能只是希望后面重新revisit做一些重构
  • 或者可能只是不是想catch-block空着

不管是任何理由,都应该在注释里写清楚,如果希望revisit就写上TODO或者FIXME,如果暂时没考虑清楚要不要catch-block,那也写上TODO或者FIXME,并记录一个item,然后做完手上的一个case之后,回头过来把这里重构了,然后删掉这段注释。

Redundant Comments

这种注释也非常常见。例如:

// Utility method that returns when this.closed is true. Throws an exception 
// if the timeout is reached.
public synchronized void waitForClose(final long timeoutMillis) throws Exception {
    if(!closed)
    {
        wait(timeoutMillis);
        if(!closed) 
            throw new Exception("MockResponseSender could not be closed");
    }
}

再例如:

void read_from_file(const char *name)
{
    char buf[10] = {0};
    
    // open a file
    int fd = open(name, 'r');
    
    // read from it
    int nr = read(fd, buf, sizeof(buf));
    
    return atoi(buf);

这里的注释没有添加任何的附加信息,但是却增加了维护成本,因为代码改,注释就得改,否则就是misleading。我认为绝大多数程序员写这样注释的冲动,只是因为这样的注释让你自我感觉良好,因为我在写注释。

Misleading Comments

这往往出现在一段复杂的逻辑,开发者希望通过注释阐述逻辑的意义,但如果叙述不当,容易产生误解,再如果逻辑有了些许变更,而注释没跟上。那么这个注释就会变成一个大坑,让原本就难以理解的代码更加晦涩难懂。
例如这一段:

// Utility method that returns when this.closed is true. Throws an exception 
// if the timeout is reached.
public synchronized void waitForClose(final long timeoutMillis) throws Exception {
    if(!closed)
    {
        wait(timeoutMillis);
        if(!closed) 
            throw new Exception("MockResponseSender could not be closed");
    }
}

第二个if(!closed),没有出现在注释里,是后加的,还是一开始就没描述清楚?到底是注释对还是代码对?
这种情况,应该删掉注释。否则注释和代码印证不了,到底应该选择相信谁?

Mandated Comments & Javadocs in Nonpublic Code

Mandated Comments的意思是强制的注释。有些不懂的人,往往是Manager,他们不懂技术,他们评价代码好坏的唯一标准就是有没有注释。所以他们也喜欢强调,代码一定要多些注释。更有甚者,每个函数都应该有函数头,为了便于doxygen或javadoc文档话,那要写规范的函数头:

/** 
  *
  * @param title The title of the CD * @param author The author of the CD
  * @param tracks The number of tracks on the CD
  * @param durationInMinutes The duration of the CD in minutes
  */
  public void addCD(String title, String author, int tracks, int durationInMinutes) {...}

这样的函数头在接口文档中是有用的,也是必须的。但每一个函数都加上就有点不伦不类了。甚至是Nonpublic的(C里面,可能就是文件里的static函数)。你看这个函数头,就是变量名的简单重复,有什么意义?未来重构的时候想改个变量名,还得改两遍,少改一点就又会给自己或者别人挖坑了。

Journal Comments & Attributions and Bylines

这两者也比较类似,前者是修改记录,后者表示代码的owner。两者都可以由commit记录表示。后者更可以配合issue system,让信息更加完整

* Changes (from 11-Oct-2001)
* -------------------------
* 11-Oct-2001 : Re-organised the class and moved it to new package
*               com.jrefinery.date (DG);
* 05-Nov-2001 : Added a getDescription() method, and eliminated NotableDate
*               class (DG);
* 12-Nov-2001 : IBD requires setDescription() method, now that NotableDate
*               class is gone (DG); Changed getPreviousDayOfWeek(),
*               getFollowingDayOfWeek() and getNearestDayOfWeek() to correct
*               bugs (DG);

这种注释见的少了,曾经没有版本管理工具的时候,这种类似变更记录的注释会比较多吧。反正我是基本没见过了。

Noise Comments & Scary Noise

跟前面的redundant comment差不多,就是毫无意义的代码的机械重复,只不过noise和scary noise重复的更加令人发指。

/**
  * Default constructor.
  */ 
  protected AnnualDateRule() { }
  
/**
  * Returns the day of the month.
  *
  * @return the day of the month.
  */
  public int getDayOfMonth() { return dayOfMonth; }

Sometimes you see comments that are nothing but noise. They restate the obvious and provide no new information.

把变量名在注释里再打一遍,是不是noise?scary noise就更烦人了:

    /** The name. */
    private String name;

    /** The version. */
    private String version;

    /** The licenceName. */
    private String licenceName;

    /** The version. */
    private String info;

还是那句话,写这些注释只是让自己自我感觉良好,没有什么更多的价值了。

Don’t Use a Comment When You Can Use a Function or a Variable

这一句应当是我们时刻牢记的,当你想注释的时候,先想想是不是能用函数名和变量名来替换你的注释想表达的意思,如果不行再加注释。
你看这一段注释:

// does the module from the global list <mod> depend on the
// subsystem we are part of?
if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))

就可以用这一段代码来阐述

ArrayList moduleDependees = smodule.getDependSubsystems();
String ourSubSystem = subSysMod.getSubSystem();
if (moduleDependees.contains(ourSubSystem))

代码在未来是可以参与重构的,而注释不行,你必须花费额外的精力来维护所有的注释。

Function Headers通常就是这样的一种注释,一个好的名字,的确要好于一个好的header注释。

Position Markers & Closing Brace Comments

这两种有点类似,前者是要凸显某个位置的代码,后者是标记括号的归属者。
前者应当用函数来替换你要凸显处的代码,后者你要缩短大括号中的代码长度。

Commented-Out Code

这个是现在命令禁止的了。因为注释掉的代码,有用,但应该是个暂态,在提交之前应该清理。因为一旦提交,别人或者过一段时间以后作者自己,再也没法说清它到底是有用还是没用。所以确定不需要的代码,应该在提交之前做清理,利用版本管理系统来帮你记住这些变更。

HTML Comments

这种注释我见的也不多,似乎是希望用HTML工具来格式化显示代码注释。
例如:

Nonlocal Information

If you must write a comment, then make sure it describes the code it appears near. Don’t offer systemwide information in the context of a local comment.

这种注释见的也比较少,或者可能之前没太注意。应当值得关注。这就像变量的声明应当离使用它的地方越近越好,道理应该是一样的。

Too Much Information

Don’t put interesting historical discussions or irrelevant descriptions of details into your comments.

这里的意思可能是不要放与代码本身逻辑不太相关的,然后很长的注释。但我认为作者不是一味的反对长篇注释。长篇注释在解释复杂的设计时还是有用的。
例如最近在看golang scheduler设计,这其中好些设计细节,就是靠代码文件篇首的长篇注释阐述的。

Inobvious Connection

The connection between a comment and the code it describes should be obvious.

例如:

/*
 * start with an array that is big enough to hold all the pixels
 * (plus filter bytes), and an extra 200 bytes for header info
 */
 this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200];

What is a filter byte?
Does it relate to the +1?
Or to the *3? Both?
Is a pixel a byte? Why 200?

注释隐含了代码未见的信息。在创作代码的时候,可能开发者心里是门儿清的。但你能保证3天以后,几周几年以后还能知道这些隐含的意思吗?你还能猜得出来吗?

总结

首先得说代码注释是有意义的,肯定是有帮助的,但肯定并不那么包治百病。很多时候我们想注释,其实只是想偷懒。或者想写又懒得写的很完整。记住这就是在为自己或别人挖坑。
我建议,在写注释之前,可以先

  • 思考是否可以通过重构,用代码来阐述注释想表达的内容。
  • 如果只是想简单记录,并且回头再做重构,那就在代码里加上TODO/FIXME。

另外,感谢Uncle Bob给了我们一份不错的checklist。我认为以下几种bad comment特别值得注意:

  • Mumbling
  • Misleading Comments
  • Redundant Comments,Noise,Scary Noise
  • Inobvious Connection
  • Javadocs in Nonpublic Code
%E4%BB%A3%E7%A0%81%E6%B3%A8%E9%87%8A%E9%97%AE%E9%A2%98%E6%98%AF%E6%9C%80%E5%AE%B9%E6%98%93%E8%A2%AB%E8%AE%A8%E8%AE%BA%E7%9A%84%E3%80%82%E6%88%91%E4%BB%AC%E5%B8%B8%E5%B8%B8%E5%90%AC%E5%88%B0%E8%BF%99%E7%A7%8D%E8%AF%B4%E6%B3%95%EF%BC%8C%E4%B8%80%E4%BB%BD%E5%A5%BD%E7%9A%84%E4%BB%A3%E7%A0%81%E6%9C%89%E4%B8%80%E4%BB%BD%E5%AE%8C%E5%A4%87%E7%9A%84%E6%B3%A8%E9%87%8A%E3%80%82%E5%8F%88%E6%9C%89%E4%B8%80%E7%A7%8D%E8%AF%B4%E6%B3%95%EF%BC%8C%E5%A5%BD%E7%9A%84%E4%BB%A3%E7%A0%81%E6%98%AF%E8%87%AA%E6%B3%A8%E9%87%8A%E7%9A%84%E3%80%82%0A%E8%AF%B4%E5%89%8D%E8%80%85%E7%9A%84%EF%BC%8C%E5%BE%80%E5%BE%80%E5%BF%BD%E8%A7%86%E4%BA%86%E4%BB%A3%E7%A0%81%E7%BB%B4%E6%8A%A4%E7%9A%84%E9%9A%BE%E5%BA%A6%E3%80%82%E6%88%96%E8%80%85%E5%B9%B2%E8%84%86%E5%B0%B1%E6%98%AF%E5%A4%96%E8%A1%8C%EF%BC%8C%E5%9B%A0%E4%B8%BA%E5%A4%96%E8%A1%8C%E6%80%8E%E4%B9%88%E8%83%BD%E7%AE%80%E5%8D%95%E7%B2%97%E6%9A%B4%E7%9A%84%E8%AF%84%E4%BB%B7%E4%B8%80%E4%BB%BD%E4%BB%A3%E7%A0%81%E7%9A%84%E5%A5%BD%E5%9D%8F%E5%91%A2%EF%BC%9F%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E6%96%B9%E6%B3%95%E5%B0%B1%E6%98%AF%EF%BC%8C%E6%B3%A8%E9%87%8A%E5%A4%9A%E5%B0%B1%E6%98%AF%E5%A5%BD%E4%BB%A3%E7%A0%81%EF%BC%8C%E6%B2%A1%E6%B3%A8%E9%87%8A%E5%B0%B1%E6%98%AF%E7%83%82%E4%BB%A3%E7%A0%81%E3%80%82%0A%E8%AF%B4%E5%90%8E%E8%80%85%E7%9A%84%E5%BE%80%E5%BE%80%E6%98%AF%E7%BB%8F%E8%BF%87%E4%B8%80%E4%BA%9B%E4%B8%93%E4%B8%9A%E7%9A%84%E8%AE%AD%E7%BB%83%EF%BC%8C%E5%B9%B6%E6%9C%89%E4%B8%80%E4%BA%9B%E5%AF%B9%E7%BB%B4%E6%8A%A4%E4%BB%A3%E7%A0%81%E8%87%AA%E8%BA%AB%E7%9A%84%E8%AE%A4%E8%AF%86%E7%9A%84%E3%80%82%E4%B8%8D%E8%BF%87%E5%BE%88%E5%A4%9A%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E8%87%AA%E6%B3%A8%E9%87%8A%E6%98%AF%E7%90%86%E6%83%B3%E7%8A%B6%E6%80%81%E3%80%82%E6%B3%A8%E9%87%8A%E6%9C%89%E6%97%B6%E6%98%AF%E9%9A%BE%E5%85%8D%E7%9A%84%E3%80%82%0A%E6%88%91%E8%AE%A4%E4%B8%BA%EF%BC%8C%E9%80%9A%E5%B8%B8%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E5%BD%93%E4%BD%A0%E6%83%B3%E6%B3%A8%E9%87%8A%E4%B8%80%E6%AE%B5%E4%BB%A3%E7%A0%81%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E5%BE%80%E5%BE%80%E5%BA%94%E8%AF%A5%E8%80%83%E8%99%91%E6%80%8E%E4%B9%88%E9%87%8D%E6%9E%84%E5%AE%83%EF%BC%8C%E8%80%8C%E8%AE%A9%E5%AE%83%E6%9B%B4%E5%8A%A0semantic%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%AE%9E%E5%9C%A8%E5%81%9A%E4%B8%8D%E5%88%B0%EF%BC%8C%E6%88%96%E8%80%85%E9%87%8D%E6%9E%84%E7%9A%84effort%E9%9D%9E%E5%B8%B8%E5%A4%A7%EF%BC%8C%E9%82%A3%E4%B9%88%E5%8F%AF%E4%BB%A5%E5%8A%A0%E4%B8%80%E6%AE%B5%E6%B3%A8%E9%87%8A%EF%BC%8C%E6%88%96%E8%80%85%E6%94%BE%E4%B8%80%E4%B8%AATODO%E3%80%82%E4%BD%86%E8%B5%B7%E7%A0%81%E6%B3%A8%E9%87%8A%E6%98%AF%E4%B8%80%E7%A7%8D%E6%8F%90%E9%86%92%EF%BC%8C%E4%BD%A0%E7%9A%84%E4%BB%A3%E7%A0%81%E6%88%96%E5%A4%9A%E6%88%96%E5%B0%91%E6%9C%89%E4%B8%80%E7%82%B9%E7%82%B9%E5%9D%8F%E5%91%B3%E9%81%93%E4%BA%86%E3%80%82%0A%23%23%20Good%20comments%0A%E6%9C%89%E4%B8%80%E4%BA%9B%E6%83%85%E5%86%B5%E7%9A%84comment%E9%81%BF%E5%85%8D%E4%B8%8D%E4%BA%86%EF%BC%8C%E6%9C%AC%E4%B9%A6%E7%A7%B0%E4%B9%8B%E4%B8%BAgood%20comment%EF%BC%8C%E6%9A%82%E4%B8%94%E7%BD%97%E5%88%97%EF%BC%8C%E5%85%B7%E4%BD%93%E4%B9%9F%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83Uncle%20Bob%E7%9A%84%E4%B9%A6%0A-%20Legal%20Comments%0A-%20Informative%20Comments%EF%BC%9A%E6%B3%A8%E9%87%8A%E9%87%8C%E6%94%BE%E4%B8%80%E4%BA%9B%E9%80%BB%E8%BE%91%E6%8A%BD%E8%B1%A1%E4%BF%A1%E6%81%AF%EF%BC%8C%E8%80%8C%E4%B8%8D%E8%A6%81%E7%AE%80%E5%8D%95%E6%9C%BA%E6%A2%B0%E7%9A%84%E9%87%8D%E5%A4%8D%E5%85%B7%E4%BD%93%E7%9A%84%E5%AE%9E%E7%8E%B0%E4%BB%A3%E7%A0%81%0A-%20Explanation%20of%20Intent%0A-%20Clari%EF%AC%81cation%0A-%20Warning%20of%20Consequences%0A-%20TODO%20Comments%0A-%20Ampli%EF%AC%81cation%0A-%20Javadocs%20in%20Public%20APIs%0A%0A%E5%8D%B3%E4%BE%BF%E6%98%AF%E8%BF%99%E4%BA%9B%E6%89%80%E8%B0%93%E7%9A%84good%20comment%EF%BC%8C%E5%9C%A8%E6%B7%BB%E5%8A%A0%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E4%B9%9F%E4%B8%8D%E5%BA%94%E5%BD%93%E6%98%AF%E5%BF%83%E5%AE%89%E7%90%86%E5%BE%97%E7%9A%84%E3%80%82%E7%9C%8B%E4%BD%9C%E8%80%85%E7%9A%84%E5%91%8A%E8%AF%AB%EF%BC%9A%0A%3EIf%20you%20are%20writing%20a%20public%20API%2C%20then%20you%20should%20certainly%20write%20good%20javadocs%20for%20it.%20But%20keep%20in%20mind%20the%20rest%20of%20the%20advice%20in%20this%20chapter.%20Javadocs%20can%20be%20just%20as%20misleading%2C%20nonlocal%2C%20and%20dishonest%20as%20any%20other%20kind%20of%20comment.%0A%0A%E5%8D%B3%E4%BE%BF%E6%88%91%E4%BB%AC%E8%AE%A4%E4%B8%BA%E7%9A%84%E7%BB%9D%E5%AF%B9%E6%AD%A3%E4%B9%89%E7%9A%84java%20doc%EF%BC%8C%E4%BD%9C%E8%80%85%E4%B9%9F%E5%9C%A8%E8%AD%A6%E9%86%92%E6%88%91%E4%BB%AC%EF%BC%8C%E8%BF%99%E4%BA%9B%E6%B3%A8%E9%87%8A%E4%BB%8D%E7%84%B6%E4%BC%9A%E5%B9%B4%E4%B9%85%E5%A4%B1%E4%BF%AE%EF%BC%8C%E6%88%96%E8%80%85%E4%BC%A0%E9%80%92%E9%94%99%E8%AF%AF%E4%BF%A1%E6%81%AF%E3%80%82%0A%E8%AF%9A%E7%84%B6%EF%BC%81%E8%BF%99%E4%B9%9F%E6%98%AF%E6%88%91%E7%9A%84%E7%BB%8F%E9%AA%8C%E3%80%82%0A%0A%23%23%20Bad%20comments%0A%E5%9C%A8%E6%88%91%E7%9A%84%E7%BB%8F%E9%AA%8C%E9%87%8C%EF%BC%8C%E4%BB%8D%E7%84%B6%E6%9C%89%E5%BE%88%E5%A4%9A%E4%BA%BA%E4%BB%8D%E7%84%B6%E6%8A%B1%E7%9D%80%E6%B3%A8%E9%87%8A%E5%8D%B3%E6%AD%A3%E4%B9%89%E7%9A%84%E6%80%9D%E8%B7%AF%E3%80%82%E6%89%80%E4%BB%A5%E8%BF%98%E6%98%AF%E6%83%B3%E7%9D%80%E9%87%8D%E6%8C%87%E5%87%BA%E4%BB%80%E4%B9%88%E6%A0%B7%E7%9A%84%E6%B3%A8%E9%87%8A%E6%98%AF%E4%B8%8D%E5%BA%94%E8%AF%A5%E7%9A%84%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E8%A6%81%E4%B9%88%E6%98%AF%E6%97%A0%E7%94%A8%E7%9A%84%E9%87%8D%E5%A4%8D%EF%BC%8C%E8%A6%81%E4%B9%88%E6%98%AF%E5%81%B7%E6%87%92%E7%9A%84%E8%A1%A8%E7%8E%B0%E3%80%82Clean%20Code%E4%B8%80%E4%B9%A6%E7%BB%99%E5%87%BA%E7%9A%8418%E4%B8%AA%E4%BE%8B%E5%AD%90%E5%8F%AF%E4%BB%A5%E6%88%90%E4%B8%BA%E4%B8%80%E4%BB%BDchecklist%E6%9D%A5%E6%A3%80%E9%AA%8C%E6%88%91%E4%BB%AC%E7%9A%84%E4%BB%A3%E7%A0%81%E3%80%82%E6%9C%AC%E6%96%87%E9%80%89%E5%8F%96%E6%88%91%E7%BB%8F%E5%B8%B8%E9%81%87%E5%88%B0%E7%9A%84%E5%87%A0%E7%A7%8D%0A%0A%23%23%23%20Mumbling%0A%E8%BF%99%E7%A7%8Dcomment%E6%8C%87%E7%9A%84%E6%98%AF%EF%BC%8C%E6%9C%89%E6%97%B6%E5%80%99%EF%BC%8C%E4%BB%A3%E7%A0%81%E4%BD%9C%E8%80%85%E5%9C%A8%E5%86%99%E4%BB%A3%E7%A0%81%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E6%83%B3%E8%A6%81%E8%A7%A3%E9%87%8A%E6%88%96%E8%80%85%E8%AE%B0%E5%BD%95%E4%B8%80%E4%BA%9B%E4%BF%A1%E6%81%AF%EF%BC%8C%E4%BE%BF%E4%BA%8E%E5%90%8E%E7%BB%AD%E6%9F%A5%E9%98%85%E3%80%82%E4%BD%86%E8%BF%99%E6%97%B6%E5%80%99%E9%80%9A%E5%B8%B8%E9%83%BD%E6%98%AF%E4%BB%A5%E5%BD%93%E6%97%B6%E5%BC%80%E5%8F%91%E6%97%B6%E7%9A%84%E5%BF%83%E5%A2%83%EF%BC%8C%E5%86%99%E4%B8%8B%E7%9A%84%E6%B3%A8%E9%87%8A%EF%BC%8C%E5%BE%80%E5%BE%80%E7%BC%BA%E4%B9%8F%E5%BE%88%E5%A4%9A%E9%9A%90%E5%90%AB%E4%BF%A1%E6%81%AF%E7%9A%84%E6%8F%8F%E8%BF%B0%E3%80%82%E8%80%8C%E8%BF%99%E6%A0%B7%E7%9A%84%E4%BF%A1%E6%81%AF%EF%BC%8C%E5%9C%A8%E7%BB%8F%E8%BF%87%E4%B8%80%E6%AE%B5%E6%97%B6%E9%97%B4%E5%90%8E%EF%BC%8C%E5%B9%B6%E4%B8%8D%E8%83%BD%E6%8F%90%E4%BE%9B%E5%BE%88%E5%A4%9A%E6%9C%89%E7%94%A8%E7%9A%84%E4%BF%A1%E6%81%AF%EF%BC%8C%E8%80%8C%E4%B8%94%E5%A6%82%E6%9E%9C%E5%BD%93%E5%88%9D%E7%9A%84%E4%BB%A3%E7%A0%81%E9%80%BB%E8%BE%91%E7%A8%8D%E4%BD%9C%E5%8F%98%E6%9B%B4%EF%BC%8C%E8%80%8C%E6%B3%A8%E9%87%8A%E6%B2%A1%E8%B7%9F%E4%B8%8A%E7%9A%84%E8%AF%9D%EF%BC%8C%E5%BE%80%E5%BE%80%E5%B0%B1%E4%BC%9A%E9%80%A0%E6%88%90%E5%BE%88%E5%A4%9A%E5%9B%B0%E6%89%B0%E3%80%82%0A%E4%BE%8B%E5%A6%82%E6%96%87%E4%B8%AD%E7%9A%84%E8%BF%99%E4%B8%AA%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%60%60%60java%0Apublic%20void%20loadProperties()%20%7B%0A%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20String%20propertiesPath%20%3D%20propertiesLocation%20%2B%20%22%2F%22%20%2B%20PROPERTIES_FILE%3B%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20FileInputStream%20propertiesStream%20%3D%20new%20FileInputStream(propertiesPath)%3B%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20loadedProperties.load(propertiesStream)%3B%0A%20%20%20%20%7D%20catch(IOException%20e)%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20No%20properties%20files%20means%20all%20defaults%20are%20loaded%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%E8%BF%99%E6%A0%B7%E7%9A%84%E4%BE%8B%E5%AD%90%E5%9C%A8%E6%88%91%E4%BB%AC%E7%9A%84%E4%BB%A3%E7%A0%81%E4%B8%AD%E9%9D%9E%E5%B8%B8%E5%B8%B8%E8%A7%81%EF%BC%8C%E6%88%91%E7%8C%9C%E8%BF%99%E4%B9%9F%E6%98%AF%E4%BD%9C%E8%80%85%E6%8A%8A%E8%BF%99%E7%A7%8D%E7%B1%BB%E5%9E%8B%E7%9A%84comment%E6%94%BE%E5%88%B0%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%9A%84%E5%8E%9F%E5%9B%A0%E5%90%A7%E3%80%82%E5%9C%A8%E5%86%99%E4%BB%A3%E7%A0%81%E6%97%B6%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BE%80%E5%BE%80%E9%83%BD%E4%BC%9A%E6%9C%89%E8%BF%99%E6%A0%B7%E7%9A%84%E5%86%B2%E5%8A%A8%EF%BC%8C%E8%80%8C%E4%B8%94%E5%BE%80%E5%BE%80%E8%BF%99%E6%97%B6%E5%80%99%E6%88%91%E4%BB%AC%E9%83%BD%E8%87%AA%E6%88%91%E6%84%9F%E8%A7%89%E8%89%AF%E5%A5%BD%E2%80%94%E2%80%94%E7%9C%8B%EF%BC%8C%E6%88%91%E5%9C%A8%E5%81%9A%E6%B3%A8%E9%87%8A%E4%BA%86%EF%BC%8C%E4%BB%A5%E5%90%8E%E7%9A%84%E4%BA%BA%EF%BC%88%E6%9C%89%E5%8F%AF%E8%83%BD%E5%B0%B1%E6%98%AF%E5%87%A0%E5%A4%A9%E6%88%96%E8%80%85%E5%87%A0%E5%91%A8%E5%90%8E%E7%9A%84%E6%88%91%EF%BC%89%E8%82%AF%E5%AE%9A%E4%BC%9A%E6%84%9F%E6%BF%80%E6%88%91%E3%80%82%0AUncle%20Bob%E9%92%88%E5%AF%B9%E8%BF%99%E6%AE%B5%E6%B3%A8%E9%87%8A%EF%BC%8C%E5%8F%91%E5%87%BA%E4%BA%86%E7%81%B5%E9%AD%82%E6%8B%B7%E9%97%AE%EF%BC%9A%0A%3EApparently%2C%20if%20we%20get%20an%20IOException%2C%20it%20means%20that%20there%20was%20no%20properties%20%EF%AC%81le%3B%20and%20in%20that%20case%20all%20the%20defaults%20are%20loaded.%20%0A%3E-%20**But%20who%20loads%20all%20the%20defaults%3F**%0A%3E-%20**Were%20they%20loaded%20before%20the%20call%20to%20loadProperties.load%3F**%0A%3E-%20**Or%20did%20loadProperties.load%20catch%20the%20exception%2C%20load%20the%20defaults%2C%20and%20then%20pass%20the%20exception%20on%20for%20us%20to%20ignore%3F**%0A%3E-%20**Or%20did%20loadProperties.load%20load%20all%20the%20defaults%20before%20attempting%20to%20load%20the%20%EF%AC%81le%3F**%0A%3E%0A%3EWas%20the%20author%20trying%20to%20comfort%20himself%20about%20the%20fact%20that%20he%20was%20leaving%20the%20catch%20block%20empty%3F%20Or%E2%80%94and%20this%20is%20the%20scary%20possibility%20was%20the%20author%20trying%20to%20tell%20himself%20to%20come%20back%20here%20later%20and%20write%20the%20code%20that%20would%20load%20the%20defaults%3F%0A%0A%E6%88%91%E8%AE%A4%E4%B8%BA%E8%BF%99%E6%A0%B7%E7%9A%84%E6%B3%A8%E9%87%8A%E5%8F%AF%E4%BB%A5%E5%87%BA%E7%8E%B0%E5%9C%A8%E6%9C%80%E5%BC%80%E5%A7%8B%E7%9A%84%E7%89%88%E6%9C%AC%E9%87%8C%EF%BC%8C%E5%83%8F%E4%BD%9C%E8%80%85%E8%AF%B4%E7%9A%84%0A-%20%E4%BD%A0%E5%8F%AF%E8%83%BD%E5%8F%AA%E6%98%AF%E5%B8%8C%E6%9C%9B%E5%90%8E%E9%9D%A2%E9%87%8D%E6%96%B0revisit%E5%81%9A%E4%B8%80%E4%BA%9B%E9%87%8D%E6%9E%84%0A-%20%E6%88%96%E8%80%85%E5%8F%AF%E8%83%BD%E5%8F%AA%E6%98%AF%E4%B8%8D%E6%98%AF%E6%83%B3catch-block%E7%A9%BA%E7%9D%80%0A%0A%E4%B8%8D%E7%AE%A1%E6%98%AF%E4%BB%BB%E4%BD%95%E7%90%86%E7%94%B1%EF%BC%8C%E9%83%BD%E5%BA%94%E8%AF%A5%E5%9C%A8%E6%B3%A8%E9%87%8A%E9%87%8C%E5%86%99%E6%B8%85%E6%A5%9A%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%B8%8C%E6%9C%9Brevisit%E5%B0%B1%E5%86%99%E4%B8%8ATODO%E6%88%96%E8%80%85FIXME%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9A%82%E6%97%B6%E6%B2%A1%E8%80%83%E8%99%91%E6%B8%85%E6%A5%9A%E8%A6%81%E4%B8%8D%E8%A6%81catch-block%EF%BC%8C%E9%82%A3%E4%B9%9F%E5%86%99%E4%B8%8ATODO%E6%88%96%E8%80%85FIXME%EF%BC%8C%E5%B9%B6%E8%AE%B0%E5%BD%95%E4%B8%80%E4%B8%AAitem%EF%BC%8C%E7%84%B6%E5%90%8E%E5%81%9A%E5%AE%8C%E6%89%8B%E4%B8%8A%E7%9A%84%E4%B8%80%E4%B8%AAcase%E4%B9%8B%E5%90%8E%EF%BC%8C%E5%9B%9E%E5%A4%B4%E8%BF%87%E6%9D%A5%E6%8A%8A%E8%BF%99%E9%87%8C%E9%87%8D%E6%9E%84%E4%BA%86%EF%BC%8C%E7%84%B6%E5%90%8E%E5%88%A0%E6%8E%89%E8%BF%99%E6%AE%B5%E6%B3%A8%E9%87%8A%E3%80%82%0A%0A%23%23%23%20Redundant%20Comments%0A%E8%BF%99%E7%A7%8D%E6%B3%A8%E9%87%8A%E4%B9%9F%E9%9D%9E%E5%B8%B8%E5%B8%B8%E8%A7%81%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%9A%0A%60%60%60java%0A%2F%2F%20Utility%20method%20that%20returns%20when%20this.closed%20is%20true.%20Throws%20an%20exception%20%0A%2F%2F%20if%20the%20timeout%20is%20reached.%0Apublic%20synchronized%20void%20waitForClose(final%20long%20timeoutMillis)%20throws%20Exception%20%7B%0A%20%20%20%20if(!closed)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20wait(timeoutMillis)%3B%0A%20%20%20%20%20%20%20%20if(!closed)%20%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Exception(%22MockResponseSender%20could%20not%20be%20closed%22)%3B%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%E5%86%8D%E4%BE%8B%E5%A6%82%EF%BC%9A%0A%60%60%60c%0Avoid%20read_from_file(const%20char%20*name)%0A%7B%0A%20%20%20%20char%20buf%5B10%5D%20%3D%20%7B0%7D%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20open%20a%20file%0A%20%20%20%20int%20fd%20%3D%20open(name%2C%20'r')%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20read%20from%20it%0A%20%20%20%20int%20nr%20%3D%20read(fd%2C%20buf%2C%20sizeof(buf))%3B%0A%20%20%20%20%0A%20%20%20%20return%20atoi(buf)%3B%0A%60%60%60%0A%E8%BF%99%E9%87%8C%E7%9A%84%E6%B3%A8%E9%87%8A**%E6%B2%A1%E6%9C%89%E6%B7%BB%E5%8A%A0%E4%BB%BB%E4%BD%95%E7%9A%84%E9%99%84%E5%8A%A0%E4%BF%A1%E6%81%AF%EF%BC%8C%E4%BD%86%E6%98%AF%E5%8D%B4%E5%A2%9E%E5%8A%A0%E4%BA%86%E7%BB%B4%E6%8A%A4%E6%88%90%E6%9C%AC**%EF%BC%8C%E5%9B%A0%E4%B8%BA%E4%BB%A3%E7%A0%81%E6%94%B9%EF%BC%8C%E6%B3%A8%E9%87%8A%E5%B0%B1%E5%BE%97%E6%94%B9%EF%BC%8C%E5%90%A6%E5%88%99%E5%B0%B1%E6%98%AFmisleading%E3%80%82%E6%88%91%E8%AE%A4%E4%B8%BA%E7%BB%9D%E5%A4%A7%E5%A4%9A%E6%95%B0%E7%A8%8B%E5%BA%8F%E5%91%98%E5%86%99%E8%BF%99%E6%A0%B7%E6%B3%A8%E9%87%8A%E7%9A%84%E5%86%B2%E5%8A%A8%EF%BC%8C%E5%8F%AA%E6%98%AF%E5%9B%A0%E4%B8%BA%E8%BF%99%E6%A0%B7%E7%9A%84%E6%B3%A8%E9%87%8A%E8%AE%A9%E4%BD%A0%E8%87%AA%E6%88%91%E6%84%9F%E8%A7%89%E8%89%AF%E5%A5%BD%EF%BC%8C%E5%9B%A0%E4%B8%BA%E6%88%91%E5%9C%A8%E5%86%99%E6%B3%A8%E9%87%8A%E3%80%82%0A%0A%23%23%23%23%20Misleading%20Comments%0A%E8%BF%99%E5%BE%80%E5%BE%80%E5%87%BA%E7%8E%B0%E5%9C%A8%E4%B8%80%E6%AE%B5%E5%A4%8D%E6%9D%82%E7%9A%84%E9%80%BB%E8%BE%91%EF%BC%8C%E5%BC%80%E5%8F%91%E8%80%85%E5%B8%8C%E6%9C%9B%E9%80%9A%E8%BF%87%E6%B3%A8%E9%87%8A%E9%98%90%E8%BF%B0%E9%80%BB%E8%BE%91%E7%9A%84%E6%84%8F%E4%B9%89%EF%BC%8C%E4%BD%86%E5%A6%82%E6%9E%9C%E5%8F%99%E8%BF%B0%E4%B8%8D%E5%BD%93%EF%BC%8C%E5%AE%B9%E6%98%93%E4%BA%A7%E7%94%9F%E8%AF%AF%E8%A7%A3%EF%BC%8C%E5%86%8D%E5%A6%82%E6%9E%9C%E9%80%BB%E8%BE%91%E6%9C%89%E4%BA%86%E4%BA%9B%E8%AE%B8%E5%8F%98%E6%9B%B4%EF%BC%8C%E8%80%8C%E6%B3%A8%E9%87%8A%E6%B2%A1%E8%B7%9F%E4%B8%8A%E3%80%82%E9%82%A3%E4%B9%88%E8%BF%99%E4%B8%AA%E6%B3%A8%E9%87%8A%E5%B0%B1%E4%BC%9A%E5%8F%98%E6%88%90%E4%B8%80%E4%B8%AA%E5%A4%A7%E5%9D%91%EF%BC%8C%E8%AE%A9%E5%8E%9F%E6%9C%AC%E5%B0%B1%E9%9A%BE%E4%BB%A5%E7%90%86%E8%A7%A3%E7%9A%84%E4%BB%A3%E7%A0%81%E6%9B%B4%E5%8A%A0%E6%99%A6%E6%B6%A9%E9%9A%BE%E6%87%82%E3%80%82%0A%E4%BE%8B%E5%A6%82%E8%BF%99%E4%B8%80%E6%AE%B5%EF%BC%9A%0A%60%60%60java%0A%2F%2F%20Utility%20method%20that%20returns%20when%20this.closed%20is%20true.%20Throws%20an%20exception%20%0A%2F%2F%20if%20the%20timeout%20is%20reached.%0Apublic%20synchronized%20void%20waitForClose(final%20long%20timeoutMillis)%20throws%20Exception%20%7B%0A%20%20%20%20if(!closed)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20wait(timeoutMillis)%3B%0A%20%20%20%20%20%20%20%20if(!closed)%20%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20Exception(%22MockResponseSender%20could%20not%20be%20closed%22)%3B%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%E7%AC%AC%E4%BA%8C%E4%B8%AA%60if(!closed)%60%2C%E6%B2%A1%E6%9C%89%E5%87%BA%E7%8E%B0%E5%9C%A8%E6%B3%A8%E9%87%8A%E9%87%8C%EF%BC%8C%E6%98%AF%E5%90%8E%E5%8A%A0%E7%9A%84%EF%BC%8C%E8%BF%98%E6%98%AF%E4%B8%80%E5%BC%80%E5%A7%8B%E5%B0%B1%E6%B2%A1%E6%8F%8F%E8%BF%B0%E6%B8%85%E6%A5%9A%EF%BC%9F%E5%88%B0%E5%BA%95%E6%98%AF%E6%B3%A8%E9%87%8A%E5%AF%B9%E8%BF%98%E6%98%AF%E4%BB%A3%E7%A0%81%E5%AF%B9%EF%BC%9F%0A%E8%BF%99%E7%A7%8D%E6%83%85%E5%86%B5%EF%BC%8C%E5%BA%94%E8%AF%A5%E5%88%A0%E6%8E%89%E6%B3%A8%E9%87%8A%E3%80%82%E5%90%A6%E5%88%99%E6%B3%A8%E9%87%8A%E5%92%8C%E4%BB%A3%E7%A0%81%E5%8D%B0%E8%AF%81%E4%B8%8D%E4%BA%86%EF%BC%8C%E5%88%B0%E5%BA%95%E5%BA%94%E8%AF%A5%E9%80%89%E6%8B%A9%E7%9B%B8%E4%BF%A1%E8%B0%81%EF%BC%9F%0A%0A%23%23%23%20Mandated%20Comments%20%26%20Javadocs%20in%20Nonpublic%20Code%0AMandated%20Comments%E7%9A%84%E6%84%8F%E6%80%9D%E6%98%AF%E5%BC%BA%E5%88%B6%E7%9A%84%E6%B3%A8%E9%87%8A%E3%80%82%E6%9C%89%E4%BA%9B%E4%B8%8D%E6%87%82%E7%9A%84%E4%BA%BA%EF%BC%8C%E5%BE%80%E5%BE%80%E6%98%AFManager%EF%BC%8C%E4%BB%96%E4%BB%AC%E4%B8%8D%E6%87%82%E6%8A%80%E6%9C%AF%EF%BC%8C%E4%BB%96%E4%BB%AC%E8%AF%84%E4%BB%B7%E4%BB%A3%E7%A0%81%E5%A5%BD%E5%9D%8F%E7%9A%84%E5%94%AF%E4%B8%80%E6%A0%87%E5%87%86%E5%B0%B1%E6%98%AF%E6%9C%89%E6%B2%A1%E6%9C%89%E6%B3%A8%E9%87%8A%E3%80%82%E6%89%80%E4%BB%A5%E4%BB%96%E4%BB%AC%E4%B9%9F%E5%96%9C%E6%AC%A2%E5%BC%BA%E8%B0%83%EF%BC%8C%E4%BB%A3%E7%A0%81%E4%B8%80%E5%AE%9A%E8%A6%81%E5%A4%9A%E4%BA%9B%E6%B3%A8%E9%87%8A%E3%80%82%E6%9B%B4%E6%9C%89%E7%94%9A%E8%80%85%EF%BC%8C%E6%AF%8F%E4%B8%AA%E5%87%BD%E6%95%B0%E9%83%BD%E5%BA%94%E8%AF%A5%E6%9C%89%E5%87%BD%E6%95%B0%E5%A4%B4%EF%BC%8C%E4%B8%BA%E4%BA%86%E4%BE%BF%E4%BA%8Edoxygen%E6%88%96javadoc%E6%96%87%E6%A1%A3%E8%AF%9D%EF%BC%8C%E9%82%A3%E8%A6%81%E5%86%99%E8%A7%84%E8%8C%83%E7%9A%84%E5%87%BD%E6%95%B0%E5%A4%B4%EF%BC%9A%0A%60%60%60java%0A%2F**%20%0A%20%20*%0A%20%20*%20%40param%20title%20The%20title%20of%20the%20CD%20*%20%40param%20author%20The%20author%20of%20the%20CD%0A%20%20*%20%40param%20tracks%20The%20number%20of%20tracks%20on%20the%20CD%0A%20%20*%20%40param%20durationInMinutes%20The%20duration%20of%20the%20CD%20in%20minutes%0A%20%20*%2F%0A%20%20public%20void%20addCD(String%20title%2C%20String%20author%2C%20int%20tracks%2C%20int%20durationInMinutes)%20%7B...%7D%0A%60%60%60%0A%E8%BF%99%E6%A0%B7%E7%9A%84%E5%87%BD%E6%95%B0%E5%A4%B4%E5%9C%A8%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3%E4%B8%AD%E6%98%AF%E6%9C%89%E7%94%A8%E7%9A%84%EF%BC%8C%E4%B9%9F%E6%98%AF%E5%BF%85%E9%A1%BB%E7%9A%84%E3%80%82%E4%BD%86%E6%AF%8F%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E9%83%BD%E5%8A%A0%E4%B8%8A%E5%B0%B1%E6%9C%89%E7%82%B9%E4%B8%8D%E4%BC%A6%E4%B8%8D%E7%B1%BB%E4%BA%86%E3%80%82%E7%94%9A%E8%87%B3%E6%98%AFNonpublic%E7%9A%84%EF%BC%88C%E9%87%8C%E9%9D%A2%EF%BC%8C%E5%8F%AF%E8%83%BD%E5%B0%B1%E6%98%AF%E6%96%87%E4%BB%B6%E9%87%8C%E7%9A%84static%E5%87%BD%E6%95%B0%EF%BC%89%E3%80%82%E4%BD%A0%E7%9C%8B%E8%BF%99%E4%B8%AA%E5%87%BD%E6%95%B0%E5%A4%B4%EF%BC%8C%E5%B0%B1%E6%98%AF%E5%8F%98%E9%87%8F%E5%90%8D%E7%9A%84%E7%AE%80%E5%8D%95%E9%87%8D%E5%A4%8D%EF%BC%8C%E6%9C%89%E4%BB%80%E4%B9%88%E6%84%8F%E4%B9%89%EF%BC%9F%E6%9C%AA%E6%9D%A5%E9%87%8D%E6%9E%84%E7%9A%84%E6%97%B6%E5%80%99%E6%83%B3%E6%94%B9%E4%B8%AA%E5%8F%98%E9%87%8F%E5%90%8D%EF%BC%8C%E8%BF%98%E5%BE%97%E6%94%B9%E4%B8%A4%E9%81%8D%EF%BC%8C%E5%B0%91%E6%94%B9%E4%B8%80%E7%82%B9%E5%B0%B1%E5%8F%88%E4%BC%9A%E7%BB%99%E8%87%AA%E5%B7%B1%E6%88%96%E8%80%85%E5%88%AB%E4%BA%BA%E6%8C%96%E5%9D%91%E4%BA%86%E3%80%82%0A%0A%23%23%23%23%20Journal%20Comments%20%26%20Attributions%20and%20Bylines%0A%E8%BF%99%E4%B8%A4%E8%80%85%E4%B9%9F%E6%AF%94%E8%BE%83%E7%B1%BB%E4%BC%BC%EF%BC%8C%E5%89%8D%E8%80%85%E6%98%AF%E4%BF%AE%E6%94%B9%E8%AE%B0%E5%BD%95%EF%BC%8C%E5%90%8E%E8%80%85%E8%A1%A8%E7%A4%BA%E4%BB%A3%E7%A0%81%E7%9A%84owner%E3%80%82%E4%B8%A4%E8%80%85%E9%83%BD%E5%8F%AF%E4%BB%A5%E7%94%B1commit%E8%AE%B0%E5%BD%95%E8%A1%A8%E7%A4%BA%E3%80%82%E5%90%8E%E8%80%85%E6%9B%B4%E5%8F%AF%E4%BB%A5%E9%85%8D%E5%90%88issue%20system%EF%BC%8C%E8%AE%A9%E4%BF%A1%E6%81%AF%E6%9B%B4%E5%8A%A0%E5%AE%8C%E6%95%B4%0A%60%60%60%0A*%20Changes%20(from%2011-Oct-2001)%0A*%20-------------------------%0A*%2011-Oct-2001%20%3A%20Re-organised%20the%20class%20and%20moved%20it%20to%20new%20package%0A*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20com.jrefinery.date%20(DG)%3B%0A*%2005-Nov-2001%20%3A%20Added%20a%20getDescription()%20method%2C%20and%20eliminated%20NotableDate%0A*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20class%20(DG)%3B%0A*%2012-Nov-2001%20%3A%20IBD%20requires%20setDescription()%20method%2C%20now%20that%20NotableDate%0A*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20class%20is%20gone%20(DG)%3B%20Changed%20getPreviousDayOfWeek()%2C%0A*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20getFollowingDayOfWeek()%20and%20getNearestDayOfWeek()%20to%20correct%0A*%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bugs%20(DG)%3B%0A%60%60%60%0A%E8%BF%99%E7%A7%8D%E6%B3%A8%E9%87%8A%E8%A7%81%E7%9A%84%E5%B0%91%E4%BA%86%EF%BC%8C%E6%9B%BE%E7%BB%8F%E6%B2%A1%E6%9C%89%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E8%BF%99%E7%A7%8D%E7%B1%BB%E4%BC%BC%E5%8F%98%E6%9B%B4%E8%AE%B0%E5%BD%95%E7%9A%84%E6%B3%A8%E9%87%8A%E4%BC%9A%E6%AF%94%E8%BE%83%E5%A4%9A%E5%90%A7%E3%80%82%E5%8F%8D%E6%AD%A3%E6%88%91%E6%98%AF%E5%9F%BA%E6%9C%AC%E6%B2%A1%E8%A7%81%E8%BF%87%E4%BA%86%E3%80%82%0A%0A%23%23%23%20Noise%20Comments%20%26%20Scary%20Noise%0A%E8%B7%9F%E5%89%8D%E9%9D%A2%E7%9A%84redundant%20comment%E5%B7%AE%E4%B8%8D%E5%A4%9A%EF%BC%8C%E5%B0%B1%E6%98%AF%E6%AF%AB%E6%97%A0%E6%84%8F%E4%B9%89%E7%9A%84%E4%BB%A3%E7%A0%81%E7%9A%84%E6%9C%BA%E6%A2%B0%E9%87%8D%E5%A4%8D%EF%BC%8C%E5%8F%AA%E4%B8%8D%E8%BF%87noise%E5%92%8Cscary%20noise%E9%87%8D%E5%A4%8D%E7%9A%84%E6%9B%B4%E5%8A%A0%E4%BB%A4%E4%BA%BA%E5%8F%91%E6%8C%87%E3%80%82%0A%60%60%60java%0A%2F**%0A%20%20*%20Default%20constructor.%0A%20%20*%2F%20%0A%20%20protected%20AnnualDateRule()%20%7B%20%7D%0A%20%20%0A%2F**%0A%20%20*%20Returns%20the%20day%20of%20the%20month.%0A%20%20*%0A%20%20*%20%40return%20the%20day%20of%20the%20month.%0A%20%20*%2F%0A%20%20public%20int%20getDayOfMonth()%20%7B%20return%20dayOfMonth%3B%20%7D%0A%60%60%60%0A%3E%20Sometimes%20you%20see%20comments%20that%20are%20nothing%20but%20noise.%20They%20restate%20the%20obvious%20and%20provide%20no%20new%20information.%0A%0A%0A%E6%8A%8A%E5%8F%98%E9%87%8F%E5%90%8D%E5%9C%A8%E6%B3%A8%E9%87%8A%E9%87%8C%E5%86%8D%E6%89%93%E4%B8%80%E9%81%8D%EF%BC%8C%E6%98%AF%E4%B8%8D%E6%98%AFnoise%EF%BC%9Fscary%20noise%E5%B0%B1%E6%9B%B4%E7%83%A6%E4%BA%BA%E4%BA%86%EF%BC%9A%0A%60%60%60java%0A%20%20%20%20%2F**%20The%20name.%20*%2F%0A%20%20%20%20private%20String%20name%3B%0A%0A%20%20%20%20%2F**%20The%20version.%20*%2F%0A%20%20%20%20private%20String%20version%3B%0A%0A%20%20%20%20%2F**%20The%20licenceName.%20*%2F%0A%20%20%20%20private%20String%20licenceName%3B%0A%0A%20%20%20%20%2F**%20The%20version.%20*%2F%0A%20%20%20%20private%20String%20info%3B%0A%60%60%60%0A%E8%BF%98%E6%98%AF%E9%82%A3%E5%8F%A5%E8%AF%9D%EF%BC%8C%E5%86%99%E8%BF%99%E4%BA%9B%E6%B3%A8%E9%87%8A%E5%8F%AA%E6%98%AF%E8%AE%A9%E8%87%AA%E5%B7%B1%E8%87%AA%E6%88%91%E6%84%9F%E8%A7%89%E8%89%AF%E5%A5%BD%EF%BC%8C%E6%B2%A1%E6%9C%89%E4%BB%80%E4%B9%88%E6%9B%B4%E5%A4%9A%E7%9A%84%E4%BB%B7%E5%80%BC%E4%BA%86%E3%80%82%0A%0A%23%23%23%20Don%E2%80%99t%20Use%20a%20Comment%20When%20You%20Can%20Use%20a%20Function%20or%20a%20Variable%0A%E8%BF%99%E4%B8%80%E5%8F%A5%E5%BA%94%E5%BD%93%E6%98%AF%E6%88%91%E4%BB%AC%E6%97%B6%E5%88%BB%E7%89%A2%E8%AE%B0%E7%9A%84%EF%BC%8C%E5%BD%93%E4%BD%A0%E6%83%B3%E6%B3%A8%E9%87%8A%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E5%85%88%E6%83%B3%E6%83%B3%E6%98%AF%E4%B8%8D%E6%98%AF%E8%83%BD%E7%94%A8%E5%87%BD%E6%95%B0%E5%90%8D%E5%92%8C%E5%8F%98%E9%87%8F%E5%90%8D%E6%9D%A5%E6%9B%BF%E6%8D%A2%E4%BD%A0%E7%9A%84%E6%B3%A8%E9%87%8A%E6%83%B3%E8%A1%A8%E8%BE%BE%E7%9A%84%E6%84%8F%E6%80%9D%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%B8%8D%E8%A1%8C%E5%86%8D%E5%8A%A0%E6%B3%A8%E9%87%8A%E3%80%82%0A%E4%BD%A0%E7%9C%8B%E8%BF%99%E4%B8%80%E6%AE%B5%E6%B3%A8%E9%87%8A%EF%BC%9A%0A%60%60%60java%0A%2F%2F%20does%20the%20module%20from%20the%20global%20list%20%3Cmod%3E%20depend%20on%20the%0A%2F%2F%20subsystem%20we%20are%20part%20of%3F%0Aif%20(smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))%0A%60%60%60%0A%E5%B0%B1%E5%8F%AF%E4%BB%A5%E7%94%A8%E8%BF%99%E4%B8%80%E6%AE%B5%E4%BB%A3%E7%A0%81%E6%9D%A5%E9%98%90%E8%BF%B0%0A%60%60%60java%0AArrayList%20moduleDependees%20%3D%20smodule.getDependSubsystems()%3B%0AString%20ourSubSystem%20%3D%20subSysMod.getSubSystem()%3B%0Aif%20(moduleDependees.contains(ourSubSystem))%0A%60%60%60%0A%E4%BB%A3%E7%A0%81%E5%9C%A8%E6%9C%AA%E6%9D%A5%E6%98%AF%E5%8F%AF%E4%BB%A5%E5%8F%82%E4%B8%8E%E9%87%8D%E6%9E%84%E7%9A%84%EF%BC%8C%E8%80%8C%E6%B3%A8%E9%87%8A%E4%B8%8D%E8%A1%8C%EF%BC%8C%E4%BD%A0%E5%BF%85%E9%A1%BB%E8%8A%B1%E8%B4%B9%E9%A2%9D%E5%A4%96%E7%9A%84%E7%B2%BE%E5%8A%9B%E6%9D%A5%E7%BB%B4%E6%8A%A4%E6%89%80%E6%9C%89%E7%9A%84%E6%B3%A8%E9%87%8A%E3%80%82%0A%0A**Function%20Headers**%E9%80%9A%E5%B8%B8%E5%B0%B1%E6%98%AF%E8%BF%99%E6%A0%B7%E7%9A%84%E4%B8%80%E7%A7%8D%E6%B3%A8%E9%87%8A%EF%BC%8C%E4%B8%80%E4%B8%AA%E5%A5%BD%E7%9A%84%E5%90%8D%E5%AD%97%EF%BC%8C%E7%9A%84%E7%A1%AE%E8%A6%81%E5%A5%BD%E4%BA%8E%E4%B8%80%E4%B8%AA%E5%A5%BD%E7%9A%84header%E6%B3%A8%E9%87%8A%E3%80%82%0A%0A%23%23%23%20Position%20Markers%20%26%20Closing%20Brace%20Comments%0A%E8%BF%99%E4%B8%A4%E7%A7%8D%E6%9C%89%E7%82%B9%E7%B1%BB%E4%BC%BC%EF%BC%8C%E5%89%8D%E8%80%85%E6%98%AF%E8%A6%81%E5%87%B8%E6%98%BE%E6%9F%90%E4%B8%AA%E4%BD%8D%E7%BD%AE%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%90%8E%E8%80%85%E6%98%AF%E6%A0%87%E8%AE%B0%E6%8B%AC%E5%8F%B7%E7%9A%84%E5%BD%92%E5%B1%9E%E8%80%85%E3%80%82%0A%E5%89%8D%E8%80%85%E5%BA%94%E5%BD%93%E7%94%A8%E5%87%BD%E6%95%B0%E6%9D%A5%E6%9B%BF%E6%8D%A2%E4%BD%A0%E8%A6%81%E5%87%B8%E6%98%BE%E5%A4%84%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%90%8E%E8%80%85%E4%BD%A0%E8%A6%81%E7%BC%A9%E7%9F%AD%E5%A4%A7%E6%8B%AC%E5%8F%B7%E4%B8%AD%E7%9A%84%E4%BB%A3%E7%A0%81%E9%95%BF%E5%BA%A6%E3%80%82%0A%0A%23%23%23%20Commented-Out%20Code%0A%E8%BF%99%E4%B8%AA%E6%98%AF%E7%8E%B0%E5%9C%A8%E5%91%BD%E4%BB%A4%E7%A6%81%E6%AD%A2%E7%9A%84%E4%BA%86%E3%80%82%E5%9B%A0%E4%B8%BA%E6%B3%A8%E9%87%8A%E6%8E%89%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%E6%9C%89%E7%94%A8%EF%BC%8C%E4%BD%86%E5%BA%94%E8%AF%A5%E6%98%AF%E4%B8%AA%E6%9A%82%E6%80%81%EF%BC%8C%E5%9C%A8%E6%8F%90%E4%BA%A4%E4%B9%8B%E5%89%8D%E5%BA%94%E8%AF%A5%E6%B8%85%E7%90%86%E3%80%82%E5%9B%A0%E4%B8%BA%E4%B8%80%E6%97%A6%E6%8F%90%E4%BA%A4%EF%BC%8C%E5%88%AB%E4%BA%BA%E6%88%96%E8%80%85%E8%BF%87%E4%B8%80%E6%AE%B5%E6%97%B6%E9%97%B4%E4%BB%A5%E5%90%8E%E4%BD%9C%E8%80%85%E8%87%AA%E5%B7%B1%EF%BC%8C%E5%86%8D%E4%B9%9F%E6%B2%A1%E6%B3%95%E8%AF%B4%E6%B8%85%E5%AE%83%E5%88%B0%E5%BA%95%E6%98%AF%E6%9C%89%E7%94%A8%E8%BF%98%E6%98%AF%E6%B2%A1%E7%94%A8%E3%80%82%E6%89%80%E4%BB%A5%E7%A1%AE%E5%AE%9A%E4%B8%8D%E9%9C%80%E8%A6%81%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%BA%94%E8%AF%A5%E5%9C%A8%E6%8F%90%E4%BA%A4%E4%B9%8B%E5%89%8D%E5%81%9A%E6%B8%85%E7%90%86%EF%BC%8C%E5%88%A9%E7%94%A8%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%E6%9D%A5%E5%B8%AE%E4%BD%A0%E8%AE%B0%E4%BD%8F%E8%BF%99%E4%BA%9B%E5%8F%98%E6%9B%B4%E3%80%82%0A%0A%23%23%23%20HTML%20Comments%0A%E8%BF%99%E7%A7%8D%E6%B3%A8%E9%87%8A%E6%88%91%E8%A7%81%E7%9A%84%E4%B9%9F%E4%B8%8D%E5%A4%9A%EF%BC%8C%E4%BC%BC%E4%B9%8E%E6%98%AF%E5%B8%8C%E6%9C%9B%E7%94%A8HTML%E5%B7%A5%E5%85%B7%E6%9D%A5%E6%A0%BC%E5%BC%8F%E5%8C%96%E6%98%BE%E7%A4%BA%E4%BB%A3%E7%A0%81%E6%B3%A8%E9%87%8A%E3%80%82%0A%E4%BE%8B%E5%A6%82%EF%BC%9A%0A!%5B3afcf568c2cee7f9069a698d179c6019.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6066)%0AUncle%20Bob%E5%BB%BA%E8%AE%AE%EF%BC%8C%E5%BA%94%E8%AF%A5%E7%94%B1%E8%A7%A3%E6%9E%90%E6%B3%A8%E9%87%8A%E7%9A%84%E5%B7%A5%E5%85%B7%E6%9D%A5%E8%AE%BE%E8%AE%A1%E8%BF%99%E4%BA%9BHTML%20markup%EF%BC%8C%E8%80%8C%E4%B8%8D%E5%BA%94%E8%AF%A5%E5%86%99%E5%9C%A8%E6%B3%A8%E9%87%8A%E9%87%8C%0A%0A%23%23%23%20Nonlocal%20Information%0A%3E%20If%20you%20must%20write%20a%20comment%2C%20then%20make%20sure%20it%20describes%20the%20code%20it%20appears%20near.%20Don%E2%80%99t%20offer%20systemwide%20information%20in%20the%20context%20of%20a%20local%20comment.%0A%0A%E8%BF%99%E7%A7%8D%E6%B3%A8%E9%87%8A%E8%A7%81%E7%9A%84%E4%B9%9F%E6%AF%94%E8%BE%83%E5%B0%91%EF%BC%8C%E6%88%96%E8%80%85%E5%8F%AF%E8%83%BD%E4%B9%8B%E5%89%8D%E6%B2%A1%E5%A4%AA%E6%B3%A8%E6%84%8F%E3%80%82%E5%BA%94%E5%BD%93%E5%80%BC%E5%BE%97%E5%85%B3%E6%B3%A8%E3%80%82%E8%BF%99%E5%B0%B1%E5%83%8F%E5%8F%98%E9%87%8F%E7%9A%84%E5%A3%B0%E6%98%8E%E5%BA%94%E5%BD%93%E7%A6%BB%E4%BD%BF%E7%94%A8%E5%AE%83%E7%9A%84%E5%9C%B0%E6%96%B9%E8%B6%8A%E8%BF%91%E8%B6%8A%E5%A5%BD%EF%BC%8C%E9%81%93%E7%90%86%E5%BA%94%E8%AF%A5%E6%98%AF%E4%B8%80%E6%A0%B7%E7%9A%84%E3%80%82%0A%0A%23%23%23%20Too%20Much%20Information%0A%3E%20Don%E2%80%99t%20put%20interesting%20historical%20discussions%20or%20irrelevant%20descriptions%20of%20details%20into%20your%20comments.%0A%0A%E8%BF%99%E9%87%8C%E7%9A%84%E6%84%8F%E6%80%9D%E5%8F%AF%E8%83%BD%E6%98%AF%E4%B8%8D%E8%A6%81%E6%94%BE%E4%B8%8E%E4%BB%A3%E7%A0%81%E6%9C%AC%E8%BA%AB%E9%80%BB%E8%BE%91%E4%B8%8D%E5%A4%AA%E7%9B%B8%E5%85%B3%E7%9A%84%EF%BC%8C%E7%84%B6%E5%90%8E%E5%BE%88%E9%95%BF%E7%9A%84%E6%B3%A8%E9%87%8A%E3%80%82%E4%BD%86%E6%88%91%E8%AE%A4%E4%B8%BA%E4%BD%9C%E8%80%85%E4%B8%8D%E6%98%AF%E4%B8%80%E5%91%B3%E7%9A%84%E5%8F%8D%E5%AF%B9%E9%95%BF%E7%AF%87%E6%B3%A8%E9%87%8A%E3%80%82%E9%95%BF%E7%AF%87%E6%B3%A8%E9%87%8A%E5%9C%A8%E8%A7%A3%E9%87%8A%E5%A4%8D%E6%9D%82%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%97%B6%E8%BF%98%E6%98%AF%E6%9C%89%E7%94%A8%E7%9A%84%E3%80%82%0A%E4%BE%8B%E5%A6%82%E6%9C%80%E8%BF%91%E5%9C%A8%E7%9C%8Bgolang%20scheduler%E8%AE%BE%E8%AE%A1%EF%BC%8C%E8%BF%99%E5%85%B6%E4%B8%AD%E5%A5%BD%E4%BA%9B%E8%AE%BE%E8%AE%A1%E7%BB%86%E8%8A%82%EF%BC%8C%E5%B0%B1%E6%98%AF%E9%9D%A0%E4%BB%A3%E7%A0%81%E6%96%87%E4%BB%B6%E7%AF%87%E9%A6%96%E7%9A%84%E9%95%BF%E7%AF%87%E6%B3%A8%E9%87%8A%E9%98%90%E8%BF%B0%E7%9A%84%E3%80%82%0A%0A%23%23%23%20Inobvious%20Connection%0A%3E%20The%20connection%20between%20a%20comment%20and%20the%20code%20it%20describes%20should%20be%20obvious.%0A%0A%E4%BE%8B%E5%A6%82%EF%BC%9A%0A%60%60%60java%0A%2F*%0A%20*%20start%20with%20an%20array%20that%20is%20big%20enough%20to%20hold%20all%20the%20pixels%0A%20*%20(plus%20filter%20bytes)%2C%20and%20an%20extra%20200%20bytes%20for%20header%20info%0A%20*%2F%0A%20this.pngBytes%20%3D%20new%20byte%5B((this.width%20%2B%201)%20*%20this.height%20*%203)%20%2B%20200%5D%3B%0A%60%60%60%0A%3EWhat%20is%20a%20%EF%AC%81lter%20byte%3F%20%0A%3EDoes%20it%20relate%20to%20the%20%2B1%3F%0A%3EOr%20to%20the%20%5C*3%3F%20Both%3F%0A%3EIs%20a%20pixel%20a%20byte%3F%20Why%20200%3F%0A%0A%E6%B3%A8%E9%87%8A%E9%9A%90%E5%90%AB%E4%BA%86%E4%BB%A3%E7%A0%81%E6%9C%AA%E8%A7%81%E7%9A%84%E4%BF%A1%E6%81%AF%E3%80%82%E5%9C%A8%E5%88%9B%E4%BD%9C%E4%BB%A3%E7%A0%81%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E5%8F%AF%E8%83%BD%E5%BC%80%E5%8F%91%E8%80%85%E5%BF%83%E9%87%8C%E6%98%AF%E9%97%A8%E5%84%BF%E6%B8%85%E7%9A%84%E3%80%82%E4%BD%86%E4%BD%A0%E8%83%BD%E4%BF%9D%E8%AF%813%E5%A4%A9%E4%BB%A5%E5%90%8E%EF%BC%8C%E5%87%A0%E5%91%A8%E5%87%A0%E5%B9%B4%E4%BB%A5%E5%90%8E%E8%BF%98%E8%83%BD%E7%9F%A5%E9%81%93%E8%BF%99%E4%BA%9B%E9%9A%90%E5%90%AB%E7%9A%84%E6%84%8F%E6%80%9D%E5%90%97%EF%BC%9F%E4%BD%A0%E8%BF%98%E8%83%BD%E7%8C%9C%E5%BE%97%E5%87%BA%E6%9D%A5%E5%90%97%EF%BC%9F%0A%0A%23%23%20%E6%80%BB%E7%BB%93%0A%E9%A6%96%E5%85%88%E5%BE%97%E8%AF%B4%E4%BB%A3%E7%A0%81%E6%B3%A8%E9%87%8A%E6%98%AF%E6%9C%89%E6%84%8F%E4%B9%89%E7%9A%84%EF%BC%8C%E8%82%AF%E5%AE%9A%E6%98%AF%E6%9C%89%E5%B8%AE%E5%8A%A9%E7%9A%84%EF%BC%8C%E4%BD%86%E8%82%AF%E5%AE%9A%E5%B9%B6%E4%B8%8D%E9%82%A3%E4%B9%88%E5%8C%85%E6%B2%BB%E7%99%BE%E7%97%85%E3%80%82%E5%BE%88%E5%A4%9A%E6%97%B6%E5%80%99%E6%88%91%E4%BB%AC%E6%83%B3%E6%B3%A8%E9%87%8A%EF%BC%8C%E5%85%B6%E5%AE%9E%E5%8F%AA%E6%98%AF%E6%83%B3%E5%81%B7%E6%87%92%E3%80%82%E6%88%96%E8%80%85%E6%83%B3%E5%86%99%E5%8F%88%E6%87%92%E5%BE%97%E5%86%99%E7%9A%84%E5%BE%88%E5%AE%8C%E6%95%B4%E3%80%82%E8%AE%B0%E4%BD%8F%E8%BF%99%E5%B0%B1%E6%98%AF%E5%9C%A8%E4%B8%BA%E8%87%AA%E5%B7%B1%E6%88%96%E5%88%AB%E4%BA%BA%E6%8C%96%E5%9D%91%E3%80%82%0A%E6%88%91%E5%BB%BA%E8%AE%AE%EF%BC%8C%E5%9C%A8%E5%86%99%E6%B3%A8%E9%87%8A%E4%B9%8B%E5%89%8D%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%85%88%0A-%20%E6%80%9D%E8%80%83%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E9%87%8D%E6%9E%84%EF%BC%8C%E7%94%A8%E4%BB%A3%E7%A0%81%E6%9D%A5%E9%98%90%E8%BF%B0%E6%B3%A8%E9%87%8A%E6%83%B3%E8%A1%A8%E8%BE%BE%E7%9A%84%E5%86%85%E5%AE%B9%E3%80%82%0A-%20%E5%A6%82%E6%9E%9C%E5%8F%AA%E6%98%AF%E6%83%B3%E7%AE%80%E5%8D%95%E8%AE%B0%E5%BD%95%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%9B%9E%E5%A4%B4%E5%86%8D%E5%81%9A%E9%87%8D%E6%9E%84%EF%BC%8C%E9%82%A3%E5%B0%B1%E5%9C%A8%E4%BB%A3%E7%A0%81%E9%87%8C%E5%8A%A0%E4%B8%8ATODO%2FFIXME%E3%80%82%0A%0A%E5%8F%A6%E5%A4%96%EF%BC%8C%E6%84%9F%E8%B0%A2Uncle%20Bob%E7%BB%99%E4%BA%86%E6%88%91%E4%BB%AC%E4%B8%80%E4%BB%BD%E4%B8%8D%E9%94%99%E7%9A%84checklist%E3%80%82%E6%88%91%E8%AE%A4%E4%B8%BA%E4%BB%A5%E4%B8%8B%E5%87%A0%E7%A7%8Dbad%20comment%E7%89%B9%E5%88%AB%E5%80%BC%E5%BE%97%E6%B3%A8%E6%84%8F%EF%BC%9A%0A-%20Mumbling%0A-%20Misleading%20Comments%0A-%20Redundant%20Comments%EF%BC%8CNoise%EF%BC%8CScary%20Noise%0A-%20Inobvious%20Connection%0A-%20Javadocs%20in%20Nonpublic%20Code%0A%0A

先说说我想解决的问题是什么。
其实主要还是想提升Linux下编程的效率。因为我的工作环境是Ubuntu (Linux) + gcc +Makefile,所以之前一直以来都是Vim编辑文件,terminal底下编译(make)调试(gdb)。因为要从文件编辑器(Vim)跳出到终端,实际上是做了两次上下文切换,没有IDE那样可以very focus。于是想到,可否通过Vim(或者NeoVim)插件来做到编译和调试。结论是可以的,只是工作的不是那么完美。
Vim GDB也有很多选择,目前我选择的是sakhnik/nvim-gdb。使用体验还不错,配合nvim,可以做到vim下进行GDB调试。虽然有bug,但还好不太影响正常使用。
Vim make相信其实也是比较普通的需求了,可以通过:make + makeprg参数来解决。缺点是不能异步执行,如果是一个大项目,就只能在那儿等着了。后来翻到"著名"的Neomake。网上搜了一下,发现虽然口碑不错,但真正用的人似乎不多,所以我用了个双引号。尤其用Neomake来编译C程序的就更凤毛麟角了。
因为没有什么快速入门的文档,所以打算写这篇博文,一方面记录自己的心得,便于以后回顾,另一方面帮助需要的人。

简单介绍

按照作者的说法,Neomake的诞生只是为了证明Vim的老牌lint插件syntastic可以异步执行。

Its origin is a proof-of-concept for Syntastic to be asynchronous.

不过现在的Neomake能做的显然比syntax checking(也就是所谓的linting)要多。起码我想用的功能就不是syntax checking。从我对Neomake文档的理解,起码有以下两大功能:
1.Syntax checking,支持各种语言,前提是指定对应的lint工具
2.automake,自动编译,其实还是目标做lint工具
3.异步make,用quickfix,location window过滤错误信息
前两者对我毫无吸引力,因为自动编译耗时耗资源,没什么意义。况且因为工作语言是C语言,这种强类型语言,编译设置太麻烦,所以没有lint的价值。
为什么要用第3条,原因是,平时用vim或nvim编辑文件,然后切到终端编译调试,上下文切换太多,感觉没有达到极致效率。当然如果能用上IDE,这一切都不是问题。IDE需要的是图形界面,工作环境里没有,否则用VS code或JetBrain家族的CLion也是个不错的选择

Neomake使用简单介绍

Neomake提供了2个基本命令来执行所谓的make操作。
第一种就是最简单默认的Neomake,它是针对文件的。主要的用途就是做lint检查,也就是很多IDE都提供的语法检查或者叫Instant build。
另一种是Neomake!,带个感叹号,它是针对项目的,即当前的工作目录(也可以通过maker的选项设置)。主要用途就是是编译,在设置好的目录下进行编译。所有的设置都是由maker提供,后文详述。
Neomake还提供了其他的功能,例如NeomakeSh来运行shell命令等等,本文不作讨论。
下面是运行Neomake做lint的界面:

automake

Neomake的automake和IDE的syntax checking非常相似。可以自动触发语法检查。但是对于C/C++这种强类型语言似乎不太友好。因为要特别的去设置头文件搜索路径,否则永远都是头文件找不到的错误。不过看起来这个功能还是挺高级的,而且似乎并不很影响性能。试试:help neomake-automake了解更多详细内容。
简单来说automake可以根据不同的模式设置编译延时时间,例如:

" When writing a buffer.
call neomake#configure#automake('w')
" When writing a buffer, and on normal mode changes (after 750ms).
call neomake#configure#automake('nw', 750)
" When reading a buffer (after 1s), and when writing.
call neomake#configure#automake('rw', 1000)

这样设置的目的是为了少做无意义的编译。当然你还可以在vimrc中做更多的酷炫的配置。
但其实我想分享的是disable automake的方法,可能因为它对C/C++不太友好吧。有两种方法可以禁止:

  • :NeomakeDisable/Toggle
  • call neomake#configure#disable_automake()
    第二种方法是从Neomake源码中搜索出来的,不知道效果如何。

Maker

maker定义了Neomake如何来lint或compile。其实就是定义了具体的命令行,以及需要识别的error format。

A maker is an object that tells Neomake how to run a job for you.

通常使用maker的方法是调用下面的Vim命令

:Neomake <maker name>

当不传入maker name的时候,Neomake会使用系统默认的maker,即makeprg maker。看,按照作者的推荐,如果只是想异步地执行make,只要配置好makeprg和error format就已经可以用了。

If you just want an easy way to run |:make| asynchronously, you're all set.
Just set your |'makeprg'| and |'errorformat'| as usual, and run |:Neomake!|.

自定义maker

定义一个最简单的maker如下:

let g:neomake_make_maker = {
    \ 'exe': 'make',
    \ 'args': ['--build'],
    \ 'errorformat': '%f:%l:%c: %m',
    \ }
" Use the maker like this:
:Neomake! make

这几个参数还是比较直接的。具体也可以参考:help neomake。对于makeprg maker,exe就是make,args就是makeprg指定的参数,而error format就是Vim默认的error format,可以通过命令set efm=xxx来设置。error format那些神奇的占位符可以参考:help errorformat帮助文档。

*注:当前目录下的.clang文件会影响到clang maker的参数。例如在.clang里写上

{
    "c": "c11",
    "cpp": "c++1z",
    "objc": "c11",
    "objcpp": "c++1z",
}

Neomake的参数会多出下面这一溜:

Define a new filetype or project-level maker

g:neomake_<name>_maker
g:neomake_<ft>_<name>_maker
" <ft> = filetype, 例如定义一个C语言的maker
g:neomake_c_clang_maker = {...}

Configure properties for a maker

g:neomake_<name>_<property>
g:neomake_<ft>_<name>_<property>
b:neomake_<name>_<property>
b:neomake_<ft>_<name>_<property>
" g: 表示全局变量, b: 表示buffer级变量

where <property> is one of 'exe', 'args', 'errorformat', 'buffer_output', 'remove_invalid_entries', 'append_file', or 'supports_stdin'.

Eabled makers

" This setting will tell Neomake which makers to use by default for the given filetype `<ft>` (when called without a maker as an argument,
g:neomake_enabled_makers
b:neomake_enabled_makers

" This setting will tell Neomake which makers to use by default for the given filetype `<ft>` (when called without a maker as an argument,
g:neomake_<ft>_enabled_makers
b:neomake_<ft>_enabled_makers

通过查看上面的全局变量可以了解到当前使能的一些maker。所有语言相关的maker都定义在neomake/neomake/autoload/neomake/makers/中。例如neomake/neomake/autoload/neomake/makers/ft/c.vim, neomake/neomake/autoload/neomake/makers/ft/cpp.vim等等。
当用户调用Neomake并传入maker名时,则直接使用对应的maker来编译。如果未传入maker名,则根据以上使能的maker来调用对应的maker编译。

当使用:Neomake时:

  • 首先尝试使用g:neomake_<ft>_enabled_makers<ft>为当前buffer的filetype
  • 若当前没有为<ft>定义的maker,则使用g:neomake_enabled_makers定义的maker

当使用:Neomake!时,则直接使用g:neomake_enabled_makers定义的maker

有用的配置

Neomake的所有信息都在它的帮助文档里,用:help neomake命令来查看吧。也可以看网页版
下面摘录一些我通读过neomake帮助文档后,认为有用的一些信息,以飨读者。

neomake-args-file

When running a maker on a file with |:Neomake|, you may want to control where in the args list the file's path will appear. To do this, insert '%t' in the args list and use append_file=0:

let g:neomake_c_lint_maker = {
    \ 'exe': 'lint',
    \ 'args': ['%t', '--option', 'x'],
    \ 'append_file': 0,
    \ 'errorformat': '%f:%l:%c: %m',
    \ }

This will cause "lint /path/to/file.c --option x" to be run instead of
"lint --option x /path/to/file.c".

%t gets replaced with the absolute path to the file (handling any temporary
file).

neomake-makers-remove_invalid_entries

Default: 0
This option filters invalid entries from makers from the location/quickfix
list (i.e. entries that do not match the |'errorformat'|, and that would show
up with a || prefix in the location/quickfix list):

    let g:neomake_ft_maker_remove_invalid_entries = 1

NOTE: the default for this is 0, because unhandled/unexpected output might be
useful, e.g. when the program displays some error.
Makers should handle this properly through |errorformat|, e.g. by using '%-G'(see |efm-ignore| and |neomake-faq-errorformat|).
* 注: 事实证明有时候啥都没有,是因为error format没设置好

neomake-makers-cwd

The working directory of a maker defaults to the current working directory of the make run (|getcwd()|).
The cwd property overrides this, and gets expanded in the context of the current buffer. Special buffers (like fugitive blobs) get handled for values starting with %: (typically used in this context), falling back to |expand()|. See |filename-modifiers|.
Example: change to the buffer's directory:

let g:neomake_my_example_maker = {
    \ 'exe': 'pwd',
    \ 'cwd': '%:p:h'
    \ }

neomake_open_list

g:neomake_open_list
This setting will open the |location-list| or |quickfix| list (depending on whether it is operating on a file) when adding entries. A value of 2 will preserve the cursor position when the |location-list| or |quickfix| window is opened. Defaults to 0.
* 解释:当有新entry来的时候是否打开quickfix或location-list,取值为2时,表示打开,并且能keep原先的位置。显然选2比较好

neomake_virtualtext_current_error

g:neomake_virtualtext_current_error
选择是否显示virtual text,显然要显示啊,多么酷炫。

neomake log

g:neomake_verbose

0 - Errors only
1 - Quiet message
2 - Loud message (may log multiple messages at once, making the screen shift momentarily)
3 - Debug information (all messages). This will also add time information to messages.

这个在使用Neomake时毫无反应时,特别有用。开启log再用:messages命令查看就可以知道发生了什么。

总结

Neomake是个异步编译不错的选择,可以考虑取代vim自带的make + makeprg,并做到异步编译。不过前提是还是要好好了解一下error format,这其中对错误处的跳转和显示有着决定性的作用。

%E5%85%88%E8%AF%B4%E8%AF%B4%E6%88%91%E6%83%B3%E8%A7%A3%E5%86%B3%E7%9A%84%E9%97%AE%E9%A2%98%E6%98%AF%E4%BB%80%E4%B9%88%E3%80%82%0A%E5%85%B6%E5%AE%9E%E4%B8%BB%E8%A6%81%E8%BF%98%E6%98%AF%E6%83%B3%E6%8F%90%E5%8D%87Linux%E4%B8%8B%E7%BC%96%E7%A8%8B%E7%9A%84%E6%95%88%E7%8E%87%E3%80%82%E5%9B%A0%E4%B8%BA%E6%88%91%E7%9A%84%E5%B7%A5%E4%BD%9C%E7%8E%AF%E5%A2%83%E6%98%AFUbuntu%20(Linux)%20%2B%20gcc%20%2BMakefile%2C%E6%89%80%E4%BB%A5%E4%B9%8B%E5%89%8D%E4%B8%80%E7%9B%B4%E4%BB%A5%E6%9D%A5%E9%83%BD%E6%98%AFVim%E7%BC%96%E8%BE%91%E6%96%87%E4%BB%B6%EF%BC%8Cterminal%E5%BA%95%E4%B8%8B%E7%BC%96%E8%AF%91(make)%E8%B0%83%E8%AF%95(gdb)%E3%80%82%E5%9B%A0%E4%B8%BA%E8%A6%81%E4%BB%8E%E6%96%87%E4%BB%B6%E7%BC%96%E8%BE%91%E5%99%A8(Vim)%E8%B7%B3%E5%87%BA%E5%88%B0%E7%BB%88%E7%AB%AF%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E6%98%AF%E5%81%9A%E4%BA%86%E4%B8%A4%E6%AC%A1%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%EF%BC%8C%E6%B2%A1%E6%9C%89IDE%E9%82%A3%E6%A0%B7%E5%8F%AF%E4%BB%A5very%20focus%E3%80%82%E4%BA%8E%E6%98%AF%E6%83%B3%E5%88%B0%EF%BC%8C%E5%8F%AF%E5%90%A6%E9%80%9A%E8%BF%87Vim(%E6%88%96%E8%80%85NeoVim%EF%BC%89%E6%8F%92%E4%BB%B6%E6%9D%A5%E5%81%9A%E5%88%B0%E7%BC%96%E8%AF%91%E5%92%8C%E8%B0%83%E8%AF%95%E3%80%82%E7%BB%93%E8%AE%BA%E6%98%AF%E5%8F%AF%E4%BB%A5%E7%9A%84%EF%BC%8C%E5%8F%AA%E6%98%AF%E5%B7%A5%E4%BD%9C%E7%9A%84%E4%B8%8D%E6%98%AF%E9%82%A3%E4%B9%88%E5%AE%8C%E7%BE%8E%E3%80%82%0AVim%20GDB%E4%B9%9F%E6%9C%89%E5%BE%88%E5%A4%9A%E9%80%89%E6%8B%A9%EF%BC%8C%E7%9B%AE%E5%89%8D%E6%88%91%E9%80%89%E6%8B%A9%E7%9A%84%E6%98%AF%5Bsakhnik%2Fnvim-gdb%5D(https%3A%2F%2Fgithub.com%2Fsakhnik%2Fnvim-gdb)%E3%80%82%E4%BD%BF%E7%94%A8%E4%BD%93%E9%AA%8C%E8%BF%98%E4%B8%8D%E9%94%99%EF%BC%8C%E9%85%8D%E5%90%88nvim%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%81%9A%E5%88%B0vim%E4%B8%8B%E8%BF%9B%E8%A1%8CGDB%E8%B0%83%E8%AF%95%E3%80%82%E8%99%BD%E7%84%B6%E6%9C%89bug%EF%BC%8C%E4%BD%86%E8%BF%98%E5%A5%BD%E4%B8%8D%E5%A4%AA%E5%BD%B1%E5%93%8D%E6%AD%A3%E5%B8%B8%E4%BD%BF%E7%94%A8%E3%80%82%0AVim%20make%E7%9B%B8%E4%BF%A1%E5%85%B6%E5%AE%9E%E4%B9%9F%E6%98%AF%E6%AF%94%E8%BE%83%E6%99%AE%E9%80%9A%E7%9A%84%E9%9C%80%E6%B1%82%E4%BA%86%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%3Amake%20%2B%20makeprg%E5%8F%82%E6%95%B0%E6%9D%A5%E8%A7%A3%E5%86%B3%E3%80%82%E7%BC%BA%E7%82%B9%E6%98%AF%E4%B8%8D%E8%83%BD%E5%BC%82%E6%AD%A5%E6%89%A7%E8%A1%8C%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%98%AF%E4%B8%80%E4%B8%AA%E5%A4%A7%E9%A1%B9%E7%9B%AE%EF%BC%8C%E5%B0%B1%E5%8F%AA%E8%83%BD%E5%9C%A8%E9%82%A3%E5%84%BF%E7%AD%89%E7%9D%80%E4%BA%86%E3%80%82%E5%90%8E%E6%9D%A5%E7%BF%BB%E5%88%B0%22%E8%91%97%E5%90%8D%22%E7%9A%84Neomake%E3%80%82%E7%BD%91%E4%B8%8A%E6%90%9C%E4%BA%86%E4%B8%80%E4%B8%8B%EF%BC%8C%E5%8F%91%E7%8E%B0%E8%99%BD%E7%84%B6%E5%8F%A3%E7%A2%91%E4%B8%8D%E9%94%99%EF%BC%8C%E4%BD%86%E7%9C%9F%E6%AD%A3%E7%94%A8%E7%9A%84%E4%BA%BA%E4%BC%BC%E4%B9%8E%E4%B8%8D%E5%A4%9A%EF%BC%8C%E6%89%80%E4%BB%A5%E6%88%91%E7%94%A8%E4%BA%86%E4%B8%AA%E5%8F%8C%E5%BC%95%E5%8F%B7%E3%80%82%E5%B0%A4%E5%85%B6%E7%94%A8Neomake%E6%9D%A5%E7%BC%96%E8%AF%91C%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%B0%B1%E6%9B%B4%E5%87%A4%E6%AF%9B%E9%BA%9F%E8%A7%92%E4%BA%86%E3%80%82%0A%E5%9B%A0%E4%B8%BA%E6%B2%A1%E6%9C%89%E4%BB%80%E4%B9%88%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8%E7%9A%84%E6%96%87%E6%A1%A3%EF%BC%8C%E6%89%80%E4%BB%A5%E6%89%93%E7%AE%97%E5%86%99%E8%BF%99%E7%AF%87%E5%8D%9A%E6%96%87%EF%BC%8C%E4%B8%80%E6%96%B9%E9%9D%A2%E8%AE%B0%E5%BD%95%E8%87%AA%E5%B7%B1%E7%9A%84%E5%BF%83%E5%BE%97%EF%BC%8C%E4%BE%BF%E4%BA%8E%E4%BB%A5%E5%90%8E%E5%9B%9E%E9%A1%BE%EF%BC%8C%E5%8F%A6%E4%B8%80%E6%96%B9%E9%9D%A2%E5%B8%AE%E5%8A%A9%E9%9C%80%E8%A6%81%E7%9A%84%E4%BA%BA%E3%80%82%0A%23%23%20%E7%AE%80%E5%8D%95%E4%BB%8B%E7%BB%8D%0A%E6%8C%89%E7%85%A7%E4%BD%9C%E8%80%85%E7%9A%84%E8%AF%B4%E6%B3%95%EF%BC%8CNeomake%E7%9A%84%E8%AF%9E%E7%94%9F%E5%8F%AA%E6%98%AF%E4%B8%BA%E4%BA%86%E8%AF%81%E6%98%8EVim%E7%9A%84%E8%80%81%E7%89%8Clint%E6%8F%92%E4%BB%B6%5Bsyntastic%5D(https%3A%2F%2Fgithub.com%2Fvim-syntastic%2Fsyntastic)%E5%8F%AF%E4%BB%A5%E5%BC%82%E6%AD%A5%E6%89%A7%E8%A1%8C%E3%80%82%0A%3E%20%20Its%20origin%20is%20a%20proof-of-concept%20for%20Syntastic%20to%20be%20asynchronous.%0A%0A%E4%B8%8D%E8%BF%87%E7%8E%B0%E5%9C%A8%E7%9A%84Neomake%E8%83%BD%E5%81%9A%E7%9A%84%E6%98%BE%E7%84%B6%E6%AF%94syntax%20checking%EF%BC%88%E4%B9%9F%E5%B0%B1%E6%98%AF%E6%89%80%E8%B0%93%E7%9A%84linting%EF%BC%89%E8%A6%81%E5%A4%9A%E3%80%82%E8%B5%B7%E7%A0%81%E6%88%91%E6%83%B3%E7%94%A8%E7%9A%84%E5%8A%9F%E8%83%BD%E5%B0%B1%E4%B8%8D%E6%98%AFsyntax%20checking%E3%80%82%E4%BB%8E%E6%88%91%E5%AF%B9Neomake%E6%96%87%E6%A1%A3%E7%9A%84%E7%90%86%E8%A7%A3%EF%BC%8C%E8%B5%B7%E7%A0%81%E6%9C%89%E4%BB%A5%E4%B8%8B%E4%B8%A4%E5%A4%A7%E5%8A%9F%E8%83%BD%EF%BC%9A%0A1.Syntax%20checking%EF%BC%8C%E6%94%AF%E6%8C%81%E5%90%84%E7%A7%8D%E8%AF%AD%E8%A8%80%EF%BC%8C%E5%89%8D%E6%8F%90%E6%98%AF%E6%8C%87%E5%AE%9A%E5%AF%B9%E5%BA%94%E7%9A%84lint%E5%B7%A5%E5%85%B7%0A2.automake%EF%BC%8C%E8%87%AA%E5%8A%A8%E7%BC%96%E8%AF%91%EF%BC%8C%E5%85%B6%E5%AE%9E%E8%BF%98%E6%98%AF%E7%9B%AE%E6%A0%87%E5%81%9Alint%E5%B7%A5%E5%85%B7%0A3.%E5%BC%82%E6%AD%A5make%EF%BC%8C%E7%94%A8quickfix%EF%BC%8Clocation%20window%E8%BF%87%E6%BB%A4%E9%94%99%E8%AF%AF%E4%BF%A1%E6%81%AF%0A%E5%89%8D%E4%B8%A4%E8%80%85%E5%AF%B9%E6%88%91%E6%AF%AB%E6%97%A0%E5%90%B8%E5%BC%95%E5%8A%9B%EF%BC%8C%E5%9B%A0%E4%B8%BA%E8%87%AA%E5%8A%A8%E7%BC%96%E8%AF%91%E8%80%97%E6%97%B6%E8%80%97%E8%B5%84%E6%BA%90%EF%BC%8C%E6%B2%A1%E4%BB%80%E4%B9%88%E6%84%8F%E4%B9%89%E3%80%82%E5%86%B5%E4%B8%94%E5%9B%A0%E4%B8%BA%E5%B7%A5%E4%BD%9C%E8%AF%AD%E8%A8%80%E6%98%AFC%E8%AF%AD%E8%A8%80%EF%BC%8C%E8%BF%99%E7%A7%8D%E5%BC%BA%E7%B1%BB%E5%9E%8B%E8%AF%AD%E8%A8%80%EF%BC%8C%E7%BC%96%E8%AF%91%E8%AE%BE%E7%BD%AE%E5%A4%AA%E9%BA%BB%E7%83%A6%EF%BC%8C%E6%89%80%E4%BB%A5%E6%B2%A1%E6%9C%89lint%E7%9A%84%E4%BB%B7%E5%80%BC%E3%80%82%0A%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E7%94%A8%E7%AC%AC3%E6%9D%A1%EF%BC%8C%E5%8E%9F%E5%9B%A0%E6%98%AF%EF%BC%8C%E5%B9%B3%E6%97%B6%E7%94%A8vim%E6%88%96nvim%E7%BC%96%E8%BE%91%E6%96%87%E4%BB%B6%EF%BC%8C%E7%84%B6%E5%90%8E%E5%88%87%E5%88%B0%E7%BB%88%E7%AB%AF%E7%BC%96%E8%AF%91%E8%B0%83%E8%AF%95%EF%BC%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%A4%AA%E5%A4%9A%EF%BC%8C%E6%84%9F%E8%A7%89%E6%B2%A1%E6%9C%89%E8%BE%BE%E5%88%B0%E6%9E%81%E8%87%B4%E6%95%88%E7%8E%87%E3%80%82%E5%BD%93%E7%84%B6%E5%A6%82%E6%9E%9C%E8%83%BD%E7%94%A8%E4%B8%8AIDE%EF%BC%8C%E8%BF%99%E4%B8%80%E5%88%87%E9%83%BD%E4%B8%8D%E6%98%AF%E9%97%AE%E9%A2%98%E3%80%82IDE%E9%9C%80%E8%A6%81%E7%9A%84%E6%98%AF%E5%9B%BE%E5%BD%A2%E7%95%8C%E9%9D%A2%EF%BC%8C%E5%B7%A5%E4%BD%9C%E7%8E%AF%E5%A2%83%E9%87%8C%E6%B2%A1%E6%9C%89%EF%BC%8C%E5%90%A6%E5%88%99%E7%94%A8VS%20code%E6%88%96JetBrain%E5%AE%B6%E6%97%8F%E7%9A%84CLion%E4%B9%9F%E6%98%AF%E4%B8%AA%E4%B8%8D%E9%94%99%E7%9A%84%E9%80%89%E6%8B%A9%0A%23%23%23%20Neomake%E4%BD%BF%E7%94%A8%E7%AE%80%E5%8D%95%E4%BB%8B%E7%BB%8D%0ANeomake%E6%8F%90%E4%BE%9B%E4%BA%862%E4%B8%AA%E5%9F%BA%E6%9C%AC%E5%91%BD%E4%BB%A4%E6%9D%A5%E6%89%A7%E8%A1%8C%E6%89%80%E8%B0%93%E7%9A%84make%E6%93%8D%E4%BD%9C%E3%80%82%0A%E7%AC%AC%E4%B8%80%E7%A7%8D%E5%B0%B1%E6%98%AF%E6%9C%80%E7%AE%80%E5%8D%95%E9%BB%98%E8%AE%A4%E7%9A%84Neomake%EF%BC%8C%E5%AE%83%E6%98%AF%E9%92%88%E5%AF%B9%E6%96%87%E4%BB%B6%E7%9A%84%E3%80%82%E4%B8%BB%E8%A6%81%E7%9A%84%E7%94%A8%E9%80%94%E5%B0%B1%E6%98%AF%E5%81%9Alint%E6%A3%80%E6%9F%A5%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AF%E5%BE%88%E5%A4%9AIDE%E9%83%BD%E6%8F%90%E4%BE%9B%E7%9A%84%E8%AF%AD%E6%B3%95%E6%A3%80%E6%9F%A5%E6%88%96%E8%80%85%E5%8F%ABInstant%20build%E3%80%82%0A%E5%8F%A6%E4%B8%80%E7%A7%8D%E6%98%AFNeomake%EF%BC%81%EF%BC%8C%E5%B8%A6%E4%B8%AA%E6%84%9F%E5%8F%B9%E5%8F%B7%EF%BC%8C%E5%AE%83%E6%98%AF%E9%92%88%E5%AF%B9%E9%A1%B9%E7%9B%AE%E7%9A%84%EF%BC%8C%E5%8D%B3%E5%BD%93%E5%89%8D%E7%9A%84%E5%B7%A5%E4%BD%9C%E7%9B%AE%E5%BD%95%EF%BC%88%E4%B9%9F%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87maker%E7%9A%84%E9%80%89%E9%A1%B9%E8%AE%BE%E7%BD%AE%EF%BC%89%E3%80%82%E4%B8%BB%E8%A6%81%E7%94%A8%E9%80%94%E5%B0%B1%E6%98%AF%E6%98%AF%E7%BC%96%E8%AF%91%EF%BC%8C%E5%9C%A8%E8%AE%BE%E7%BD%AE%E5%A5%BD%E7%9A%84%E7%9B%AE%E5%BD%95%E4%B8%8B%E8%BF%9B%E8%A1%8C%E7%BC%96%E8%AF%91%E3%80%82%E6%89%80%E6%9C%89%E7%9A%84%E8%AE%BE%E7%BD%AE%E9%83%BD%E6%98%AF%E7%94%B1maker%E6%8F%90%E4%BE%9B%EF%BC%8C%E5%90%8E%E6%96%87%E8%AF%A6%E8%BF%B0%E3%80%82%0ANeomake%E8%BF%98%E6%8F%90%E4%BE%9B%E4%BA%86%E5%85%B6%E4%BB%96%E7%9A%84%E5%8A%9F%E8%83%BD%EF%BC%8C%E4%BE%8B%E5%A6%82NeomakeSh%E6%9D%A5%E8%BF%90%E8%A1%8Cshell%E5%91%BD%E4%BB%A4%E7%AD%89%E7%AD%89%EF%BC%8C%E6%9C%AC%E6%96%87%E4%B8%8D%E4%BD%9C%E8%AE%A8%E8%AE%BA%E3%80%82%0A%E4%B8%8B%E9%9D%A2%E6%98%AF%E8%BF%90%E8%A1%8CNeomake%E5%81%9Alint%E7%9A%84%E7%95%8C%E9%9D%A2%EF%BC%9A%0A!%5Bffa363045ddb3db71e03a65a70bde5c9.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6061)%0A%E5%9C%A8Vim%E7%9A%84%E4%BB%A3%E7%A0%81%E7%95%8C%E9%9D%A2%EF%BC%8CNeomake%E4%B8%BA%E7%94%A8%E6%88%B7%E5%87%86%E5%A4%87%E4%BA%86%E5%B7%A6%E4%BE%A7%E5%B0%8F%E5%9B%BE%E6%A0%87%EF%BC%8C%E8%A1%A8%E7%A4%BA%E9%94%99%E8%AF%AF%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%8C%E4%BB%A3%E7%A0%81%E8%A1%8C%E4%B8%8B%E9%9D%A2%E6%9A%97%E6%9A%97%E7%9A%84%E4%B8%80%E8%A1%8C%E5%AD%97%E6%98%AFvirtual%20text%E6%98%BE%E7%A4%BA%E7%9A%84%E9%94%99%E8%AF%AF%E4%BF%A1%E6%81%AF%E3%80%82%E8%BF%99%E4%BA%9B%E9%83%BD%E6%98%AF%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87Neomake%E7%9A%84%E9%80%89%E9%A1%B9%E8%AE%BE%E7%BD%AE%E6%88%96%E8%80%85%E5%85%B3%E9%97%AD%E7%9A%84%E3%80%82%0A%E8%AF%A6%E7%BB%86%E7%9A%84%E9%94%99%E8%AF%AF%E4%BF%A1%E6%81%AF%E5%9C%A8quick%20fix%E6%88%96%E8%80%85location%20window%E4%B8%AD%E6%98%BE%E7%A4%BA%EF%BC%8C%E5%A6%82%E4%B8%8B%0A!%5B7cc28089f3f8bd6c477c6edfd4fb84cd.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6062)%0A%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E6%98%BE%E7%A4%BA%E8%BF%9B%E8%A1%8C%E8%B7%B3%E8%BD%AC%E3%80%82%E8%83%BD%E4%B8%8D%E8%83%BD%E8%AF%86%E5%88%AB%E5%88%B0%E9%94%99%E8%AF%AF%E4%BD%8D%E7%BD%AE%EF%BC%8C%E5%8F%96%E5%86%B3%E4%BA%8Eerror%20format%E7%9A%84%E8%AE%BE%E7%BD%AE%E3%80%82Neomake!%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B9%9F%E6%98%AF%E7%B1%BB%E4%BC%BC%E7%9A%84%EF%BC%8C%E4%B9%9F%E4%BC%9A%E4%BA%A7%E7%94%9F%E4%B8%80%E4%BA%9B%E9%94%99%E8%AF%AF%EF%BC%8C%E7%84%B6%E5%90%8E%E6%98%BE%E7%A4%BA%E5%9C%A8quick%20fix%E6%88%96location%20window%E4%B8%AD%E3%80%82%0A%23%23%23%20automake%0ANeomake%E7%9A%84automake%E5%92%8CIDE%E7%9A%84syntax%20checking%E9%9D%9E%E5%B8%B8%E7%9B%B8%E4%BC%BC%E3%80%82%E5%8F%AF%E4%BB%A5%E8%87%AA%E5%8A%A8%E8%A7%A6%E5%8F%91%E8%AF%AD%E6%B3%95%E6%A3%80%E6%9F%A5%E3%80%82%E4%BD%86%E6%98%AF%E5%AF%B9%E4%BA%8EC%2FC%2B%2B%E8%BF%99%E7%A7%8D%E5%BC%BA%E7%B1%BB%E5%9E%8B%E8%AF%AD%E8%A8%80%E4%BC%BC%E4%B9%8E%E4%B8%8D%E5%A4%AA%E5%8F%8B%E5%A5%BD%E3%80%82%E5%9B%A0%E4%B8%BA%E8%A6%81%E7%89%B9%E5%88%AB%E7%9A%84%E5%8E%BB%E8%AE%BE%E7%BD%AE%E5%A4%B4%E6%96%87%E4%BB%B6%E6%90%9C%E7%B4%A2%E8%B7%AF%E5%BE%84%EF%BC%8C%E5%90%A6%E5%88%99%E6%B0%B8%E8%BF%9C%E9%83%BD%E6%98%AF%E5%A4%B4%E6%96%87%E4%BB%B6%E6%89%BE%E4%B8%8D%E5%88%B0%E7%9A%84%E9%94%99%E8%AF%AF%E3%80%82%E4%B8%8D%E8%BF%87%E7%9C%8B%E8%B5%B7%E6%9D%A5%E8%BF%99%E4%B8%AA%E5%8A%9F%E8%83%BD%E8%BF%98%E6%98%AF%E6%8C%BA%E9%AB%98%E7%BA%A7%E7%9A%84%EF%BC%8C%E8%80%8C%E4%B8%94%E4%BC%BC%E4%B9%8E%E5%B9%B6%E4%B8%8D%E5%BE%88%E5%BD%B1%E5%93%8D%E6%80%A7%E8%83%BD%E3%80%82%E8%AF%95%E8%AF%95%60%3Ahelp%20neomake-automake%60%E4%BA%86%E8%A7%A3%E6%9B%B4%E5%A4%9A%E8%AF%A6%E7%BB%86%E5%86%85%E5%AE%B9%E3%80%82%0A%E7%AE%80%E5%8D%95%E6%9D%A5%E8%AF%B4automake%E5%8F%AF%E4%BB%A5%E6%A0%B9%E6%8D%AE%E4%B8%8D%E5%90%8C%E7%9A%84%E6%A8%A1%E5%BC%8F%E8%AE%BE%E7%BD%AE%E7%BC%96%E8%AF%91%E5%BB%B6%E6%97%B6%E6%97%B6%E9%97%B4%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%9A%0A%60%60%60%20vim%0A%22%20When%20writing%20a%20buffer.%0Acall%20neomake%23configure%23automake('w')%0A%22%20When%20writing%20a%20buffer%2C%20and%20on%20normal%20mode%20changes%20(after%20750ms).%0Acall%20neomake%23configure%23automake('nw'%2C%20750)%0A%22%20When%20reading%20a%20buffer%20(after%201s)%2C%20and%20when%20writing.%0Acall%20neomake%23configure%23automake('rw'%2C%201000)%0A%60%60%60%0A%E8%BF%99%E6%A0%B7%E8%AE%BE%E7%BD%AE%E7%9A%84%E7%9B%AE%E7%9A%84%E6%98%AF%E4%B8%BA%E4%BA%86%E5%B0%91%E5%81%9A%E6%97%A0%E6%84%8F%E4%B9%89%E7%9A%84%E7%BC%96%E8%AF%91%E3%80%82%E5%BD%93%E7%84%B6%E4%BD%A0%E8%BF%98%E5%8F%AF%E4%BB%A5%E5%9C%A8vimrc%E4%B8%AD%E5%81%9A%E6%9B%B4%E5%A4%9A%E7%9A%84%E9%85%B7%E7%82%AB%E7%9A%84%E9%85%8D%E7%BD%AE%E3%80%82%0A%E4%BD%86%E5%85%B6%E5%AE%9E%E6%88%91%E6%83%B3%E5%88%86%E4%BA%AB%E7%9A%84%E6%98%AFdisable%20automake%E7%9A%84%E6%96%B9%E6%B3%95%EF%BC%8C%E5%8F%AF%E8%83%BD%E5%9B%A0%E4%B8%BA%E5%AE%83%E5%AF%B9C%2FC%2B%2B%E4%B8%8D%E5%A4%AA%E5%8F%8B%E5%A5%BD%E5%90%A7%E3%80%82%E6%9C%89%E4%B8%A4%E7%A7%8D%E6%96%B9%E6%B3%95%E5%8F%AF%E4%BB%A5%E7%A6%81%E6%AD%A2%EF%BC%9A%0A-%20%3ANeomakeDisable%2FToggle%0A-%20call%20neomake%23configure%23disable_automake()%0A%E7%AC%AC%E4%BA%8C%E7%A7%8D%E6%96%B9%E6%B3%95%E6%98%AF%E4%BB%8ENeomake%E6%BA%90%E7%A0%81%E4%B8%AD%E6%90%9C%E7%B4%A2%E5%87%BA%E6%9D%A5%E7%9A%84%EF%BC%8C%E4%B8%8D%E7%9F%A5%E9%81%93%E6%95%88%E6%9E%9C%E5%A6%82%E4%BD%95%E3%80%82%0A%0A%23%23%20Maker%0Amaker%E5%AE%9A%E4%B9%89%E4%BA%86Neomake%E5%A6%82%E4%BD%95%E6%9D%A5lint%E6%88%96compile%E3%80%82%E5%85%B6%E5%AE%9E%E5%B0%B1%E6%98%AF%E5%AE%9A%E4%B9%89%E4%BA%86%E5%85%B7%E4%BD%93%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%EF%BC%8C%E4%BB%A5%E5%8F%8A%E9%9C%80%E8%A6%81%E8%AF%86%E5%88%AB%E7%9A%84error%20format%E3%80%82%0A%3E%20A%20maker%20is%20an%20object%20that%20tells%20Neomake%20how%20to%20run%20a%20job%20for%20you.%0A%0A%E9%80%9A%E5%B8%B8%E4%BD%BF%E7%94%A8maker%E7%9A%84%E6%96%B9%E6%B3%95%E6%98%AF%E8%B0%83%E7%94%A8%E4%B8%8B%E9%9D%A2%E7%9A%84Vim%E5%91%BD%E4%BB%A4%0A%60%60%60vim%0A%3ANeomake%20%3Cmaker%20name%3E%0A%60%60%60%0A%E5%BD%93%E4%B8%8D%E4%BC%A0%E5%85%A5maker%20name%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8CNeomake%E4%BC%9A%E4%BD%BF%E7%94%A8%E7%B3%BB%E7%BB%9F%E9%BB%98%E8%AE%A4%E7%9A%84maker%EF%BC%8C%E5%8D%B3makeprg%20maker%E3%80%82%E7%9C%8B%EF%BC%8C%E6%8C%89%E7%85%A7%E4%BD%9C%E8%80%85%E7%9A%84%E6%8E%A8%E8%8D%90%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%8F%AA%E6%98%AF%E6%83%B3%E5%BC%82%E6%AD%A5%E5%9C%B0%E6%89%A7%E8%A1%8Cmake%EF%BC%8C%E5%8F%AA%E8%A6%81%E9%85%8D%E7%BD%AE%E5%A5%BDmakeprg%E5%92%8Cerror%20format%E5%B0%B1%E5%B7%B2%E7%BB%8F%E5%8F%AF%E4%BB%A5%E7%94%A8%E4%BA%86%E3%80%82%0A%3EIf%20you%20just%20want%20an%20easy%20way%20to%20run%20%7C%3Amake%7C%20asynchronously%2C%20you're%20all%20set.%0AJust%20set%20your%20%7C'makeprg'%7C%20and%20%7C'errorformat'%7C%20as%20usual%2C%20and%20run%20%7C%3ANeomake!%7C.%0A%23%23%23%20%E8%87%AA%E5%AE%9A%E4%B9%89maker%0A%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AA%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84maker%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60vim%0Alet%20g%3Aneomake_make_maker%20%3D%20%7B%0A%20%20%20%20%5C%20'exe'%3A%20'make'%2C%0A%20%20%20%20%5C%20'args'%3A%20%5B'--build'%5D%2C%0A%20%20%20%20%5C%20'errorformat'%3A%20'%25f%3A%25l%3A%25c%3A%20%25m'%2C%0A%20%20%20%20%5C%20%7D%0A%22%20Use%20the%20maker%20like%20this%3A%0A%3ANeomake!%20make%0A%60%60%60%0A%E8%BF%99%E5%87%A0%E4%B8%AA%E5%8F%82%E6%95%B0%E8%BF%98%E6%98%AF%E6%AF%94%E8%BE%83%E7%9B%B4%E6%8E%A5%E7%9A%84%E3%80%82%E5%85%B7%E4%BD%93%E4%B9%9F%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%60%3Ahelp%20neomake%60%E3%80%82%E5%AF%B9%E4%BA%8Emakeprg%20maker%EF%BC%8Cexe%E5%B0%B1%E6%98%AFmake%EF%BC%8Cargs%E5%B0%B1%E6%98%AFmakeprg%E6%8C%87%E5%AE%9A%E7%9A%84%E5%8F%82%E6%95%B0%EF%BC%8C%E8%80%8Cerror%20format%E5%B0%B1%E6%98%AFVim%E9%BB%98%E8%AE%A4%E7%9A%84error%20format%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E5%91%BD%E4%BB%A4%60set%20efm%3Dxxx%60%E6%9D%A5%E8%AE%BE%E7%BD%AE%E3%80%82error%20format%E9%82%A3%E4%BA%9B%E7%A5%9E%E5%A5%87%E7%9A%84%E5%8D%A0%E4%BD%8D%E7%AC%A6%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%60%3Ahelp%20errorformat%60%E5%B8%AE%E5%8A%A9%E6%96%87%E6%A1%A3%E3%80%82%0A%0A%5C**%E6%B3%A8%EF%BC%9A%E5%BD%93%E5%89%8D%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84.clang%E6%96%87%E4%BB%B6%E4%BC%9A%E5%BD%B1%E5%93%8D%E5%88%B0clang%20maker%E7%9A%84%E5%8F%82%E6%95%B0%E3%80%82%E4%BE%8B%E5%A6%82%E5%9C%A8.clang%E9%87%8C%E5%86%99%E4%B8%8A*%0A%60%60%60json%0A%7B%0A%20%20%20%20%22c%22%3A%20%22c11%22%2C%0A%20%20%20%20%22cpp%22%3A%20%22c%2B%2B1z%22%2C%0A%20%20%20%20%22objc%22%3A%20%22c11%22%2C%0A%20%20%20%20%22objcpp%22%3A%20%22c%2B%2B1z%22%2C%0A%7D%0A%60%60%60%0ANeomake%E7%9A%84%E5%8F%82%E6%95%B0%E4%BC%9A%E5%A4%9A%E5%87%BA%E4%B8%8B%E9%9D%A2%E8%BF%99%E4%B8%80%E6%BA%9C%EF%BC%9A%0A!%5B1515429d7a7775c66c7264357294af48.png%5D(evernotecid%3A%2F%2F22617523-9521-4D00-B771-5F27B85F00EB%2Fappyinxiangcom%2F161681%2FENResource%2Fp6063)%0A%E6%98%BE%E7%84%B6%E5%B0%B1%E6%98%AF%E6%8A%8A%E9%82%A3%E4%B8%AAjson%E5%AD%97%E5%85%B8%E6%94%BE%E5%88%B0%E5%8F%82%E6%95%B0%E9%87%8C%E5%8E%BB%E4%BA%86%E3%80%82SpaceVim%E7%94%A8.clang%E6%96%87%E4%BB%B6%E5%8F%AF%E4%BB%A5%E8%AF%86%E5%88%AB%E9%A1%B9%E7%9B%AE%E6%A0%B9%E7%9B%AE%E5%BD%95%EF%BC%8C%E6%89%80%E4%BB%A5%E8%A6%81%E5%B0%8F%E5%BF%83%E4%BA%86%EF%BC%8C%E4%B8%8D%E8%A6%81%E8%AE%A9%E4%BB%96%E7%A0%B4%E5%9D%8F%E4%BA%86Neomake%E7%9A%84%E5%8A%9F%E8%83%BD%E3%80%82%0A%0A%23%23%23%23%20Define%20a%20new%20filetype%20or%20project-level%20maker%0A%60%60%60vim%0Ag%3Aneomake_%3Cname%3E_maker%0Ag%3Aneomake_%3Cft%3E_%3Cname%3E_maker%0A%22%20%3Cft%3E%20%3D%20filetype%2C%20%E4%BE%8B%E5%A6%82%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AAC%E8%AF%AD%E8%A8%80%E7%9A%84maker%0Ag%3Aneomake_c_clang_maker%20%3D%20%7B...%7D%0A%60%60%60%0A%23%23%23%23%20Configure%20properties%20for%20a%20maker%0A%60%60%60vim%0Ag%3Aneomake_%3Cname%3E_%3Cproperty%3E%0Ag%3Aneomake_%3Cft%3E_%3Cname%3E_%3Cproperty%3E%0Ab%3Aneomake_%3Cname%3E_%3Cproperty%3E%0Ab%3Aneomake_%3Cft%3E_%3Cname%3E_%3Cproperty%3E%0A%22%20g%3A%20%E8%A1%A8%E7%A4%BA%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%EF%BC%8C%20b%3A%20%E8%A1%A8%E7%A4%BAbuffer%E7%BA%A7%E5%8F%98%E9%87%8F%0A%60%60%60%0Awhere%20%3Cproperty%3E%20is%20one%20of%20%60'exe'%2C%20'args'%2C%20'errorformat'%2C%20'buffer_output'%2C%20'remove_invalid_entries'%2C%20'append_file'%2C%20or%20'supports_stdin'%60.%0A%23%23%23%23%20Eabled%20makers%0A%60%60%60vim%0A%22%20This%20setting%20will%20tell%20Neomake%20which%20makers%20to%20use%20by%20default%20for%20the%20given%20filetype%20%60%3Cft%3E%60%20(when%20called%20without%20a%20maker%20as%20an%20argument%2C%0Ag%3Aneomake_enabled_makers%0Ab%3Aneomake_enabled_makers%0A%0A%22%20This%20setting%20will%20tell%20Neomake%20which%20makers%20to%20use%20by%20default%20for%20the%20given%20filetype%20%60%3Cft%3E%60%20(when%20called%20without%20a%20maker%20as%20an%20argument%2C%0Ag%3Aneomake_%3Cft%3E_enabled_makers%0Ab%3Aneomake_%3Cft%3E_enabled_makers%0A%60%60%60%0A%E9%80%9A%E8%BF%87%E6%9F%A5%E7%9C%8B%E4%B8%8A%E9%9D%A2%E7%9A%84%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E5%8F%AF%E4%BB%A5%E4%BA%86%E8%A7%A3%E5%88%B0%E5%BD%93%E5%89%8D%E4%BD%BF%E8%83%BD%E7%9A%84%E4%B8%80%E4%BA%9Bmaker%E3%80%82%E6%89%80%E6%9C%89%E8%AF%AD%E8%A8%80%E7%9B%B8%E5%85%B3%E7%9A%84maker%E9%83%BD%E5%AE%9A%E4%B9%89%E5%9C%A8%60neomake%2Fneomake%2Fautoload%2Fneomake%2Fmakers%2F%60%E4%B8%AD%E3%80%82%E4%BE%8B%E5%A6%82%60neomake%2Fneomake%2Fautoload%2Fneomake%2Fmakers%2Fft%2Fc.vim%60%2C%20%60neomake%2Fneomake%2Fautoload%2Fneomake%2Fmakers%2Fft%2Fcpp.vim%60%E7%AD%89%E7%AD%89%E3%80%82%0A%E5%BD%93%E7%94%A8%E6%88%B7%E8%B0%83%E7%94%A8Neomake%E5%B9%B6%E4%BC%A0%E5%85%A5maker%E5%90%8D%E6%97%B6%EF%BC%8C%E5%88%99%E7%9B%B4%E6%8E%A5%E4%BD%BF%E7%94%A8%E5%AF%B9%E5%BA%94%E7%9A%84maker%E6%9D%A5%E7%BC%96%E8%AF%91%E3%80%82%E5%A6%82%E6%9E%9C%E6%9C%AA%E4%BC%A0%E5%85%A5maker%E5%90%8D%EF%BC%8C%E5%88%99%E6%A0%B9%E6%8D%AE%E4%BB%A5%E4%B8%8A%E4%BD%BF%E8%83%BD%E7%9A%84maker%E6%9D%A5%E8%B0%83%E7%94%A8%E5%AF%B9%E5%BA%94%E7%9A%84maker%E7%BC%96%E8%AF%91%E3%80%82%0A%0A%E5%BD%93%E4%BD%BF%E7%94%A8%60%3ANeomake%60%E6%97%B6%EF%BC%9A%0A-%20%E9%A6%96%E5%85%88%E5%B0%9D%E8%AF%95%E4%BD%BF%E7%94%A8%60g%3Aneomake_%3Cft%3E_enabled_makers%60%EF%BC%8C%60%3Cft%3E%60%E4%B8%BA%E5%BD%93%E5%89%8Dbuffer%E7%9A%84filetype%0A-%20%E8%8B%A5%E5%BD%93%E5%89%8D%E6%B2%A1%E6%9C%89%E4%B8%BA%60%3Cft%3E%60%E5%AE%9A%E4%B9%89%E7%9A%84maker%EF%BC%8C%E5%88%99%E4%BD%BF%E7%94%A8%60g%3Aneomake_enabled_makers%60%E5%AE%9A%E4%B9%89%E7%9A%84maker%0A%0A%E5%BD%93%E4%BD%BF%E7%94%A8%60%3ANeomake!%60%E6%97%B6%2C%E5%88%99%E7%9B%B4%E6%8E%A5%E4%BD%BF%E7%94%A8%60g%3Aneomake_enabled_makers%60%E5%AE%9A%E4%B9%89%E7%9A%84maker%0A%0A%23%23%20%E6%9C%89%E7%94%A8%E7%9A%84%E9%85%8D%E7%BD%AE%0ANeomake%E7%9A%84%E6%89%80%E6%9C%89%E4%BF%A1%E6%81%AF%E9%83%BD%E5%9C%A8%E5%AE%83%E7%9A%84%E5%B8%AE%E5%8A%A9%E6%96%87%E6%A1%A3%E9%87%8C%EF%BC%8C%E7%94%A8%60%3Ahelp%20neomake%60%E5%91%BD%E4%BB%A4%E6%9D%A5%E6%9F%A5%E7%9C%8B%E5%90%A7%E3%80%82%E4%B9%9F%E5%8F%AF%E4%BB%A5%E7%9C%8B%5B%E7%BD%91%E9%A1%B5%E7%89%88%5D(https%3A%2F%2Fgithub.com%2Fneomake%2Fneomake%2Fblob%2Fmaster%2Fdoc%2Fneomake.txt)%E3%80%82%0A%E4%B8%8B%E9%9D%A2%E6%91%98%E5%BD%95%E4%B8%80%E4%BA%9B%E6%88%91%E9%80%9A%E8%AF%BB%E8%BF%87neomake%E5%B8%AE%E5%8A%A9%E6%96%87%E6%A1%A3%E5%90%8E%EF%BC%8C%E8%AE%A4%E4%B8%BA%E6%9C%89%E7%94%A8%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BF%A1%E6%81%AF%EF%BC%8C%E4%BB%A5%E9%A3%A8%E8%AF%BB%E8%80%85%E3%80%82%0A%0A%23%23%23%20neomake-args-file%0AWhen%20running%20a%20maker%20on%20a%20file%20with%20%7C%3ANeomake%7C%2C%20you%20may%20want%20to%20control%20where%20in%20the%20%60args%60%20list%20the%20file's%20path%20will%20appear.%20To%20do%20this%2C%20insert%20'%25t'%20in%20the%20%60args%60%20list%20and%20use%20%60append_file%3D0%60%3A%20%0A%60%60%60%20vim%0Alet%20g%3Aneomake_c_lint_maker%20%3D%20%7B%0A%20%20%20%20%5C%20'exe'%3A%20'lint'%2C%0A%20%20%20%20%5C%20'args'%3A%20%5B'%25t'%2C%20'--option'%2C%20'x'%5D%2C%0A%20%20%20%20%5C%20'append_file'%3A%200%2C%0A%20%20%20%20%5C%20'errorformat'%3A%20'%25f%3A%25l%3A%25c%3A%20%25m'%2C%0A%20%20%20%20%5C%20%7D%0A%60%60%60%0AThis%20will%20cause%20%22lint%20%2Fpath%2Fto%2Ffile.c%20--option%20x%22%20to%20be%20run%20instead%20of%0A%22lint%20--option%20x%20%2Fpath%2Fto%2Ffile.c%22.%0A%0A%60%25t%60%20gets%20replaced%20with%20the%20absolute%20path%20to%20the%20file%20(handling%20any%20temporary%0Afile).%0A%0A%23%23%23%20neomake-makers-remove_invalid_entries%0ADefault%3A%200%0AThis%20option%20filters%20invalid%20entries%20from%20makers%20from%20the%20location%2Fquickfix%0Alist%20(i.e.%20entries%20that%20do%20not%20match%20the%20%7C'errorformat'%7C%2C%20and%20that%20would%20show%0Aup%20with%20a%20%60%7C%7C%60%20prefix%20in%20the%20location%2Fquickfix%20list)%3A%0A%60%60%60%20vim%0A%20%20%20%20let%20g%3Aneomake_ft_maker_remove_invalid_entries%20%3D%201%0A%60%60%60%0ANOTE%3A%20the%20default%20for%20this%20is%200%2C%20because%20unhandled%2Funexpected%20output%20might%20be%0Auseful%2C%20e.g.%20when%20the%20program%20displays%20some%20error.%0A**Makers%20should%20handle%20this%20properly%20through%20%7Cerrorformat%7C%2C%20e.g.%20by%20using%20'%25-G'**(see%20%7Cefm-ignore%7C%20and%20%7Cneomake-faq-errorformat%7C).%0A%5C*%20*%E6%B3%A8%3A%20%E4%BA%8B%E5%AE%9E%E8%AF%81%E6%98%8E%E6%9C%89%E6%97%B6%E5%80%99%E5%95%A5%E9%83%BD%E6%B2%A1%E6%9C%89%EF%BC%8C%E6%98%AF%E5%9B%A0%E4%B8%BAerror%20format%E6%B2%A1%E8%AE%BE%E7%BD%AE%E5%A5%BD*%0A%0A%23%23%23%20neomake-makers-cwd%0AThe%20working%20directory%20of%20a%20maker%20defaults%20to%20the%20current%20working%20directory%20of%20the%20make%20run%20(%7Cgetcwd()%7C).%0AThe%20%60cwd%60%20property%20overrides%20this%2C%20and%20gets%20expanded%20in%20the%20context%20of%20the%20current%20buffer.%20Special%20buffers%20(like%20fugitive%20blobs)%20get%20handled%20for%20values%20starting%20with%20%60%25%3A%60%20(typically%20used%20in%20this%20context)%2C%20falling%20back%20to%20%7Cexpand()%7C.%20See%20%7Cfilename-modifiers%7C.%0AExample%3A%20change%20to%20the%20buffer's%20directory%3A%0A%60%60%60%20vim%0Alet%20g%3Aneomake_my_example_maker%20%3D%20%7B%0A%20%20%20%20%5C%20'exe'%3A%20'pwd'%2C%0A%20%20%20%20%5C%20'cwd'%3A%20'%25%3Ap%3Ah'%0A%20%20%20%20%5C%20%7D%0A%60%60%60%0A%0A%23%23%23%20neomake_open_list%0Ag%3Aneomake_open_list%0AThis%20setting%20will%20open%20the%20%7Clocation-list%7C%20or%20%7Cquickfix%7C%20list%20(depending%20on%20whether%20it%20is%20operating%20on%20a%20file)%20when%20adding%20entries.%20A%20value%20of%202%20will%20preserve%20the%20cursor%20position%20when%20the%20%7Clocation-list%7C%20or%20%7Cquickfix%7C%20window%20is%20opened.%20Defaults%20to%200.%0A%5C*%20*%E8%A7%A3%E9%87%8A%EF%BC%9A%E5%BD%93%E6%9C%89%E6%96%B0entry%E6%9D%A5%E7%9A%84%E6%97%B6%E5%80%99%E6%98%AF%E5%90%A6%E6%89%93%E5%BC%80quickfix%E6%88%96location-list%EF%BC%8C%E5%8F%96%E5%80%BC%E4%B8%BA2%E6%97%B6%EF%BC%8C%E8%A1%A8%E7%A4%BA%E6%89%93%E5%BC%80%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%83%BDkeep%E5%8E%9F%E5%85%88%E7%9A%84%E4%BD%8D%E7%BD%AE%E3%80%82%E6%98%BE%E7%84%B6%E9%80%892%E6%AF%94%E8%BE%83%E5%A5%BD*%0A%0A%23%23%23%20neomake_virtualtext_current_error%0Ag%3Aneomake_virtualtext_current_error%0A%E9%80%89%E6%8B%A9%E6%98%AF%E5%90%A6%E6%98%BE%E7%A4%BAvirtual%20text%EF%BC%8C%E6%98%BE%E7%84%B6%E8%A6%81%E6%98%BE%E7%A4%BA%E5%95%8A%EF%BC%8C%E5%A4%9A%E4%B9%88%E9%85%B7%E7%82%AB%E3%80%82%0A%0A%23%23%23%20neomake%20log%0Ag%3Aneomake_verbose%0A%3E%200%20-%20Errors%20only%0A%20%201%20-%20Quiet%20message%0A%20%202%20-%20Loud%20message%20(may%20log%20multiple%20messages%20at%20once%2C%20making%20the%20screen%20shift%20momentarily)%0A%20%203%20-%20Debug%20information%20(all%20messages).%20This%20will%20also%20add%20time%20information%20to%20messages.%0A%20%20%0A%E8%BF%99%E4%B8%AA%E5%9C%A8%E4%BD%BF%E7%94%A8Neomake%E6%97%B6%E6%AF%AB%E6%97%A0%E5%8F%8D%E5%BA%94%E6%97%B6%EF%BC%8C%E7%89%B9%E5%88%AB%E6%9C%89%E7%94%A8%E3%80%82%E5%BC%80%E5%90%AFlog%E5%86%8D%E7%94%A8%60%3Amessages%60%E5%91%BD%E4%BB%A4%E6%9F%A5%E7%9C%8B%E5%B0%B1%E5%8F%AF%E4%BB%A5%E7%9F%A5%E9%81%93%E5%8F%91%E7%94%9F%E4%BA%86%E4%BB%80%E4%B9%88%E3%80%82%0A%0A%23%23%20%E6%80%BB%E7%BB%93%0ANeomake%E6%98%AF%E4%B8%AA%E5%BC%82%E6%AD%A5%E7%BC%96%E8%AF%91%E4%B8%8D%E9%94%99%E7%9A%84%E9%80%89%E6%8B%A9%EF%BC%8C%E5%8F%AF%E4%BB%A5%E8%80%83%E8%99%91%E5%8F%96%E4%BB%A3vim%E8%87%AA%E5%B8%A6%E7%9A%84make%20%2B%20makeprg%EF%BC%8C%E5%B9%B6%E5%81%9A%E5%88%B0%E5%BC%82%E6%AD%A5%E7%BC%96%E8%AF%91%E3%80%82%E4%B8%8D%E8%BF%87%E5%89%8D%E6%8F%90%E6%98%AF%E8%BF%98%E6%98%AF%E8%A6%81%E5%A5%BD%E5%A5%BD%E4%BA%86%E8%A7%A3%E4%B8%80%E4%B8%8Berror%20format%EF%BC%8C%E8%BF%99%E5%85%B6%E4%B8%AD%E5%AF%B9%E9%94%99%E8%AF%AF%E5%A4%84%E7%9A%84%E8%B7%B3%E8%BD%AC%E5%92%8C%E6%98%BE%E7%A4%BA%E6%9C%89%E7%9D%80%E5%86%B3%E5%AE%9A%E6%80%A7%E7%9A%84%E4%BD%9C%E7%94%A8%E3%80%82