func Core(coreFile, base, exePath string) (*Process, error) {
	core, err := os.Open(coreFile)
	if err != nil {
		return nil, fmt.Errorf("failed to open core file: %v", err)
	}

	p := &Process{base: base, files: make(map[string]*file)}
	if exePath != "" {
		bin, err := os.Open(exePath)
		if err != nil {
			return nil, fmt.Errorf("failed to open executable file: %v", err)
		}
		p.exe = bin
	}

	if err := p.readExec(p.exe); err != nil {
		return nil, err
	}

	if err := p.readCore(core); err != nil {
		return nil, err
	}

	if err := p.readDebugInfo(); err != nil {
		return nil, err
	}

	// Sort then merge mappings, just to clean up a bit.
	mappings := p.memory.mappings
	sort.Slice(mappings, func(i, j int) bool {
		return mappings[i].min < mappings[j].min
	})
	ms := mappings[1:]
	mappings = mappings[:1]
	for _, m := range ms {
		k := mappings[len(mappings)-1]
		if m.min == k.max &&
			m.perm == k.perm &&
			m.f == k.f &&
			m.off == k.off+k.Size() {
			k.max = m.max
			// TODO: also check origF?
		} else {
			mappings = append(mappings, m)
		}
	}
	p.memory.mappings = mappings

	// Memory map all the mappings.
	hostPageSize := int64(syscall.Getpagesize())
	for _, m := range p.memory.mappings {
		size := m.max.Sub(m.min)
		if m.f == nil {
			// We don't have any source for this data.
			// Could be a mapped file that we couldn't find.
			// Could be a mapping madvised as MADV_DONTDUMP.
			// Pretend this is read-as-zero.
			// The other option is to just throw away
			// the mapping (and thus make Read*s of this
			// mapping fail).
			p.warnings = append(p.warnings,
				fmt.Sprintf("Missing data at addresses [%x %x]. Assuming all zero.", m.min, m.max))
			// TODO: this allocation could be large.
			// Use mmap to avoid real backing store for all those zeros, or
			// perhaps split the mapping up into chunks and share the zero contents among them.
			m.contents = make([]byte, size)
			continue
		}
		if m.perm&Write != 0 && m.f != core {
			p.warnings = append(p.warnings,
				fmt.Sprintf("Writeable data at [%x %x] missing from core. Using possibly stale backup source %s.", m.min, m.max, m.f.Name()))
		}
		// Data in core file might not be aligned enough for the host.
		// Expand memory range so we can map full pages.
		minOff := m.off
		maxOff := m.off + size
		minOff -= minOff % hostPageSize
		if maxOff%hostPageSize != 0 {
			maxOff += hostPageSize - maxOff%hostPageSize
		}

		// Read data from file.
		data, err := mapFile(int(m.f.Fd()), minOff, int(maxOff-minOff))
		if err != nil {
			return nil, fmt.Errorf("can't memory map %s at %x: %s\n", m.f.Name(), minOff, err)
		}

		// Trim any data we mapped but don't need.
		data = data[m.off-minOff:]
		data = data[:size]

		m.contents = data
	}

	// Build page table for mapping lookup.
	for _, m := range p.memory.mappings {
		err := p.addMapping(m)
		if err != nil {
			return nil, err
		}
	}

	return p, nil
}
func Core(coreFile, base, exePath string) (*Process, error) {
	core, err := os.Open(coreFile)
	if err != nil {
		return nil, fmt.Errorf("failed to open core file: %v", err)
	}

	p := &Process{base: base, files: make(map[string]*file)}
	if exePath != "" {
		bin, err := os.Open(exePath)
		if err != nil {
			return nil, fmt.Errorf("failed to open executable file: %v", err)
		}
		p.exe = bin
	}

	if err := p.readExec(p.exe); err != nil {
		return nil, err
	}

	if err := p.readCore(core); err != nil {
		return nil, err
	}

	if err := p.readDebugInfo(); err != nil {
		return nil, err
	}

	
	mappings := p.memory.mappings
	sort.Slice(mappings, func(i, j int) bool {
		return mappings[i].min < mappings[j].min
	})
	ms := mappings[1:]
	mappings = mappings[:1]
	for _, m := range ms {
		k := mappings[len(mappings)-1]
		if m.min == k.max &&
			m.perm == k.perm &&
			m.f == k.f &&
			m.off == k.off+k.Size() {
			k.max = m.max
			
		} else {
			mappings = append(mappings, m)
		}
	}
	p.memory.mappings = mappings

	
	hostPageSize := int64(syscall.Getpagesize())
	for _, m := range p.memory.mappings {
		size := m.max.Sub(m.min)
		if m.f == nil {
			
			
			
			
			
			
			
			p.warnings = append(p.warnings,
				fmt.Sprintf("Missing data at addresses [%x %x]. Assuming all zero.", m.min, m.max))
			
			
			
			m.contents = make([]byte, size)
			continue
		}
		if m.perm&Write != 0 && m.f != core {
			p.warnings = append(p.warnings,
				fmt.Sprintf("Writeable data at [%x %x] missing from core. Using possibly stale backup source %s.", m.min, m.max, m.f.Name()))
		}
		
		
		minOff := m.off
		maxOff := m.off + size
		minOff -= minOff % hostPageSize
		if maxOff%hostPageSize != 0 {
			maxOff += hostPageSize - maxOff%hostPageSize
		}

		
		data, err := mapFile(int(m.f.Fd()), minOff, int(maxOff-minOff))
		if err != nil {
			return nil, fmt.Errorf("can't memory map %s at %x: %s\n", m.f.Name(), minOff, err)
		}

		
		data = data[m.off-minOff:]
		data = data[:size]

		m.contents = data
	}

	
	for _, m := range p.memory.mappings {
		err := p.addMapping(m)
		if err != nil {
			return nil, err
		}
	}

	return p, nil
}
func Core ( coreFile , base , exePath string ) ( * Process , error ) { core , err := os . Open ( coreFile ) if err != nil { return nil , fmt . Errorf ( " " , err ) } p := & Process { base : base , files : make ( map [ string ] * file ) } if exePath != " " { bin , err := os . Open ( exePath ) if err != nil { return nil , fmt . Errorf ( " " , err ) } p . exe = bin } if err := p . readExec ( p . exe ) ; err != nil { return nil , err } if err := p . readCore ( core ) ; err != nil { return nil , err } if err := p . readDebugInfo ( ) ; err != nil { return nil , err } // Sort then merge mappings, just to clean up a bit. mappings := p . memory . mappings sort . Slice ( mappings , func ( i , j int ) bool { return mappings [ i ] . min < mappings [ j ] . min } ) ms := mappings [ 1 : ] mappings = mappings [ : 1 ] for _ , m := range ms { k := mappings [ len ( mappings ) - 1 ] if m . min == k . max && m . perm == k . perm && m . f == k . f && m . off == k . off + k . Size ( ) { k . max = m . max // TODO: also check origF? } else { mappings = append ( mappings , m ) } } p . memory . mappings = mappings // Memory map all the mappings. hostPageSize := int64 ( syscall . Getpagesize ( ) ) for _ , m := range p . memory . mappings { size := m . max . Sub ( m . min ) if m . f == nil { // We don't have any source for this data. // Could be a mapped file that we couldn't find. // Could be a mapping madvised as MADV_DONTDUMP. // Pretend this is read-as-zero. // The other option is to just throw away // the mapping (and thus make Read*s of this // mapping fail). p . warnings = append ( p . warnings , fmt . Sprintf ( " " , m . min , m . max ) ) // TODO: this allocation could be large. // Use mmap to avoid real backing store for all those zeros, or // perhaps split the mapping up into chunks and share the zero contents among them. m . contents = make ( [ ] byte , size ) continue } if m . perm & Write != 0 && m . f != core { p . warnings = append ( p . warnings , fmt . Sprintf ( " " , m . min , m . max , m . f . Name ( ) ) ) } // Data in core file might not be aligned enough for the host. // Expand memory range so we can map full pages. minOff := m . off maxOff := m . off + size minOff -= minOff % hostPageSize if maxOff % hostPageSize != 0 { maxOff += hostPageSize - maxOff % hostPageSize } // Read data from file. data , err := mapFile ( int ( m . f . Fd ( ) ) , minOff , int ( maxOff - minOff ) ) if err != nil { return nil , fmt . Errorf ( " \n " , m . f . Name ( ) , minOff , err ) } // Trim any data we mapped but don't need. data = data [ m . off - minOff : ] data = data [ : size ] m . contents = data } // Build page table for mapping lookup. for _ , m := range p . memory . mappings { err := p . addMapping ( m ) if err != nil { return nil , err } } return p , nil }
// Core takes the name of a core file and returns a Process that
// represents the state of the inferior that generated the core file.
Core takes the name of a core file and returns a Process that represents the state of the inferior that generated the core file .