mirror of
https://github.com/thunderbrewhq/binana.git
synced 2025-12-12 01:42:29 +00:00
feat(go): show where in main.sym that errors appear
This commit is contained in:
parent
cf049a801f
commit
adb68c759c
1 changed files with 141 additions and 139 deletions
|
|
@ -1,139 +1,141 @@
|
||||||
package symfile
|
package symfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const min_columns = 3
|
const min_columns = 3
|
||||||
|
|
||||||
type loader struct {
|
type loader struct {
|
||||||
input *bufio.Reader
|
input *bufio.Reader
|
||||||
table Table
|
table Table
|
||||||
line_number int
|
line_number int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loader) read_line() (line string, err error) {
|
func (l *loader) read_line() (line string, err error) {
|
||||||
l.line_number++
|
l.line_number++
|
||||||
line, err = l.input.ReadString('\n')
|
line, err = l.input.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
line = strings.TrimRight(line, "\r\n")
|
line = strings.TrimRight(line, "\r\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loader) parse_line(line string) (err error) {
|
func (l *loader) parse_line(line string) (err error) {
|
||||||
// trim extraneous whitespace
|
// trim extraneous whitespace
|
||||||
line = strings.Trim(line, " \t")
|
line = strings.Trim(line, " \t")
|
||||||
|
|
||||||
// split into columns
|
// split into columns
|
||||||
columns := strings.Split(line, " ")
|
columns := strings.Split(line, " ")
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
if len(columns) < min_columns {
|
if len(columns) < min_columns {
|
||||||
// this line is discarded but not in error
|
// this line is discarded but not in error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
start_address uint64
|
start_address uint64
|
||||||
comment_text string
|
comment_text string
|
||||||
)
|
)
|
||||||
|
|
||||||
// get name of symbol
|
// get name of symbol
|
||||||
name_column := columns[0]
|
name_column := columns[0]
|
||||||
if name_column == "" {
|
if name_column == "" {
|
||||||
return fmt.Errorf("symfile: (*loader).parse_line: line %d: entry has invalid name '%s", l.line_number, name_column)
|
return fmt.Errorf("symfile: (*loader).parse_line: line %d: entry has invalid name '%s", l.line_number, name_column)
|
||||||
}
|
}
|
||||||
|
|
||||||
start_address, err = strconv.ParseUint(columns[1], 16, 64)
|
start_address, err = strconv.ParseUint(columns[1], 16, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
kind_column := columns[2]
|
kind_column := columns[2]
|
||||||
if len(kind_column) != 1 {
|
if len(kind_column) != 1 {
|
||||||
return fmt.Errorf("symfile: (*loader).parse_line: line %d: entry has invalid kind", l.line_number)
|
return fmt.Errorf("symfile: (*loader).parse_line: line %d: entry has invalid kind", l.line_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
kind := EntryKind(kind_column[0])
|
kind := EntryKind(kind_column[0])
|
||||||
|
|
||||||
if !slices.Contains(valid_kinds, kind) {
|
if !slices.Contains(valid_kinds, kind) {
|
||||||
return fmt.Errorf("symfile: (*loader).parse_line: line %d: entry has invalid kind", l.line_number)
|
return fmt.Errorf("symfile: (*loader).parse_line: line %d: entry has invalid kind", l.line_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// find index of comment column
|
// find index of comment column
|
||||||
index_of_comment := slices.Index(columns, ";")
|
index_of_comment := slices.Index(columns, ";")
|
||||||
|
|
||||||
var num_semantic_columns int
|
var num_semantic_columns int
|
||||||
|
|
||||||
if index_of_comment != -1 {
|
if index_of_comment != -1 {
|
||||||
num_semantic_columns = index_of_comment
|
num_semantic_columns = index_of_comment
|
||||||
comment_text_columns := columns[index_of_comment+1:]
|
comment_text_columns := columns[index_of_comment+1:]
|
||||||
comment_text = strings.Join(comment_text_columns, " ")
|
comment_text = strings.Join(comment_text_columns, " ")
|
||||||
} else {
|
} else {
|
||||||
num_semantic_columns = len(columns)
|
num_semantic_columns = len(columns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start to build entry
|
// Start to build entry
|
||||||
var entry Entry
|
var entry Entry
|
||||||
entry.Name = name_column
|
entry.Name = name_column
|
||||||
entry.StartAddress = start_address
|
entry.StartAddress = start_address
|
||||||
entry.Kind = kind
|
entry.Kind = kind
|
||||||
entry.Comment = comment_text
|
entry.Comment = comment_text
|
||||||
|
|
||||||
// build attributes
|
// build attributes
|
||||||
if num_semantic_columns > 3 {
|
if num_semantic_columns > 3 {
|
||||||
for _, column := range columns[3:] {
|
for _, column := range columns[3:] {
|
||||||
key, value, found := strings.Cut(column, "=")
|
key, value, found := strings.Cut(column, "=")
|
||||||
if found {
|
if found {
|
||||||
switch key {
|
switch key {
|
||||||
case "end":
|
case "end":
|
||||||
entry.EndAddress, err = strconv.ParseUint(value, 16, 64)
|
entry.EndAddress, err = strconv.ParseUint(value, 16, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("symfile: (*loader).parse_line: line %d: unknown attribute '%s'", l.line_number, key)
|
return fmt.Errorf("symfile: (*loader).parse_line: line %d: unknown attribute '%s'", l.line_number, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.table.Insert(&entry)
|
err = l.table.Insert(&entry)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func load(text io.Reader, table Table) (err error) {
|
func load(text io.Reader, table Table) (err error) {
|
||||||
l := new(loader)
|
l := new(loader)
|
||||||
|
|
||||||
l.input = bufio.NewReader(text)
|
l.input = bufio.NewReader(text)
|
||||||
l.table = table
|
l.table = table
|
||||||
|
|
||||||
var (
|
var (
|
||||||
line string
|
line string
|
||||||
)
|
)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
line, err = l.read_line()
|
line, err = l.read_line()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, io.EOF) {
|
if errors.Is(err, io.EOF) {
|
||||||
err = nil
|
err = nil
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
return
|
err = fmt.Errorf("symfile: error reading at line %d: %w", l.line_number, err)
|
||||||
}
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if err = l.parse_line(line); err != nil {
|
|
||||||
return
|
if err = l.parse_line(line); err != nil {
|
||||||
}
|
err = fmt.Errorf("symfile: error parsing at line %d: %w", l.line_number, err)
|
||||||
}
|
return
|
||||||
|
}
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue