Skip to content

Commit 162fd62

Browse files
committed
macaw-riscv: Add riscvPLTStubInfo
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.
1 parent 32c4915 commit 162fd62

21 files changed

+69
-8
lines changed

macaw-riscv-symbolic/tests/Main.hs

+2-8
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import qualified Test.Tasty.Runners as TTR
3232
import qualified Data.Macaw.Architecture.Info as MAI
3333
import qualified Data.Macaw.CFG as MC
3434
import qualified Data.Macaw.Discovery as M
35-
import qualified Data.Macaw.Memory.ElfLoader.PLTStubs as MMELP
3635
import qualified Data.Macaw.Symbolic as MS
3736
import qualified Data.Macaw.Symbolic.Testing as MST
3837
import qualified Data.Macaw.RISCV as MR
@@ -133,8 +132,8 @@ symExTestSized :: forall rv w arch
133132
, 16 <= w
134133
, MC.ArchConstraints arch
135134
, arch ~ MR.RISCV rv
135+
, Elf.ElfWidthConstraints w
136136
, KnownNat w
137-
, Show (Elf.ElfWordType w)
138137
, MS.ArchInfo arch
139138
)
140139
=> MST.SimulationResult
@@ -147,12 +146,7 @@ symExTestSized :: forall rv w arch
147146
-> MAI.ArchitectureInfo arch
148147
-> TTH.Assertion
149148
symExTestSized expected mmPreset exePath saveSMT saveMacaw step ehi archInfo = do
150-
binfo <- MST.runDiscovery ehi exePath MST.toAddrSymMap archInfo
151-
-- Test cases involving shared libraries are not
152-
-- yet supported on the RISC-V backend. At a
153-
-- minimum, this is blocked on
154-
-- https://github.com/GaloisInc/elf-edit/issues/36.
155-
(MMELP.noPLTStubInfo "RISC-V")
149+
binfo <- MST.runDiscovery ehi exePath MST.toAddrSymMap archInfo MR.riscvPLTStubInfo
156150
let funInfos = Map.elems (MST.binaryDiscState (MST.mainBinaryInfo binfo) ^. M.funInfo)
157151
let testEntryPoints = mapMaybe hasTestPrefix funInfos
158152
F.forM_ testEntryPoints $ \(name, Some dfi) -> do

macaw-riscv-symbolic/tests/pass/Makefile

+31
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
CC64=riscv64-linux-musl-gcc
33
CC32=riscv32-linux-musl-gcc
44
CFLAGS=-nostdlib -no-pie -static -fno-stack-protector
5+
SO_CFLAGS=-nostdlib -fno-stack-protector -fcf-protection=none
56

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

