github.com/decomp/exp@v0.0.0-20210624183419-6d058f5e1da6/cmd/bin2asm/header.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "path/filepath" 8 "strings" 9 10 "github.com/mewkiz/pkg/goutil" 11 "github.com/mewrev/pe" 12 "github.com/pkg/errors" 13 ) 14 15 // bin2asmDir specifies the source directory of the bin2asm command. 16 var bin2asmDir string 17 18 func init() { 19 var err error 20 bin2asmDir, err = goutil.SrcDir("github.com/decomp/exp/cmd/bin2asm") 21 if err != nil { 22 panic(fmt.Errorf("unable to locate source directory of bin2asm; %v", err)) 23 } 24 } 25 26 // dumpCommon dumps a common include file of the executable. 27 func dumpCommon(file *pe.File) error { 28 buf := &bytes.Buffer{} 29 const commonFormat = ` 30 %%ifndef __COMMON_INC__ 31 %%define __COMMON_INC__ 32 33 %%define IMAGE_BASE 0x%08X 34 %%define CODE_BASE 0x%08X 35 %%define DATA_BASE 0x%08X 36 37 hdr_vstart equ IMAGE_BASE 38 ` 39 optHdr, err := file.OptHeader() 40 if err != nil { 41 return errors.WithStack(err) 42 } 43 sectHdrs, err := file.SectHeaders() 44 if err != nil { 45 return errors.WithStack(err) 46 } 47 fmt.Fprintf(buf, commonFormat[1:], optHdr.ImageBase, optHdr.CodeBase, optHdr.DataBase) 48 49 for _, sectHdr := range sectHdrs { 50 rawName := sectHdr.Name 51 sectName := strings.Replace(rawName, ".", "_", -1) 52 fmt.Fprintf(buf, " %s_vstart equ IMAGE_BASE + 0x%08X\n", sectName, sectHdr.RelAddr) 53 } 54 buf.WriteString("\n") 55 for _, sectHdr := range sectHdrs { 56 if sectHdr.VirtSize > sectHdr.Size { 57 // Section with uninitialized data. 58 buf.WriteString(";") 59 } 60 rawName := sectHdr.Name 61 sectName := strings.Replace(rawName, ".", "_", -1) 62 fmt.Fprintf(buf, " %s_size equ 0x%08X\n", sectName, sectHdr.Size) 63 } 64 buf.WriteString("\n") 65 for _, sectHdr := range sectHdrs { 66 if sectHdr.VirtSize <= sectHdr.Size { 67 // Section with padding. 68 buf.WriteString(";") 69 } 70 rawName := sectHdr.Name 71 sectName := strings.Replace(rawName, ".", "_", -1) 72 fmt.Fprintf(buf, " %s_vsize equ 0x%08X\n", sectName, sectHdr.VirtSize) 73 } 74 buf.WriteString("\n") 75 76 const bitsHeader = ` 77 BITS 32 78 79 SECTION hdr vstart=hdr_vstart 80 ` 81 buf.WriteString(bitsHeader[1:]) 82 83 prev := "hdr" 84 for _, sectHdr := range sectHdrs { 85 rawName := sectHdr.Name 86 sectName := strings.Replace(rawName, ".", "_", -1) 87 fmt.Fprintf(buf, "SECTION %s vstart=%s_vstart follows=%s\n", rawName, sectName, prev) 88 prev = rawName 89 } 90 buf.WriteString("\n") 91 buf.WriteString("%endif ; %ifndef __COMMON_INC__\n") 92 93 // Store output. 94 outPath := filepath.Join(outDir, "common.inc") 95 dbg.Printf("creating %q\n", outPath) 96 if err := ioutil.WriteFile(outPath, buf.Bytes(), 0644); err != nil { 97 return errors.WithStack(err) 98 } 99 return nil 100 }