Skip to content
This repository has been archived by the owner on Mar 9, 2019. It is now read-only.

Commit

Permalink
Merge pull request #578 from resin-os/align-fix
Browse files Browse the repository at this point in the history
Correct broken unaligned load/store in armv5
  • Loading branch information
benbjohnson committed Sep 6, 2016
2 parents 1ff46c1 + 97aba55 commit de82765
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 1 deletion.
3 changes: 3 additions & 0 deletions bolt_386.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ const maxMapSize = 0x7FFFFFFF // 2GB

// maxAllocSize is the size used when creating array pointers.
const maxAllocSize = 0xFFFFFFF

// Are unaligned load/stores broken on this arch?
var brokenUnaligned = false
3 changes: 3 additions & 0 deletions bolt_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ const maxMapSize = 0xFFFFFFFFFFFF // 256TB

// maxAllocSize is the size used when creating array pointers.
const maxAllocSize = 0x7FFFFFFF

// Are unaligned load/stores broken on this arch?
var brokenUnaligned = false
21 changes: 21 additions & 0 deletions bolt_arm.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
package bolt

import "unsafe"

// maxMapSize represents the largest mmap size supported by Bolt.
const maxMapSize = 0x7FFFFFFF // 2GB

// maxAllocSize is the size used when creating array pointers.
const maxAllocSize = 0xFFFFFFF

// Are unaligned load/stores broken on this arch?
var brokenUnaligned bool

func init() {
// Simple check to see whether this arch handles unaligned load/stores
// correctly.

// ARM9 and older devices require load/stores to be from/to aligned
// addresses. If not, the lower 2 bits are cleared and that address is
// read in a jumbled up order.

// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html

raw := [6]byte{0xfe, 0xef, 0x11, 0x22, 0x22, 0x11}
val := *(*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(&raw)) + 2))

brokenUnaligned = val != 0x11222211
}
3 changes: 3 additions & 0 deletions bolt_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ const maxMapSize = 0xFFFFFFFFFFFF // 256TB

// maxAllocSize is the size used when creating array pointers.
const maxAllocSize = 0x7FFFFFFF

// Are unaligned load/stores broken on this arch?
var brokenUnaligned = false
3 changes: 3 additions & 0 deletions bolt_ppc64le.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ const maxMapSize = 0xFFFFFFFFFFFF // 256TB

// maxAllocSize is the size used when creating array pointers.
const maxAllocSize = 0x7FFFFFFF

// Are unaligned load/stores broken on this arch?
var brokenUnaligned = false
3 changes: 3 additions & 0 deletions bolt_s390x.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ const maxMapSize = 0xFFFFFFFFFFFF // 256TB

// maxAllocSize is the size used when creating array pointers.
const maxAllocSize = 0x7FFFFFFF

// Are unaligned load/stores broken on this arch?
var brokenUnaligned = false
10 changes: 9 additions & 1 deletion bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,17 @@ func (b *Bucket) Bucket(name []byte) *Bucket {
func (b *Bucket) openBucket(value []byte) *Bucket {
var child = newBucket(b.tx)

// If unaligned load/stores are broken on this arch and value is
// unaligned simply clone to an aligned byte array.
unaligned := brokenUnaligned && uintptr(unsafe.Pointer(&value[0]))&3 != 0

if unaligned {
value = cloneBytes(value)
}

// If this is a writable transaction then we need to copy the bucket entry.
// Read-only transactions can point directly at the mmap entry.
if b.tx.writable {
if b.tx.writable && !unaligned {
child.bucket = &bucket{}
*child.bucket = *(*bucket)(unsafe.Pointer(&value[0]))
} else {
Expand Down

0 comments on commit de82765

Please sign in to comment.