Skip to content

Latest commit

 

History

History
232 lines (118 loc) · 16 KB

defs_linux_s390x.go.md

File metadata and controls

232 lines (118 loc) · 16 KB

File: defs_linux_s390x.go

defs_linux_s390x.go是Go语言运行时系统(runtime)的一个文件,它是针对Linux平台下s390x架构的操作系统的运行时系统定义文件。

该文件的作用是定义了基于Linux s390x平台的安全栈,其在Go程序中实现了对栈缓冲区溢出攻击的防护机制。在该文件中,主要实现了利用硬件保护功能(registers-per-page)来隔离栈页,提高程序的安全性。

此外,defs_linux_s390x.go文件还定义了一些与s390x平台相关的系统调用,如dup3、openat2等函数,以及线程和信号量的相关定义。

总之,该文件为Go语言在s390x架构下的运行时系统提供了重要的底层支持。


Structs:

timespec

timespec是一个包含秒和纳秒数量的结构体,在Linux系统下通常用于表示时间。该结构体在Go语言的运行时(runtime)中定义,用于在s390x架构上进行系统调用时传递时间参数。

在defs_linux_s390x.go文件中,定义了timespec结构体的两个字段:Sec和Nsec,分别表示秒数和纳秒数。这个结构体通常用于进行时间戳的计算和比较。在系统调用中,参数需要按照特定的格式传递,而使用timespec结构体可以方便地将时间参数传递给系统调用。

总的来说,timespec结构体在Linux系统下通常用于表示时间,而在Go语言的运行时中则用于在s390x架构上进行系统调用时传递时间参数,具有重要的作用。

timeval

在defs_linux_s390x.go中,timeval是一个结构体,它用于在Linux s390x上表示时间值。具体来说,它包含了两个字段:

  1. tv_sec:表示自1970年1月1日00:00:00以来经过的秒数,类型为int64。
  2. tv_usec:表示自1970年1月1日00:00:00以来经过的微秒数,类型为int64。

这个结构体主要被用于获取系统时间,特别是在实现定时器、时间片轮转等功能时。通过获取当前时间,可以精确地控制程序的行为。在Linux上,timeval结构体常常被用作与时间相关系统调用的参数,例如gettimeofday()系统调用。它也可以被用于文件时间戳和进程执行时间的计算。

sigactiont

defs_linux_s390x.go是Go语言运行时在Linux/s390x下的实现文件,该文件中定义了一些与平台相关的数据类型、常量、系统调用等。其中,sigactiont结构体定义了Linux下的信号处理函数信息。

信号是Linux操作系统的一种通信机制,用于处理来自系统的异常事件和异步事件。sigactiont结构体定义了信号处理函数的指针类型,并提供了一些控制信号处理行为的选项,如SA_RESTART、SA_SIGINFO、SA_ONSTACK、SA_NOCLDSTOP等。其中,SA_RESTART表示在被信号打断的系统调用结束后,自动重新开始该系统调用;SA_SIGINFO表示信号处理函数能够获取更多的关于信号的信息;SA_ONSTACK表示在备用栈上使用信号处理函数;SA_NOCLDSTOP表示忽略子进程停止和恢复的信号。

在Go语言中,使用signal包来处理信号,其中的SIGACT函数调用就是通过sigactiont结构体来定义信号处理函数和控制信号处理行为的。因此,了解sigactiont结构体的定义和作用对于理解Go语言中的信号处理机制十分重要。

siginfoFields

在Go语言运行时的s390x架构上,defs_linux_s390x.go文件中的siginfoFields结构体用于描述用于信号处理的siginfo_t结构的字段。siginfo_t结构是一个包含信号信息的结构体,当进程收到信号时,会向进程发送一个包含该信号信息的siginfo_t结构。

siginfoFields结构体包含了以下字段:

  • Signo:表示收到的信号的编号。
  • Code:表示引起信号的原因,例如SEGV代表了有一个非法的内存引用。
  • Errno:表示有关信号或产生信号的那个进程的错误代码。
  • Trapno:表示在引起信号的情况下在系统中引发的trap(processor exception)的编号。
  • PID:表示进程的进程ID(PID)。
  • UID:表示进程的用户ID。
  • Status:表示进程的状态。
  • Band:表示使用SIGPOLL时,它的带值。
  • Overrun:表示定时服务计数器是否已经过期。
  • Timerid:表示用于触发该信号的定时器ID。
  • Signame:表示信号的名称。
  • Coredump:表示是否生成了核心转储文件。

这些字段提供了信号处理过程中的关键信息,包括信号的类型、进程的状态、信号的抛出原因和引发信号的程序。

需要注意的是,这些字段是为了方便Linux系统内核和用户空间之间的通信而定义的,这些字段的具体含义也并不是每个架构都相同。此外,Go语言运行时使用sigaction函数来设置信号处理程序,sigaction函数可以为信号处理程序提供许多其他信息,例如值和其他选项,而不仅仅是上述字段。

siginfo

siginfo是一个结构体类型,用于在信号处理程序中传递关于信号的信息。在go/src/runtime中的defs_linux_s390x.go文件中,siginfo 结构体是针对Linux下的s390x平台的定义。

在 s390x 平台上,siginfo 结构体包含以下字段:

  • Signo:信号的编号。
  • Errno:设置errno的值。
  • Code:信号代码。对于大多数信号该字段为 SI_USER,表示该信号是由用户进程发送的。其他一些信号有不同的代码,例如SIGILL信号的代码可能是 SI_KERNEL,表示与内核处理器的错误有关。
  • Pad_cgo_0_to_3:golang对齐所需的填充字段。
  • _pid_t:信号发送进程的ID。
  • _uid_t:信号发送进程的用户ID。
  • Status:如果信号产生了一个子进程,这个字段包含了它的退出状态。
  • Band:用于SIGPOLL信号的位掩码。
  • Pad_cgo_4_to_7:golang对齐所需的填充字段。

siginfo结构体的定义为实现信号处理程序时提供了一个重要的工具,使它们能够获得信号相关的信息以及产生信号的进程相关的信息。这个结构体是直接由操作系统内核传递给信号处理程序的,因此它是非常重要和高效的。

itimerspec

在 Linux 系统中,itimerspec 结构体用于描述 POSIX 定时器的状态。POSIX定时器是一种计时器,它可以与进程关联并允许进程在指定的时间间隔内重复触发定时器事件。在 Linux 中,POSIX 定时器主要由两种类型:ITIMER_REAL和ITIMER_VIRTUAL。ITIMER_REAL 类型用于计算实际经过的时间,而 ITIMER_VIRTUAL 类型用于计算进程在虚拟地址空间中运行的 CPU 时间。

itimerspec 结构体是在文件 defs_linux_s390x.go 中定义的,它具有以下成员:

type itimerspec struct {
    it_interval syscall.Timespec // 定时器重复间隔
    it_value    syscall.Timespec // 定时器初始值
}

其中,it_interval 成员描述定时器事件重复触发的时间间隔,it_value 成员描述定时器事件第一次触发的时间。

在 Linux 系统中,itimerspec 结构体是用于设置和获取 POSIX 定时器状态的重要数据结构。当我们需要在代码中使用 POSIX 定时器时,通过设置 itimerspec 结构体的成员变量,就可以控制定时器的触发频率和初始触发时间,从而实现我们需要的计时功能。

itimerval

在Go语言的运行时中,defs_linux_s390x.go这个文件定义了一些与操作系统相关的底层数据结构和类型,其中包括itimerval结构体。

itimerval结构体表示了一个定时器的时间值,它由两个成员变量组成:

  1. it_interval:表示定时器的定时周期,即定时器在一次到期后再次到期的时间间隔。

  2. it_value:表示定时器的当前时间值,即距离下一次到期还有多长时间。

在操作系统中,定时器是常用的工具之一,可以用来实现定时任务、事件触发等功能。在Go语言的运行时中,通过定义itimerval结构体,可以方便地获取、设置定时器的时间值,并在需要时启动、停止定时器。

举个例子,假设我们需要每隔一段时间执行一次某个函数。可以使用以下代码启动一个定时器:

var timer itimerval
timer.it_interval = syscall.NsecToTimeval(interval)
timer.it_value = syscall.NsecToTimeval(interval)
syscall.Setitimer(syscall.ITIMER_REAL, &timer, nil)

上述代码中,interval表示定时器的定时周期,单位为纳秒。通过调用syscall.NsecToTimeval将interval转换为符合itimerval结构体的格式,然后传递给syscall.Setitimer函数启动一个定时器。

总之,itimerval结构体的作用是在Go语言的运行时中定义了一个与操作系统相关的底层数据结构,可以方便地获取、设置定时器的时间值,并启动、停止定时器。

sigeventFields

在Go语言的runtime包中,defs_linux_s390x.go文件定义了一些常量和结构体,用于Linux平台上的System z系列(s390x架构)的操作系统。其中,sigeventFields这个结构体用于描述Linux系统信号事件参数。

具体来说,sigeventFields结构体包含三个字段,分别是:

  • Value:表示该事件相关联的值;
  • Signo:表示要发送的信号编号;
  • Notify:表示通知方式。

这三个字段中,最重要的是Signo字段,因为它决定了要发送哪个信号。在Linux系统中,当程序需要和外界进行通信时,可以使用信号机制来交换信息。例如,当一些操作完成后,可以发送SIGUSR1信号,让另一个进程做出响应。在这种情况下,可使用sigeventFields结构体来描述要发送的信号事件。

除了上述作用外,sigeventFields结构体还与timer进行了绑定。当创建定时器时,需要指定一个sigeventFields结构体,用于描述要发送的定时器信号事件。这样,当定时器到期时,就会发送指定的信号,通知相关进程执行相应操作。

总之,sigeventFields结构体是在Linux系统上操作信号和定时器时使用的一个重要工具,用于描述相关的参数和事件。

sigevent

sigevent结构体定义在Go语言运行时的defs_linux_s390x.go文件中,用于描述信号通知事件。

在Unix/Linux系统中,进程可以通过signal函数向另一个进程或进程组发送信号。当信号到达目标进程或进程组后,目标进程可以通过信号处理函数进行对应的处理。但在某些场景中,目标进程需要知道是哪个事件导致了信号的产生,比如异步I/O操作完成时,操作系统会向进程发送一个信号通知I/O操作完成,此时进程需要获知是哪个具体的I/O操作完成了。

为了解决这个问题,sigevent结构体就应运而生了。它描述了一个引起信号通知的事件,包括事件类型、目标进程的ID、通知的数据等信息。当事件发生时,操作系统会以sigevent结构体的形式将通知信息发送给目标进程,进程通过对sigevent结构体进行解析,就可以得到事件的相关信息,从而进行对应的处理。

在Go语言运行时中,sigevent结构体主要用于描述异步I/O操作完成的相关信息,具体可以参考Go语言运行时中关于异步I/O的相关实现。

stackt

在Go语言的runtime包下的defs_linux_s390x.go文件中,定义了一个名为stackt的结构体,它表示一个线程的堆栈。

堆栈是程序运行时存储局部变量、函数调用信息等重要数据的内存区域。在操作系统层面,一个线程需要一个堆栈来保存它的执行状态。在Go语言中,一般将线程的堆栈从堆上分配,然后使用stackt结构体来表示堆栈的相关信息。

在stackt结构体中,定义了以下字段:

  • ss_sp:指向堆栈区域的起始地址。
  • ss_size:堆栈区域的大小,单位为字节。
  • ss_flags:堆栈的属性标志,例如是否可执行、是否可写等。
  • ss_reserved:保留字段。

除此之外,stackt结构体还有一个名为guard的内嵌结构体,用于定义堆栈的保护区域。保护区域一般放置在堆栈的边缘,用于检测堆栈的溢出情况,防止堆栈溢出导致的异常程序行为。保护区域的大小和属性可以通过guard结构体中的字段进行定义。

综上所述,defs_linux_s390x.go文件中的stackt结构体定义了Linux平台下线程堆栈的相关信息,包括堆栈区域的起始地址、大小、属性标志以及保护区域的大小和属性等。这些信息对于实现Go语言的协程调度、内存管理等功能非常重要。

sigcontext

在GO语言的运行时源码中,defs_linux_s390x.go这个文件定义了与Linux s390x平台相关的底层函数和数据结构。其中,sigcontext结构体是用于访问信号处理程序上下文信息的数据结构。

在Linux中,当进程接收到信号时,内核会将进程的当前状态保存在一个称为信号处理程序上下文的数据结构中,然后调用信号处理程序。信号处理程序可以访问这个上下文信息以了解信号被接收时进程的状态,例如CPU寄存器、堆栈指针、程序计数器等。

在SIGCONTEXT结构体中,包含了保存在注册时状态中的所有通用寄存器的值和其他与信号相关的状态信息。该结构体的定义和内容通常是由特定的平台和操作系统所确定的,并且由操作系统提供对信号处理的支持。

在GO语言的运行时环境中,该结构体主要用于实现对信号处理程序的支持。通过访问这个结构体可以获取到当前进程运行时的总体状态信息,有了这些信息,就可以在信号处理程序中完成一些自定义处理,从而达到保护进程的目的。

ucontext

在Linux s390x(IBM System z)平台上,ucontext结构体用于表示线程或信号处理程序的上下文信息,包含一组CPU寄存器的值、程序计数器和一些其他的控制寄存器。当发生异常或信号处理时,操作系统会把线程或信号处理程序的上下文信息保存在ucontext结构体中,然后将控制权转移到相应的异常处理程序或信号处理程序中。在程序计数器和寄存器的值被恢复后,线程或信号处理程序就可以恢复执行状态,继续执行之前被中断的代码。

在Go语言运行时的实现中,ucontext结构体被用于表示一个goroutine的上下文信息。当一个goroutine被抢占或是等待I/O完成时,会将该goroutine的上下文保存到ucontext结构体中。在goroutine重新获得执行时,该上下文会被恢复,让goroutine能够继续执行之前被中断的代码。

Functions:

setNsec

setNsec函数是用于将秒和纳秒转换为一个整数表示纳秒的函数。在Linux s390x架构中,时间戳由两部分组成,一部分是秒数,另一部分是纳秒数。而在Go语言中,时间戳是以纳秒为单位表示的。因此,需要将这两部分组合成一个整数表示纳秒。

setNsec函数接受两个参数,一个是秒数,另一个是纳秒数。将它们相加并将结果乘以1e9,从而将时间戳转换为纳秒。这个函数被用于设置goroutine的开始时间和结束时间,并被多个地方调用,包括调用Go语言的time包中的函数。

在Linux s390x架构中,setNsec函数的实现与其他平台可能会有所不同,因为不同的平台有不同的硬件时钟和系统调用,因此需要对其进行适当的修改以确保正确的时间戳。

set_usec

set_usec是用于设置Linux平台上S390x架构系统的定时器的函数。

在S390x架构系统上,定时器的计时单位是微秒(usec),set_usec函数就是用于设置定时器的计时周期。这个周期定义了定时器每个滴答之间的微秒数,它会影响到计时器的精确度和性能。

在set_usec函数中,它首先将给定的计时周期参数转换为一个64位的整数类型,然后将这个值存储到与定时器相关的数据结构中,最后通过调用kernel中的setitimer系统调用函数来启动定时器。

定时器在S390x架构系统中通常被用于实现一些时间相关的功能,例如计时器、调度器、网络协议等。set_usec函数的作用就是为这些功能提供精确的时间基准,并确保它们按照期望的方式运行。