Skip to content

Commit

Permalink
macaw-riscv: Add riscvPLTStubInfo
Browse files Browse the repository at this point in the history
Now that we can load RISC-V relocations in `macaw` (building on top of the work
in GaloisInc/elf-edit#45), this patch adds PLT stub heuristics for RISC-V
binaries. I have added some test cases in `macaw-riscv-symbolic` which
demonstrate that the basic idea works.

Note that due to #416, these test cases will print warnings when loaded into
`macaw`. These warnings are ultimately harmless, however, as the same
relocations are loaded at the same addresses multiple times, which causes no
change in behavior.

Fixes #414.
  • Loading branch information
RyanGlScott committed Jul 30, 2024
1 parent 32c4915 commit 162fd62
Show file tree
Hide file tree
Showing 21 changed files with 69 additions and 8 deletions.
10 changes: 2 additions & 8 deletions macaw-riscv-symbolic/tests/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import qualified Test.Tasty.Runners as TTR
import qualified Data.Macaw.Architecture.Info as MAI
import qualified Data.Macaw.CFG as MC
import qualified Data.Macaw.Discovery as M
import qualified Data.Macaw.Memory.ElfLoader.PLTStubs as MMELP
import qualified Data.Macaw.Symbolic as MS
import qualified Data.Macaw.Symbolic.Testing as MST
import qualified Data.Macaw.RISCV as MR
Expand Down Expand Up @@ -133,8 +132,8 @@ symExTestSized :: forall rv w arch
, 16 <= w
, MC.ArchConstraints arch
, arch ~ MR.RISCV rv
, Elf.ElfWidthConstraints w
, KnownNat w
, Show (Elf.ElfWordType w)
, MS.ArchInfo arch
)
=> MST.SimulationResult
Expand All @@ -147,12 +146,7 @@ symExTestSized :: forall rv w arch
-> MAI.ArchitectureInfo arch
-> TTH.Assertion
symExTestSized expected mmPreset exePath saveSMT saveMacaw step ehi archInfo = do
binfo <- MST.runDiscovery ehi exePath MST.toAddrSymMap archInfo
-- Test cases involving shared libraries are not
-- yet supported on the RISC-V backend. At a
-- minimum, this is blocked on
-- https://github.com/GaloisInc/elf-edit/issues/36.
(MMELP.noPLTStubInfo "RISC-V")
binfo <- MST.runDiscovery ehi exePath MST.toAddrSymMap archInfo MR.riscvPLTStubInfo
let funInfos = Map.elems (MST.binaryDiscState (MST.mainBinaryInfo binfo) ^. M.funInfo)
let testEntryPoints = mapMaybe hasTestPrefix funInfos
F.forM_ testEntryPoints $ \(name, Some dfi) -> do
Expand Down
31 changes: 31 additions & 0 deletions macaw-riscv-symbolic/tests/pass/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
CC64=riscv64-linux-musl-gcc
CC32=riscv32-linux-musl-gcc
CFLAGS=-nostdlib -no-pie -static -fno-stack-protector
SO_CFLAGS=-nostdlib -fno-stack-protector -fcf-protection=none

unopt32 = $(patsubst %.c,%.unopt32.exe,$(wildcard *.c))
unopt64 = $(patsubst %.c,%.unopt64.exe,$(wildcard *.c))
Expand All @@ -21,3 +22,33 @@ all: $(unopt32) $(opt32) $(unopt64) $(opt64)

%.opt64.exe : %.c
$(CC64) $(CFLAGS) -O2 $< -o $@

so/libfib.unopt32.so: so/fib.c so/libgetone.unopt32.so
$(CC32) $(SO_CFLAGS) -O0 -Lso/ -Iso/ -shared $< -lgetone.unopt32 -o $@
so/libfib.opt32.so: so/fib.c so/libgetone.opt32.so
$(CC32) $(SO_CFLAGS) -O2 -Lso/ -Iso/ -shared $< -lgetone.opt32 -o $@

so/libgetone.unopt32.so : so/getone.c
$(CC32) $(SO_CFLAGS) -O0 -Iso/ -shared $< -o $@
so/libgetone.opt32.so : so/getone.c
$(CC32) $(SO_CFLAGS) -O2 -Iso/ -shared $< -o $@

so/so.unopt32.exe : so/so.c so/libfib.unopt32.so
$(CC32) $(SO_CFLAGS) -O0 -Lso/ -Iso/ $< -lfib.unopt32 -lgetone.unopt32 -o $@
so/so.opt32.exe : so/so.c so/libfib.opt32.so
$(CC32) $(SO_CFLAGS) -O2 -Lso/ -Iso/ $< -lfib.opt32 -lgetone.opt32 -o $@

so/libfib.unopt64.so: so/fib.c so/libgetone.unopt64.so
$(CC64) $(SO_CFLAGS) -O0 -Lso/ -Iso/ -shared $< -lgetone.unopt64 -o $@
so/libfib.opt64.so: so/fib.c so/libgetone.opt64.so
$(CC64) $(SO_CFLAGS) -O2 -Lso/ -Iso/ -shared $< -lgetone.opt64 -o $@

so/libgetone.unopt64.so : so/getone.c
$(CC64) $(SO_CFLAGS) -O0 -Iso/ -shared $< -o $@
so/libgetone.opt64.so : so/getone.c
$(CC64) $(SO_CFLAGS) -O2 -Iso/ -shared $< -o $@

so/so.unopt64.exe : so/so.c so/libfib.unopt64.so
$(CC64) $(SO_CFLAGS) -O0 -Lso/ -Iso/ $< -lfib.unopt64 -lgetone.unopt64 -o $@
so/so.opt64.exe : so/so.c so/libfib.opt64.so
$(CC64) $(SO_CFLAGS) -O2 -Lso/ -Iso/ $< -lfib.opt64 -lgetone.opt64 -o $@
8 changes: 8 additions & 0 deletions macaw-riscv-symbolic/tests/pass/so/fib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "fib.h"
#include "getone.h"

int fib(int n) {
if (n <= 0) return 0;
if (n == 1) return getone();
return fib(n - 1) + fib(n - 2);
}
1 change: 1 addition & 0 deletions macaw-riscv-symbolic/tests/pass/so/fib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int fib(int x);
5 changes: 5 additions & 0 deletions macaw-riscv-symbolic/tests/pass/so/getone.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "getone.h"

int getone(void) {
return 1;
}
1 change: 1 addition & 0 deletions macaw-riscv-symbolic/tests/pass/so/getone.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int getone(void);
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
9 changes: 9 additions & 0 deletions macaw-riscv-symbolic/tests/pass/so/so.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "fib.h"

int __attribute__((noinline)) test_fib(void) {
return fib(6) == 8;
}

void _start(void) {
test_fib();
}
Binary file added macaw-riscv-symbolic/tests/pass/so/so.opt32.exe
Binary file not shown.
Binary file added macaw-riscv-symbolic/tests/pass/so/so.opt64.exe
Binary file not shown.
Binary file not shown.
Binary file added macaw-riscv-symbolic/tests/pass/so/so.unopt64.exe
Binary file not shown.
1 change: 1 addition & 0 deletions macaw-riscv/macaw-riscv.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ library
bv-sized,
bytestring,
containers,
elf-edit,
grift,
lens,
macaw-base,
Expand Down
11 changes: 11 additions & 0 deletions macaw-riscv/src/Data/Macaw/RISCV.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module Data.Macaw.RISCV (
module Data.Macaw.RISCV.RISCVReg,
-- * Macaw configurations
riscv_info,
riscvPLTStubInfo,
-- * Type-level tags
G.RV(..),
G.RVRepr(..),
Expand All @@ -25,10 +26,12 @@ module Data.Macaw.RISCV (

import GHC.Stack (HasCallStack)

import qualified Data.ElfEdit as EE
import qualified Data.Macaw.CFG as MC
import qualified Data.Macaw.CFG.DemandSet as MD
import Data.Macaw.Discovery ( defaultClassifier )
import qualified Data.Macaw.Architecture.Info as MI
import qualified Data.Macaw.Memory.ElfLoader.PLTStubs as MMEP
import Data.Parameterized ( type(<=) )
import qualified GRIFT.Types as G

Expand Down Expand Up @@ -79,3 +82,11 @@ riscv_info rvRepr =
, MI.postArchTermStmtAbsState = \_ _ _ _ _ -> error $ "postArchTermStmtAbsState unimplemented in riscv_info"
, MI.archClassifier = defaultClassifier
}

-- | PLT stub information for ARM32 relocation types.
riscvPLTStubInfo :: MMEP.PLTStubInfo (EE.RISCV_RelocationType w)
riscvPLTStubInfo = MMEP.PLTStubInfo
{ MMEP.pltFunSize = 32
, MMEP.pltStubSize = 16
, MMEP.pltGotStubSize = error "Unexpected .plt.got section in RISC-V binary"
}

0 comments on commit 162fd62

Please sign in to comment.