Beispiel #1
0
func dump(tab *gosym.Table, lookup lookupFunc, disasm disasmFunc, syms []Sym, textData []byte, textStart uint64) {
	stdout := bufio.NewWriter(os.Stdout)
	defer stdout.Flush()

	printed := false
	for _, sym := range syms {
		if sym.Code != 'T' || sym.Size == 0 || sym.Name == "_text" || sym.Name == "text" || sym.Addr < textStart || symRE != nil && !symRE.MatchString(sym.Name) {
			continue
		}
		if sym.Addr >= textStart+uint64(len(textData)) || sym.Addr+uint64(sym.Size) > textStart+uint64(len(textData)) {
			break
		}
		if printed {
			fmt.Fprintf(stdout, "\n")
		} else {
			printed = true
		}
		file, _, _ := tab.PCToLine(sym.Addr)
		fmt.Fprintf(stdout, "TEXT %s(SB) %s\n", sym.Name, file)
		tw := tabwriter.NewWriter(stdout, 1, 8, 1, '\t', 0)
		start := sym.Addr
		end := sym.Addr + uint64(sym.Size)
		for pc := start; pc < end; {
			i := pc - textStart
			text, size := disasm(textData[i:end-textStart], pc, lookup)
			file, line, _ := tab.PCToLine(pc)
			fmt.Fprintf(tw, "\t%s:%d\t%#x\t%x\t%s\n", base(file), line, pc, textData[i:i+uint64(size)], text)
			pc += uint64(size)
		}
		tw.Flush()
	}
}
Beispiel #2
0
func gnuDump(tab *gosym.Table, lookup lookupFunc, disasm disasmFunc, textData []byte, textStart uint64) {
	start, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(1), "0x"), 16, 64)
	if err != nil {
		log.Fatalf("invalid start PC: %v", err)
	}
	end, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(2), "0x"), 16, 64)
	if err != nil {
		log.Fatalf("invalid end PC: %v", err)
	}
	if start < textStart {
		start = textStart
	}
	if end < start {
		end = start
	}
	if end > textStart+uint64(len(textData)) {
		end = textStart + uint64(len(textData))
	}

	stdout := bufio.NewWriter(os.Stdout)
	defer stdout.Flush()

	// For now, find spans of same PC/line/fn and
	// emit them as having dummy instructions.
	var (
		spanPC   uint64
		spanFile string
		spanLine int
		spanFn   *gosym.Func
	)

	flush := func(endPC uint64) {
		if spanPC == 0 {
			return
		}
		fmt.Fprintf(stdout, "%s:%d\n", spanFile, spanLine)
		for pc := spanPC; pc < endPC; {
			text, size := disasm(textData[pc-textStart:], pc, lookup)
			fmt.Fprintf(stdout, " %x: %s\n", pc, text)
			pc += uint64(size)
		}
		spanPC = 0
	}

	for pc := start; pc < end; pc++ {
		file, line, fn := tab.PCToLine(pc)
		if file != spanFile || line != spanLine || fn != spanFn {
			flush(pc)
			spanPC, spanFile, spanLine, spanFn = pc, file, line, fn
		}
	}
	flush(end)
}
Beispiel #3
0
func dump(tab *gosym.Table, lookup lookupFunc, disasm disasmFunc, goarch string, syms []Sym, textData []byte, textStart uint64) {
	stdout := bufio.NewWriter(os.Stdout)
	defer stdout.Flush()

	printed := false
	for _, sym := range syms {
		if sym.Code != 'T' || sym.Size == 0 || sym.Name == "_text" || sym.Name == "text" || sym.Addr < textStart || symRE != nil && !symRE.MatchString(sym.Name) {
			continue
		}
		if sym.Addr >= textStart+uint64(len(textData)) || sym.Addr+uint64(sym.Size) > textStart+uint64(len(textData)) {
			break
		}
		if printed {
			fmt.Fprintf(stdout, "\n")
		} else {
			printed = true
		}
		file, _, _ := tab.PCToLine(sym.Addr)
		fmt.Fprintf(stdout, "TEXT %s(SB) %s\n", sym.Name, file)
		tw := tabwriter.NewWriter(stdout, 1, 8, 1, '\t', 0)
		start := sym.Addr
		end := sym.Addr + uint64(sym.Size)
		for pc := start; pc < end; {
			i := pc - textStart
			text, size := disasm(textData[i:end-textStart], pc, lookup)
			file, line, _ := tab.PCToLine(pc)

			// ARM is word-based, so show actual word hex, not byte hex.
			// Since ARM is little endian, they're different.
			if goarch == "arm" && size == 4 {
				fmt.Fprintf(tw, "\t%s:%d\t%#x\t%08x\t%s\n", base(file), line, pc, binary.LittleEndian.Uint32(textData[i:i+uint64(size)]), text)
			} else {
				fmt.Fprintf(tw, "\t%s:%d\t%#x\t%x\t%s\n", base(file), line, pc, textData[i:i+uint64(size)], text)
			}
			pc += uint64(size)
		}
		tw.Flush()
	}
}