Update for android compatibility

This commit is contained in:
Joe Hendrix 2019-07-29 11:41:50 -07:00
parent bb66fd64ec
commit a99d999fd0
No known key found for this signature in database
GPG Key ID: 8DFA5FF784098C4F
3 changed files with 98 additions and 55 deletions

View File

@ -34,7 +34,7 @@ library
binary-symbols >= 0.1.3, binary-symbols >= 0.1.3,
bytestring, bytestring,
containers >= 0.5.8.1, containers >= 0.5.8.1,
elf-edit >= 0.34.1, elf-edit >= 0.35,
galois-dwarf, galois-dwarf,
IntervalMap >= 0.5, IntervalMap >= 0.5,
lens >= 4.7, lens >= 4.7,

View File

@ -53,6 +53,7 @@ module Data.Macaw.Memory
, MemWidth(..) , MemWidth(..)
, MemWord , MemWord
, memWord , memWord
, memWordValue
, memWordToUnsigned , memWordToUnsigned
, memWordToSigned , memWordToSigned
, addrRead , addrRead

View File

@ -67,6 +67,7 @@ import Data.ElfEdit
, ElfSymbolTableEntry , ElfSymbolTableEntry
) )
import qualified Data.ElfEdit as Elf import qualified Data.ElfEdit as Elf
import Data.Foldable
import Data.IntervalMap.Strict (Interval(..), IntervalMap) import Data.IntervalMap.Strict (Interval(..), IntervalMap)
import qualified Data.IntervalMap.Strict as IMap import qualified Data.IntervalMap.Strict as IMap
import Data.Map.Strict (Map) import Data.Map.Strict (Map)
@ -173,13 +174,6 @@ data MemLoadWarning
| MultipleSectionsWithName !SectionName | MultipleSectionsWithName !SectionName
| MultipleDynamicSegments | MultipleDynamicSegments
| OverlappingLoadableSegments | OverlappingLoadableSegments
| RelocationParseFailure !String
| DynamicRelaAndRelPresent
-- ^ Issued if the dynamic section contains table for DT_REL and
-- DT_RELA.
| SectionRelaAndRelPresent !BS.ByteString
-- ^ @SectionRelaAndRelPresent nm@ is issued if we encounter
-- both section ".rela$nm" and ".rel$nm".
| UnsupportedSection !SectionName | UnsupportedSection !SectionName
| UnknownDefinedSymbolBinding !SymbolName Elf.ElfSymbolBinding | UnknownDefinedSymbolBinding !SymbolName Elf.ElfSymbolBinding
| UnknownDefinedSymbolType !SymbolName Elf.ElfSymbolType | UnknownDefinedSymbolType !SymbolName Elf.ElfSymbolType
@ -189,6 +183,12 @@ data MemLoadWarning
| ExpectedSectionSymbolLocal | ExpectedSectionSymbolLocal
| InvalidSectionSymbolIndex !Elf.ElfSectionIndex | InvalidSectionSymbolIndex !Elf.ElfSectionIndex
| UnsupportedProcessorSpecificSymbolIndex !SymbolName !ElfSectionIndex | UnsupportedProcessorSpecificSymbolIndex !SymbolName !ElfSectionIndex
| MultipleRelocationTables
-- ^ Issued if the file contains multiple relocation tables.
| RelocationParseFailure !String
| MultipleRelocationsAtAddr !Word64
-- ^ Multiple relocations at the given offset
| IgnoreRelocation !Integer !String !RelocationError | IgnoreRelocation !Integer !String !RelocationError
-- ^ @IgnoreRelocation idx tp err@ warns we ignored the location at index @idx@ due to @err@. -- ^ @IgnoreRelocation idx tp err@ warns we ignored the location at index @idx@ due to @err@.
-- --
@ -208,14 +208,6 @@ instance Show MemLoadWarning where
"Found multiple dynamic segments; choosing first one." "Found multiple dynamic segments; choosing first one."
show OverlappingLoadableSegments = show OverlappingLoadableSegments =
"File segments containing overlapping addresses; skipping relocations." "File segments containing overlapping addresses; skipping relocations."
show (RelocationParseFailure msg) =
"Error parsing relocations: " ++ msg
show DynamicRelaAndRelPresent =
"PT_DYNAMIC segment contains contain offsets for both DT_REL and DT_RELA relocation tables; "
++ " Using only DT_RELA relocations."
show (SectionRelaAndRelPresent (BSC.unpack -> nm)) =
"File contains both .rela" ++ nm ++ " and .rel" ++ nm
++ " sections; Using only .rela" ++ nm ++ " sections."
show (UnsupportedSection nm) = show (UnsupportedSection nm) =
"Do not support section " ++ BSC.unpack nm "Do not support section " ++ BSC.unpack nm
show (UnknownDefinedSymbolBinding nm bnd) = show (UnknownDefinedSymbolBinding nm bnd) =
@ -238,8 +230,15 @@ instance Show MemLoadWarning where
"Expected section symbol to have a valid index instead of " ++ show idx ++ "." "Expected section symbol to have a valid index instead of " ++ show idx ++ "."
show (UnsupportedProcessorSpecificSymbolIndex nm idx) = show (UnsupportedProcessorSpecificSymbolIndex nm idx) =
"Could not resolve symbol index " ++ show idx ++ " for symbol " ++ BSC.unpack nm ++ "." "Could not resolve symbol index " ++ show idx ++ " for symbol " ++ BSC.unpack nm ++ "."
show MultipleRelocationTables =
"File contains multiple relocation tables; these are being merged."
show (RelocationParseFailure msg) =
"Error parsing relocations: " ++ msg
show (IgnoreRelocation idx typeName err) = show (IgnoreRelocation idx typeName err) =
"Ignoring relocation " ++ show idx ++ " with type " ++ typeName ++ ": " ++ show err "Ignoring relocation " ++ show idx ++ " with type " ++ typeName ++ ": " ++ show err
show (MultipleRelocationsAtAddr addr) =
"Multiple relocations modify " ++ showHex addr "."
data MemLoaderState w = MLS { _mlsMemory :: !(Memory w) data MemLoaderState w = MLS { _mlsMemory :: !(Memory w)
, mlsEndianness :: !Endianness , mlsEndianness :: !Endianness
@ -723,7 +722,7 @@ relaTargetARM64 :: Endianness
-> Maybe SegmentIndex -> Maybe SegmentIndex
-- ^ Index of segment for dynamic relocations -- ^ Index of segment for dynamic relocations
-> SymbolTable -- ^ Symbol table -> SymbolTable -- ^ Symbol table
-> Elf.RelEntry Elf.ARM64_RelocationType -- ^ Relocaiton entry -> Elf.RelEntry Elf.AArch64_RelocationType -- ^ Relocaiton entry
-> MemWord 64 -> MemWord 64
-- ^ Addend of symbol -- ^ Addend of symbol
-> RelFlag -> RelFlag
@ -867,29 +866,65 @@ relocFromRel end symtab resolver idx r =
} }
) )
relocMapFromRelAndRela :: (Elf.IsRelocationType tp, w ~ Elf.RelocationWidth tp)
=> Elf.ElfData -- | Maps address that relocations apply to to the relocation information.
-- ^ Endianness type RelocMap w = Map (MemWord w) (RelocEntry (MemLoader w) w)
-> RelocationResolver tp
-> SymbolTable -- | Add a relocation entry to the map.
-- ^ Map from symbol indices to associated symbol addRelocEntry :: RelocMap w
-> Maybe L.ByteString -> (MemWord w, RelocEntry (MemLoader w) w)
-- ^ Buffer containing relocation entries in Rel format -> MemLoader w (RelocMap w)
-> Maybe L.ByteString addRelocEntry m (addr, e) =
-- ^ Buffer containing relocation entries in Rela format case Map.insertLookupWithKey (\_k _new old -> old) addr e m of
-> MemLoader w (Map (MemWord w) (RelocEntry (MemLoader w) w)) (Nothing, m') -> pure m'
relocMapFromRelAndRela _dta _resolver _symtab Nothing Nothing = do (Just _, _) -> do
pure Map.empty addWarning $ MultipleRelocationsAtAddr (memWordValue addr)
relocMapFromRelAndRela dta resolver symtab _ (Just relaBuffer) = do pure m
addRelocEntries :: RelocMap w
-> [(MemWord w, RelocEntry (MemLoader w) w)]
-> MemLoader w (RelocMap w)
addRelocEntries = foldlM addRelocEntry
-- | Add rela relocation entries to map.
addRelaEntries :: (Elf.IsRelocationType tp, w ~ Elf.RelocationWidth tp)
=> RelocMap w
-> Elf.ElfData
-- ^ Endianness
-> RelocationResolver tp
-> SymbolTable
-- ^ Map from symbol indices to associated symbol
-> Maybe L.ByteString
-- ^ Buffer containing relocation entries in Rela format
-> MemLoader w (RelocMap w)
addRelaEntries m _ _ _ Nothing =
pure m
addRelaEntries m dta resolver symtab (Just relaBuffer) = do
w <- uses mlsMemory memAddrWidth w <- uses mlsMemory memAddrWidth
reprConstraints w $ do reprConstraints w $ do
case Elf.elfRelaEntries dta relaBuffer of case Elf.elfRelaEntries dta relaBuffer of
Left msg -> do Left msg -> do
addWarning (RelocationParseFailure msg) addWarning (RelocationParseFailure msg)
pure Map.empty pure m
Right entries -> do Right entries -> do
pure $ Map.fromList $ zipWith (relocFromRela symtab resolver) [0..] entries addRelocEntries m $
relocMapFromRelAndRela dta resolver symtab (Just relBuffer) Nothing = do zipWith (relocFromRela symtab resolver) [0..] entries
-- | Add rel relocation entries to map.
addRelEntries :: (Elf.IsRelocationType tp, w ~ Elf.RelocationWidth tp)
=> RelocMap w
-> Elf.ElfData
-- ^ Endianness
-> RelocationResolver tp
-> SymbolTable
-- ^ Map from symbol indices to associated symbol
-> Maybe L.ByteString
-- ^ Buffer containing relocation entries in Rel format
-> MemLoader w (RelocMap w)
addRelEntries m _ _ _ Nothing =
pure m
addRelEntries m dta resolver symtab (Just relBuffer) = do
w <- uses mlsMemory memAddrWidth w <- uses mlsMemory memAddrWidth
reprConstraints w $ do reprConstraints w $ do
case Elf.elfRelEntries dta relBuffer of case Elf.elfRelEntries dta relBuffer of
@ -897,7 +932,8 @@ relocMapFromRelAndRela dta resolver symtab (Just relBuffer) Nothing = do
addWarning (RelocationParseFailure msg) addWarning (RelocationParseFailure msg)
pure Map.empty pure Map.empty
Right entries -> do Right entries -> do
pure $ Map.fromList $ zipWith (relocFromRel (toEndianness dta) symtab resolver) [0..] entries addRelocEntries m $
zipWith (relocFromRel (toEndianness dta) symtab resolver) [0..] entries
-- | This checks a computation that returns a dynamic error or succeeds. -- | This checks a computation that returns a dynamic error or succeeds.
runDynamic :: Either Elf.DynamicError a -> MemLoader w a runDynamic :: Either Elf.DynamicError a -> MemLoader w a
@ -927,27 +963,31 @@ dynamicRelocationMap hdr ph contents =
-- Find th dynamic section from the contents. -- Find th dynamic section from the contents.
dynSection <- runDynamic $ dynSection <- runDynamic $
Elf.dynamicEntries (Elf.headerData hdr) (Elf.headerClass hdr) virtMap dynContents Elf.dynamicEntries (Elf.headerData hdr) (Elf.headerClass hdr) virtMap dynContents
let dta = Elf.headerData hdr
SomeRelocationResolver resolver <- getRelocationResolver hdr
let symtab = dynamicSymbolTable dynSection let symtab = dynamicSymbolTable dynSection
-- Parse relocations
mRelBuffer <- runDynamic $ Elf.dynRelBuffer dynSection mRelBuffer <- runDynamic $ Elf.dynRelBuffer dynSection
mRelaBuffer <- runDynamic $ Elf.dynRelaBuffer dynSection mRelaBuffer <- runDynamic $ Elf.dynRelaBuffer dynSection
SomeRelocationResolver resolver <- getRelocationResolver hdr relocs0 <- addRelaEntries Map.empty dta resolver symtab mRelaBuffer
relocs1 <- addRelEntries relocs0 dta resolver symtab mRelBuffer
when (isJust mRelBuffer && isJust mRelaBuffer) $ do when (isJust mRelBuffer && isJust mRelaBuffer) $ do
addWarning $ DynamicRelaAndRelPresent addWarning $ MultipleRelocationTables
let dta = Elf.headerData hdr
loadtimeRelocs <- case Elf.dynPLTRel dynSection of
relocMapFromRelAndRela dta resolver symtab mRelBuffer mRelaBuffer Left e -> do
pltRelocs <- addWarning $ RelocationParseFailure (show e)
case Elf.dynPLTRel dynSection of pure $! relocs1
Left e -> do Right Elf.PLTEmpty -> do
addWarning $ RelocationParseFailure (show e) pure $! relocs1
pure $! Map.empty Right (Elf.PLTRel entries) -> do
Right Elf.PLTEmpty -> do addRelocEntries relocs1 $
pure $! Map.empty zipWith (relocFromRel (toEndianness dta) symtab resolver) [0..] entries
Right (Elf.PLTRel entries) -> do Right (Elf.PLTRela entries) -> do
pure $! Map.fromList $ zipWith (relocFromRel (toEndianness dta) symtab resolver) [0..] entries addRelocEntries relocs1 $
Right (Elf.PLTRela entries) -> do zipWith (relocFromRela symtab resolver) [0..] entries
pure $! Map.fromList $ zipWith (relocFromRela symtab resolver) [0..] entries
pure $ Map.union loadtimeRelocs pltRelocs
------------------------------------------------------------------------ ------------------------------------------------------------------------
-- Elf segment loading -- Elf segment loading
@ -1152,9 +1192,11 @@ insertAllocatedSection hdr symtab sectionMap regIdx nm = do
-- Create memory segment -- Create memory segment
SomeRelocationResolver resolver <- getRelocationResolver hdr SomeRelocationResolver resolver <- getRelocationResolver hdr
when (isJust mRelBuffer && isJust mRelaBuffer) $ do when (isJust mRelBuffer && isJust mRelaBuffer) $ do
addWarning $ SectionRelaAndRelPresent nm addWarning $ MultipleRelocationTables
relocMap <- relocMap <- do
relocMapFromRelAndRela (Elf.headerData hdr) resolver symtab mRelBuffer mRelaBuffer let dta = Elf.headerData hdr
m1 <- addRelaEntries Map.empty dta resolver symtab mRelaBuffer
addRelEntries m1 dta resolver symtab mRelBuffer
seg <- seg <-
memSegment relocMap regIdx 0 Nothing (fromIntegral base) flags bytes (fromIntegral secSize) memSegment relocMap regIdx 0 Nothing (fromIntegral base) flags bytes (fromIntegral secSize)
-- Load memory segment. -- Load memory segment.