@@ -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
@@ -207,6 +212,14 @@ module Directive = struct
207
212
comment : string option
208
213
}
209
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
+ }
210
223
211
224
let bprintf = Printf. bprintf
212
225
@@ -271,6 +284,8 @@ module Directive = struct
271
284
bprintf buf " \t .ascii\t\" %s\" "
272
285
(string_of_string_literal (String. sub s ! i (l - ! i)))
273
286
287
+ let reloc_type_to_string = function R_X86_64_PLT32 -> " R_X86_64_PLT32"
288
+
274
289
let print_gas buf t =
275
290
let gas_comment_opt comment_opt =
276
291
if not (emit_comments () )
@@ -281,7 +296,9 @@ module Directive = struct
281
296
| Some comment -> Printf. sprintf " \t /* %s */" comment
282
297
in
283
298
match t with
284
- | 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. *)
285
302
(* Some assemblers interpret the integer n as a 2^n alignment and others
286
303
as a number of bytes. *)
287
304
let n =
@@ -381,6 +398,14 @@ module Directive = struct
381
398
Misc. fatal_error
382
399
" Cannot emit [Direct_assignment] except on macOS-like assemblers" )
383
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
384
409
385
410
let print_masm buf t =
386
411
let unsupported name =
@@ -395,7 +420,10 @@ module Directive = struct
395
420
| Some comment -> Printf. sprintf " \t ; %s" comment
396
421
in
397
422
match t with
398
- | 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
399
427
| Bytes { str; comment } ->
400
428
buf_bytes_directive buf ~directive: " BYTE" str;
401
429
bprintf buf " %s" (masm_comment_opt comment)
@@ -441,6 +469,11 @@ module Directive = struct
441
469
| Uleb128 _ -> unsupported " Uleb128"
442
470
| Direct_assignment _ -> unsupported " Direct_assignment"
443
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"
444
477
445
478
let print b t =
446
479
match TS. assembler () with
@@ -485,6 +518,13 @@ let const_variable var = Variable var
485
518
486
519
let const_int64 i : expr = Signed_int i
487
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
+
488
528
let emit_ref = ref None
489
529
490
530
let emit (d : Directive.t ) =
@@ -497,7 +537,7 @@ let emit_non_masm (d : Directive.t) =
497
537
498
538
let section ~names ~flags ~args = emit (Section { names; flags; args })
499
539
500
- let align ~bytes = emit (Align { bytes })
540
+ let align ~data_section ~ bytes = emit (Align { bytes; data_section })
501
541
502
542
let should_generate_cfi () =
503
543
(* We generate CFI info even if we're not generating any other debugging
@@ -548,8 +588,16 @@ let indirect_symbol symbol = emit (Indirect_symbol (Asm_symbol.encode symbol))
548
588
549
589
let private_extern symbol = emit (Private_extern (Asm_symbol. encode symbol))
550
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
+
551
597
let size symbol cst = emit (Size (Asm_symbol. encode symbol, lower_expr cst))
552
598
599
+ let size_const sym n = emit (Size (Asm_symbol. encode sym, Signed_int n))
600
+
553
601
let type_ symbol ~type_ = emit (Type (symbol, type_))
554
602
555
603
let sleb128 ?comment i =
@@ -626,7 +674,7 @@ let label ?comment label = const_machine_width ?comment (Label label)
626
674
let label_plus_offset ?comment lab ~offset_in_bytes =
627
675
let offset_in_bytes = Targetint. to_int64 offset_in_bytes in
628
676
let lab = const_label lab in
629
- const_machine_width ?comment (const_add lab (const_int64 offset_in_bytes) )
677
+ const_machine_width ?comment (const_with_offset lab offset_in_bytes)
630
678
631
679
let define_label label =
632
680
let lbl_section = Asm_label. section label in
@@ -797,7 +845,7 @@ let symbol ?comment sym = const_machine_width ?comment (Symbol sym)
797
845
798
846
let symbol_plus_offset symbol ~offset_in_bytes =
799
847
let offset_in_bytes = Targetint. to_int64 offset_in_bytes in
800
- const_machine_width (Add (Symbol symbol, Signed_int offset_in_bytes) )
848
+ const_machine_width (const_with_offset (Symbol symbol) offset_in_bytes)
801
849
802
850
let int8 ?comment i =
803
851
const ?comment (Signed_int (Int64. of_int (Int8. to_int i))) Eight
@@ -890,9 +938,11 @@ let between_labels_16_bit ?comment:_ ~upper:_ ~lower:_ () =
890
938
(* CR poechsel: use the arguments *)
891
939
Misc. fatal_error " between_labels_16_bit not implemented yet"
892
940
893
- let between_labels_32_bit ?comment :_ ~upper:_ ~lower:_ () =
894
- (* CR poechsel: use the arguments *)
895
- 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
896
946
897
947
let between_labels_64_bit ?comment :_ ~upper:_ ~lower:_ () =
898
948
(* CR poechsel: use the arguments *)
@@ -1065,3 +1115,14 @@ let offset_into_dwarf_section_symbol ?comment:_comment
1065
1115
match width with
1066
1116
| Thirty_two -> const expr Thirty_two
1067
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