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
6727a049
Commit
6727a049
authored
7 years ago
by
jdh8d
Browse files
Options
Downloads
Patches
Plain Diff
Former-commit-id: e1599842e39838ca2ed7c4ae897d8dd3a8d195d9
parent
7c6fd723
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
.gitattributes
+1
-0
1 addition, 0 deletions
.gitattributes
tools/transforms/EhUpdater.cpp
+250
-0
250 additions, 0 deletions
tools/transforms/EhUpdater.cpp
with
251 additions
and
0 deletions
.gitattributes
+
1
−
0
View file @
6727a049
...
...
@@ -1207,6 +1207,7 @@ tools/transforms/AnnotationBoundaryGenerator.cpp -text
tools/transforms/AnnotationBoundaryGenerator.hpp -text
tools/transforms/DirectOffsetInference.cpp -text
tools/transforms/DirectOffsetInference.hpp -text
tools/transforms/EhUpdater.cpp -text
tools/transforms/EhUpdater.hpp -text
tools/transforms/General_Utility.cpp -text
tools/transforms/General_Utility.hpp -text
...
...
This diff is collapsed.
Click to expand it.
tools/transforms/EhUpdater.cpp
0 → 100644
+
250
−
0
View file @
6727a049
#include
"EhUpdater.hpp"
#include
<string>
#include
<map>
using
namespace
std
;
using
namespace
libIRDB
;
extern
map
<
Function_t
*
,
set
<
Instruction_t
*>
>
inserted_instr
;
//used to undo inserted instructions
// see https://en.wikipedia.org/wiki/LEB128
static
bool
read_uleb128
(
uint64_t
&
result
,
uint32_t
&
position
,
const
uint8_t
*
const
data
,
const
uint32_t
max
)
{
result
=
0
;
auto
shift
=
0
;
while
(
position
<
max
)
{
auto
byte
=
data
[
position
];
position
++
;
result
|=
(
(
byte
&
0x7f
)
<<
shift
);
if
(
(
byte
&
0x80
)
==
0
)
break
;
shift
+=
7
;
}
return
(
position
>=
max
);
}
// see https://en.wikipedia.org/wiki/LEB128
static
bool
read_sleb128
(
int64_t
&
result
,
uint32_t
&
position
,
const
uint8_t
*
const
data
,
const
uint32_t
max
)
{
result
=
0
;
auto
shift
=
0
;
auto
size
=
64
;
// number of bits in signed integer;
auto
byte
=
uint8_t
(
0
);
do
{
byte
=
data
[
position
];
position
++
;
result
|=
((
byte
&
0x7f
)
<<
shift
);
shift
+=
7
;
}
while
(
(
byte
&
0x80
)
!=
0
);
/* sign bit of byte is second high order bit (0x40) */
if
((
shift
<
size
)
&&
(
(
byte
&
0x40
)
!=
0
/* sign bit of byte is set */
))
/* sign extend */
result
|=
-
(
1
<<
shift
);
return
(
position
>=
max
);
}
static
string
to_uleb128
(
uint64_t
value
)
{
auto
output_str
=
string
(
""
);
do
{
auto
byte
=
value
&
0x7f
;
// low order 7 bits of value;
value
>>=
7
;
if
(
value
!=
0
)
// more bytes to come
byte
|=
0x80
;
// set high order bit of byte;
output_str
.
push_back
(
byte
);
}
while
(
value
!=
0
);
return
output_str
;
}
static
string
to_sleb128
(
int64_t
value
)
{
auto
output_str
=
string
(
""
);
auto
more
=
true
;
auto
negative
=
(
value
<
0
);
auto
size
=
sizeof
(
value
)
*
8
;
// no. of bits in signed integer;
while
(
more
)
{
auto
byte
=
value
&
0x7f
;
// low order 7 bits of value;
value
>>=
7
;
/* the following is unnecessary if the implementation of >>= uses an
arithmetic rather than logical shift for a signed left operand */
if
(
negative
)
value
|=
-
(
1
<<
(
size
-
7
));
/* sign extend */
/* sign bit of byte is second high order bit (0x40) */
const
bool
sign_bit_clear
=
(
byte
&
0x40
)
==
0
;
const
bool
sign_bit_set
=
!
sign_bit_clear
;
// if ((value == 0 && sign bit of byte is clear)
// || (value == -1 && sign bit of byte is set))
if
((
value
==
0
&&
sign_bit_clear
)
||
(
value
==
-
1
&&
sign_bit_set
))
more
=
false
;
else
byte
|=
0x80
;
// set high order bit of byte;
output_str
.
push_back
(
byte
);
// emit byte
}
return
output_str
;
}
/* transform any eh handling info for the FDE program*/
bool
EhUpdater_t
::
update_program
(
EhProgram_t
*
ehpgm
)
{
assert
(
ehpgm
);
const
auto
daf
=
ehpgm
->
GetDataAlignmentFactor
();
const
auto
saved_reg_size
=
m_layout
->
GetSavedRegsSize
();
const
auto
orig_frame_size
=
m_layout
->
GetOriginalAllocSize
();
const
auto
altered_frame_size
=
m_layout
->
GetAlteredAllocSize
();
/* change the offset, as needed, in a dwarf instruction. the offset is at location 'pos' */
const
auto
change_offset
=
[
&
](
string
&
dwarf_insn
,
const
uint32_t
offset_pos
,
const
bool
factored
)
->
void
{
/* handle */
/* format: [(char)(opcode+reg#)] [(uleb128) offset/data_alignment_factor] */
/* we need to adjust factored offset if it's greater than the saved reg size */
auto
factored_offset
=
uint64_t
(
0
);
auto
pos_to_read
=
(
uint32_t
)
1
;
const
auto
data
=
reinterpret_cast
<
const
uint8_t
*>
(
dwarf_insn
.
data
());
const
auto
res
=
read_uleb128
(
factored_offset
,
pos_to_read
,
data
,
dwarf_insn
.
size
());
assert
(
res
);
auto
offset
=
factored_offset
;
if
(
factored
)
offset
*=
daf
;
if
(
offset
>
saved_reg_size
)
{
const
auto
new_offset
=
offset
+
(
altered_frame_size
-
orig_frame_size
);
auto
factored_new_offset
=
new_offset
;
if
(
factored
)
factored_new_offset
/=
daf
;
const
auto
encoded_factored_new_offset
=
to_uleb128
(
factored_new_offset
);
auto
new_dwarf_insn
=
string
(
""
);
for
(
auto
i
=
0
;
i
<
offset_pos
;
i
++
)
new_dwarf_insn
.
push_back
(
dwarf_insn
[
i
]);
new_dwarf_insn
+=
encoded_factored_new_offset
;
dwarf_insn
=
new_dwarf_insn
;
}
};
for
(
auto
&
dwarf_insn
:
ehpgm
->
GetFDEProgram
())
{
auto
opcode
=
dwarf_insn
[
0
];
auto
opcode_upper2
=
(
uint8_t
)(
opcode
>>
6
);
auto
opcode_lower6
=
(
uint8_t
)(
opcode
&
(
0x3f
));
switch
(
opcode_upper2
)
{
/* case DW_CFA_offset: */
/* reg should be restored from CFA+(offset*daf) */
case
0x2
:
/* DW_CFA_offset: */
{
change_offset
(
dwarf_insn
,
1
,
true
);
break
;
};
case
0
:
{
switch
(
opcode_lower6
)
{
/* sanitize */
case
0xd
:
/* DW_CFA_def_cfa_register: */
{
/* [ (char)opcode ] [ (uleb)register ] */
/* assert if register != sp (if bp not used) or bp (if bp is used) */
/* never update this insn */
assert
(
0
);
}
/* handle */
case
0xe
:
/* DW_CFA_def_cfa_offset: */
{
/* [(char)opcode] [(uleb)offset] */
/* if offset > saved reg size, new_offset=offset+(new_frame_size-old_frame_size) */
change_offset
(
dwarf_insn
,
1
,
false
);
break
;
}
case
0x11
:
/*DW_CFA_def_cfa_offset_sf: */
{
/* [(char)opcode] [(sleb)offset/data_alignment_factor] */
/* if offset > saved reg size, new_offset=offset+(new_frame_size-old_frame_size) */
assert
(
0
);
}
case
0x5
:
/*DW_CFA_offset_extended: */
{
/* [ (char)opcode ] [ (uleb)reg # ] [ (uleb) offset] */
/* we need to adjust factored offset if it's greater than the saved reg size */
change_offset
(
dwarf_insn
,
2
,
true
);
break
;
}
default
:
break
;
}
}
default
:
break
;
}
}
return
true
;
}
/* transform any eh handling info for the instruction */
bool
EhUpdater_t
::
update_instructions
(
Instruction_t
*
insn
)
{
const
auto
ehpgm
=
insn
->
GetEhProgram
();
/* no program == no update */
if
(
ehpgm
==
NULL
)
return
true
;
const
auto
new_eh_pgm
=
new
EhProgram_t
(
*
ehpgm
);
insn
->
SetEhProgram
(
new_eh_pgm
);
m_firp
->
GetAllEhPrograms
().
insert
(
new_eh_pgm
);
return
update_program
(
new_eh_pgm
);
}
/* transform any eh handling info for each instruction */
bool
EhUpdater_t
::
update_instructions
()
{
// for all instructions in the fuunction.
for
(
const
auto
&
i
:
m_func
->
GetInstructions
())
update_instructions
(
i
);
// plus any instructions we allocated for the function
for
(
const
auto
&
i
:
inserted_instr
[
m_func
])
update_instructions
(
i
);
return
true
;
}
/* transform any eh handling info for the function */
bool
EhUpdater_t
::
execute
()
{
if
(
m_func
->
GetUseFramePointer
())
/* no updates needed if a frame pointer is used */
return
true
;
/* can only update for p1 functions */
if
(
!
m_layout
->
IsP1
()
)
return
false
;
return
update_instructions
();
}
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