mirror of
				https://github.com/taigrr/gopher-os
				synced 2025-01-18 04:43:13 -08:00 
			
		
		
		
	Merge pull request #66 from achilleasa/ensure-kernel-builds-with-different-go-versions
Ensure kernel builds with different go versions
This commit is contained in:
		
						commit
						c88c72657d
					
				
							
								
								
									
										30
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								.travis.yml
									
									
									
									
									
								
							| @ -1,9 +1,29 @@ | |||||||
| language: go | language: go | ||||||
| sudo: required | sudo: required | ||||||
|  | addons: | ||||||
|  |   apt: | ||||||
|  |     packages: | ||||||
|  |     - nasm | ||||||
|  |     - binutils-2.26 | ||||||
|  | # Compile kernel with various go versions | ||||||
| go: | go: | ||||||
|  |   - 1.7.x | ||||||
|  |   - 1.8.x | ||||||
|  |   - 1.9.x | ||||||
|  |   - 1.10.x | ||||||
|   - 1.x |   - 1.x | ||||||
| script: | stage: build kernel | ||||||
|   - make lint | before_install: | ||||||
|   - make collect-coverage |   - export PATH=/usr/lib/binutils-2.26/bin:${PATH} | ||||||
| after_success: | script: make kernel | ||||||
|   - bash <(curl -s https://codecov.io/bash) | 
 | ||||||
|  | # Run the tests against the latest go version | ||||||
|  | jobs: | ||||||
|  |   include: | ||||||
|  |     - stage: run tests | ||||||
|  |       go: 1.x | ||||||
|  |       script: | ||||||
|  |         - make lint | ||||||
|  |         - make collect-coverage | ||||||
|  |       after_success: | ||||||
|  |         - bash <(curl -s https://codecov.io/bash) | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								BUILD.md
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								BUILD.md
									
									
									
									
									
								
							| @ -11,7 +11,7 @@ To compile gopher-os wheh running on Linux you need a fairly recent version of: | |||||||
| - grub | - grub | ||||||
| - nasm  | - nasm  | ||||||
| - gcc (for GNU ld) | - gcc (for GNU ld) | ||||||
| - go (1.6+; recommended: 1.8) | - go 1.7+ | ||||||
| 
 | 
 | ||||||
| The above dependencies can be installed using the appropriate package manager  | The above dependencies can be installed using the appropriate package manager  | ||||||
| for each particular Linux distribution. | for each particular Linux distribution. | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								Makefile
									
									
									
									
									
								
							| @ -22,7 +22,6 @@ FUZZ_PKG_LIST := src/gopheros/device/acpi/aml | |||||||
| ifeq ($(OS), Linux) | ifeq ($(OS), Linux) | ||||||
| export SHELL := /bin/bash -o pipefail | export SHELL := /bin/bash -o pipefail | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| LD := ld | LD := ld | ||||||
| AS := nasm | AS := nasm | ||||||
| 
 | 
 | ||||||
| @ -62,11 +61,13 @@ go.o: | |||||||
| 	    -e "1s|^|export GOOS=$(GOOS)\n|" \
 | 	    -e "1s|^|export GOOS=$(GOOS)\n|" \
 | ||||||
| 	    -e "1s|^|export GOARCH=$(GOARCH)\n|" \
 | 	    -e "1s|^|export GOARCH=$(GOARCH)\n|" \
 | ||||||
| 	    -e "1s|^|export GOROOT=$(GOROOT)\n|" \
 | 	    -e "1s|^|export GOROOT=$(GOROOT)\n|" \
 | ||||||
| 	    -e "1s|^|WORK='$(BUILD_ABS_DIR)'\n|" \
 | 	    -e "1s|^|export CGO_ENABLED=0\n|" \
 | ||||||
| 	    -e "1s|^|alias pack='$(GO) tool pack'\n|" \
 | 	    -e "1s|^|alias pack='$(GO) tool pack'\n|" \
 | ||||||
| 	    -e "/^mv/d" \
 | 	    -e "/^mv/d" \
 | ||||||
|  | 	    -e "/\/buildid/d" \
 | ||||||
| 	    -e "s|-extld|-tmpdir='$(BUILD_ABS_DIR)' -linkmode=external -extldflags='-nostartfiles -nodefaultlibs -nostdlib -r' -extld|g" \
 | 	    -e "s|-extld|-tmpdir='$(BUILD_ABS_DIR)' -linkmode=external -extldflags='-nostartfiles -nodefaultlibs -nostdlib -r' -extld|g" \
 | ||||||
| 	    | sh 2>&1 | sed -e "s/^/  | /g" | 	    -e 's|$$WORK|$(BUILD_ABS_DIR)|g' \
 | ||||||
|  |             | sh 2>&1 |  sed -e "s/^/  | /g" | ||||||
| 
 | 
 | ||||||
| 	@# build/go.o is a elf32 object file but all go symbols are unexported. Our | 	@# build/go.o is a elf32 object file but all go symbols are unexported. Our | ||||||
| 	@# asm entrypoint code needs to know the address to 'main.main' so we use | 	@# asm entrypoint code needs to know the address to 'main.main' so we use | ||||||
| @ -105,7 +106,7 @@ $(BUILD_DIR)/go_asm_offsets.inc: | |||||||
| 	@mkdir -p $(BUILD_DIR) | 	@mkdir -p $(BUILD_DIR) | ||||||
| 
 | 
 | ||||||
| 	@echo "[tools:offsets] calculating OS/arch-specific offsets for g, m and stack structs" | 	@echo "[tools:offsets] calculating OS/arch-specific offsets for g, m and stack structs" | ||||||
| 	@GOPATH=$(GOPATH) $(GO) run tools/offsets/offsets.go -target-os $(GOOS) -target-arch $(GOARCH) -go-binary $(GO) -out $@ | 	@GOROOT=$(GOROOT) GOPATH=$(GOPATH) $(GO) run tools/offsets/offsets.go -target-os $(GOOS) -target-arch $(GOARCH) -go-binary $(GO) -out $@ | ||||||
| 
 | 
 | ||||||
| $(BUILD_DIR)/arch/$(ARCH)/asm/%.o: src/arch/$(ARCH)/asm/%.s | $(BUILD_DIR)/arch/$(ARCH)/asm/%.o: src/arch/$(ARCH)/asm/%.s | ||||||
| 	@mkdir -p $(shell dirname $@) | 	@mkdir -p $(shell dirname $@) | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							| @ -4,6 +4,17 @@ | |||||||
| [](https://goreportcard.com/report/github.com/achilleasa/gopher-os) | [](https://goreportcard.com/report/github.com/achilleasa/gopher-os) | ||||||
| [](LICENSE) | [](LICENSE) | ||||||
| 
 | 
 | ||||||
|  | | Go 1.7.x            | Go 1.8.x            | Go 1.9.x            | Go 1.10.x            | Go 1.x            | | ||||||
|  | |---------------------|---------------------|---------------------|----------------------|-------------------| | ||||||
|  | | [![go 1.7.x][1]][6] | [![go 1.8.x][2]][6] | [![Go 1.9.x][3]][6] | [![go 1.10.x][4]][6] | [![go 1.x][5]][6] | | ||||||
|  | 
 | ||||||
|  | [1]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/1 | ||||||
|  | [2]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/2 | ||||||
|  | [3]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/3 | ||||||
|  | [4]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/4 | ||||||
|  | [5]: https://travis-matrix-badges.herokuapp.com/repos/achilleasa/gopher-os/branches/master/5 | ||||||
|  | [6]: https://travis-ci.org/achilleasa/gopher-os | ||||||
|  | 
 | ||||||
| The goal of this project is to build a 64-bit POSIX-compliant tick-less kernel | The goal of this project is to build a 64-bit POSIX-compliant tick-less kernel | ||||||
| with a Linux-compatible syscall implementation using [Go](https://golang.org).  | with a Linux-compatible syscall implementation using [Go](https://golang.org).  | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ bits 64 | |||||||
| global x_cgo_callers | global x_cgo_callers | ||||||
| global x_cgo_init | global x_cgo_init | ||||||
| global x_cgo_mmap | global x_cgo_mmap | ||||||
|  | global x_cgo_munmap | ||||||
| global x_cgo_notify_runtime_init_done | global x_cgo_notify_runtime_init_done | ||||||
| global x_cgo_sigaction | global x_cgo_sigaction | ||||||
| global x_cgo_thread_start | global x_cgo_thread_start | ||||||
| @ -17,6 +18,7 @@ global _cgo_yield | |||||||
| x_cgo_callers: | x_cgo_callers: | ||||||
| x_cgo_init: | x_cgo_init: | ||||||
| x_cgo_mmap: | x_cgo_mmap: | ||||||
|  | x_cgo_munmap: | ||||||
| x_cgo_notify_runtime_init_done: | x_cgo_notify_runtime_init_done: | ||||||
| x_cgo_sigaction: | x_cgo_sigaction: | ||||||
| x_cgo_thread_start: | x_cgo_thread_start: | ||||||
|  | |||||||
| @ -17,17 +17,17 @@ _rt0_idt_desc: | |||||||
| 	resw 1 | 	resw 1 | ||||||
| 	resq 1 | 	resq 1 | ||||||
| 
 | 
 | ||||||
| ; Allocates space for the IRQ handlers pointers registered by the IRQ package 
 | ; Allocates space for the IRQ handlers pointers registered by the IRQ package
 | ||||||
| _rt0_irq_handlers resq IDT_ENTRIES | _rt0_irq_handlers resq IDT_ENTRIES | ||||||
| 
 | 
 | ||||||
| ; According to the "ELF handling for TLS" document section 3.4.6
 | ; According to the "ELF handling for TLS" document section 3.4.6
 | ||||||
| ; (https://www.akkadia.org/drepper/tls.pdf) for the GNU variant for x86-64,
 | ; (https://www.akkadia.org/drepper/tls.pdf) for the GNU variant for x86-64,
 | ||||||
| ; fs:0x00 contains a pointer to the TCB. Variables in the TLS are stored 
 | ; fs:0x00 contains a pointer to the TCB. Variables in the TLS are stored
 | ||||||
| ; before the TCB and are accessed using negative offsets from the TCB address.
 | ; before the TCB and are accessed using negative offsets from the TCB address.
 | ||||||
| r0_g_ptr:  resq 1  | r0_g_ptr:  resq 1 | ||||||
| tcb_ptr:   resq 1  | tcb_ptr:   resq 1 | ||||||
| 
 | 
 | ||||||
| section .text  | section .text | ||||||
| 
 | 
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| ; Kernel 64-bit entry point
 | ; Kernel 64-bit entry point
 | ||||||
| @ -36,7 +36,7 @@ section .text | |||||||
| ; - it has entered long mode and enabled paging
 | ; - it has entered long mode and enabled paging
 | ||||||
| ; - it has loaded a 64bit GDT
 | ; - it has loaded a 64bit GDT
 | ||||||
| ; - it has set up identity paging for the physical 0-8M region and the
 | ; - it has set up identity paging for the physical 0-8M region and the
 | ||||||
| ;   PAGE_OFFSET to PAGE_OFFSET+8M region. 
 | ;   PAGE_OFFSET to PAGE_OFFSET+8M region.
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| global _rt0_64_entry | global _rt0_64_entry | ||||||
| _rt0_64_entry: | _rt0_64_entry: | ||||||
| @ -50,7 +50,7 @@ _rt0_64_entry: | |||||||
| 	extern _kernel_start | 	extern _kernel_start | ||||||
| 	extern _kernel_end | 	extern _kernel_end | ||||||
| 	extern kernel.Kmain | 	extern kernel.Kmain | ||||||
| 	 | 
 | ||||||
| 	mov rax, PAGE_OFFSET | 	mov rax, PAGE_OFFSET | ||||||
| 	push rax | 	push rax | ||||||
| 	mov rax, _kernel_end - PAGE_OFFSET | 	mov rax, _kernel_end - PAGE_OFFSET | ||||||
| @ -60,7 +60,7 @@ _rt0_64_entry: | |||||||
| 	mov rax, multiboot_data | 	mov rax, multiboot_data | ||||||
| 	push rax | 	push rax | ||||||
| 	call kernel.Kmain | 	call kernel.Kmain | ||||||
| 	 | 
 | ||||||
| 	; Main should never return; halt the CPU
 | 	; Main should never return; halt the CPU
 | ||||||
| 	mov rdi, err_kmain_returned | 	mov rdi, err_kmain_returned | ||||||
| 	call write_string | 	call write_string | ||||||
| @ -75,13 +75,15 @@ _rt0_64_entry: | |||||||
| _rt0_64_setup_go_runtime_structs: | _rt0_64_setup_go_runtime_structs: | ||||||
| 	%include "go_asm_offsets.inc" ; generated by tools/offsets
 | 	%include "go_asm_offsets.inc" ; generated by tools/offsets
 | ||||||
| 
 | 
 | ||||||
|  | 	%ifndef SKIP_PAGESIZE_SETUP | ||||||
| 	; The Go allocator expects this symbol to be set to the system page size
 | 	; The Go allocator expects this symbol to be set to the system page size
 | ||||||
| 	; As the kernel bypass osinit() this needs to be set here.
 | 	; As the kernel bypasses osinit() this needs to be manually set here.
 | ||||||
| 	extern runtime.physPageSize | 	extern runtime.physPageSize | ||||||
| 	mov rax, runtime.physPageSize | 	mov rax, runtime.physPageSize | ||||||
| 	mov qword [rax], 0x1000 ; 4096
 | 	mov qword [rax], 0x1000 ; 4096
 | ||||||
| 	 | 	%endif | ||||||
| 	; Setup r0_g stack limits using the reserved stack 
 | 
 | ||||||
|  | 	; Setup r0_g stack limits using the reserved stack
 | ||||||
| 	extern stack_top | 	extern stack_top | ||||||
| 	extern stack_bottom | 	extern stack_bottom | ||||||
| 	extern runtime.g0 | 	extern runtime.g0 | ||||||
| @ -99,21 +101,21 @@ _rt0_64_setup_go_runtime_structs: | |||||||
| 	mov qword [rbx+GO_M_G0], rsi       ; m.g0 = g0
 | 	mov qword [rbx+GO_M_G0], rsi       ; m.g0 = g0
 | ||||||
| 	mov qword [rsi+GO_G_M], rbx        ; g.m = m
 | 	mov qword [rsi+GO_G_M], rbx        ; g.m = m
 | ||||||
| 
 | 
 | ||||||
| 	; Store the address of g0 in r0_g_ptr 
 | 	; Store the address of g0 in r0_g_ptr
 | ||||||
| 	mov rax, r0_g_ptr | 	mov rax, r0_g_ptr | ||||||
| 	mov qword [rax], rsi | 	mov qword [rax], rsi | ||||||
| 
 | 
 | ||||||
| 	; According to the x86-64 ABI requirements fs:0x0 should point to the 
 | 	; According to the x86-64 ABI requirements fs:0x0 should point to the
 | ||||||
| 	; TCB.
 | 	; TCB.
 | ||||||
| 	mov rax, tcb_ptr | 	mov rax, tcb_ptr | ||||||
| 	mov qword [rax], rax | 	mov qword [rax], rax | ||||||
| 
 | 
 | ||||||
| 	; Load 64-bit FS register address 
 | 	; Load 64-bit FS register address
 | ||||||
| 	; eax -> lower 32 bits 
 | 	; eax -> lower 32 bits
 | ||||||
| 	; edx -> upper 32 bits
 | 	; edx -> upper 32 bits
 | ||||||
| 	mov ecx, 0xc0000100  ; fs_base
 | 	mov ecx, 0xc0000100  ; fs_base
 | ||||||
| 	mov rsi, tcb_ptr | 	mov rsi, tcb_ptr | ||||||
| 	mov rax, rsi         ; lower 32 bits 
 | 	mov rax, rsi         ; lower 32 bits
 | ||||||
| 	shr rsi, 32 | 	shr rsi, 32 | ||||||
| 	mov rdx, rsi         ; high 32 bits
 | 	mov rdx, rsi         ; high 32 bits
 | ||||||
| 	wrmsr | 	wrmsr | ||||||
| @ -122,26 +124,26 @@ _rt0_64_setup_go_runtime_structs: | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| ; Setup and load IDT. We preload each IDT entry with a pointer to a gate handler 
 | ; Setup and load IDT. We preload each IDT entry with a pointer to a gate handler
 | ||||||
| ; but set it as inactive. The code in irq_amd64 is responsible for enabling 
 | ; but set it as inactive. The code in irq_amd64 is responsible for enabling
 | ||||||
| ; individual IDT entries when handlers are installed.
 | ; individual IDT entries when handlers are installed.
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| _rt0_64_load_idt: | _rt0_64_load_idt: | ||||||
| 	mov rax, _rt0_idt_start | 	mov rax, _rt0_idt_start | ||||||
| 
 | 
 | ||||||
| %assign gate_num 0  | %assign gate_num 0 | ||||||
| %rep    IDT_ENTRIES | %rep    IDT_ENTRIES | ||||||
| 	mov rbx, _rt0_64_gate_entry_%+ gate_num | 	mov rbx, _rt0_64_gate_entry_%+ gate_num | ||||||
| 	mov word [rax], bx        ; gate entry bits 0-15
 | 	mov word [rax], bx        ; gate entry bits 0-15
 | ||||||
| 	mov word [rax+2], 0x8     ; GDT descriptor
 | 	mov word [rax+2], 0x8     ; GDT descriptor
 | ||||||
| 	mov byte [rax+5], 0x0     ; Mark the entry as NOT present 
 | 	mov byte [rax+5], 0x0     ; Mark the entry as NOT present
 | ||||||
| 	shr rbx, 16 | 	shr rbx, 16 | ||||||
| 	mov word [rax+6], bx      ; gate entry bits 16-31
 | 	mov word [rax+6], bx      ; gate entry bits 16-31
 | ||||||
| 	shr rbx, 16 | 	shr rbx, 16 | ||||||
| 	mov dword [rax+8], ebx    ; gate entry bits 32-63
 | 	mov dword [rax+8], ebx    ; gate entry bits 32-63
 | ||||||
| 
 | 
 | ||||||
| 	add rax, 16		  ; size of IDT entry
 | 	add rax, 16		  ; size of IDT entry
 | ||||||
| %assign gate_num gate_num+1  | %assign gate_num gate_num+1 | ||||||
| %endrep | %endrep | ||||||
| 	mov rax, _rt0_idt_desc | 	mov rax, _rt0_idt_desc | ||||||
| 	mov word [rax], _rt0_idt_end - _rt0_idt_start - 1 ; similar to GDT this must be len(IDT) - 1
 | 	mov word [rax], _rt0_idt_end - _rt0_idt_start - 1 ; similar to GDT this must be len(IDT) - 1
 | ||||||
| @ -152,15 +154,15 @@ ret | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| ; Generate gate entries. Each gate handler pushes the address of the registered 
 | ; Generate gate entries. Each gate handler pushes the address of the registered
 | ||||||
| ; handler to the stack before jumping to a dispatcher function.
 | ; handler to the stack before jumping to a dispatcher function.
 | ||||||
| ;
 | ;
 | ||||||
| ; Some exceptions push an error code to the stack after the stack frame. This
 | ; Some exceptions push an error code to the stack after the stack frame. This
 | ||||||
| ; code must be popped off the stack before calling iretq. The generated handlers 
 | ; code must be popped off the stack before calling iretq. The generated handlers
 | ||||||
| ; are aware whether they need to deal with the code or not and jump to the 
 | ; are aware whether they need to deal with the code or not and jump to the
 | ||||||
| ; appropriate get dispatcher.
 | ; appropriate get dispatcher.
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| %assign gate_num 0  | %assign gate_num 0 | ||||||
| %rep    IDT_ENTRIES | %rep    IDT_ENTRIES | ||||||
| extern _rt0_interrupt_handlers | extern _rt0_interrupt_handlers | ||||||
| _rt0_64_gate_entry_%+ gate_num: | _rt0_64_gate_entry_%+ gate_num: | ||||||
| @ -177,13 +179,13 @@ _rt0_64_gate_entry_%+ gate_num: | |||||||
| 	%else | 	%else | ||||||
| 		jmp _rt0_64_gate_dispatcher_without_code | 		jmp _rt0_64_gate_dispatcher_without_code | ||||||
| 	%endif | 	%endif | ||||||
| %assign gate_num gate_num+1  | %assign gate_num gate_num+1 | ||||||
| %endrep | %endrep | ||||||
| 
 | 
 | ||||||
| %macro save_regs 0 | %macro save_regs 0 | ||||||
| 	push r15  | 	push r15 | ||||||
| 	push r14 | 	push r14 | ||||||
| 	push r13  | 	push r13 | ||||||
| 	push r12 | 	push r12 | ||||||
| 	push r11 | 	push r11 | ||||||
| 	push r10 | 	push r10 | ||||||
| @ -191,10 +193,10 @@ _rt0_64_gate_entry_%+ gate_num: | |||||||
| 	push r8 | 	push r8 | ||||||
| 	push rbp | 	push rbp | ||||||
| 	push rdi | 	push rdi | ||||||
| 	push rsi  | 	push rsi | ||||||
| 	push rdx  | 	push rdx | ||||||
| 	push rcx  | 	push rcx | ||||||
| 	push rbx  | 	push rbx | ||||||
| 	push rax | 	push rax | ||||||
| %endmacro | %endmacro | ||||||
| 
 | 
 | ||||||
| @ -203,13 +205,13 @@ _rt0_64_gate_entry_%+ gate_num: | |||||||
| 	pop rbx | 	pop rbx | ||||||
| 	pop rcx | 	pop rcx | ||||||
| 	pop rdx | 	pop rdx | ||||||
| 	pop rsi  | 	pop rsi | ||||||
| 	pop rdi | 	pop rdi | ||||||
| 	pop rbp  | 	pop rbp | ||||||
| 	pop r8 | 	pop r8 | ||||||
| 	pop r9 | 	pop r9 | ||||||
| 	pop r10 | 	pop r10 | ||||||
| 	pop r11  | 	pop r11 | ||||||
| 	pop r12 | 	pop r12 | ||||||
| 	pop r13 | 	pop r13 | ||||||
| 	pop r14 | 	pop r14 | ||||||
| @ -217,14 +219,14 @@ _rt0_64_gate_entry_%+ gate_num: | |||||||
| %endmacro | %endmacro | ||||||
| 
 | 
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| ; This dispatcher is invoked by gate entries that expect a code to be pushed 
 | ; This dispatcher is invoked by gate entries that expect a code to be pushed
 | ||||||
| ; by the CPU to the stack. It performs the following functions:
 | ; by the CPU to the stack. It performs the following functions:
 | ||||||
| ; - save registers
 | ; - save registers
 | ||||||
| ; - push pointer to saved regs 
 | ; - push pointer to saved regs
 | ||||||
| ; - push pointer to stack frame 
 | ; - push pointer to stack frame
 | ||||||
| ; - read and push exception code 
 | ; - read and push exception code
 | ||||||
| ; - invoke handler(code, &frame, ®s)
 | ; - invoke handler(code, &frame, ®s)
 | ||||||
| ; - restore registers 
 | ; - restore registers
 | ||||||
| ; - pop exception code from stack so rsp points to the stack frame
 | ; - pop exception code from stack so rsp points to the stack frame
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| _rt0_64_gate_dispatcher_with_code: | _rt0_64_gate_dispatcher_with_code: | ||||||
| @ -236,7 +238,7 @@ _rt0_64_gate_dispatcher_with_code: | |||||||
| 	;-----------------|
 | 	;-----------------|
 | ||||||
| 	; Exception code  | <- needs to be removed from stack before calling iretq
 | 	; Exception code  | <- needs to be removed from stack before calling iretq
 | ||||||
| 	;-----------------|
 | 	;-----------------|
 | ||||||
| 	; RIP             | <- exception frame             
 | 	; RIP             | <- exception frame
 | ||||||
| 	; CS              |
 | 	; CS              |
 | ||||||
| 	; RFLAGS          |
 | 	; RFLAGS          |
 | ||||||
| 	; RSP             |
 | 	; RSP             |
 | ||||||
| @ -244,12 +246,12 @@ _rt0_64_gate_dispatcher_with_code: | |||||||
| 	;-----------------
 | 	;-----------------
 | ||||||
| 	cld | 	cld | ||||||
| 
 | 
 | ||||||
| 	; save regs and push a pointer to them 
 | 	; save regs and push a pointer to them
 | ||||||
| 	save_regs | 	save_regs | ||||||
| 	mov rax, rsp   ; rax points to saved rax
 | 	mov rax, rsp   ; rax points to saved rax
 | ||||||
| 	push rax       ; push pointer to saved regs
 | 	push rax       ; push pointer to saved regs
 | ||||||
| 
 | 
 | ||||||
| 	; push pointer to exception stack frame (we have used 15 qwords for the 
 | 	; push pointer to exception stack frame (we have used 15 qwords for the
 | ||||||
| 	; saved registers plus one qword for the data pushed by the gate entry
 | 	; saved registers plus one qword for the data pushed by the gate entry
 | ||||||
| 	; plus one extra qword to jump over the exception code)
 | 	; plus one extra qword to jump over the exception code)
 | ||||||
| 	add rax, 17*8 | 	add rax, 17*8 | ||||||
| @ -261,7 +263,7 @@ _rt0_64_gate_dispatcher_with_code: | |||||||
| 
 | 
 | ||||||
| 	call [rsp + 18*8] ; call registered irq handler
 | 	call [rsp + 18*8] ; call registered irq handler
 | ||||||
| 
 | 
 | ||||||
| 	add rsp, 3 * 8    ; unshift the pushed arguments so rsp points to the saved regs 
 | 	add rsp, 3 * 8    ; unshift the pushed arguments so rsp points to the saved regs
 | ||||||
| 	restore_regs | 	restore_regs | ||||||
| 
 | 
 | ||||||
| 	add rsp, 16	  ; pop handler address and exception code off the stack before returning
 | 	add rsp, 16	  ; pop handler address and exception code off the stack before returning
 | ||||||
| @ -271,10 +273,10 @@ _rt0_64_gate_dispatcher_with_code: | |||||||
| ; This dispatcher is invoked by gate entries that do not use exception codes.
 | ; This dispatcher is invoked by gate entries that do not use exception codes.
 | ||||||
| ; It performs the following functions:
 | ; It performs the following functions:
 | ||||||
| ; - save registers
 | ; - save registers
 | ||||||
| ; - push pointer to saved regs 
 | ; - push pointer to saved regs
 | ||||||
| ; - push pointer to stack frame 
 | ; - push pointer to stack frame
 | ||||||
| ; - invoke handler(&frame, ®s)
 | ; - invoke handler(&frame, ®s)
 | ||||||
| ; - restore registers 
 | ; - restore registers
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| _rt0_64_gate_dispatcher_without_code: | _rt0_64_gate_dispatcher_without_code: | ||||||
| 	; This is how the stack looks like when entering this function:
 | 	; This is how the stack looks like when entering this function:
 | ||||||
| @ -283,7 +285,7 @@ _rt0_64_gate_dispatcher_without_code: | |||||||
| 	;------------------
 | 	;------------------
 | ||||||
| 	; handler address | <- pushed by gate_entry_xxx (RSP points here)
 | 	; handler address | <- pushed by gate_entry_xxx (RSP points here)
 | ||||||
| 	;-----------------|
 | 	;-----------------|
 | ||||||
| 	; RIP             | <- exception frame             
 | 	; RIP             | <- exception frame
 | ||||||
| 	; CS              |
 | 	; CS              |
 | ||||||
| 	; RFLAGS          |
 | 	; RFLAGS          |
 | ||||||
| 	; RSP             |
 | 	; RSP             |
 | ||||||
| @ -291,21 +293,21 @@ _rt0_64_gate_dispatcher_without_code: | |||||||
| 	;-----------------
 | 	;-----------------
 | ||||||
| 	cld | 	cld | ||||||
| 
 | 
 | ||||||
| 	; save regs and push a pointer to them 
 | 	; save regs and push a pointer to them
 | ||||||
| 	save_regs | 	save_regs | ||||||
| 	mov rax, rsp   ; rax points to saved rax
 | 	mov rax, rsp   ; rax points to saved rax
 | ||||||
| 	push rax       ; push pointer to saved regs
 | 	push rax       ; push pointer to saved regs
 | ||||||
| 
 | 
 | ||||||
| 	; push pointer to exception stack frame (we have used 15 qwords for the 
 | 	; push pointer to exception stack frame (we have used 15 qwords for the
 | ||||||
| 	; saved registers plus one qword for the data pushed by the gate entry)
 | 	; saved registers plus one qword for the data pushed by the gate entry)
 | ||||||
| 	add rax, 16*8 | 	add rax, 16*8 | ||||||
| 	push rax | 	push rax | ||||||
| 
 | 
 | ||||||
| 	call [rsp + 17*8] ; call registered irq handler
 | 	call [rsp + 17*8] ; call registered irq handler
 | ||||||
| 
 | 
 | ||||||
| 	add rsp, 2 * 8    ; unshift the pushed arguments so rsp points to the saved regs 
 | 	add rsp, 2 * 8    ; unshift the pushed arguments so rsp points to the saved regs
 | ||||||
| 	restore_regs | 	restore_regs | ||||||
| 	 | 
 | ||||||
| 	add rsp, 8	  ; pop handler address off the stack before returning
 | 	add rsp, 8	  ; pop handler address off the stack before returning
 | ||||||
| 	iretq | 	iretq | ||||||
| 
 | 
 | ||||||
| @ -340,13 +342,13 @@ write_string: | |||||||
| ; runtime functions to the kernel's own implementation without the need to
 | ; runtime functions to the kernel's own implementation without the need to
 | ||||||
| ; export/globalize any symbols. This works by first setting up a redirect table
 | ; export/globalize any symbols. This works by first setting up a redirect table
 | ||||||
| ; (populated by a post-link step) that contains the addresses of the symbol to
 | ; (populated by a post-link step) that contains the addresses of the symbol to
 | ||||||
| ; hook and the address where calls to that symbol should be redirected. 
 | ; hook and the address where calls to that symbol should be redirected.
 | ||||||
| ;
 | ;
 | ||||||
| ; This function iterates the redirect table entries and for each entry it
 | ; This function iterates the redirect table entries and for each entry it
 | ||||||
| ; sets up a trampoline to the dst symbol and overwrites the code in src with
 | ; sets up a trampoline to the dst symbol and overwrites the code in src with
 | ||||||
| ; the 14-byte long _rt0_redirect_trampoline code. 
 | ; the 14-byte long _rt0_redirect_trampoline code.
 | ||||||
| ;
 | ;
 | ||||||
| ; Note: this code modification is only possible because we are currently 
 | ; Note: this code modification is only possible because we are currently
 | ||||||
| ; operating in supervisor mode with no memory protection enabled. Under normal
 | ; operating in supervisor mode with no memory protection enabled. Under normal
 | ||||||
| ; conditions the .text section should be flagged as read-only.
 | ; conditions the .text section should be flagged as read-only.
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| @ -355,7 +357,7 @@ _rt0_install_redirect_trampolines: | |||||||
| 	mov rdx, NUM_REDIRECTS | 	mov rdx, NUM_REDIRECTS | ||||||
| 
 | 
 | ||||||
| _rt0_install_redirect_rampolines.next: | _rt0_install_redirect_rampolines.next: | ||||||
| 	mov rdi, [rax]	 ; the symbol address to hook 
 | 	mov rdi, [rax]	 ; the symbol address to hook
 | ||||||
| 	mov rbx, [rax+8] ; the symbol to redirect to
 | 	mov rbx, [rax+8] ; the symbol to redirect to
 | ||||||
| 
 | 
 | ||||||
| 	; setup trampoline target and copy it to the hooked symbol
 | 	; setup trampoline target and copy it to the hooked symbol
 | ||||||
| @ -364,15 +366,15 @@ _rt0_install_redirect_rampolines.next: | |||||||
| 	mov rcx, 14 | 	mov rcx, 14 | ||||||
| 	rep movsb ; copy rcx bytes from rsi to rdi
 | 	rep movsb ; copy rcx bytes from rsi to rdi
 | ||||||
| 
 | 
 | ||||||
| 	add rax, 16  | 	add rax, 16 | ||||||
| 	dec rdx  | 	dec rdx | ||||||
| 	jnz _rt0_install_redirect_rampolines.next | 	jnz _rt0_install_redirect_rampolines.next | ||||||
| 
 | 
 | ||||||
| 	ret | 	ret | ||||||
| 
 | 
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| ; This trampoline exploits rip-relative addressing to allow a jump to a 
 | ; This trampoline exploits rip-relative addressing to allow a jump to a
 | ||||||
| ; 64-bit address without the need to touch any registers. The generated 
 | ; 64-bit address without the need to touch any registers. The generated
 | ||||||
| ; code is equivalent to:
 | ; code is equivalent to:
 | ||||||
| ;
 | ;
 | ||||||
| ; jmp [rip+0]
 | ; jmp [rip+0]
 | ||||||
| @ -380,14 +382,14 @@ _rt0_install_redirect_rampolines.next: | |||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| _rt0_redirect_trampoline: | _rt0_redirect_trampoline: | ||||||
| 	db 0xff ; the first 6 bytes encode a "jmp [rip+0]" instruction
 | 	db 0xff ; the first 6 bytes encode a "jmp [rip+0]" instruction
 | ||||||
| 	db 0x25  | 	db 0x25 | ||||||
| 	dd 0x00    | 	dd 0x00 | ||||||
| 	dq 0x00 ; the absolute address to jump to
 | 	dq 0x00 ; the absolute address to jump to
 | ||||||
| 
 | 
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| ; The redirect table is placed in a dedicated section allowing us to easily 
 | ; The redirect table is placed in a dedicated section allowing us to easily
 | ||||||
| ; find its offset in the kernel image file. As the VMA addresses of the src
 | ; find its offset in the kernel image file. As the VMA addresses of the src
 | ||||||
| ; and target symbols for the redirect are now known in advance we just reserve 
 | ; and target symbols for the redirect are now known in advance we just reserve
 | ||||||
| ; enough space space for the src and dst addresses using the NUM_REDIRECTS
 | ; enough space space for the src and dst addresses using the NUM_REDIRECTS
 | ||||||
| ; define which is calculated by the Makefile and passed to nasm.
 | ; define which is calculated by the Makefile and passed to nasm.
 | ||||||
| ;------------------------------------------------------------------------------
 | ;------------------------------------------------------------------------------
 | ||||||
| @ -395,7 +397,7 @@ section .goredirectstbl | |||||||
| 
 | 
 | ||||||
| _rt0_redirect_table: | _rt0_redirect_table: | ||||||
| 	%rep NUM_REDIRECTS | 	%rep NUM_REDIRECTS | ||||||
| 	dq 0  ; src: address of the symbol we want to redirect 
 | 	dq 0  ; src: address of the symbol we want to redirect
 | ||||||
| 	dq 0  ; dst: address of the symbol where calls to src are redirected to
 | 	dq 0  ; dst: address of the symbol where calls to src are redirected to
 | ||||||
| 	%endrep | 	%endrep | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -27,27 +27,6 @@ var ( | |||||||
| 	prngSeed = 0xdeadc0de | 	prngSeed = 0xdeadc0de | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| //go:linkname algInit runtime.alginit |  | ||||||
| func algInit() |  | ||||||
| 
 |  | ||||||
| //go:linkname modulesInit runtime.modulesinit |  | ||||||
| func modulesInit() |  | ||||||
| 
 |  | ||||||
| //go:linkname typeLinksInit runtime.typelinksinit |  | ||||||
| func typeLinksInit() |  | ||||||
| 
 |  | ||||||
| //go:linkname itabsInit runtime.itabsinit |  | ||||||
| func itabsInit() |  | ||||||
| 
 |  | ||||||
| //go:linkname mallocInit runtime.mallocinit |  | ||||||
| func mallocInit() |  | ||||||
| 
 |  | ||||||
| //go:linkname mSysStatInc runtime.mSysStatInc |  | ||||||
| func mSysStatInc(*uint64, uintptr) |  | ||||||
| 
 |  | ||||||
| //go:linkname procResize runtime.procresize |  | ||||||
| func procResize(int32) uintptr |  | ||||||
| 
 |  | ||||||
| // initGoPackages is an alias to main.init which recursively calls the init() | // initGoPackages is an alias to main.init which recursively calls the init() | ||||||
| // methods in all imported packages. Unless this function is called, things like | // methods in all imported packages. Unless this function is called, things like | ||||||
| // package errors will not be properly initialized causing various problems when | // package errors will not be properly initialized causing various problems when | ||||||
| @ -184,7 +163,7 @@ func getRandomData(r []byte) { | |||||||
| func Init() *kernel.Error { | func Init() *kernel.Error { | ||||||
| 	mallocInitFn() | 	mallocInitFn() | ||||||
| 	algInitFn()       // setup hash implementation for map keys | 	algInitFn()       // setup hash implementation for map keys | ||||||
| 	modulesInitFn()   // provides activeModules | 	modulesInitFn()   // provides activeModules (go 1.8+) | ||||||
| 	typeLinksInitFn() // uses maps, activeModules | 	typeLinksInitFn() // uses maps, activeModules | ||||||
| 	itabsInitFn()     // uses activeModules | 	itabsInitFn()     // uses activeModules | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								src/gopheros/kernel/goruntime/bootstrap_go17.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/gopheros/kernel/goruntime/bootstrap_go17.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | // +build go1.7,!go1.8 | ||||||
|  | 
 | ||||||
|  | package goruntime | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	_ "unsafe" // required for go:linkname | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | //go:linkname algInit runtime.alginit | ||||||
|  | func algInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname typeLinksInit runtime.typelinksinit | ||||||
|  | func typeLinksInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname itabsInit runtime.itabsinit | ||||||
|  | func itabsInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname mallocInit runtime.mallocinit | ||||||
|  | func mallocInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname mSysStatInc runtime.mSysStatInc | ||||||
|  | func mSysStatInc(*uint64, uintptr) | ||||||
|  | 
 | ||||||
|  | //go:linkname procResize runtime.procresize | ||||||
|  | func procResize(int32) uintptr | ||||||
|  | 
 | ||||||
|  | // modulesInit is defined on go1.8 so just declare an empty | ||||||
|  | // stub for go 1.7 to keep the compiler happy. | ||||||
|  | func modulesInit() { | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								src/gopheros/kernel/goruntime/bootstrap_go18+.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/gopheros/kernel/goruntime/bootstrap_go18+.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | // +build go1.8 | ||||||
|  | 
 | ||||||
|  | package goruntime | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	_ "unsafe" // required for go:linkname | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | //go:linkname algInit runtime.alginit | ||||||
|  | func algInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname modulesInit runtime.modulesinit | ||||||
|  | func modulesInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname typeLinksInit runtime.typelinksinit | ||||||
|  | func typeLinksInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname itabsInit runtime.itabsinit | ||||||
|  | func itabsInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname mallocInit runtime.mallocinit | ||||||
|  | func mallocInit() | ||||||
|  | 
 | ||||||
|  | //go:linkname mSysStatInc runtime.mSysStatInc | ||||||
|  | func mSysStatInc(*uint64, uintptr) | ||||||
|  | 
 | ||||||
|  | //go:linkname procResize runtime.procresize | ||||||
|  | func procResize(int32) uintptr | ||||||
| @ -7,6 +7,8 @@ import ( | |||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/exec" | 	"os/exec" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"runtime" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| @ -30,6 +32,7 @@ func genBuildScript(targetOS, targetArch, goBinary, workDir string) ([]byte, err | |||||||
| 	// rebuild the runtime packages. | 	// rebuild the runtime packages. | ||||||
| 	cmd := exec.Command(goBinary, "build", "-a", "-n") | 	cmd := exec.Command(goBinary, "build", "-a", "-n") | ||||||
| 	cmd.Dir = workDir | 	cmd.Dir = workDir | ||||||
|  | 	cmd.Env = append(cmd.Env, fmt.Sprintf("GOROOT=%s", os.Getenv("GOROOT"))) | ||||||
| 	cmd.Env = append(cmd.Env, fmt.Sprintf("GOOS=%s", targetOS)) | 	cmd.Env = append(cmd.Env, fmt.Sprintf("GOOS=%s", targetOS)) | ||||||
| 	cmd.Env = append(cmd.Env, fmt.Sprintf("GOARCH=%s", targetArch)) | 	cmd.Env = append(cmd.Env, fmt.Sprintf("GOARCH=%s", targetArch)) | ||||||
| 	out, err := cmd.CombinedOutput() | 	out, err := cmd.CombinedOutput() | ||||||
| @ -41,13 +44,18 @@ func genBuildScript(targetOS, targetArch, goBinary, workDir string) ([]byte, err | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func patchBuildScript(script []byte, workDir, targetOS, targetArch, goBinary string) ([]byte, error) { | func patchBuildScript(script []byte, workDir, targetOS, targetArch, goBinary string) ([]byte, error) { | ||||||
| 	lines := strings.Split(string(script), "\n") | 	// Replace $WORK with the workDir location. This is required for executing | ||||||
|  | 	// build scripts generated by go 1.10 | ||||||
|  | 	lines := strings.Split( | ||||||
|  | 		strings.Replace(string(script), "$WORK", workDir, -1), | ||||||
|  | 		"\n", | ||||||
|  | 	) | ||||||
| 
 | 
 | ||||||
| 	// Inject os/arch and workdir to the top of the build file | 	// Inject os/arch and workdir to the top of the build file | ||||||
| 	header := []string{ | 	header := []string{ | ||||||
|  | 		fmt.Sprintf("export GOROOT=%s", os.Getenv("GOROOT")), | ||||||
| 		fmt.Sprintf("export GOOS=%s", targetOS), | 		fmt.Sprintf("export GOOS=%s", targetOS), | ||||||
| 		fmt.Sprintf("export GOARCH=%s", targetArch), | 		fmt.Sprintf("export GOARCH=%s", targetArch), | ||||||
| 		fmt.Sprintf("WORK=%q", workDir), |  | ||||||
| 		fmt.Sprintf("alias pack='%s tool pack'", goBinary), | 		fmt.Sprintf("alias pack='%s tool pack'", goBinary), | ||||||
| 	} | 	} | ||||||
| 	lines = append(header, lines...) | 	lines = append(header, lines...) | ||||||
| @ -58,7 +66,7 @@ func patchBuildScript(script []byte, workDir, targetOS, targetArch, goBinary str | |||||||
| 	var stopOnNextComment bool | 	var stopOnNextComment bool | ||||||
| 	for lineIndex := 0; lineIndex < len(lines); lineIndex++ { | 	for lineIndex := 0; lineIndex < len(lines); lineIndex++ { | ||||||
| 		// Ignore empty comments | 		// Ignore empty comments | ||||||
| 		if lines[lineIndex] == "#" { | 		if strings.TrimSpace(lines[lineIndex]) == "#" || strings.Contains(lines[lineIndex], "# import") { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -97,8 +105,32 @@ func execBuildScript(script []byte, workDir string) error { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func genAsmIncludes(workDir string) ([]byte, error) { | func genAsmIncludes(workDir string) ([]byte, error) { | ||||||
| 	headers, err := ioutil.ReadFile(fmt.Sprintf("%s/runtime/_obj/go_asm.h", workDir)) | 	// Find all generated go_asm.h files and concat their conentents | ||||||
| 	if err != nil { | 	var ( | ||||||
|  | 		allHeaders, headers []byte | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if err := filepath.Walk(workDir, func(path string, info os.FileInfo, err error) error { | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if info.IsDir() { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if filepath.Base(path) != "go_asm.h" { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if headers, err = ioutil.ReadFile(path); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		allHeaders = append(allHeaders, '\n') | ||||||
|  | 		allHeaders = append(allHeaders, headers...) | ||||||
|  | 		return nil | ||||||
|  | 	}); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -106,7 +138,7 @@ func genAsmIncludes(workDir string) ([]byte, error) { | |||||||
| 	includes = append(includes, "; vim: set ft=nasm :\n") | 	includes = append(includes, "; vim: set ft=nasm :\n") | ||||||
| 	includes = append(includes, fmt.Sprintf("; generated by tools/offsets at %v\n", time.Now())) | 	includes = append(includes, fmt.Sprintf("; generated by tools/offsets at %v\n", time.Now())) | ||||||
| 
 | 
 | ||||||
| 	for _, line := range strings.Split(string(headers), "\n") { | 	for _, line := range strings.Split(string(allHeaders), "\n") { | ||||||
| 		line = strings.TrimPrefix(line, "#define ") | 		line = strings.TrimPrefix(line, "#define ") | ||||||
| 
 | 
 | ||||||
| 		// We are only interested in the offsets for the g, m and stack structures | 		// We are only interested in the offsets for the g, m and stack structures | ||||||
| @ -131,6 +163,16 @@ func genAsmIncludes(workDir string) ([]byte, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// In go 1.7.x, the page size is given by the _PageSize constant whereas in | ||||||
|  | 	// newer go versions it is specified at runtime and needs to be manually set | ||||||
|  | 	// by our asm bootstrap code. | ||||||
|  | 	if strings.Contains(runtime.Version(), "go1.7") { | ||||||
|  | 		includes = append(includes, | ||||||
|  | 			"; go 1.7 runtime uses a fixed 4k page size for our target arch so our bootstrap code does not need to do any extra work to set it up", | ||||||
|  | 			"%define SKIP_PAGESIZE_SETUP 1", | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return []byte(strings.Join(includes, "\n")), nil | 	return []byte(strings.Join(includes, "\n")), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user