diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2019-12-12 11:56:06 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2019-12-12 12:03:45 -0800 |
commit | e379e5f385f874adb0b414f917adb1fc50e20de9 (patch) | |
tree | e9a1ad41c0582dd54bfebe9391afb382105f907c /gas/doc | |
parent | b65d68b8d60338a860e169aac3bac54e6bac60db (diff) | |
download | gdb-e379e5f385f874adb0b414f917adb1fc50e20de9.zip gdb-e379e5f385f874adb0b414f917adb1fc50e20de9.tar.gz gdb-e379e5f385f874adb0b414f917adb1fc50e20de9.tar.bz2 |
i386: Align branches within a fixed boundary
Add 3 command-line options to align branches within a fixed boundary
with segment prefixes or NOPs:
1. -malign-branch-boundary=NUM aligns branches within NUM byte boundary.
2. -malign-branch=TYPE[+TYPE...] specifies types of branches to align.
The supported branches are:
a. Conditional jump.
b. Fused conditional jump.
c. Unconditional jump.
d. Call.
e. Ret.
f. Indirect jump and call.
3. -malign-branch-prefix-size=NUM aligns branches with NUM segment
prefixes per instruction.
3 new rs_machine_dependent frag types are added:
1. BRANCH_PADDING. The variable size frag to insert NOP before branch.
2. BRANCH_PREFIX. The variable size frag to insert segment prefixes to
an instruction. The choices of prefixes are:
a. Use the existing segment prefix if there is one.
b. Use CS segment prefix in 64-bit mode.
c. In 32-bit mode, use SS segment prefix with ESP/EBP base register
and use DS segment prefix without ESP/EBP base register.
3. FUSED_JCC_PADDING. The variable size frag to insert NOP before fused
conditional jump.
The new rs_machine_dependent frags aren't inserted if the previous item
is a prefix or a constant directive, which may be used to hardcode an
instruction, since there is no clear instruction boundary. Segment
prefixes and NOP padding are disabled before relaxable TLS relocations
and tls_get_addr calls to keep TLS instruction sequence unchanged.
md_estimate_size_before_relax() and i386_generic_table_relax_frag() are
used to handled BRANCH_PADDING, BRANCH_PREFIX and FUSED_JCC_PADDING frags.
i386_generic_table_relax_frag() grows or shrinks sizes of segment prefix
and NOP to align the next branch frag:
1. First try to add segment prefixes to instructions before a branch.
2. If there is no sufficient room to add segment prefixes, NOP will be
inserted before a branch.
* config/tc-i386.c (_i386_insn): Add has_gotpc_tls_reloc.
(tls_get_addr): New.
(last_insn): New.
(align_branch_power): New.
(align_branch_kind): New.
(align_branch_bit): New.
(align_branch): New.
(MAX_FUSED_JCC_PADDING_SIZE): New.
(align_branch_prefix_size): New.
(BRANCH_PADDING): New.
(BRANCH_PREFIX): New.
(FUSED_JCC_PADDING): New.
(i386_generate_nops): Support BRANCH_PADDING and FUSED_JCC_PADDING.
(md_begin): Abort if align_branch_prefix_size <
MAX_FUSED_JCC_PADDING_SIZE.
(md_assemble): Set last_insn.
(maybe_fused_with_jcc_p): New.
(add_fused_jcc_padding_frag_p): New.
(add_branch_prefix_frag_p): New.
(add_branch_padding_frag_p): New.
(output_insn): Generate a BRANCH_PADDING, FUSED_JCC_PADDING or
BRANCH_PREFIX frag and terminate each frag to align branches.
(output_disp): Set i.has_gotpc_tls_reloc to TRUE for GOTPC and
relaxable TLS relocations.
(output_imm): Likewise.
(i386_next_non_empty_frag): New.
(i386_next_jcc_frag): New.
(i386_classify_machine_dependent_frag): New.
(i386_branch_padding_size): New.
(i386_generic_table_relax_frag): New.
(md_estimate_size_before_relax): Handle COND_JUMP_PADDING,
FUSED_JCC_PADDING and COND_JUMP_PREFIX frags.
(md_convert_frag): Handle BRANCH_PADDING, BRANCH_PREFIX and
FUSED_JCC_PADDING frags.
(OPTION_MALIGN_BRANCH_BOUNDARY): New.
(OPTION_MALIGN_BRANCH_PREFIX_SIZE): New.
(OPTION_MALIGN_BRANCH): New.
(md_longopts): Add -malign-branch-boundary=,
-malign-branch-prefix-size= and -malign-branch=.
(md_parse_option): Handle -malign-branch-boundary=,
-malign-branch-prefix-size= and -malign-branch=.
(md_show_usage): Display -malign-branch-boundary=,
-malign-branch-prefix-size= and -malign-branch=.
(i386_target_format): Set tls_get_addr.
(i386_cons_align): New.
* config/tc-i386.h (i386_cons_align): New.
(md_cons_align): New.
(i386_generic_table_relax_frag): New.
(md_generic_table_relax_frag): New.
(i386_tc_frag_data): Add u, padding_address, length,
max_prefix_length, prefix_length, default_prefix, cmp_size,
classified and branch_type.
(TC_FRAG_INIT): Initialize u, padding_address, length,
max_prefix_length, prefix_length, default_prefix, cmp_size,
classified and branch_type.
* doc/c-i386.texi: Document -malign-branch-boundary=,
-malign-branch= and -malign-branch-prefix-size=.
Diffstat (limited to 'gas/doc')
-rw-r--r-- | gas/doc/c-i386.texi | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index 589b426..74296e6 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -423,6 +423,32 @@ R_X86_64_REX_GOTPCRELX, in 64-bit mode. relocations. The default can be controlled by a configure option @option{--enable-x86-relax-relocations}. +@cindex @samp{-malign-branch-boundary=} option, i386 +@cindex @samp{-malign-branch-boundary=} option, x86-64 +@item -malign-branch-boundary=@var{NUM} +This option controls how the assembler should align branches with segment +prefixes or NOP. @var{NUM} must be a power of 2. It should be 0 or +no less than 16. Branches will be aligned within @var{NUM} byte +boundary. @option{-malign-branch-boundary=0}, which is the default, +doesn't align branches. + +@cindex @samp{-malign-branch=} option, i386 +@cindex @samp{-malign-branch=} option, x86-64 +@item -malign-branch=@var{TYPE}[+@var{TYPE}...] +This option specifies types of branches to align. @var{TYPE} is +combination of @samp{jcc}, which aligns conditional jumps, +@samp{fused}, which aligns fused conditional jumps, @samp{jmp}, +which aligns unconditional jumps, @samp{call} which aligns calls, +@samp{ret}, which aligns rets, @samp{indirect}, which aligns indirect +jumps and calls. The default is @option{-malign-branch=jcc+fused+jmp}. + +@cindex @samp{-malign-branch-prefix-size=} option, i386 +@cindex @samp{-malign-branch-prefix-size=} option, x86-64 +@item -malign-branch-prefix-size=@var{NUM} +This option specifies the maximum number of prefixes on an instruction +to align branches. @var{NUM} should be between 0 and 5. The default +@var{NUM} is 5. + @cindex @samp{-mx86-used-note=} option, i386 @cindex @samp{-mx86-used-note=} option, x86-64 @item -mx86-used-note=@var{no} |