<commit_before>package exe

// MacOS Mach-O executable
// NOTE: on MacOS, there is C headers in /usr/include/mach-o

// STATUS: 1%

import (
	"os"

	"github.com/martinlindhe/formats/parse"
)

var (
	machoCpuTypes = map[uint32]string{
		1:         "vax",
		2:         "romp",
		4:         "ns32032",
		5:         "ns32332",
		6:         "mc680x0",
		7:         "i386",
		8:         "mips",
		9:         "ns32532",
		11:        "hppa",
		12:        "arm",
		13:        "mc88000",
		14:        "sparc",
		15:        "i860-be",
		16:        "i860-le",
		17:        "rs6000",
		18:        "powerpc",
		255:       "veo",
		0x1000000: "abi64",
		0x1000007: "x86-64",
		0x1000018: "powerpc64",
	}
)

func MachO(c *parse.ParseChecker) (*parse.ParsedLayout, error) {

	if !isMachO(&c.Header) {
		return nil, nil
	}
	return parseMachO(c.File, c.ParsedLayout)
}

func isMachO(hdr *[0xffff]byte) bool {

	b := *hdr
	if b[3] == 0xfe && b[2] == 0xed && b[1] == 0xfa && (b[0] == 0xce || b[0] == 0xcf) {
		return true
	}

	return false
}

func parseMachO(file *os.File, pl parse.ParsedLayout) (*parse.ParsedLayout, error) {

	pos := int64(0)
	cpuTypeName, _ := parse.ReadToMap(file, parse.Uint32le, pos+4, machoCpuTypes)
	pl.FormatName = "mach-o " + cpuTypeName
	pl.FileKind = parse.Executable
	pl.Layout = []parse.Layout{{
		Offset: pos,
		Length: 28, // XXX
		Info:   "header",
		Type:   parse.Group,
		Childs: []parse.Layout{
			{Offset: pos, Length: 4, Info: "magic", Type: parse.Uint32le},
			{Offset: pos + 4, Length: 4, Info: "cpu type = " + cpuTypeName, Type: parse.Uint32le},
			{Offset: pos + 8, Length: 4, Info: "cpu subtype", Type: parse.Uint32le}, // XXX map ...
			{Offset: pos + 12, Length: 4, Info: "file type", Type: parse.Uint32le},  // XXX ?
			{Offset: pos + 16, Length: 4, Info: "n cmds", Type: parse.Uint32le},
			{Offset: pos + 20, Length: 4, Info: "size of cmds", Type: parse.Uint32le},
			{Offset: pos + 24, Length: 4, Info: "flags", Type: parse.Uint32le},
		}}}

	/* XXX

	   struct segment_command {
	     uint32_t  cmd;
	     uint32_t  cmdsize;
	     char      segname[16];
	     uint32_t  vmaddr;
	     uint32_t  vmsize;
	     uint32_t  fileoff;
	     uint32_t  filesize;
	     vm_prot_t maxprot;
	     vm_prot_t initprot;
	     uint32_t  nsects;
	     uint32_t  flags;
	   };
	*/

	return &pl, nil
}
<commit_msg>parse/mach-o: recognize more magic values<commit_after>package exe

// MacOS Mach-O executable
// NOTE: on MacOS, there is C headers in /usr/include/mach-o
// TODO: handle the CIGAM byte ordered files (ppc, need samples)

// STATUS: 1%

import (
	"encoding/binary"
	"os"

	"github.com/martinlindhe/formats/parse"
)

const (
	MH_MAGIC    = 0xfeedface
	MH_MAGIC_64 = 0xfeedfacf
	MH_CIGAM    = 0xcefaedfe
	MH_CIGAM_64 = 0xcffaedfe
)

var (
	machoMagicTypes = map[uint32]string{
		MH_MAGIC:    "MH_MAGIC",
		MH_MAGIC_64: "MH_MAGIC_64",
		MH_CIGAM:    "MH_CIGAM",
		MH_CIGAM_64: "MH_CIGAM_64",
	}
	machoCpuTypes = map[uint32]string{
		1:         "vax",
		2:         "romp",
		4:         "ns32032",
		5:         "ns32332",
		6:         "mc680x0",
		7:         "i386",
		8:         "mips",
		9:         "ns32532",
		11:        "hppa",
		12:        "arm",
		13:        "mc88000",
		14:        "sparc",
		15:        "i860-be",
		16:        "i860-le",
		17:        "rs6000",
		18:        "powerpc",
		255:       "veo",
		0x1000000: "abi64",
		0x1000007: "x86-64",
		0x1000018: "powerpc64",
	}
)

func MachO(c *parse.ParseChecker) (*parse.ParsedLayout, error) {

	if !isMachO(&c.Header) {
		return nil, nil
	}
	return parseMachO(c.File, c.ParsedLayout)
}

func isMachO(hdr *[0xffff]byte) bool {

	b := *hdr

	val := binary.LittleEndian.Uint32(b[:])

	if val == MH_MAGIC || val == MH_MAGIC_64 || val == MH_CIGAM || val == MH_CIGAM_64 {
		return true
	}
	return false
}

func parseMachO(file *os.File, pl parse.ParsedLayout) (*parse.ParsedLayout, error) {

	pos := int64(0)
	mhName, _ := parse.ReadToMap(file, parse.Uint32le, pos, machoMagicTypes)
	cpuTypeName, _ := parse.ReadToMap(file, parse.Uint32le, pos+4, machoCpuTypes)
	pl.FormatName = "mach-o " + cpuTypeName
	pl.FileKind = parse.Executable
	pl.Layout = []parse.Layout{{
		Offset: pos,
		Length: 28, // XXX
		Info:   "header",
		Type:   parse.Group,
		Childs: []parse.Layout{
			{Offset: pos, Length: 4, Info: "magic = " + mhName, Type: parse.Uint32le},
			{Offset: pos + 4, Length: 4, Info: "cpu type = " + cpuTypeName, Type: parse.Uint32le},
			{Offset: pos + 8, Length: 4, Info: "cpu subtype", Type: parse.Uint32le}, // XXX map ...
			{Offset: pos + 12, Length: 4, Info: "file type", Type: parse.Uint32le},  // XXX ?
			{Offset: pos + 16, Length: 4, Info: "n cmds", Type: parse.Uint32le},
			{Offset: pos + 20, Length: 4, Info: "size of cmds", Type: parse.Uint32le},
			{Offset: pos + 24, Length: 4, Info: "flags", Type: parse.Uint32le},
		}}}

	/* XXX

	   struct segment_command {
	     uint32_t  cmd;
	     uint32_t  cmdsize;
	     char      segname[16];
	     uint32_t  vmaddr;
	     uint32_t  vmsize;
	     uint32_t  fileoff;
	     uint32_t  filesize;
	     vm_prot_t maxprot;
	     vm_prot_t initprot;
	     uint32_t  nsects;
	     uint32_t  flags;
	   };
	*/

	return &pl, nil
}

{'fraction_non_alphanumeric': 0.15503875968992248, 'fraction_numerical': 0.06782945736434108, 'mean_word_length': 2.6141456582633054, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1422291', 'n_tokens_mistral': 2475, 'n_tokens_neox': 2113, 'n_words': 496}