Skip to content

Commit dd5e4e9

Browse files
committed
new directives on x86
1 parent 703e1ae commit dd5e4e9

File tree

11 files changed

+635
-419
lines changed

11 files changed

+635
-419
lines changed

backend/amd64/emit.ml

Lines changed: 421 additions & 364 deletions
Large diffs are not rendered by default.

backend/arm64/emit.ml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ let emit_literals p align emit_literal =
771771
(* CR sspies: The following section is incorrect. We are in a data section
772772
here. Fix this when cleaning up the section mechanism. *)
773773
D.unsafe_set_interal_section_ref Text);
774-
D.align ~bytes:align;
774+
D.align ~data_section:false ~bytes:align;
775775
List.iter emit_literal !p;
776776
p := [])
777777

@@ -2062,7 +2062,7 @@ let fundecl fundecl =
20622062
contains_calls := fundecl.fun_contains_calls;
20632063
emit_named_text_section !function_name;
20642064
let fun_sym = S.create fundecl.fun_name in
2065-
D.align ~bytes:8;
2065+
D.align ~data_section:false ~bytes:8;
20662066
D.global fun_sym;
20672067
D.type_symbol ~ty:Function fun_sym;
20682068
D.define_symbol_label ~section:Text fun_sym;
@@ -2126,11 +2126,11 @@ let emit_item (d : Cmm.data_item) =
21262126
D.symbol_plus_offset ~offset_in_bytes:(Targetint.of_int o) sym
21272127
| Cstring s -> D.string s
21282128
| Cskip n -> if n > 0 then D.space ~bytes:n
2129-
| Calign n -> D.align ~bytes:n
2129+
| Calign n -> D.align ~data_section:true ~bytes:n
21302130

21312131
let data l =
21322132
D.data ();
2133-
D.align ~bytes:8;
2133+
D.align ~data_section:true ~bytes:8;
21342134
List.iter emit_item l
21352135

21362136
let file_emitter ~file_num ~file_name =
@@ -2168,7 +2168,7 @@ let begin_assembly _unix =
21682168
if macosx
21692169
then (
21702170
DSL.ins I.NOP [||];
2171-
D.align ~bytes:8);
2171+
D.align ~data_section:false ~bytes:8);
21722172
let code_end = Cmm_helpers.make_symbol "code_end" in
21732173
Emitaux.Dwarf_helpers.begin_dwarf ~code_begin ~code_end ~file_emitter
21742174

