macaw-base
Copyright(c) Galois Inc 2015-2018
MaintainerRyan Scott <rscott@galois.com>, Langston Barrett <langston@galois.com>
Safe HaskellNone
LanguageHaskell2010

Data.Macaw.Memory

Description

Declares Memory, a type for representing pre-loader memory with permissions. This datatype provides an abstraction that is intended to support different architectures, executable formats, and object file formats. Crucially, Memory is capable of representing relocatable (i.e., position-independent) code and data.

A Memory is essentially a collection of segments, each of which belongs to one region. A region is identified by a RegionIndex and represents some address that would be chosen at runtime by the loader (e.g., the virtual address of an ELF segment containing position-independent code). Thus, in this module, an address (MemAddr) consists of a pair of a RegionIndex and an offset into that region. A MemAddr with a RegionIndex of 0 represents an absolute address.

A segment (MemSegment) is a contiguous sequence of bytes that will be loaded into runtime memory. Segments do not necessarily have a known runtime address. Instead, they use some RegionIndex as a "base" address and are located at some fixed offset from that base. Multiple segments can have the same RegionIndex as their base; this indicates that they will have a fixed offset relative to one another at runtime. A MemSegment with a RegionIndex of 0 has a statically known address, which is exactly its segmentOffset. This notion of segment is similar to an ELF segment. It is unrelated to the x86 notion of memory segmentation.

Addresses and related types

As described above, an address (MemAddr) consists of a base (RegionIndex) and an offset. This section describes a few types that are adjacent to this one, along with their intended use-cases.

A MemWord w is a w-bit machine word. This may be treated as an absolute address when w is the width of a pointer (absoluteAddr).

A MemSegmentOff is notionally a pair (MemSegment, offset), where offset is an offset into the MemSegment. The MemSegmentOffs produced by this module are guaranteed to be valid, making it possible to look up the contents of the memory they point to.

Each of the above types is parameterized by the number of bits in an address. Most have an alias prefixed with Arch that is instead parameterized by architecture, with the width parameter filled in according to the declared width of the architecture (e.g., ArchMemAddr).

Synopsis

Documentation

data Memory (w :: Natural) Source #

A datatype for describing the memory layout of binaries.

See the module-level documentation for an overview.

Region indices (RegionIndex) may not correspond precisely with segments or section indices (SectionIndex, SegmentIndex) within the binary, and so we also maintain mappings so that one can map both sections and segments in the binary to the address it is loaded at (memSectionIndexMap, memSegmentIndexMap).

Instances

