Skip to content

Commit

Permalink
Merge pull request #58 from volatilityfoundation/v0.8.0
Browse files Browse the repository at this point in the history
v0.8.0
  • Loading branch information
npetroni authored Feb 23, 2024
2 parents 15baf31 + 9a1cc85 commit 340ed1b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 128 deletions.
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

0 comments on commit 340ed1b

Please sign in to comment.