Improved Windows support
This commit is contained in:
parent
7b1a293cd0
commit
e818e5b907
3
lib/sys/sys_windows.q
Normal file
3
lib/sys/sys_windows.q
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
write(_ Int, _ Pointer, _ Int) -> Int {
|
||||||
|
return 0
|
||||||
|
}
|
@ -9,6 +9,9 @@ import (
|
|||||||
"git.akyoto.dev/cli/q/src/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/config"
|
"git.akyoto.dev/cli/q/src/config"
|
||||||
"git.akyoto.dev/cli/q/src/os/common"
|
"git.akyoto.dev/cli/q/src/os/common"
|
||||||
|
"git.akyoto.dev/cli/q/src/os/linux/elf"
|
||||||
|
"git.akyoto.dev/cli/q/src/os/mac/macho"
|
||||||
|
"git.akyoto.dev/cli/q/src/os/windows/pe"
|
||||||
"git.akyoto.dev/cli/q/src/sizeof"
|
"git.akyoto.dev/cli/q/src/sizeof"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -337,8 +340,26 @@ restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
data, dataLabels = a.Data.Finalize()
|
data, dataLabels = a.Data.Finalize()
|
||||||
dataStart := config.BaseAddress + config.CodeOffset + Address(len(code))
|
|
||||||
dataStart += int32(common.Padding(int64(dataStart), config.Align))
|
var (
|
||||||
|
codeOffset Address
|
||||||
|
align Address
|
||||||
|
)
|
||||||
|
|
||||||
|
switch config.TargetOS {
|
||||||
|
case "linux":
|
||||||
|
codeOffset = elf.CodeOffset
|
||||||
|
align = elf.Align
|
||||||
|
case "mac":
|
||||||
|
codeOffset = macho.CodeOffset
|
||||||
|
align = macho.Align
|
||||||
|
case "windows":
|
||||||
|
codeOffset = pe.CodeOffset
|
||||||
|
align = pe.Align
|
||||||
|
}
|
||||||
|
|
||||||
|
dataStart := Address(config.BaseAddress) + codeOffset + Address(len(code))
|
||||||
|
dataStart += int32(common.Padding(dataStart, align))
|
||||||
|
|
||||||
for _, pointer := range dataPointers {
|
for _, pointer := range dataPointers {
|
||||||
address := dataStart + pointer.Resolve()
|
address := dataStart + pointer.Resolve()
|
||||||
|
@ -8,12 +8,6 @@ const (
|
|||||||
|
|
||||||
// The base address is the virtual address for our ELF file.
|
// The base address is the virtual address for our ELF file.
|
||||||
BaseAddress = 0x40 * MinAddress
|
BaseAddress = 0x40 * MinAddress
|
||||||
|
|
||||||
// The code offset is the offset of the executable machine code within the file.
|
|
||||||
CodeOffset = 64 + 56 + 56
|
|
||||||
|
|
||||||
// Align decides the alignment of the sections and it must be a multiple of the page size.
|
|
||||||
Align = 0x1000
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -45,3 +39,5 @@ func Reset() {
|
|||||||
TargetOS = "mac"
|
TargetOS = "mac"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
package elf
|
package elf
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Align decides the alignment of the sections and it must be a multiple of the page size.
|
||||||
|
Align = 0x1000
|
||||||
|
|
||||||
|
// The code offset is the offset of the executable machine code within the file.
|
||||||
|
CodeOffset = HeaderSize + ProgramHeaderSize*2
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LittleEndian = 1
|
LittleEndian = 1
|
||||||
TypeExecutable = 2
|
TypeExecutable = 2
|
||||||
|
@ -22,8 +22,8 @@ type ELF struct {
|
|||||||
|
|
||||||
// New creates a new ELF binary.
|
// New creates a new ELF binary.
|
||||||
func New(code []byte, data []byte) *ELF {
|
func New(code []byte, data []byte) *ELF {
|
||||||
dataOffset := config.CodeOffset + int64(len(code))
|
dataOffset := CodeOffset + int64(len(code))
|
||||||
dataPadding := common.Padding(dataOffset, config.Align)
|
dataPadding := common.Padding(dataOffset, Align)
|
||||||
dataOffset += dataPadding
|
dataOffset += dataPadding
|
||||||
|
|
||||||
return &ELF{
|
return &ELF{
|
||||||
@ -37,7 +37,7 @@ func New(code []byte, data []byte) *ELF {
|
|||||||
Type: TypeExecutable,
|
Type: TypeExecutable,
|
||||||
Architecture: ArchitectureAMD64,
|
Architecture: ArchitectureAMD64,
|
||||||
FileVersion: 1,
|
FileVersion: 1,
|
||||||
EntryPointInMemory: config.BaseAddress + config.CodeOffset,
|
EntryPointInMemory: config.BaseAddress + CodeOffset,
|
||||||
ProgramHeaderOffset: HeaderSize,
|
ProgramHeaderOffset: HeaderSize,
|
||||||
SectionHeaderOffset: 0,
|
SectionHeaderOffset: 0,
|
||||||
Flags: 0,
|
Flags: 0,
|
||||||
@ -51,12 +51,12 @@ func New(code []byte, data []byte) *ELF {
|
|||||||
CodeHeader: ProgramHeader{
|
CodeHeader: ProgramHeader{
|
||||||
Type: ProgramTypeLOAD,
|
Type: ProgramTypeLOAD,
|
||||||
Flags: ProgramFlagsExecutable | ProgramFlagsReadable,
|
Flags: ProgramFlagsExecutable | ProgramFlagsReadable,
|
||||||
Offset: config.CodeOffset,
|
Offset: CodeOffset,
|
||||||
VirtualAddress: config.BaseAddress + config.CodeOffset,
|
VirtualAddress: config.BaseAddress + CodeOffset,
|
||||||
PhysicalAddress: config.BaseAddress + config.CodeOffset,
|
PhysicalAddress: config.BaseAddress + CodeOffset,
|
||||||
SizeInFile: int64(len(code)),
|
SizeInFile: int64(len(code)),
|
||||||
SizeInMemory: int64(len(code)),
|
SizeInMemory: int64(len(code)),
|
||||||
Align: config.Align,
|
Align: Align,
|
||||||
},
|
},
|
||||||
DataHeader: ProgramHeader{
|
DataHeader: ProgramHeader{
|
||||||
Type: ProgramTypeLOAD,
|
Type: ProgramTypeLOAD,
|
||||||
@ -66,7 +66,7 @@ func New(code []byte, data []byte) *ELF {
|
|||||||
PhysicalAddress: config.BaseAddress + dataOffset,
|
PhysicalAddress: config.BaseAddress + dataOffset,
|
||||||
SizeInFile: int64(len(data)),
|
SizeInFile: int64(len(data)),
|
||||||
SizeInMemory: int64(len(data)),
|
SizeInMemory: int64(len(data)),
|
||||||
Align: config.Align,
|
Align: Align,
|
||||||
},
|
},
|
||||||
CodePadding: nil,
|
CodePadding: nil,
|
||||||
Code: code,
|
Code: code,
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
package macho
|
package macho
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Align decides the alignment of the sections and it must be a multiple of the page size.
|
||||||
|
Align = 0x1000
|
||||||
|
|
||||||
|
// The code offset is the offset of the executable machine code within the file.
|
||||||
|
CodeOffset = 32 + 0x48*3 + 184
|
||||||
|
)
|
||||||
|
|
||||||
type CPU uint32
|
type CPU uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -25,7 +25,7 @@ func New(code []byte, data []byte) *MachO {
|
|||||||
MicroArchitecture: 3 | 0x80000000,
|
MicroArchitecture: 3 | 0x80000000,
|
||||||
Type: TypeExecute,
|
Type: TypeExecute,
|
||||||
NumCommands: 4,
|
NumCommands: 4,
|
||||||
SizeCommands: 0x48*3 + 184,
|
SizeCommands: 72*3 + 184,
|
||||||
Flags: FlagNoUndefs,
|
Flags: FlagNoUndefs,
|
||||||
Reserved: 0,
|
Reserved: 0,
|
||||||
},
|
},
|
||||||
@ -40,7 +40,7 @@ func (m *MachO) Write(writer io.Writer) {
|
|||||||
|
|
||||||
binary.Write(writer, binary.LittleEndian, &Segment64{
|
binary.Write(writer, binary.LittleEndian, &Segment64{
|
||||||
LoadCommand: LcSegment64,
|
LoadCommand: LcSegment64,
|
||||||
Length: 0x48,
|
Length: 72,
|
||||||
Name: [16]byte{'_', '_', 'P', 'A', 'G', 'E', 'Z', 'E', 'R', 'O'},
|
Name: [16]byte{'_', '_', 'P', 'A', 'G', 'E', 'Z', 'E', 'R', 'O'},
|
||||||
Address: 0,
|
Address: 0,
|
||||||
SizeInMemory: config.BaseAddress,
|
SizeInMemory: config.BaseAddress,
|
||||||
@ -55,12 +55,12 @@ func (m *MachO) Write(writer io.Writer) {
|
|||||||
codeStart := uint64(32 + m.Header.SizeCommands)
|
codeStart := uint64(32 + m.Header.SizeCommands)
|
||||||
codeLength := uint64(len(m.Code))
|
codeLength := uint64(len(m.Code))
|
||||||
codeEnd := codeStart + codeLength
|
codeEnd := codeStart + codeLength
|
||||||
dataPadding := common.Padding(codeEnd, config.Align)
|
dataPadding := common.Padding(codeEnd, Align)
|
||||||
dataStart := codeEnd + dataPadding
|
dataStart := codeEnd + dataPadding
|
||||||
|
|
||||||
binary.Write(writer, binary.LittleEndian, &Segment64{
|
binary.Write(writer, binary.LittleEndian, &Segment64{
|
||||||
LoadCommand: LcSegment64,
|
LoadCommand: LcSegment64,
|
||||||
Length: 0x48,
|
Length: 72,
|
||||||
Name: [16]byte{'_', '_', 'T', 'E', 'X', 'T'},
|
Name: [16]byte{'_', '_', 'T', 'E', 'X', 'T'},
|
||||||
Address: config.BaseAddress + codeStart,
|
Address: config.BaseAddress + codeStart,
|
||||||
SizeInMemory: codeLength,
|
SizeInMemory: codeLength,
|
||||||
@ -74,7 +74,7 @@ func (m *MachO) Write(writer io.Writer) {
|
|||||||
|
|
||||||
binary.Write(writer, binary.LittleEndian, &Segment64{
|
binary.Write(writer, binary.LittleEndian, &Segment64{
|
||||||
LoadCommand: LcSegment64,
|
LoadCommand: LcSegment64,
|
||||||
Length: 0x48,
|
Length: 72,
|
||||||
Name: [16]byte{'_', '_', 'D', 'A', 'T', 'A'},
|
Name: [16]byte{'_', '_', 'D', 'A', 'T', 'A'},
|
||||||
Address: config.BaseAddress + dataStart,
|
Address: config.BaseAddress + dataStart,
|
||||||
SizeInMemory: uint64(len(m.Data)),
|
SizeInMemory: uint64(len(m.Data)),
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
package pe
|
package pe
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Align decides the alignment of the sections.
|
||||||
|
Align = 0x200
|
||||||
|
|
||||||
|
// The code offset is the offset of the executable machine code within the file.
|
||||||
|
CodeOffset = Align
|
||||||
|
)
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
const (
|
const (
|
||||||
IMAGE_FILE_MACHINE_AMD64 = 0x8664
|
IMAGE_FILE_MACHINE_AMD64 = 0x8664
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package pe
|
package pe
|
||||||
|
|
||||||
|
const DOSHeaderSize = 64
|
||||||
|
|
||||||
// DOSHeader is at the beginning of each EXE file and nowadays just points
|
// DOSHeader is at the beginning of each EXE file and nowadays just points
|
||||||
// to the NTHeader using an absolute file offset.
|
// to the PEHeader using an absolute file offset.
|
||||||
type DOSHeader struct {
|
type DOSHeader struct {
|
||||||
Magic [4]byte
|
Magic [4]byte
|
||||||
_ [56]byte
|
_ [56]byte
|
||||||
NTHeaderOffset uint32
|
PEHeaderOffset uint32
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package pe
|
package pe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
@ -8,53 +9,58 @@ import (
|
|||||||
"git.akyoto.dev/cli/q/src/os/common"
|
"git.akyoto.dev/cli/q/src/os/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const NumSections = 2
|
||||||
|
|
||||||
// EXE is the portable executable format used on Windows.
|
// EXE is the portable executable format used on Windows.
|
||||||
type EXE struct {
|
type EXE struct {
|
||||||
DOSHeader
|
DOSHeader
|
||||||
NTHeader
|
PEHeader
|
||||||
OptionalHeader64
|
OptionalHeader64
|
||||||
CodeHeader SectionHeader
|
Sections [NumSections]SectionHeader
|
||||||
Code []byte
|
CodePadding []byte
|
||||||
Data []byte
|
Code []byte
|
||||||
|
DataPadding []byte
|
||||||
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new EXE file.
|
// New creates a new EXE file.
|
||||||
func New(code []byte, data []byte) *EXE {
|
func New(code []byte, data []byte) *EXE {
|
||||||
const codeStart = 0x170
|
codeStart := uint32(DOSHeaderSize + PEHeaderSize + OptionalHeader64Size + SectionHeaderSize*NumSections)
|
||||||
const optHeaderSize = 0xF0
|
codePadding := common.Padding(codeStart, Align)
|
||||||
|
codeStart += codePadding
|
||||||
|
|
||||||
codeSize := uint32(len(code))
|
dataStart := codeStart + uint32(len(code))
|
||||||
headerSize := uint32(codeStart)
|
dataPadding := common.Padding(dataStart, Align)
|
||||||
sectionAlign := uint32(0x10)
|
dataStart += dataPadding
|
||||||
fileAlign := uint32(0x10)
|
|
||||||
imageSize := uint32(codeStart + len(code))
|
imageSize := uint32(dataStart + uint32(len(data)))
|
||||||
imageSize += common.Padding(imageSize, sectionAlign)
|
imageSize += common.Padding(imageSize, Align)
|
||||||
|
|
||||||
return &EXE{
|
return &EXE{
|
||||||
DOSHeader: DOSHeader{
|
DOSHeader: DOSHeader{
|
||||||
Magic: [4]byte{'M', 'Z', 0, 0},
|
Magic: [4]byte{'M', 'Z', 0, 0},
|
||||||
NTHeaderOffset: 0x40,
|
PEHeaderOffset: 0x40,
|
||||||
},
|
},
|
||||||
NTHeader: NTHeader{
|
PEHeader: PEHeader{
|
||||||
Signature: [4]byte{'P', 'E', 0, 0},
|
Signature: [4]byte{'P', 'E', 0, 0},
|
||||||
Machine: IMAGE_FILE_MACHINE_AMD64,
|
Machine: IMAGE_FILE_MACHINE_AMD64,
|
||||||
NumberOfSections: 1,
|
NumberOfSections: NumSections,
|
||||||
SizeOfOptionalHeader: optHeaderSize,
|
SizeOfOptionalHeader: OptionalHeader64Size,
|
||||||
Characteristics: IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE,
|
Characteristics: IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE,
|
||||||
},
|
},
|
||||||
OptionalHeader64: OptionalHeader64{
|
OptionalHeader64: OptionalHeader64{
|
||||||
Magic: 0x020B, // PE32+ executable
|
Magic: 0x020B, // PE32+ executable
|
||||||
MajorLinkerVersion: 0x0E,
|
MajorLinkerVersion: 0x0E,
|
||||||
MinorLinkerVersion: 0x16,
|
MinorLinkerVersion: 0x16,
|
||||||
SizeOfCode: codeSize,
|
SizeOfCode: uint32(len(code)),
|
||||||
AddressOfEntryPoint: codeStart,
|
AddressOfEntryPoint: codeStart,
|
||||||
ImageBase: config.BaseAddress,
|
ImageBase: config.BaseAddress,
|
||||||
SectionAlignment: sectionAlign, // power of 2, must be greater than or equal to FileAlignment
|
SectionAlignment: Align, // power of 2, must be greater than or equal to FileAlignment
|
||||||
FileAlignment: fileAlign, // power of 2
|
FileAlignment: Align, // power of 2
|
||||||
MajorOperatingSystemVersion: 0x06,
|
MajorOperatingSystemVersion: 0x06,
|
||||||
MajorSubsystemVersion: 0x06,
|
MajorSubsystemVersion: 0x06,
|
||||||
SizeOfImage: imageSize,
|
SizeOfImage: imageSize,
|
||||||
SizeOfHeaders: headerSize,
|
SizeOfHeaders: codeStart, // section bodies begin here
|
||||||
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI,
|
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI,
|
||||||
DllCharacteristics: IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE,
|
DllCharacteristics: IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE,
|
||||||
SizeOfStackReserve: 0x100000,
|
SizeOfStackReserve: 0x100000,
|
||||||
@ -81,25 +87,39 @@ func New(code []byte, data []byte) *EXE {
|
|||||||
{VirtualAddress: 0, Size: 0},
|
{VirtualAddress: 0, Size: 0},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CodeHeader: SectionHeader{
|
Sections: [NumSections]SectionHeader{
|
||||||
Name: [8]byte{'.', 't', 'e', 'x', 't'},
|
{
|
||||||
VirtualSize: uint32(len(code)),
|
Name: [8]byte{'.', 'c', 'o', 'd', 'e'},
|
||||||
VirtualAddress: codeStart,
|
VirtualSize: uint32(len(code)),
|
||||||
RawSize: uint32(len(code)), // must be a multiple of FileAlignment
|
VirtualAddress: codeStart,
|
||||||
RawAddress: codeStart, // must be a multiple of FileAlignment
|
RawSize: uint32(len(code)), // must be a multiple of FileAlignment
|
||||||
Characteristics: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ,
|
RawAddress: codeStart, // must be a multiple of FileAlignment
|
||||||
|
Characteristics: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: [8]byte{'.', 'd', 'a', 't', 'a'},
|
||||||
|
VirtualSize: uint32(len(data)),
|
||||||
|
VirtualAddress: dataStart,
|
||||||
|
RawSize: uint32(len(data)), // must be a multiple of FileAlignment
|
||||||
|
RawAddress: dataStart, // must be a multiple of FileAlignment
|
||||||
|
Characteristics: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Code: code,
|
CodePadding: bytes.Repeat([]byte{0}, int(codePadding)),
|
||||||
// Data: data,
|
Code: code,
|
||||||
|
DataPadding: bytes.Repeat([]byte{0}, int(dataPadding)),
|
||||||
|
Data: data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes the EXE file to the given writer.
|
// Write writes the EXE file to the given writer.
|
||||||
func (pe *EXE) Write(writer io.Writer) {
|
func (pe *EXE) Write(writer io.Writer) {
|
||||||
binary.Write(writer, binary.LittleEndian, &pe.DOSHeader)
|
binary.Write(writer, binary.LittleEndian, &pe.DOSHeader)
|
||||||
binary.Write(writer, binary.LittleEndian, &pe.NTHeader)
|
binary.Write(writer, binary.LittleEndian, &pe.PEHeader)
|
||||||
binary.Write(writer, binary.LittleEndian, &pe.OptionalHeader64)
|
binary.Write(writer, binary.LittleEndian, &pe.OptionalHeader64)
|
||||||
binary.Write(writer, binary.LittleEndian, &pe.CodeHeader)
|
binary.Write(writer, binary.LittleEndian, &pe.Sections)
|
||||||
|
binary.Write(writer, binary.LittleEndian, &pe.CodePadding)
|
||||||
binary.Write(writer, binary.LittleEndian, &pe.Code)
|
binary.Write(writer, binary.LittleEndian, &pe.Code)
|
||||||
// binary.Write(writer, binary.LittleEndian, &pe.Data)
|
binary.Write(writer, binary.LittleEndian, &pe.DataPadding)
|
||||||
|
binary.Write(writer, binary.LittleEndian, &pe.Data)
|
||||||
}
|
}
|
||||||
|
9
src/os/windows/pe/ImportDirectory.go
Normal file
9
src/os/windows/pe/ImportDirectory.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package pe
|
||||||
|
|
||||||
|
type ImportDirectory struct {
|
||||||
|
OriginalFirstThunk uint32
|
||||||
|
TimeDateStamp uint32
|
||||||
|
ForwarderChain uint32
|
||||||
|
Name uint32
|
||||||
|
FirstThunk uint32
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package pe
|
package pe
|
||||||
|
|
||||||
|
const OptionalHeader64Size = 240
|
||||||
|
|
||||||
type OptionalHeader64 struct {
|
type OptionalHeader64 struct {
|
||||||
Magic uint16
|
Magic uint16
|
||||||
MajorLinkerVersion uint8
|
MajorLinkerVersion uint8
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package pe
|
package pe
|
||||||
|
|
||||||
type NTHeader struct {
|
const PEHeaderSize = 24
|
||||||
|
|
||||||
|
type PEHeader struct {
|
||||||
Signature [4]byte
|
Signature [4]byte
|
||||||
Machine uint16
|
Machine uint16
|
||||||
NumberOfSections uint16
|
NumberOfSections uint16
|
@ -1,5 +1,7 @@
|
|||||||
package pe
|
package pe
|
||||||
|
|
||||||
|
const SectionHeaderSize = 40
|
||||||
|
|
||||||
type SectionHeader struct {
|
type SectionHeader struct {
|
||||||
Name [8]byte
|
Name [8]byte
|
||||||
VirtualSize uint32
|
VirtualSize uint32
|
||||||
|
@ -29,6 +29,10 @@ func (s *Scanner) queueDirectory(directory string, pkg string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(name, "_windows.q") && config.TargetOS != "windows" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
fullPath := filepath.Join(directory, name)
|
fullPath := filepath.Join(directory, name)
|
||||||
s.queueFile(fullPath, pkg)
|
s.queueFile(fullPath, pkg)
|
||||||
})
|
})
|
||||||
|
@ -249,7 +249,7 @@ func (s *Scanner) scanFile(path string, pkg string) error {
|
|||||||
register := x64.InputRegisters[count]
|
register := x64.InputRegisters[count]
|
||||||
uses := token.Count(function.Body, contents, token.Identifier, name)
|
uses := token.Count(function.Body, contents, token.Identifier, name)
|
||||||
|
|
||||||
if uses == 0 {
|
if uses == 0 && name != "_" {
|
||||||
return errors.New(&errors.UnusedVariable{Name: name}, file, tokens[0].Position)
|
return errors.New(&errors.UnusedVariable{Name: name}, file, tokens[0].Position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user