Instances details
MemWidth w => Show (Memory w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

showsPrec :: Int -> Memory w -> ShowS #

show :: Memory w -> String #

showList :: [Memory w] -> ShowS #

Inspecting memory

memAddrWidth :: Memory w -> AddrWidthRepr w Source #

Address width of the memory

memWidth :: forall (w :: Natural). Memory w -> NatRepr w Source #

Return the number of bytes in an address.

memSegments :: forall (w :: Natural). Memory w -> [MemSegment w] Source #

Return the set of memory segments in memory.

memAsAddrPairs :: forall (w :: Natural). Memory w -> Endianness -> [(MemSegmentOff w, MemSegmentOff w)] Source #

This walks through all the memory regions and looks at each address size block of memory that is aligned at a multiple of the address size.

It returns a list of all offset and value pairs that can be interpreted as a valid offset within a memory segment.

Constructing memory

emptyMemory :: forall (w :: Natural). AddrWidthRepr w -> Memory w Source #

A memory with no segments.

insertMemSegment :: forall (w :: Nat). MemSegment w -> Memory w -> Either (InsertError w) (Memory w) Source #

Insert segment into memory or fail if this overlaps with another segment in memory.

data InsertError (w :: Nat) Source #

Describes why we could not insert segment into memory.

Constructors

OverlapSegment (MemSegment w) (MemSegment w)

The inserted segment overlaps with the given segment.

showInsertError :: forall (w :: Nat). InsertError w -> String Source #

Print description of insertion error.

Load values

memBaseAddr :: Memory w -> Maybe (MemAddr w) Source #

This denotes the base region for loads.

memSetBaseAddr :: forall (w :: Nat). MemAddr w -> Memory w -> Memory w Source #

Set the region index used or the load addresses.

memBindSectionIndex :: forall (w :: Nat). SectionIndex -> MemSegmentOff w -> Memory w -> Memory w Source #

Add a new section index to address entry.

memSectionIndexMap :: Memory w -> Map SectionIndex (MemSegmentOff w) Source #

Map from registered section indices to the segment offset it is loaded at.

memSegmentIndexMap :: Memory w -> Map SegmentIndex (MemSegment w) Source #

Map from registered segment indices to associated segment.

memBindSegmentIndex :: forall (w :: Nat). SegmentIndex -> MemSegment w -> Memory w -> Memory w Source #

Record binding from the segment index to the segment.

Memory segments

data MemSegment (w :: Nat) Source #

Information about a contiguous sequence of bytes in memory.

See the module-level documentation for an overview.

Our memory model supports relocatable code, and so segments may have either fixed (absolute) or floating addresses. Floating addresses are represented as an offset from an abstract base address (segmentBase). When segmentBase is 0, segmentOffset is the absolute address of the segment. Binaries may have floating segments that are fixed relative to each other, and this can be modeled by creating different segments with the same non-zero segmentBase identifier.

Instances

Instances details
MemWidth w => Show (MemSegment w) Source # 
Instance details

Defined in Data.Macaw.Memory

Eq (MemSegment w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

(==) :: MemSegment w -> MemSegment w -> Bool #

(/=) :: MemSegment w -> MemSegment w -> Bool #

Ord (MemSegment w) Source # 
Instance details

Defined in Data.Macaw.Memory

memSegment Source #

Arguments

:: forall m (w :: Natural). (Monad m, MemWidth w) 
=> Map (MemWord w) (RelocEntry m w)

Map from region offset to relocation entry for segment.

-> RegionIndex

Index of base (0=absolute address)

-> Integer

Offset to add to linktime address for this segment.

-> Maybe SegmentIndex

Identifier for this segment in relocation if this is created from so/exe.

-> MemWord w

Linktime address of segment.

-> Flags

Permissions for segment.

-> ByteString

File contents for segment.

-> MemWord w

Expected size (must be positive)

-> m (MemSegment w) 

This creates a memory segment from a buffer after applying relocations and options for

segmentBase :: MemSegment w -> RegionIndex Source #

Base for this segment

N.B. 0 indicates a fixed base address of zero.

type RegionIndex = Int Source #

An identifier used to support relocatable (i.e., position-independent) code.

See the module-level documentation for an overview.

Non-zero region indices represent addresses that would be chosen at runtime by the loader (e.g., the virtual address of an ELF segment containing position-independent code).

The region index 0 indicates an absolute address:

segmentOffset :: MemSegment w -> MemWord w Source #

Offset of segment relative to segmentBase

segmentFlags :: MemSegment w -> Flags Source #

Permission flags

segmentSize :: forall (w :: Natural). MemWidth w => MemSegment w -> MemWord w Source #

Return the size of the segment data.

ppMemSegment :: forall (w :: Natural) ann. MemWidth w => MemSegment w -> Doc ann Source #

Pretty print a memory segment.

MemChunk

data MemChunk (w :: Nat) Source #

A memory chunk describes a contiguous sequence of bytes within a segment.

The parameter denotes the width of a memory address.

Note that the term "region" in this type is not related to the notion of "region" described in the module-level documentation (i.e., the Region in RegionIndex).

Constructors

ByteRegion !ByteString

A region with specific bytes

RelocationRegion !(Relocation w)

A region whose contents are computed using the expression denoted by the relocation.

BSSRegion !(MemWord w)

A region containing the given number of zero-initialized bytes.

Instances

Instances details
Show (MemChunk w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

showsPrec :: Int -> MemChunk w -> ShowS #

show :: MemChunk w -> String #

showList :: [MemChunk w] -> ShowS #

data Relocation (w :: Nat) Source #

Information about a relocation. This essentially is a region of memory in a binary whose contents are unknown when the binary is generated.

For object files, relocations are created for symbol names, as the address they are stored at is assigned by the linker. The relocation generated by the compiler provides the linker with the information it needs to perform relocations.

For dynamic executables and shared libraries, relocation values are generated to allow the loader to load the file at a specific address. These may be assigned during loading, or in the case of functions, when first being invoked.

This structure contains the information needed to compute the value stored in memory, and whether there are constraints on that value.

The value to be stored in a relocation r, is the integer computed by base + off - rel where

  • base is the address of the symbol identified by relocationSym r;
  • off is the offset relocationOffset r; and
  • rel is the address the relocation is stored at if relocationIsRel r is true, and 0 otherwise.

The integer value stored is encoded in a bitvector with relocationSize r bytes. This is interpreted as a signed number using two's complement encoding when relocationIsSigned r is true, and an unsigned number otherwise. The byte order is determined by relocationEndiness r.

Because the integer value are stored in fixed width bitvectors that cannot represent all legal integer values, the code doing the relocation is not allowed to place symbols at arbitrary addresses. The integer value computed must fit within the given number of bytes, and so relocations effectively are implicit constraints on where code may be stored in memory.

Constructors

Relocation 

Fields

  • relocationSym :: !SymbolIdentifier

    The symbol whose address is used as the base of the value to store.

  • relocationOffset :: !(MemWord w)

    A constant value to add to the base to compute the relocation

  • relocationIsRel :: !Bool

    If this is true, then the value stored in the relocation will be the difference between the relocation symbol and offset and the address of the relocation.

    If false, then the value stored is just the address of the symbol plus the offset.

  • relocationSize :: !Int

    Number of bytes in memory that this relocation is stored at.

  • relocationIsSigned :: !Bool

    This indicates if the value stored will be interpreted as an signed or unsigned number.

  • relocationEndianness :: !Endianness

    The byte order used to encode the relocation in memory.

  • relocationJumpSlot :: !Bool

    Returns true if this is a jump slot relocation.

    This relocation is specifically used for global offset table entries, and are typically resolved when the function is first called rather than at load time. The address will be initially the entry sequence stub, and will be updated once resolved by the stub.

Instances

Instances details
Show (Relocation w) Source # 
Instance details

Defined in Data.Macaw.Memory

data SymbolVersion #

Instances

Instances details
Generic SymbolVersion 
Instance details

Defined in Data.BinarySymbols

Associated Types

type Rep SymbolVersion 
Instance details

Defined in Data.BinarySymbols

type Rep SymbolVersion = D1 ('MetaData "SymbolVersion" "Data.BinarySymbols" "binary-symbols-0.1.4-inplace" 'False) ((C1 ('MetaCons "UnversionedSymbol" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "ObjectDefaultSymbol" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString))) :+: (C1 ('MetaCons "ObjectNonDefaultSymbol" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString)) :+: C1 ('MetaCons "VersionedSymbol" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString))))
Show SymbolVersion 
Instance details

Defined in Data.BinarySymbols

Eq SymbolVersion 
Instance details

Defined in Data.BinarySymbols

Ord SymbolVersion 
Instance details

Defined in Data.BinarySymbols

Hashable SymbolVersion 
Instance details

Defined in Data.BinarySymbols

type Rep SymbolVersion 
Instance details

Defined in Data.BinarySymbols

type Rep SymbolVersion = D1 ('MetaData "SymbolVersion" "Data.BinarySymbols" "binary-symbols-0.1.4-inplace" 'False) ((C1 ('MetaCons "UnversionedSymbol" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "ObjectDefaultSymbol" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString))) :+: (C1 ('MetaCons "ObjectNonDefaultSymbol" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString)) :+: C1 ('MetaCons "VersionedSymbol" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString))))

data VersionedSymbol #

Instances

Instances details
Show VersionedSymbol 
Instance details

Defined in Data.BinarySymbols

data SymbolIdentifier #

Instances

Instances details
Generic SymbolIdentifier 
Instance details

Defined in Data.BinarySymbols

Associated Types

type Rep SymbolIdentifier 
Instance details

Defined in Data.BinarySymbols

Show SymbolIdentifier 
Instance details

Defined in Data.BinarySymbols

Eq SymbolIdentifier 
Instance details

Defined in Data.BinarySymbols

Ord SymbolIdentifier 
Instance details

Defined in Data.BinarySymbols

Hashable SymbolIdentifier 
Instance details

Defined in Data.BinarySymbols

type Rep SymbolIdentifier 
Instance details

Defined in Data.BinarySymbols

MemChunk operations

forcedTakeMemChunks :: forall (w :: Natural). MemWidth w => [MemChunk w] -> MemWord w -> [MemChunk w] Source #

forcedTakeMemChunks ranges cnt attempts to read cnt bytes from ranges.

It is a total function, and will return ranges if it contains less than cnt bytes. It may also return more than cnt bytes as if a relocation region spans across the break, it will return the region.

splitMemChunks :: forall (w :: Natural). MemWidth w => [MemChunk w] -> Int -> Either (SplitError w) ([MemChunk w], [MemChunk w]) Source #

Given a contiguous sequence of memory chunks and a number of bytes c, this partitions the data in two data regions. The first contains the first c bytes in the data; the second contains the rest of the data.

This will return an error if the size of the data is too small or the partition would split a relocation entry.

data SplitError (w :: Nat) Source #

Describes why we could not split the memory chunks.

Constructors

SplitUnexpectedRelocation !(Relocation w)

A relocation was right in the middle of where we tried to split chunks.

SplitInvalidAddr

The byte count to split at was longer than the number of chunks.

MemWidth

class 1 <= w => MemWidth (w :: Natural) where Source #

Typeclass for widths supported by memory addresses.

This only will work for 32 and 64bit values due to requirement to implement addrWidthRepr.

Methods

addrWidthRepr :: p w -> AddrWidthRepr w Source #

Returns AddrWidthRepr to identify width of pointer.

The argument is ignored.

addrSize :: p w -> Int Source #

Returns number of bytes in addr.

The argument is not evaluated.

addrWidthMask :: p w -> Word64 Source #

addrWidthMask w returns 2^(8 * addrSize w) - 1.

addrRotate :: MemWord w -> Int -> MemWord w Source #

Rotates the value by the given index.

Instances

Instances details
MemWidth 32 Source # 
Instance details

Defined in Data.Macaw.Memory

MemWidth 64 Source # 
Instance details

Defined in Data.Macaw.Memory

memWidthNatRepr :: forall (w :: Natural). MemWidth w => NatRepr w Source #

MemWord

data MemWord (w :: Nat) Source #

This represents a bitvector value with w bits.

Operations on it require the MemWidth constraint to be satisfied, so in practice this only works for 32 and 64-bit values.

Instances

Instances details
MemWidth w => Bits (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

MemWidth w => Bounded (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

MemWidth w => Enum (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

succ :: MemWord w -> MemWord w #

pred :: MemWord w -> MemWord w #

toEnum :: Int -> MemWord w #

fromEnum :: MemWord w -> Int #

enumFrom :: MemWord w -> [MemWord w] #

enumFromThen :: MemWord w -> MemWord w -> [MemWord w] #

enumFromTo :: MemWord w -> MemWord w -> [MemWord w] #

enumFromThenTo :: MemWord w -> MemWord w -> MemWord w -> [MemWord w] #

MemWidth w => Num (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

(+) :: MemWord w -> MemWord w -> MemWord w #

(-) :: MemWord w -> MemWord w -> MemWord w #

(*) :: MemWord w -> MemWord w -> MemWord w #

negate :: MemWord w -> MemWord w #

abs :: MemWord w -> MemWord w #

signum :: MemWord w -> MemWord w #

fromInteger :: Integer -> MemWord w #

MemWidth w => Integral (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

quot :: MemWord w -> MemWord w -> MemWord w #

rem :: MemWord w -> MemWord w -> MemWord w #

div :: MemWord w -> MemWord w -> MemWord w #

mod :: MemWord w -> MemWord w -> MemWord w #

quotRem :: MemWord w -> MemWord w -> (MemWord w, MemWord w) #

divMod :: MemWord w -> MemWord w -> (MemWord w, MemWord w) #

toInteger :: MemWord w -> Integer #

MemWidth w => Real (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

toRational :: MemWord w -> Rational #

Show (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

showsPrec :: Int -> MemWord w -> ShowS #

show :: MemWord w -> String #

showList :: [MemWord w] -> ShowS #

Eq (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

(==) :: MemWord w -> MemWord w -> Bool #

(/=) :: MemWord w -> MemWord w -> Bool #

Ord (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

compare :: MemWord w -> MemWord w -> Ordering #

(<) :: MemWord w -> MemWord w -> Bool #

(<=) :: MemWord w -> MemWord w -> Bool #

(>) :: MemWord w -> MemWord w -> Bool #

(>=) :: MemWord w -> MemWord w -> Bool #

max :: MemWord w -> MemWord w -> MemWord w #

min :: MemWord w -> MemWord w -> MemWord w #

Hashable (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

hashWithSalt :: Int -> MemWord w -> Int

hash :: MemWord w -> Int

Pretty (MemWord w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

pretty :: MemWord w -> Doc ann

prettyList :: [MemWord w] -> Doc ann

zeroMemWord :: forall (w :: Nat). MemWord w Source #

Equal to 0

memWord :: forall (w :: Natural). MemWidth w => Word64 -> MemWord w Source #

Convert word64 x into mem word x mod 2^w-1.

memWordToUnsigned :: forall (w :: Nat). MemWord w -> Integer Source #

Return the value represented by the MemWord as an unsigned integer.

memWordToSigned :: forall (w :: Natural). MemWidth w => MemWord w -> Integer Source #

Treat the word as a signed integer.

addrRead :: forall (w :: Natural). MemWidth w => Endianness -> ByteString -> Maybe (MemWord w) Source #

Read an address with the given endianess.

This returns nothing if the bytestring is too short.

MemInt

data MemInt (w :: Nat) Source #

A signed integer with the given width.

Instances

Instances details
MemWidth w => Bits (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

(.&.) :: MemInt w -> MemInt w -> MemInt w #

(.|.) :: MemInt w -> MemInt w -> MemInt w #

xor :: MemInt w -> MemInt w -> MemInt w #

complement :: MemInt w -> MemInt w #

shift :: MemInt w -> Int -> MemInt w #

rotate :: MemInt w -> Int -> MemInt w #

zeroBits :: MemInt w #

bit :: Int -> MemInt w #

setBit :: MemInt w -> Int -> MemInt w #

clearBit :: MemInt w -> Int -> MemInt w #

complementBit :: MemInt w -> Int -> MemInt w #

testBit :: MemInt w -> Int -> Bool #

bitSizeMaybe :: MemInt w -> Maybe Int #

bitSize :: MemInt w -> Int #

isSigned :: MemInt w -> Bool #

shiftL :: MemInt w -> Int -> MemInt w #

unsafeShiftL :: MemInt w -> Int -> MemInt w #

shiftR :: MemInt w -> Int -> MemInt w #

unsafeShiftR :: MemInt w -> Int -> MemInt w #

rotateL :: MemInt w -> Int -> MemInt w #

rotateR :: MemInt w -> Int -> MemInt w #

popCount :: MemInt w -> Int #

MemWidth w => Bounded (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

minBound :: MemInt w #

maxBound :: MemInt w #

MemWidth w => Enum (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

succ :: MemInt w -> MemInt w #

pred :: MemInt w -> MemInt w #

toEnum :: Int -> MemInt w #

fromEnum :: MemInt w -> Int #

enumFrom :: MemInt w -> [MemInt w] #

enumFromThen :: MemInt w -> MemInt w -> [MemInt w] #

enumFromTo :: MemInt w -> MemInt w -> [MemInt w] #

enumFromThenTo :: MemInt w -> MemInt w -> MemInt w -> [MemInt w] #

MemWidth w => Num (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

(+) :: MemInt w -> MemInt w -> MemInt w #

(-) :: MemInt w -> MemInt w -> MemInt w #

(*) :: MemInt w -> MemInt w -> MemInt w #

negate :: MemInt w -> MemInt w #

abs :: MemInt w -> MemInt w #

signum :: MemInt w -> MemInt w #

fromInteger :: Integer -> MemInt w #

MemWidth w => Integral (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

quot :: MemInt w -> MemInt w -> MemInt w #

rem :: MemInt w -> MemInt w -> MemInt w #

div :: MemInt w -> MemInt w -> MemInt w #

mod :: MemInt w -> MemInt w -> MemInt w #

quotRem :: MemInt w -> MemInt w -> (MemInt w, MemInt w) #

divMod :: MemInt w -> MemInt w -> (MemInt w, MemInt w) #

toInteger :: MemInt w -> Integer #

MemWidth w => Real (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

toRational :: MemInt w -> Rational #

Show (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

showsPrec :: Int -> MemInt w -> ShowS #

show :: MemInt w -> String #

showList :: [MemInt w] -> ShowS #

Eq (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

(==) :: MemInt w -> MemInt w -> Bool #

(/=) :: MemInt w -> MemInt w -> Bool #

Ord (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

compare :: MemInt w -> MemInt w -> Ordering #

(<) :: MemInt w -> MemInt w -> Bool #

(<=) :: MemInt w -> MemInt w -> Bool #

(>) :: MemInt w -> MemInt w -> Bool #

(>=) :: MemInt w -> MemInt w -> Bool #

max :: MemInt w -> MemInt w -> MemInt w #

min :: MemInt w -> MemInt w -> MemInt w #

Hashable (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

hashWithSalt :: Int -> MemInt w -> Int

hash :: MemInt w -> Int

Pretty (MemInt w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

pretty :: MemInt w -> Doc ann

prettyList :: [MemInt w] -> Doc ann

memInt :: forall (w :: Natural). MemWidth w => Int64 -> MemInt w Source #

Convert Int64 x into mem word x mod 2^w-1.

Addresses

data MemAddr (w :: Nat) Source #

An address in memory, represented by a base (RegionIndex) and an offset.

See the module-level documentation for an overview.

This representation does not require that the address is mapped to actual memory (see MemSegmentOff for an address representation that ensures the reference points to allocated memory).

Constructors

MemAddr 

Fields

Instances

Instances details
Show (MemAddr w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

showsPrec :: Int -> MemAddr w -> ShowS #

show :: MemAddr w -> String #

showList :: [MemAddr w] -> ShowS #

Eq (MemAddr w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

(==) :: MemAddr w -> MemAddr w -> Bool #

(/=) :: MemAddr w -> MemAddr w -> Bool #

Ord (MemAddr w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

compare :: MemAddr w -> MemAddr w -> Ordering #

(<) :: MemAddr w -> MemAddr w -> Bool #

(<=) :: MemAddr w -> MemAddr w -> Bool #

(>) :: MemAddr w -> MemAddr w -> Bool #

(>=) :: MemAddr w -> MemAddr w -> Bool #

max :: MemAddr w -> MemAddr w -> MemAddr w #

min :: MemAddr w -> MemAddr w -> MemAddr w #

Hashable (MemAddr w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

hashWithSalt :: Int -> MemAddr w -> Int

hash :: MemAddr w -> Int

Pretty (MemAddr w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

pretty :: MemAddr w -> Doc ann

prettyList :: [MemAddr w] -> Doc ann

absoluteAddr :: forall (w :: Nat). MemWord w -> MemAddr w Source #

Treat a machine word as an absolute address (with a addrBase of 0).

segmentOffAddr :: forall (w :: Natural). MemWidth w => MemSegment w -> MemWord w -> MemAddr w Source #

Construct an address from an offset from a memory segment.

asAbsoluteAddr :: forall (w :: Natural). MemWidth w => MemAddr w -> Maybe (MemWord w) Source #

Return an absolute address if the region of the MemAddr is 0.

diffAddr :: forall (w :: Natural). MemWidth w => MemAddr w -> MemAddr w -> Maybe Integer Source #

Returns the number of bytes between two addresses if they point to the same region and Nothing if they are different segments.

incAddr :: forall (w :: Natural). MemWidth w => Integer -> MemAddr w -> MemAddr w Source #

Increment an address by a fixed amount.

addrLeastBit :: forall (w :: Nat). MemAddr w -> Bool Source #

Return True if least-significant bit in addr is set.

clearAddrLeastBit :: forall (w :: Nat). MemAddr w -> MemAddr w Source #

Clear the least significant bit of an address.

asSegmentOff :: forall (w :: Natural). Memory w -> MemAddr w -> Maybe (MemSegmentOff w) Source #

Return a segment offset from the address if defined.

Segment offsets

data MemSegmentOff (w :: Nat) Source #

A pair containing a segment and offset.

Functions that return a segment-offset pair enforce that the offset is strictly less than the size of the memory segment in bytes.

Instances

Instances details
MemWidth w => Show (MemSegmentOff w) Source # 
Instance details

Defined in Data.Macaw.Memory

Eq (MemSegmentOff w) Source # 
Instance details

Defined in Data.Macaw.Memory

Ord (MemSegmentOff w) Source # 
Instance details

Defined in Data.Macaw.Memory

MemWidth w => Pretty (MemSegmentOff w) Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

pretty :: MemSegmentOff w -> Doc ann

prettyList :: [MemSegmentOff w] -> Doc ann

Queries

segoffSegment :: MemSegmentOff w -> MemSegment w Source #

The segment this is an offset of

segoffOffset :: MemSegmentOff w -> MemWord w Source #

The offset within the segment.

segoffAddr :: forall (w :: Nat). MemSegmentOff w -> MemAddr w Source #

Return the address of a segment offset.

segoffAsAbsoluteAddr :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> Maybe (MemWord w) Source #

Return the absolute address associated with the segment offset pair (if any)

segoffBytesLeft :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> Integer Source #

Return the number of bytes in the segment after this address.

segoffContentsAfter :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> Either (MemoryError w) [MemChunk w] Source #

Return the memory contents from a given offset, that is, the MemChunk at the given offset, then the following MemChunks until the end of the segment. Returns a MemoryError if the requested offset falls within a relocation, which we cannot partition.

Construction segment offsets.

resolveRegionOff :: forall (w :: Natural). Memory w -> RegionIndex -> MemWord w -> Maybe (MemSegmentOff w) Source #

Return the segment offset associated with the given region offset if any.

resolveAbsoluteAddr :: forall (w :: Natural). Memory w -> MemWord w -> Maybe (MemSegmentOff w) Source #

Return the segment associated with the given address if well-defined.

resolveSegmentOff :: forall (w :: Natural). MemWidth w => MemSegment w -> MemWord w -> Maybe (MemSegmentOff w) Source #

Make a segment offset pair after ensuring the offset is valid

Modifying

incSegmentOff :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> Integer -> Maybe (MemSegmentOff w) Source #

Increment a segment offset by a given amount.

Returns Nothing if the result would be out of range.

diffSegmentOff :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> MemSegmentOff w -> Maybe Integer Source #

Return the difference between two segment offsets pairs or Nothing if undefined.

clearSegmentOffLeastBit :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> MemSegmentOff w Source #

Clear the least-significant bit of an segment offset.

Reading

data MemoryError (w :: Nat) Source #

Type of errors that may occur when reading memory.

Constructors

AccessViolation !(MemAddr w)

Memory could not be read, because it was not defined.

PermissionsError !(MemAddr w)

Memory could not be read due to insufficient permissions.

UnexpectedRelocation !(MemAddr w) !(Relocation w)

Read from location that partially overlaps a relocated entry

UnexpectedByteRelocation !(MemAddr w) !(Relocation w)

An relocation appeared when reading a byte.

Unsupported32ImmRelocation !(MemAddr w) !(Relocation w)

An unsupported relocation appeared when reading a 32-bit immediate.

UnsupportedJumpOffsetRelocation !(MemAddr w) !(Relocation w)

An unsupported relocation appeared when reading a jump offset.

UnexpectedBSS !(MemAddr w)

We unexpectedly encountered a BSS segment/section.

InvalidAddr !(MemAddr w)

The data at the given address did not refer to a valid memory location.

InvalidRead !(MemSegmentOff w) !Word64

Can't read the given number of bytes from the offset as that is outside allocated memory.

Instances

Instances details
MemWidth w => Show (MemoryError w) Source # 
Instance details

Defined in Data.Macaw.Memory

addrContentsAfter :: forall (w :: Natural). Memory w -> MemAddr w -> Either (MemoryError w) [MemChunk w] Source #

Return contents starting from location or throw a memory error if there is an unaligned relocation.

readByteString Source #

Arguments

:: forall (w :: Natural). Memory w 
-> MemAddr w 
-> Word64

Number of bytes to read

-> Either (MemoryError w) ByteString 

Attempt to read a bytestring of the given length

readAddr :: forall (w :: Natural). Memory w -> Endianness -> MemAddr w -> Either (MemoryError w) (MemAddr w) Source #

Read an address from the value in the segment or report a memory error.

readSegmentOff :: forall (w :: Natural). Memory w -> Endianness -> MemAddr w -> Either (MemoryError w) (MemSegmentOff w) Source #

Read the given address as a reference to a memory segment offset, or report a memory read error.

readWord8 :: forall (w :: Natural). Memory w -> MemAddr w -> Either (MemoryError w) Word8 Source #

Read a single byte.

readWord16be :: forall (w :: Natural). Memory w -> MemAddr w -> Either (MemoryError w) Word16 Source #

Read a big endian word16

readWord16le :: forall (w :: Natural). Memory w -> MemAddr w -> Either (MemoryError w) Word16 Source #

Read a little endian word16

readWord32be :: forall (w :: Natural). Memory w -> MemAddr w -> Either (MemoryError w) Word32 Source #

Read a big endian word32

readWord32le :: forall (w :: Natural). Memory w -> MemAddr w -> Either (MemoryError w) Word32 Source #

Read a little endian word32

readWord64be :: forall (w :: Natural). Memory w -> MemAddr w -> Either (MemoryError w) Word64 Source #

Read a big endian word64

readWord64le :: forall (w :: Natural). Memory w -> MemAddr w -> Either (MemoryError w) Word64 Source #

Read a little endian word64

readNullTermString :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> NullTermString w Source #

Attempt to read a null terminated bytesting.

AddrWidthRepr

data AddrWidthRepr (w :: Natural) Source #

An address width

Constructors

w ~ 32 => Addr32

A 32-bit address

w ~ 64 => Addr64

A 64-bit address

Instances

Instances details
TestEquality AddrWidthRepr Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

testEquality :: forall (a :: Natural) (b :: Natural). AddrWidthRepr a -> AddrWidthRepr b -> Maybe (a :~: b) #

OrdF AddrWidthRepr Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

compareF :: forall (x :: Natural) (y :: Natural). AddrWidthRepr x -> AddrWidthRepr y -> OrderingF x y

leqF :: forall (x :: Natural) (y :: Natural). AddrWidthRepr x -> AddrWidthRepr y -> Bool

ltF :: forall (x :: Natural) (y :: Natural). AddrWidthRepr x -> AddrWidthRepr y -> Bool

geqF :: forall (x :: Natural) (y :: Natural). AddrWidthRepr x -> AddrWidthRepr y -> Bool

gtF :: forall (x :: Natural) (y :: Natural). AddrWidthRepr x -> AddrWidthRepr y -> Bool

Show (AddrWidthRepr w) Source # 
Instance details

Defined in Data.Macaw.Memory

addrWidthReprByteCount :: forall (w :: Natural). AddrWidthRepr w -> Natural Source #

Number of bytes in addr width repr.

addrWidthNatRepr :: forall (w :: Natural). AddrWidthRepr w -> NatRepr w Source #

The nat representation of this address.

addrWidthClass :: forall (w :: Natural) a. AddrWidthRepr w -> (MemWidth w => a) -> a Source #

Number of bytes in an address

Endianness

data Endianness Source #

Indicates whether bytes are stored in big or little endian representation.

In a big endian representation, the most significant byte is stored first; In a little endian representation, the most significant byte is stored last.

Constructors

BigEndian 
LittleEndian 

Instances

Instances details
Show Endianness Source # 
Instance details

Defined in Data.Macaw.Memory

Eq Endianness Source # 
Instance details

Defined in Data.Macaw.Memory

Ord Endianness Source # 
Instance details

Defined in Data.Macaw.Memory

Hashable Endianness Source # 
Instance details

Defined in Data.Macaw.Memory

Lift Endianness Source # 
Instance details

Defined in Data.Macaw.Memory

Methods

lift :: Quote m => Endianness -> m Exp #

liftTyped :: forall (m :: Type -> Type). Quote m => Endianness -> Code m Endianness #

bytesToInteger :: Endianness -> ByteString -> Integer Source #

Convert a byte string to an integer using the provided endianness.

bsWord32 :: Endianness -> ByteString -> Word32 Source #

Convert a bytestring to an unsigned with the given endianness.

Memory search

findByteStringMatches Source #

Arguments

:: forall (w :: Natural). MemWidth w 
=> ByteString

Pattern to search for within memory segments

-> Integer

Offset within the contents region where search is to start

-> [(MemAddr w, MemChunk w)]

Contents of memory along with its relative address from the segment base address.

-> [MemAddr w] 

Naive string matching algorithm identifies matches to given pattern within the list of memory segments and their corresponding offset within memory. Relocations are treated as wildcards.

relativeSegmentContents :: forall (w :: Natural). MemWidth w => [MemSegment w] -> [(MemAddr w, MemChunk w)] Source #

Return list of segment content memory segment ranges with its content's address offset relative to segment offsets

Generating [MemChunk] values from relocations.

data RelocEntry (m :: Type -> Type) (w :: Nat) Source #

Information about a relocation sufficient to know how many bytes are affected, and how to replaces the existing bytes.

Constructors

RelocEntry 

Fields

type ResolveFn (m :: Type -> Type) (w :: Nat) = Maybe SegmentIndex -> ByteString -> m (Maybe (Relocation w)) Source #

Function for resolving the new contents of a relocation entry given an optional index for the current segment and the existing contents.

The segment index is used for dynamic relocations and set to Nothing for static relocations.

Deprecated declarations

type SegmentRange = MemChunk Source #

Deprecated: Use MemChunk

takeSegmentPrefix :: forall (w :: Natural). MemWidth w => [MemChunk w] -> MemWord w -> [MemChunk w] Source #

Deprecated: Use forcedTakeMemChunks

splitSegmentRangeList :: forall (w :: Natural). MemWidth w => [MemChunk w] -> Int -> Either (SplitError w) ([MemChunk w], [MemChunk w]) Source #

Deprecated: Use splitMemChunks

Given a segment data and a number of bytes c, this partitions the data in two data regions. The first contains the first c bytes in the data; the second contains the rest of the data.

This will return an exception if the size of the data is too small or the partition would split a relocation entry.

dropSegmentRangeListBytes :: forall (w :: Natural). MemWidth w => [MemChunk w] -> Int -> Either (SplitError w) [MemChunk w] Source #

Deprecated: Use splitMemChunks

Given a contiguous list of segment ranges and a number of bytes to drop, this returns the remaining segment ranges or throws an error.

dropErrorAsMemError :: forall (w :: Nat). MemAddr w -> SplitError w -> MemoryError w Source #

Deprecated: dropErrorAsMemError is not being used by the rest of Macaw, and a candidate for deletion.

Convert SplitError to equivalent MemoryError.

Note. External code does not use this, so unless we get feedback otherwise, it will be dropped in a future Macaw release.

executableSegments :: forall (w :: Natural). Memory w -> [MemSegment w] Source #

Deprecated: Use filter (Perm.isExecutable . segmentFlags) . memSegments.

Return segments with executable permissions.

readonlySegments :: forall (w :: Natural). Memory w -> [MemSegment w] Source #

Deprecated: Filter memSegments directly.

Return segments with read-only permissions.

memWordInteger :: forall (w :: Nat). MemWord w -> Integer Source #

Deprecated: Use memWordToUnsigned

Treat the word as an integer.

memWordSigned :: forall (w :: Natural). MemWidth w => MemWord w -> Integer Source #

Treat the word as a signed integer.

resolveAddr :: forall (w :: Natural). Memory w -> RegionIndex -> MemWord w -> Maybe (MemSegmentOff w) Source #

Deprecated: Use resolveRegionOff

Return the segment offset associated with the given region offset if any.

relativeSegmentAddr :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> MemAddr w Source #

Deprecated: Use segoffAddr

Convert the segment offset to an address.

msegAddr :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> Maybe (MemWord w) Source #

Deprecated: Use segoffAsAbsoluteAddr

Return the absolute address associated with the segment offset pair (if any)

contentsAfterSegmentOff :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> Either (MemoryError w) [MemChunk w] Source #

Deprecated: Use segoffContentsAfter

msegSegment :: forall (w :: Nat). MemSegmentOff w -> MemSegment w Source #

Deprecated: Use segoffSegment

Return segment this is offset of.

msegOffset :: forall (w :: Nat). MemSegmentOff w -> MemWord w Source #

Deprecated: Use segoffOffset

Return offset of segment

msegByteCountAfter :: forall (w :: Natural). MemWidth w => MemSegmentOff w -> Integer Source #

Deprecated: Use segoffBytesLeft

Return the number of bytes in the segment after this address.

relativeAddr :: forall (w :: Natural). MemWidth w => MemSegment w -> MemWord w -> MemAddr w Source #

Deprecated: Use segmentOffAddr

Construct an address relative to an existing memory segment.