Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Z
Zipr Toolchain
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Open Source Software
Zipr Toolchain
Commits
3d320815
Commit
3d320815
authored
5 years ago
by
Jason Hiser
Browse files
Options
Downloads
Patches
Plain Diff
fixed for ldr [pc,reg]
parent
271ae947
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
unpin_arm32.cpp
+94
-3
94 additions, 3 deletions
unpin_arm32.cpp
with
94 additions
and
3 deletions
unpin_arm32.cpp
+
94
−
3
View file @
3d320815
...
...
@@ -224,7 +224,7 @@ void UnpinArm32_t::HandlePcrelReloc(Instruction_t* from_insn, Relocation_t* relo
<<
hex
<<
L0
<<
"-"
<<
L0
+
tramp_size
-
1
<<
endl
;
}
else
if
(
is_ldr_type
&&
!
is_rd_pc
)
else
if
(
is_ldr_type
&&
!
is_rd_pc
&&
!
I_bit_set
)
/* ldr <not pc>, [pc, imm] */
{
/*
* We need to patch an ldr[b][cond] reg, [pc + constant]
...
...
@@ -296,6 +296,97 @@ void UnpinArm32_t::HandlePcrelReloc(Instruction_t* from_insn, Relocation_t* relo
// should be few enough of these to always print
cout
<<
"Had to trampoline "
<<
disasm
->
getDisassembly
()
<<
" @"
<<
FA
<<
" to "
<<
hex
<<
L0
<<
"-"
<<
L0
+
tramp_size
-
1
<<
" ldr_imm = "
<<
ldr_imm
<<
endl
;
}
else
if
(
is_ldr_type
&&
!
is_rd_pc
&&
I_bit_set
)
/* ldr <not pc>, [pc, reg/shift] */
{
/*
* We need to patch a ldr Rd [pc, Rm <shift type> <shift amt>]@FA
* to be at a new location.
*
* The plan:
* FA: bne L0
* FT:
* ..
* L0: str Rt, [sp, # - fc] # spill tmp reg (Rt), use tmp_reg instead of r0
* L1: ldr Rt, [pc, #k] # where L1+8+k == L6 or k = L6-L1-8
* L2: add Rt, pc, Rt # add in pc
* L3: ldr Rd, [Rt, Rm <shift type> <shift smt> ]
* # copy of orig insn with pc (Rn field) replaced with Rt.
* L4: ldr Rt, [sp, # - fc] # spill tmp reg (Rt), use tmp_reg instead of r0
* L5: b FT
* L6: .word L2 - orig_insn_addr
*/
const
auto
tramp_size
=
6
*
4
+
4
;
// 6 insns, 4 bytes each, plus one word of read-only data
const
auto
tramp_range
=
ms
.
getFreeRange
(
tramp_size
);
const
auto
tramp_start
=
tramp_range
.
getStart
();
// don't be too fancy, just reserve tramp_size bytes.
ms
.
splitFreeRange
({
tramp_start
,
tramp_start
+
tramp_size
});
// and give the bytes some names
const
auto
FA
=
from_insn_location
;
const
auto
FT
=
FA
+
4
;
const
auto
L0
=
tramp_start
;
const
auto
L1
=
L0
+
4
;
const
auto
L2
=
L1
+
4
;
const
auto
L3
=
L2
+
4
;
const
auto
L4
=
L3
+
4
;
const
auto
L5
=
L4
+
4
;
const
auto
L6
=
L5
+
4
;
// Create a branch to put over the original ldr
// and set the conditional bits equal to
// the original instruction conditional bits
auto
my_branch_bytes
=
branch_bytes
;
my_branch_bytes
[
3
]
&=
0x0f
;
// clear always condition bits
my_branch_bytes
[
3
]
|=
(
insn_bytes
[
3
]
&
0xf0
);
ms
.
plopBytes
(
FA
,
my_branch_bytes
.
c_str
(),
4
);
// and make it point at L0
zo
->
applyPatch
(
FA
,
L0
);
// spill tmp_reg at L0, e50d00fc
auto
spill_insn
=
string
(
"
\xfc\x00\x0d\xe5
"
,
4
);
spill_insn
[
1
]
|=
(
tmp_reg
<<
4
);
ms
.
plopBytes
(
L0
,
spill_insn
.
c_str
(),
4
);
// ldr dest_reg, [pc+k] (where pc+8+k == L6)
auto
ldr_imm_insn
=
string
(
"
\x0c\x00\x9f\xe5
"
,
4
);
ldr_imm_insn
[
1
]
|=
(
tmp_reg
<<
4
);
ms
.
plopBytes
(
L1
,
ldr_imm_insn
.
c_str
(),
4
);
// put down L2
auto
new_add_word
=
string
(
"
\x00\x00\x8f\xe0
"
,
4
);
// e08f0000 add r0, pc, r0
new_add_word
[
1
]
|=
(
tmp_reg
<<
4
);
new_add_word
[
0
]
|=
(
tmp_reg
<<
0
);
ms
.
plopBytes
(
L2
,
new_add_word
.
c_str
(),
4
);
// put down L3 (orig insn with pc fields set to r0)
auto
orig_ldr
=
from_insn
->
getDataBits
();
orig_ldr
[
3
]
&=
0b00001111
;
// clear the cond bits.
orig_ldr
[
3
]
|=
0b11100000
;
// set the cond bits to "always".
orig_ldr
[
2
]
&=
~
(
mask4
<<
0
);
// clear this instruction's Rn field (i.e., set to r0)
orig_ldr
[
2
]
|=
(
tmp_reg
<<
0
);
// set Rn fields o tmp_reg
ms
.
plopBytes
(
L3
,
orig_ldr
.
c_str
(),
4
);
// put down L4, restore of scratch reg r0
auto
restore_insn
=
string
(
"
\xfc\x00\x1d\xe5
"
,
4
);
restore_insn
[
1
]
|=
(
tmp_reg
<<
4
);
// set Rd field
ms
.
plopBytes
(
L4
,
restore_insn
.
c_str
(),
4
);
// put an uncond branch the end of the trampoline
// and make it jump at FT
ms
.
plopBytes
(
L5
,
branch_bytes
.
c_str
(),
4
);
zo
->
applyPatch
(
L5
,
FT
);
// put the calculated pc-rel offset at L6
const
auto
new_offset
=
orig_insn_addr
-
L2
;
ms
.
plopBytes
(
L6
,
reinterpret_cast
<
const
char
*>
(
&
new_offset
),
4
);
// endianness of host must match target
// should be few enough of these to always print
cout
<<
"Had to trampoline "
<<
disasm
->
getDisassembly
()
<<
" @"
<<
hex
<<
FA
<<
" to "
<<
L0
<<
"-"
<<
L0
+
tramp_size
-
1
<<
endl
;
}
else
if
((
is_ldrls_type
||
is_addne_type
||
is_addls_type
)
&&
is_rd_pc
&&
is_rn_pc
)
{
...
...
@@ -366,8 +457,8 @@ void UnpinArm32_t::HandlePcrelReloc(Instruction_t* from_insn, Relocation_t* relo
orig_add
[
3
]
|=
0b11100000
;
// set the cond bits to "always".
orig_add
[
1
]
&=
~
(
mask4
<<
4
);
// clear this instruction's Rd field (i.e., set to r0)
orig_add
[
2
]
&=
~
(
mask4
<<
0
);
// clear this instruction's Rn field (i.e., set to r0)
orig_add
[
1
]
|=
(
tmp_reg
<<
4
);
// set Rd and Rn fields to tmp_reg
orig_add
[
2
]
|=
(
tmp_reg
<<
0
);
orig_add
[
1
]
|=
(
tmp_reg
<<
4
);
// set Rd and Rn fields to tmp_reg
orig_add
[
2
]
|=
(
tmp_reg
<<
0
);
ms
.
plopBytes
(
L3
,
orig_add
.
c_str
(),
4
);
// put down L4, store of calc'd pc.
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment