@@ -150,10 +150,15 @@ module Directive = struct
150
150
| Code
151
151
| Machine_width_data
152
152
153
+ type reloc_type = R_X86_64_PLT32
154
+
153
155
type comment = string
154
156
155
157
type t =
156
- | Align of { bytes : int }
158
+ | Align of
159
+ { bytes : int ;
160
+ data_section : bool
161
+ }
157
162
| Bytes of
158
163
{ str : string ;
159
164
comment : string option
@@ -166,6 +171,9 @@ module Directive = struct
166
171
offset : int
167
172
}
168
173
| Cfi_startproc
174
+ | Cfi_remember_state
175
+ | Cfi_restore_state
176
+ | Cfi_def_cfa_register of string
169
177
| Comment of comment
170
178
| Const of
171
179
{ constant : Constant_with_width .t ;
@@ -204,6 +212,14 @@ module Directive = struct
204
212
comment : string option
205
213
}
206
214
| 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
+ }
207
223
208
224
let bprintf = Printf. bprintf
209
225
@@ -268,6 +284,8 @@ module Directive = struct
268
284
bprintf buf " \t .ascii\t\" %s\" "
269
285
(string_of_string_literal (String. sub s ! i (l - ! i)))
270
286
287
+ let reloc_type_to_string = function R_X86_64_PLT32 -> " R_X86_64_PLT32"
288
+
271
289
let print_gas buf t =
272
290
let gas_comment_opt comment_opt =
273
291
if not (emit_comments () )
@@ -278,7 +296,9 @@ module Directive = struct
278
296
| Some comment -> Printf. sprintf " \t /* %s */" comment
279
297
in
280
298
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. *)
282
302
(* Some assemblers interpret the integer n as a 2^n alignment and others
283
303
as a number of bytes. *)
284
304
let n =
@@ -333,6 +353,9 @@ module Directive = struct
333
353
| Cfi_offset { reg; offset } ->
334
354
bprintf buf " \t .cfi_offset %d, %d" reg offset
335
355
| 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
336
359
| File { file_num = None ; filename } ->
337
360
bprintf buf " \t .file\t\" %s\" " filename
338
361
| File { file_num = Some file_num ; filename } ->
@@ -375,6 +398,14 @@ module Directive = struct
375
398
Misc. fatal_error
376
399
" Cannot emit [Direct_assignment] except on macOS-like assemblers" )
377
400
| 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
378
409
379
410
let print_masm buf t =
380
411
let unsupported name =
@@ -389,7 +420,10 @@ module Directive = struct
389
420
| Some comment -> Printf. sprintf " \t ; %s" comment
390
421
in
391
422
match t with
392
- | Align { bytes } -> bprintf buf " \t ALIGN\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 " \t ALIGN\t %d" bytes
393
427
| Bytes { str; comment } ->
394
428
buf_bytes_directive buf ~directive: " BYTE" str;
395
429
bprintf buf " %s" (masm_comment_opt comment)
@@ -422,6 +456,9 @@ module Directive = struct
422
456
| Cfi_endproc -> unsupported " Cfi_endproc"
423
457
| Cfi_offset _ -> unsupported " Cfi_offset"
424
458
| 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"
425
462
| File _ -> unsupported " File"
426
463
| Indirect_symbol _ -> unsupported " Indirect_symbol"
427
464
| Loc _ -> unsupported " Loc"
@@ -432,6 +469,11 @@ module Directive = struct
432
469
| Uleb128 _ -> unsupported " Uleb128"
433
470
| Direct_assignment _ -> unsupported " Direct_assignment"
434
471
| Protected _ -> unsupported " Protected"
472
+ | Hidden _ -> unsupported " Hidden"
473
+ | Weak _ -> unsupported " Weak"
474
+ | External s -> bprintf buf " \t EXTRN\t %s: NEAR" s
475
+ (* The only supported "type" on EXTRN declarations i NEAR. *)
476
+ | Reloc _ -> unsupported " Reloc"
435
477
436
478
let print b t =
437
479
match TS. assembler () with
@@ -476,6 +518,13 @@ let const_variable var = Variable var
476
518
477
519
let const_int64 i : expr = Signed_int i
478
520
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
+
479
528
let emit_ref = ref None
480
529
481
530
let emit (d : Directive.t ) =
@@ -488,7 +537,7 @@ let emit_non_masm (d : Directive.t) =
488
537
489
538
let section ~names ~flags ~args = emit (Section { names; flags; args })
490
539
491
- let align ~bytes = emit (Align { bytes })
540
+ let align ~data_section ~ bytes = emit (Align { bytes; data_section })
492
541
493
542
let should_generate_cfi () =
494
543
(* We generate CFI info even if we're not generating any other debugging
@@ -512,6 +561,14 @@ let cfi_offset ~reg ~offset =
512
561
513
562
let cfi_startproc () = if should_generate_cfi () then emit Cfi_startproc
514
563
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
+
515
572
let comment text = if emit_comments () then emit (Comment text)
516
573
517
574
let loc ~file_num ~line ~col ?discriminator () =
@@ -531,8 +588,16 @@ let indirect_symbol symbol = emit (Indirect_symbol (Asm_symbol.encode symbol))
531
588
532
589
let private_extern symbol = emit (Private_extern (Asm_symbol. encode symbol))
533
590
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
+
534
597
let size symbol cst = emit (Size (Asm_symbol. encode symbol, lower_expr cst))
535
598
599
+ let size_const sym n = emit (Size (Asm_symbol. encode sym, Signed_int n))
600
+
536
601
let type_ symbol ~type_ = emit (Type (symbol, type_))
537
602
538
603
let sleb128 ?comment i =
@@ -609,7 +674,7 @@ let label ?comment label = const_machine_width ?comment (Label label)
609
674
let label_plus_offset ?comment lab ~offset_in_bytes =
610
675
let offset_in_bytes = Targetint. to_int64 offset_in_bytes in
611
676
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)
613
678
614
679
let define_label label =
615
680
let lbl_section = Asm_label. section label in
@@ -780,7 +845,7 @@ let symbol ?comment sym = const_machine_width ?comment (Symbol sym)
780
845
781
846
let symbol_plus_offset symbol ~offset_in_bytes =
782
847
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)
784
849
785
850
let int8 ?comment i =
786
851
const ?comment (Signed_int (Int64. of_int (Int8. to_int i))) Eight
@@ -873,9 +938,11 @@ let between_labels_16_bit ?comment:_ ~upper:_ ~lower:_ () =
873
938
(* CR poechsel: use the arguments *)
874
939
Misc. fatal_error " between_labels_16_bit not implemented yet"
875
940
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
879
946
880
947
let between_labels_64_bit ?comment :_ ~upper:_ ~lower:_ () =
881
948
(* CR poechsel: use the arguments *)
@@ -1048,3 +1115,14 @@ let offset_into_dwarf_section_symbol ?comment:_comment
1048
1115
match width with
1049
1116
| Thirty_two -> const expr Thirty_two
1050
1117
| 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
+ })
0 commit comments