@@ -2186,7 +2186,7 @@ let end_assembly () =
21862186
D.global data_end_sym;
21872187
D.define_symbol_label ~section:Data data_end_sym;
21882188
D.int64 0L;
2189-
D.align ~bytes:8;
2189+
D.align ~data_section:true ~bytes:8;
21902190
(* #7887 *)
21912191
let frametable = Cmm_helpers.make_symbol "frametable" in
21922192
let frametable_sym = S.create frametable in
@@ -2215,7 +2215,7 @@ let end_assembly () =
22152215
(* [efa_word] is [D.targetint (Targetint.of_int_exn n)] in
22162216
mshinwell/ocaml#gdb-names-gpr x86 emitter *)
22172217
efa_word = (fun n -> D.targetint (Targetint.of_int_exn n));
2218-
efa_align = (fun n -> D.align ~bytes:n);
2218+
efa_align = (fun n -> D.align ~data_section:true ~bytes:n);
22192219
efa_label_rel =
22202220
(fun lbl ofs ->
22212221
let lbl = label_to_asm_label ~section:Data lbl in

backend/asm_targets/asm_directives_new.ml

Lines changed: 87 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,15 @@ module Directive = struct
150150
| Code
151151
| Machine_width_data
152152

153+
type reloc_type = R_X86_64_PLT32
154+
153155
type comment = string
154156

155157
type t =
156-
| Align of { bytes : int }
158+
| Align of
159+
{ bytes : int;
160+
data_section : bool
161+
}
157162
| Bytes of
158163
{ str : string;
159164
comment : string option
@@ -166,6 +171,9 @@ module Directive = struct
166171
offset : int
167172
}
168173
| Cfi_startproc
174+
| Cfi_remember_state
175+
| Cfi_restore_state
176+
| Cfi_def_cfa_register of string
169177
| Comment of comment
170178
| Const of
171179
{ constant : Constant_with_width.t;
@@ -204,6 +212,14 @@ module Directive = struct
204212
comment : string option
205213
}
206214
| Protected of string
215+
| Hidden of string
216+
| Weak of string
217+
| External of string
218+
| Reloc of
219+
{ offset : Constant.t;
220+
name : reloc_type;
221+
expr : Constant.t
222+
}
207223

208224
let bprintf = Printf.bprintf
209225

@@ -268,6 +284,8 @@ module Directive = struct
268284
bprintf buf "\t.ascii\t\"%s\""
269285
(string_of_string_literal (String.sub s !i (l - !i)))
270286

287+
let reloc_type_to_string = function R_X86_64_PLT32 -> "R_X86_64_PLT32"
288+
271289
let print_gas buf t =
272290
let gas_comment_opt comment_opt =
273291
if not (emit_comments ())
@@ -278,7 +296,9 @@ module Directive = struct
278296
| Some comment -> Printf.sprintf "\t/* %s */" comment
279297
in
280298
match t with
281-
| Align { bytes = n } ->
299+
| Align { bytes = n; data_section = _ } ->
300+
(* The data_section is only relevant for the binary emitter. On GAS, we
301+
can ignore it and just use [.align] in both cases. *)
282302
(* Some assemblers interpret the integer n as a 2^n alignment and others
283303
as a number of bytes. *)
284304
let n =
@@ -333,6 +353,9 @@ module Directive = struct
333353
| Cfi_offset { reg; offset } ->
334354
bprintf buf "\t.cfi_offset %d, %d" reg offset
335355
| Cfi_startproc -> bprintf buf "\t.cfi_startproc"
356+
| Cfi_remember_state -> bprintf buf "\t.cfi_remember_state"
357+
| Cfi_restore_state -> bprintf buf "\t.cfi_restore_state"
358+
| Cfi_def_cfa_register reg -> bprintf buf "\t.cfi_def_cfa_register %%%s" reg
336359
| File { file_num = None; filename } ->
337360
bprintf buf "\t.file\t\"%s\"" filename
338361
| File { file_num = Some file_num; filename } ->
@@ -375,6 +398,14 @@ module Directive = struct
375398
Misc.fatal_error
376399
"Cannot emit [Direct_assignment] except on macOS-like assemblers")
377400
| Protected s -> bprintf buf "\t.protected\t%s" s
401+
| Hidden s -> bprintf buf "\t.hidden\t%s" s
402+
| Weak s -> bprintf buf "\t.weak\t%s" s
403+
(* masm only *)
404+
| External _ -> assert false
405+
| Reloc { offset; name; expr } ->
406+
bprintf buf "\t.reloc\t%a, %s, %a" Constant.print offset
407+
(reloc_type_to_string name)
408+
Constant.print expr
378409

379410
let print_masm buf t =
380411
let unsupported name =
@@ -389,7 +420,10 @@ module Directive = struct
389420
| Some comment -> Printf.sprintf "\t; %s" comment
390421
in
391422
match t with
392-
| Align { bytes } -> bprintf buf "\tALIGN\t%d" bytes
423+
| Align { bytes; data_section = _ } ->
424+
(* The data_section is only relevant for the binary emitter. On MASM, we
425+
can ignore it. *)
426+
bprintf buf "\tALIGN\t%d" bytes
393427
| Bytes { str; comment } ->
394428
buf_bytes_directive buf ~directive:"BYTE" str;
395429
bprintf buf "%s" (masm_comment_opt comment)
@@ -422,6 +456,9 @@ module Directive = struct
422456
| Cfi_endproc -> unsupported "Cfi_endproc"
423457
| Cfi_offset _ -> unsupported "Cfi_offset"
424458
| Cfi_startproc -> unsupported "Cfi_startproc"
459+
| Cfi_remember_state -> unsupported "Cfi_remember_state"
460+
| Cfi_restore_state -> unsupported "Cfi_restore_state"
461+
| Cfi_def_cfa_register _ -> unsupported "Cfi_def_cfa_register"
425462
| File _ -> unsupported "File"
426463
| Indirect_symbol _ -> unsupported "Indirect_symbol"
427464
| Loc _ -> unsupported "Loc"
@@ -432,6 +469,11 @@ module Directive = struct
432469
| Uleb128 _ -> unsupported "Uleb128"
433470
| Direct_assignment _ -> unsupported "Direct_assignment"
434471
| Protected _ -> unsupported "Protected"
472+
| Hidden _ -> unsupported "Hidden"
473+
| Weak _ -> unsupported "Weak"
474+
| External s -> bprintf buf "\tEXTRN\t%s: NEAR" s
475+
(* The only supported "type" on EXTRN declarations i NEAR. *)
476+
| Reloc _ -> unsupported "Reloc"
435477

436478
let print b t =
437479
match TS.assembler () with
@@ -476,6 +518,13 @@ let const_variable var = Variable var
476518

477519
let const_int64 i : expr = Signed_int i
478520

521+
let const_with_offset const (offset : int64) =
522+
if Int64.equal offset 0L
523+
then const
524+
else if Int64.compare offset 0L < 0
525+
then Add (const, Signed_int (Int64.neg offset))
526+
else Add (const, Signed_int offset)
527+
479528
let emit_ref = ref None
480529

481530
let emit (d : Directive.t) =
@@ -488,7 +537,7 @@ let emit_non_masm (d : Directive.t) =
488537

489538
let section ~names ~flags ~args = emit (Section { names; flags; args })
490539

491-
let align ~bytes = emit (Align { bytes })
540+
let align ~data_section ~bytes = emit (Align { bytes; data_section })
492541

493542
let should_generate_cfi () =
494543
(* We generate CFI info even if we're not generating any other debugging
@@ -512,6 +561,14 @@ let cfi_offset ~reg ~offset =
512561

513562
let cfi_startproc () = if should_generate_cfi () then emit Cfi_startproc
514563

564+
let cfi_remember_state () =
565+
if should_generate_cfi () then emit Cfi_remember_state
566+
567+
let cfi_restore_state () = if should_generate_cfi () then emit Cfi_restore_state
568+
569+
let cfi_def_cfa_register ~reg =
570+
if should_generate_cfi () then emit (Cfi_def_cfa_register reg)
571+
515572
let comment text = if emit_comments () then emit (Comment text)
516573

517574
let loc ~file_num ~line ~col ?discriminator () =
@@ -531,8 +588,16 @@ let indirect_symbol symbol = emit (Indirect_symbol (Asm_symbol.encode symbol))
531588

532589
let private_extern symbol = emit (Private_extern (Asm_symbol.encode symbol))
533590

591+
let extrn symbol = emit (External (Asm_symbol.encode symbol))
592+
593+
let hidden symbol = emit (Hidden (Asm_symbol.encode symbol))
594+
595+
let weak symbol = emit (Weak (Asm_symbol.encode symbol))
596+
534597
let size symbol cst = emit (Size (Asm_symbol.encode symbol, lower_expr cst))
535598

599+
let size_const sym n = emit (Size (Asm_symbol.encode sym, Signed_int n))
600+
536601
let type_ symbol ~type_ = emit (Type (symbol, type_))
537602

538603
let sleb128 ?comment i =
@@ -609,7 +674,7 @@ let label ?comment label = const_machine_width ?comment (Label label)
609674
let label_plus_offset ?comment lab ~offset_in_bytes =
610675
let offset_in_bytes = Targetint.to_int64 offset_in_bytes in
611676
let lab = const_label lab in
612-
const_machine_width ?comment (const_add lab (const_int64 offset_in_bytes))
677+
const_machine_width ?comment (const_with_offset lab offset_in_bytes)
613678

614679
let define_label label =
615680
let lbl_section = Asm_label.section label in
@@ -780,7 +845,7 @@ let symbol ?comment sym = const_machine_width ?comment (Symbol sym)
780845

781846
let symbol_plus_offset symbol ~offset_in_bytes =
782847
let offset_in_bytes = Targetint.to_int64 offset_in_bytes in
783-
const_machine_width (Add (Symbol symbol, Signed_int offset_in_bytes))
848+
const_machine_width (const_with_offset (Symbol symbol) offset_in_bytes)
784849

785850
let int8 ?comment i =
786851
const ?comment (Signed_int (Int64.of_int (Int8.to_int i))) Eight
@@ -873,9 +938,11 @@ let between_labels_16_bit ?comment:_ ~upper:_ ~lower:_ () =
873938
(* CR poechsel: use the arguments *)
874939
Misc.fatal_error "between_labels_16_bit not implemented yet"
875940

876-
let between_labels_32_bit ?comment:_ ~upper:_ ~lower:_ () =
877-
(* CR poechsel: use the arguments *)
878-
Misc.fatal_error "between_labels_32_bit not implemented yet"
941+
let between_labels_32_bit ?comment:_comment ~upper ~lower () =
942+
let expr = const_sub (const_label upper) (const_label lower) in
943+
(* CR sspies: Following the x86 implementation, we *do not* force an assembly
944+
time constant here. *)
945+
const expr Thirty_two
879946

880947
let between_labels_64_bit ?comment:_ ~upper:_ ~lower:_ () =
881948
(* CR poechsel: use the arguments *)
@@ -1048,3 +1115,14 @@ let offset_into_dwarf_section_symbol ?comment:_comment
10481115
match width with
10491116
| Thirty_two -> const expr Thirty_two
10501117
| Sixty_four -> const expr Sixty_four
1118+
1119+
let reloc_x86_64_plt32 ~offset_from_this ~target_symbol ~rel_offset_from_next =
1120+
emit
1121+
(Reloc
1122+
{ offset = Sub (This, Signed_int offset_from_this);
1123+
name = R_X86_64_PLT32;
1124+
expr =
1125+
Sub
1126+
( Named_thing (Asm_symbol.encode target_symbol),
1127+
Signed_int rel_offset_from_next )
1128+
})

backend/asm_targets/asm_directives_new.mli

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,21 @@ val cfi_startproc : unit -> unit
145145
(** Mark the end of a function, for CFI purposes. *)
146146
val cfi_endproc : unit -> unit
147147

148+
(** Remember the current state for CFI purposes. *)
149+
val cfi_remember_state : unit -> unit
150+
151+
(** Restore the state for CFI purposes. *)
152+
val cfi_restore_state : unit -> unit
153+
154+
(** Define a CFA register, for CFI purposes. *)
155+
val cfi_def_cfa_register : reg:string -> unit
156+
148157
(** Mark that the call stack is not to be executable at runtime. Not
149158
supported on all platforms. *)
150159
val mark_stack_non_executable : unit -> unit
151160

152161
(** Leave as much space as is required to achieve the given alignment. *)
153-
val align : bytes:int -> unit
162+
val align : data_section:bool -> bytes:int -> unit
154163

155164
(** Emit a directive giving the displacement between the given symbol and
156165
the current position. This should only be used to state sizes of
@@ -159,6 +168,8 @@ val align : bytes:int -> unit
159168
from that whose size is being stated (e.g. on POWER with ELF ABI v1). *)
160169
val size : ?size_of:Asm_symbol.t -> Asm_symbol.t -> unit
161170

171+
val size_const : Asm_symbol.t -> int64 -> unit
172+
162173
(** Leave a gap in the object file. *)
163174
val space : bytes:int -> unit
164175

@@ -188,6 +199,15 @@ val protected : Asm_symbol.t -> unit
188199
details). *)
189200
val private_extern : Asm_symbol.t -> unit
190201

202+
(** Mark an already encoded symbol as external. *)
203+
val extrn : Asm_symbol.t -> unit
204+
205+
(** Mark an already encoded symbol or label as hidden. *)
206+
val hidden : Asm_symbol.t -> unit
207+
208+
(** Mark an already encoded symbol or label as weak. *)
209+
val weak : Asm_symbol.t -> unit
210+
191211
(** Marker inside the definition of a lazy symbol stub (see platform or
192212
assembler documentation for details). *)
193213
val indirect_symbol : Asm_symbol.t -> unit
@@ -297,6 +317,12 @@ val offset_into_dwarf_section_symbol :
297317
Asm_symbol.t ->
298318
unit
299319

320+
val reloc_x86_64_plt32 :
321+
offset_from_this:int64 ->
322+
target_symbol:Asm_symbol.t ->
323+
rel_offset_from_next:int64 ->
324+
unit
325+
300326
module Directive : sig
301327
module Constant : sig
302328
(* CR sspies: make this private again once the first-class module has been
@@ -345,6 +371,10 @@ module Directive : sig
345371
removed *)
346372
type comment = string
347373

374+
(* ELF specific *)
375+
type reloc_type = R_X86_64_PLT32
376+
(* X86 only *)
377+
348378
(* CR sspies: make this private again once the first-class module has been
349379
removed *)
350380

@@ -354,7 +384,14 @@ module Directive : sig
354384
have had all necessary prefixing, mangling, escaping and suffixing
355385
applied. *)
356386
type t =
357-
| Align of { bytes : int }
387+
| Align of
388+
{ bytes : int;
389+
(** The number of bytes to align to. This will be taken log2 by the emitter on
390+
Arm and macOS platforms.*)
391+
data_section : bool
392+
(** The data_section flag controls whether the binary emitter emits NOP instructions
393+
or null bytes. *)
394+
}
358395
| Bytes of
359396
{ str : string;
360397
comment : string option
@@ -367,6 +404,9 @@ module Directive : sig
367404
offset : int
368405
}
369406
| Cfi_startproc
407+
| Cfi_remember_state
408+
| Cfi_restore_state
409+
| Cfi_def_cfa_register of string
370410
| Comment of comment
371411
| Const of
372412
{ constant : Constant_with_width.t;
@@ -405,6 +445,14 @@ module Directive : sig
405445
comment : string option
406446
}
407447
| Protected of string
448+
| Hidden of string
449+
| Weak of string
450+
| External of string
451+
| Reloc of
452+
{ offset : Constant.t;
453+
name : reloc_type;
454+
expr : Constant.t
455+
}
408456

409457
(** Translate the given directive to textual form. This produces output
410458
suitable for either gas or MASM as appropriate. *)

0 commit comments

Comments
 (0)