2223
%.opt64.exe : %.c
2324
$(CC64) $(CFLAGS) -O2 $< -o $@
25+
26+
so/libfib.unopt32.so: so/fib.c so/libgetone.unopt32.so
27+
$(CC32) $(SO_CFLAGS) -O0 -Lso/ -Iso/ -shared $< -lgetone.unopt32 -o $@
28+
so/libfib.opt32.so: so/fib.c so/libgetone.opt32.so
29+
$(CC32) $(SO_CFLAGS) -O2 -Lso/ -Iso/ -shared $< -lgetone.opt32 -o $@
30+
31+
so/libgetone.unopt32.so : so/getone.c
32+
$(CC32) $(SO_CFLAGS) -O0 -Iso/ -shared $< -o $@
33+
so/libgetone.opt32.so : so/getone.c
34+
$(CC32) $(SO_CFLAGS) -O2 -Iso/ -shared $< -o $@
35+
36+
so/so.unopt32.exe : so/so.c so/libfib.unopt32.so
37+
$(CC32) $(SO_CFLAGS) -O0 -Lso/ -Iso/ $< -lfib.unopt32 -lgetone.unopt32 -o $@
38+
so/so.opt32.exe : so/so.c so/libfib.opt32.so
39+
$(CC32) $(SO_CFLAGS) -O2 -Lso/ -Iso/ $< -lfib.opt32 -lgetone.opt32 -o $@
40+
41+
so/libfib.unopt64.so: so/fib.c so/libgetone.unopt64.so
42+
$(CC64) $(SO_CFLAGS) -O0 -Lso/ -Iso/ -shared $< -lgetone.unopt64 -o $@
43+
so/libfib.opt64.so: so/fib.c so/libgetone.opt64.so
44+
$(CC64) $(SO_CFLAGS) -O2 -Lso/ -Iso/ -shared $< -lgetone.opt64 -o $@
45+
46+
so/libgetone.unopt64.so : so/getone.c
47+
$(CC64) $(SO_CFLAGS) -O0 -Iso/ -shared $< -o $@
48+
so/libgetone.opt64.so : so/getone.c
49+
$(CC64) $(SO_CFLAGS) -O2 -Iso/ -shared $< -o $@
50+
51+
so/so.unopt64.exe : so/so.c so/libfib.unopt64.so
52+
$(CC64) $(SO_CFLAGS) -O0 -Lso/ -Iso/ $< -lfib.unopt64 -lgetone.unopt64 -o $@
53+
so/so.opt64.exe : so/so.c so/libfib.opt64.so
54+
$(CC64) $(SO_CFLAGS) -O2 -Lso/ -Iso/ $< -lfib.opt64 -lgetone.opt64 -o $@
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "fib.h"
2+
#include "getone.h"
3+
4+
int fib(int n) {
5+
if (n <= 0) return 0;
6+
if (n == 1) return getone();
7+
return fib(n - 1) + fib(n - 2);
8+
}
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int fib(int x);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "getone.h"
2+
3+
int getone(void) {
4+
return 1;
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "fib.h"
2+
3+
int __attribute__((noinline)) test_fib(void) {
4+
return fib(6) == 8;
5+
}
6+
7+
void _start(void) {
8+
test_fib();
9+
}
Binary file not shown.
5.89 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.

macaw-riscv/macaw-riscv.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ library
2525
bv-sized,
2626
bytestring,
2727
containers,
28+
elf-edit,
2829
grift,
2930
lens,
3031
macaw-base,

macaw-riscv/src/Data/Macaw/RISCV.hs

+11
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module Data.Macaw.RISCV (
1212
module Data.Macaw.RISCV.RISCVReg,
1313
-- * Macaw configurations
1414
riscv_info,
15+
riscvPLTStubInfo,
1516
-- * Type-level tags
1617
G.RV(..),
1718
G.RVRepr(..),
@@ -25,10 +26,12 @@ module Data.Macaw.RISCV (
2526

2627
import GHC.Stack (HasCallStack)
2728

29+
import qualified Data.ElfEdit as EE
2830
import qualified Data.Macaw.CFG as MC
2931
import qualified Data.Macaw.CFG.DemandSet as MD
3032
import Data.Macaw.Discovery ( defaultClassifier )
3133
import qualified Data.Macaw.Architecture.Info as MI
34+
import qualified Data.Macaw.Memory.ElfLoader.PLTStubs as MMEP
3235
import Data.Parameterized ( type(<=) )
3336
import qualified GRIFT.Types as G
3437

@@ -79,3 +82,11 @@ riscv_info rvRepr =
7982
, MI.postArchTermStmtAbsState = \_ _ _ _ _ -> error $ "postArchTermStmtAbsState unimplemented in riscv_info"
8083
, MI.archClassifier = defaultClassifier
8184
}
85+
86+
-- | PLT stub information for ARM32 relocation types.
87+
riscvPLTStubInfo :: MMEP.PLTStubInfo (EE.RISCV_RelocationType w)
88+
riscvPLTStubInfo = MMEP.PLTStubInfo
89+
{ MMEP.pltFunSize = 32
90+
, MMEP.pltStubSize = 16
91+
, MMEP.pltGotStubSize = error "Unexpected .plt.got section in RISC-V binary"
92+
}

0 commit comments

Comments
 (0)