@@ -60,6 +60,10 @@ type symbol_type =
60
60
| Function
61
61
| Object
62
62
63
+ type align_padding =
64
+ | Nop
65
+ | Zero
66
+
63
67
(* CR sspies: We should use the "STT" forms when they are supported as they are
64
68
unambiguous across platforms (cf.
65
69
https://sourceware.org/binutils/docs/as/Type.html). *)
@@ -145,10 +149,15 @@ module Directive = struct
145
149
| Code
146
150
| Machine_width_data
147
151
152
+ type reloc_type = R_X86_64_PLT32
153
+
148
154
type comment = string
149
155
150
156
type t =
151
- | Align of { bytes : int }
157
+ | Align of
158
+ { bytes : int ;
159
+ fill_x86_bin_emitter : align_padding
160
+ }
152
161
| Bytes of
153
162
{ str : string ;
154
163
comment : string option
@@ -202,6 +211,14 @@ module Directive = struct
202
211
comment : string option
203
212
}
204
213
| Protected of string
214
+ | Hidden of string
215
+ | Weak of string
216
+ | External of string
217
+ | Reloc of
218
+ { offset : Constant .t ;
219
+ name : reloc_type ;
220
+ expr : Constant .t
221
+ }
205
222
206
223
let bprintf = Printf. bprintf
207
224
@@ -266,6 +283,8 @@ module Directive = struct
266
283
bprintf buf " \t .ascii\t\" %s\" "
267
284
(string_of_string_literal (String. sub s ! i (l - ! i)))
268
285
286
+ let reloc_type_to_string = function R_X86_64_PLT32 -> " R_X86_64_PLT32"
287
+
269
288
let print_gas buf t =
270
289
let gas_comment_opt comment_opt =
271
290
if not (emit_comments () )
@@ -276,7 +295,10 @@ module Directive = struct
276
295
| Some comment -> Printf. sprintf " \t /* %s */" comment
277
296
in
278
297
match t with
279
- | Align { bytes = n } ->
298
+ | Align { bytes = n ; fill_x86_bin_emitter = _ } ->
299
+ (* The flag [fill_x86_bin_emitter] is only relevant for the binary
300
+ emitter. On GAS, we can ignore it and just use [.align] in both
301
+ cases. *)
280
302
(* Some assemblers interpret the integer n as a 2^n alignment and others
281
303
as a number of bytes. *)
282
304
let n =
@@ -376,6 +398,14 @@ module Directive = struct
376
398
Misc. fatal_error
377
399
" Cannot emit [Direct_assignment] except on macOS-like assemblers" )
378
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
379
409
380
410
let print_masm buf t =
381
411
let unsupported name =
@@ -390,7 +420,10 @@ module Directive = struct
390
420
| Some comment -> Printf. sprintf " \t ; %s" comment
391
421
in
392
422
match t with
393
- | Align { bytes } -> bprintf buf " \t ALIGN\t %d" bytes
423
+ | Align { bytes; fill_x86_bin_emitter = _ } ->
424
+ (* The flag [fill_x86_bin_emitter] is only relevant for the x86 binary
425
+ emitter. On MASM, we can ignore it. *)
426
+ bprintf buf " \t ALIGN\t %d" bytes
394
427
| Bytes { str; comment } ->
395
428
buf_bytes_directive buf ~directive: " BYTE" str;
396
429
bprintf buf " %s" (masm_comment_opt comment)
@@ -436,6 +469,11 @@ module Directive = struct
436
469
| Uleb128 _ -> unsupported " Uleb128"
437
470
| Direct_assignment _ -> unsupported " Direct_assignment"
438
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 is NEAR. *)
476
+ | Reloc _ -> unsupported " Reloc"
439
477
440
478
let print b t =
441
479
match TS. assembler () with
@@ -480,6 +518,13 @@ let const_variable var = Variable var
480
518
481
519
let const_int64 i : expr = Signed_int i
482
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 Sub (const, Signed_int (Int64. neg offset))
526
+ else Add (const, Signed_int offset)
527
+
483
528
let emit_ref = ref None
484
529
485
530
let emit (d : Directive.t ) =
@@ -492,7 +537,8 @@ let emit_non_masm (d : Directive.t) =
492
537
493
538
let section ~names ~flags ~args = emit (Section { names; flags; args })
494
539
495
- let align ~bytes = emit (Align { bytes })
540
+ let align ~fill_x86_bin_emitter ~bytes =
541
+ emit (Align { bytes; fill_x86_bin_emitter })
496
542
497
543
let should_generate_cfi () =
498
544
(* We generate CFI info even if we're not generating any other debugging
@@ -543,8 +589,16 @@ let indirect_symbol symbol = emit (Indirect_symbol (Asm_symbol.encode symbol))
543
589
544
590
let private_extern symbol = emit (Private_extern (Asm_symbol. encode symbol))
545
591
592
+ let extrn symbol = emit (External (Asm_symbol. encode symbol))
593
+
594
+ let hidden symbol = emit (Hidden (Asm_symbol. encode symbol))
595
+
596
+ let weak symbol = emit (Weak (Asm_symbol. encode symbol))
597
+
546
598
let size symbol cst = emit (Size (Asm_symbol. encode symbol, lower_expr cst))
547
599
600
+ let size_const sym n = emit (Size (Asm_symbol. encode sym, Signed_int n))
601
+
548
602
let type_ symbol ~type_ = emit (Type (symbol, type_))
549
603
550
604
let sleb128 ?comment i =
@@ -621,7 +675,7 @@ let label ?comment label = const_machine_width ?comment (Label label)
621
675
let label_plus_offset ?comment lab ~offset_in_bytes =
622
676
let offset_in_bytes = Targetint. to_int64 offset_in_bytes in
623
677
let lab = const_label lab in
624
- const_machine_width ?comment (const_add lab (const_int64 offset_in_bytes) )
678
+ const_machine_width ?comment (const_with_offset lab offset_in_bytes)
625
679
626
680
let define_label label =
627
681
let lbl_section = Asm_label. section label in
@@ -793,7 +847,7 @@ let symbol ?comment sym = const_machine_width ?comment (Symbol sym)
793
847
794
848
let symbol_plus_offset symbol ~offset_in_bytes =
795
849
let offset_in_bytes = Targetint. to_int64 offset_in_bytes in
796
- const_machine_width (Add (Symbol symbol, Signed_int offset_in_bytes) )
850
+ const_machine_width (const_with_offset (Symbol symbol) offset_in_bytes)
797
851
798
852
let int8 ?comment i =
799
853
const ?comment (Signed_int (Int64. of_int (Int8. to_int i))) Eight
@@ -884,9 +938,14 @@ let between_labels_16_bit ?comment:_ ~upper:_ ~lower:_ () =
884
938
(* CR poechsel: use the arguments *)
885
939
Misc. fatal_error " between_labels_16_bit not implemented yet"
886
940
887
- let between_labels_32_bit ?comment :_ ~upper:_ ~lower:_ () =
888
- (* CR poechsel: use the arguments *)
889
- 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: Unlike in most of the other distance computation functions in
944
+ this file, we do not force an assembly time constant in this function. This
945
+ is to follow the existing/previous implementation of the x86 backend. In
946
+ the future, we should investigate whether it would be more appropriate to
947
+ force an assembly time constant. *)
948
+ const expr Thirty_two
890
949
891
950
let between_labels_64_bit ?comment :_ ~upper:_ ~lower:_ () =
892
951
(* CR poechsel: use the arguments *)
@@ -1059,3 +1118,14 @@ let offset_into_dwarf_section_symbol ?comment:_comment
1059
1118
match width with
1060
1119
| Thirty_two -> const expr Thirty_two
1061
1120
| Sixty_four -> const expr Sixty_four
1121
+
1122
+ let reloc_x86_64_plt32 ~offset_from_this ~target_symbol ~rel_offset_from_next =
1123
+ emit
1124
+ (Reloc
1125
+ { offset = Sub (This , Signed_int offset_from_this);
1126
+ name = R_X86_64_PLT32 ;
1127
+ expr =
1128
+ Sub
1129
+ ( Named_thing (Asm_symbol. encode target_symbol),
1130
+ Signed_int rel_offset_from_next )
1131
+ })
0 commit comments