Using the PPC32 cross-compiler obtained from here:
$ powerpc-linux-musl-gcc test.c -o test.exe
And then load the resulting binary using this macaw-based program, which does nothing except load the test.exe binary and print any warnings that were emitted when calling memoryForElf:
-- Main.hs
{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import qualified Data.ByteString as BS
import qualified Data.ElfEdit as EE
import qualified Data.Macaw.Memory.ElfLoader as MME
main :: IO ()
main = do
bytes <- BS.readFile "test.exe"
case EE.decodeElfHeaderInfo bytes of
Left (_off, msg) -> fail msg
Right (EE.SomeElf e) -> do
case MME.memoryForElf options e of
Left err -> fail err
Right (_mem, _sym, warnings, _err) ->
mapM_ print warnings
where
options = MME.LoadOptions { MME.loadOffset = Just 0 }
Running this program will reveal the following warnings:
Why is macaw giving spurious warnings about the .rela.plt relocations? It's because the addresses for the JMPREL table (i.e., the PLT table) with the addresses for the RELA table (i.e., the relocation table):
Note that the RELASZ (the size of the RELA table) is 252 bytes, so starting from the RELA address, we can see that it spans the range [0x2ec, 0x3e8). Moreover, the PLTRELSZ (the size of the JMPREL table) is 48 bytes, so starting from the JMPREL address, we can see that it spans the range [0x3b8, 0x3e8). This means that the JMPREL table completely overlaps with the RELA table.
macaw, on the other hand, currently assumes that the RELA table and the JMPREL table are completely disjoint, as seen in the implementation of dynamicRelocationTable. This will parse the entirety of the RELA table (using dynRelaBuffer/addElfRelaEntrieshere) followed by the entirety of the JMPREL table (using dynPLTRel/addRelaEntrieshere). Moreover, if the JMPREL table contains any relocations that were previously found when loading the RELA table, then macaw will emit this warning (the Multiple relocations modify warning seen above). Because the relocations from the .rela.plt section are contained in both the JMPREL and RELA tables, this causes macaw to warn about them in the example above.
As it turns out, this issue has already been reported before in https://github.com/GaloisInc/elf-edit/issues/40, but in an elf-edit context rather than a macaw one. Interestingly, not all gcc architectures exhibit this overlapping table behavior, as a PPC64 version of gcc does not do this. In order to avoid these spurious warnings, macaw will likely need to implement something similar to the algorithm described in https://github.com/GaloisInc/elf-edit/issues/40#issuecomment-1960582054, which is necessary to determine if the PLT/relocation tables overlap before attempting to load them.
To reproduce this bug, compile this program:
Using the PPC32 cross-compiler obtained from here:
And then load the resulting binary using this
macaw
-based program, which does nothing except load thetest.exe
binary and print any warnings that were emitted when callingmemoryForElf
:Running this program will reveal the following warnings:
I claim that these warnings are spurious. If you look at the relocations in
test.exe
, we have:Why is
macaw
giving spurious warnings about the.rela.plt
relocations? It's because the addresses for theJMPREL
table (i.e., the PLT table) with the addresses for theRELA
table (i.e., the relocation table):Note that the
RELASZ
(the size of theRELA
table) is 252 bytes, so starting from theRELA
address, we can see that it spans the range[0x2ec, 0x3e8)
. Moreover, thePLTRELSZ
(the size of theJMPREL
table) is 48 bytes, so starting from theJMPREL
address, we can see that it spans the range[0x3b8, 0x3e8)
. This means that theJMPREL
table completely overlaps with theRELA
table.macaw
, on the other hand, currently assumes that theRELA
table and theJMPREL
table are completely disjoint, as seen in the implementation ofdynamicRelocationTable
. This will parse the entirety of theRELA
table (usingdynRelaBuffer
/addElfRelaEntries
here) followed by the entirety of theJMPREL
table (usingdynPLTRel
/addRelaEntries
here). Moreover, if theJMPREL
table contains any relocations that were previously found when loading theRELA
table, thenmacaw
will emit this warning (theMultiple relocations modify
warning seen above). Because the relocations from the.rela.plt
section are contained in both theJMPREL
andRELA
tables, this causesmacaw
to warn about them in the example above.As it turns out, this issue has already been reported before in https://github.com/GaloisInc/elf-edit/issues/40, but in an
elf-edit
context rather than amacaw
one. Interestingly, not allgcc
architectures exhibit this overlapping table behavior, as a PPC64 version ofgcc
does not do this. In order to avoid these spurious warnings,macaw
will likely need to implement something similar to the algorithm described in https://github.com/GaloisInc/elf-edit/issues/40#issuecomment-1960582054, which is necessary to determine if the PLT/relocation tables overlap before attempting to load them.