Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V0.8.0 #58

Merged
merged 6 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.15
go-version: 1.18

- name: Build Linux AMD64
run: go build -v -o dwarf2json-linux-amd64
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ analysis.

[![build](https://github.com/volatilityfoundation/dwarf2json/workflows/build/badge.svg)](https://github.com/volatilityfoundation/dwarf2json/actions?query=workflow%3Abuild)

To build (Go 1.14+ required):
To build (Go 1.18+ required):
```
$ go build
```
Expand Down
115 changes: 0 additions & 115 deletions dwarf.go

This file was deleted.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/volatilityfoundation/dwarf2json

go 1.14
go 1.18

require github.com/spf13/pflag v1.0.5
68 changes: 58 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const (

const (
TOOL_NAME = "dwarf2json"
TOOL_VERSION = "0.7.0"
TOOL_VERSION = "0.8.0"
FORMAT_VERSION = "6.2.0"
)

Expand Down Expand Up @@ -194,9 +194,9 @@ type vtypeJson struct {
Symbols map[string]*vtypeSymbol `json:"symbols"`
}

func (doc *vtypeJson) addStruct(structType *dwarf.StructType, name string) {
func (doc *vtypeJson) addStruct(structType *dwarf.StructType, name, endian string, off dwarf.Offset) error {
if structType.Incomplete {
return
return nil
}

st :=
Expand All @@ -206,6 +206,7 @@ func (doc *vtypeJson) addStruct(structType *dwarf.StructType, name string) {
Kind: structType.Kind,
}

anonymousCount := 0
for _, field := range structType.Field {
if field == nil {
continue
Expand All @@ -221,18 +222,57 @@ func (doc *vtypeJson) addStruct(structType *dwarf.StructType, name string) {
vtypeField := vtypeStructField{Offset: field.ByteOffset}
fieldName := field.Name
if fieldName == "" {
fieldName = fmt.Sprintf("unnamed_field_%x", field.ByteOffset)
fieldName = fmt.Sprintf("unnamed_field_%x", anonymousCount)
vtypeField.Anonymous = true
anonymousCount += 1
}

if field.BitSize != 0 {
vtypeField.FieldType = make(map[string]interface{})
vtypeField.FieldType["kind"] = "bitfield"
vtypeField.FieldType["bit_length"] = field.BitSize
vtypeField.FieldType["type"] = fieldType
// calculation to change the DWARF offset from MSB to LSB
maxPos := (8 * field.ByteSize) - 1
vtypeField.FieldType["bit_position"] = maxPos - (field.BitOffset + (field.BitSize - 1))

var bitOffset int64
var byteOffset int64 = field.ByteOffset

// DWARF4 introduced a new attribute for describing bitfields,
// DW_AT_data_bit_offset. This is exposed by the debug/dwarf
// library as FieldType.DataBitOffset. This new field replaces the
// old FieldType.BitOffset for DWARF versions >= 5.

// According the the debug/dwarf library, the field with a value >
// 0 should be used. However this is not enough because there are
// cases where both fields can be zero at the same time.

// Because of this ambiguity, field.ByteSize is used as a heuristic
// to decide between which field to use. The FieldType.ByteSize is
// > 0, when FieldType.BitOffset is used.
if field.ByteSize > 0 {
// assume Dwarf <=4
if field.DataBitOffset > 0 {
return fmt.Errorf("bitfield heuristic violated at offset %v because DataBitOffset > 0", off)
}

bitOffset = field.BitOffset
if endian == "little" {
// calculation to change the DWARF offset from MSB to LSB
bitOffset = 8*field.ByteSize - (field.BitOffset + field.BitSize)
}
byteOffset += bitOffset / 8
bitOffset %= 8
} else {
// assuming DWARF version > 4
if field.BitOffset > 0 {
return fmt.Errorf("bitfield heuristic violated at offset %v because BitOffset > 0", off)
}
byteOffset = field.DataBitOffset / 8
bitOffset = field.DataBitOffset % 8
}

vtypeField.Offset = byteOffset
vtypeField.FieldType["bit_position"] = bitOffset

} else {
vtypeField.FieldType = fieldType
}
Expand All @@ -241,6 +281,8 @@ func (doc *vtypeJson) addStruct(structType *dwarf.StructType, name string) {
}

doc.UserTypes[name] = st

return nil
}

func (doc *vtypeJson) addDwarf(data *dwarf.Data, endian string, extract Extract) error {
Expand Down Expand Up @@ -301,7 +343,10 @@ func (doc *vtypeJson) addDwarf(data *dwarf.Data, endian string, extract Extract)
return fmt.Errorf("%s is not a StructType?", genericType.String())
}

doc.addStruct(structType, structName(structType))
err = doc.addStruct(structType, structName(structType), endian, entry.Offset)
if err != nil {
return fmt.Errorf("could not parse struct: %s", err)
}
case dwarf.TagEnumerationType:
genericType, err := data.Type(entry.Offset)
if err != nil {
Expand Down Expand Up @@ -376,7 +421,10 @@ func (doc *vtypeJson) addDwarf(data *dwarf.Data, endian string, extract Extract)
}

if structType, ok := typedefType.Type.(*dwarf.StructType); ok && structType.Name == "" {
doc.addStruct(structType, typedefType.Name)
err := doc.addStruct(structType, typedefType.Name, endian, entry.Offset)
if err != nil {
return fmt.Errorf("could not parse struct: %s", err)
}
}

}
Expand Down Expand Up @@ -1009,7 +1057,7 @@ func generateLinux(files FilesToProcess) (*vtypeJson, error) {
endian = "big"
}

data, err := DWARF(elfFile)
data, err := elfFile.DWARF()
if err != nil {
return nil, fmt.Errorf("could not get DWARF from %s: %v", f.FilePath, err)
}
Expand Down
Loading