@@ -145,10 +145,15 @@ module Directive = struct
145
145
| Code
146
146
| Machine_width_data
147
147
148
+ type reloc_type = R_X86_64_PLT32
149
+
148
150
type comment = string
149
151
150
152
type t =
151
- | Align of { bytes : int }
153
+ | Align of
154
+ { bytes : int ;
155
+ data_section : bool
156
+ }
152
157
| Bytes of
153
158
{ str : string ;
154
159
comment : string option
@@ -202,6 +207,14 @@ module Directive = struct
202
207
comment : string option
203
208
}
204
209
| Protected of string
210
+ | Hidden of string
211
+ | Weak of string
212
+ | External of string
213
+ | Reloc of
214
+ { offset : Constant .t ;
215
+ name : reloc_type ;
216
+ expr : Constant .t
217
+ }
205
218
206
219
let bprintf = Printf. bprintf
207
220
@@ -266,6 +279,8 @@ module Directive = struct
266
279
bprintf buf " \t .ascii\t\" %s\" "
267
280
(string_of_string_literal (String. sub s ! i (l - ! i)))
268
281
282
+ let reloc_type_to_string = function R_X86_64_PLT32 -> " R_X86_64_PLT32"
283
+
269
284
let print_gas buf t =
270
285
let gas_comment_opt comment_opt =
271
286
if not (emit_comments () )
@@ -276,7 +291,9 @@ module Directive = struct
276
291
| Some comment -> Printf. sprintf " \t /* %s */" comment
277
292
in
278
293
match t with
279
- | Align { bytes = n } ->
294
+ | Align { bytes = n ; data_section = _ } ->
295
+ (* The data_section is only relevant for the binary emitter. On GAS, we
296
+ can ignore it and just use [.align] in both cases. *)
280
297
(* Some assemblers interpret the integer n as a 2^n alignment and others
281
298
as a number of bytes. *)
282
299
let n =
@@ -376,6 +393,14 @@ module Directive = struct
376
393
Misc. fatal_error
377
394
" Cannot emit [Direct_assignment] except on macOS-like assemblers" )
378
395
| Protected s -> bprintf buf " \t .protected\t %s" s
396
+ | Hidden s -> bprintf buf " \t .hidden\t %s" s
397
+ | Weak s -> bprintf buf " \t .weak\t %s" s
398
+ (* masm only *)
399
+ | External _ -> assert false
400
+ | Reloc { offset; name; expr } ->
401
+ bprintf buf " \t .reloc\t %a, %s, %a" Constant. print offset
402
+ (reloc_type_to_string name)
403
+ Constant. print expr
379
404
380
405
let print_masm buf t =
381
406
let unsupported name =
@@ -390,7 +415,10 @@ module Directive = struct
390
415
| Some comment -> Printf. sprintf " \t ; %s" comment
391
416
in
392
417
match t with
393
- | Align { bytes } -> bprintf buf " \t ALIGN\t %d" bytes
418
+ | Align { bytes; data_section = _ } ->
419
+ (* The data_section is only relevant for the binary emitter. On MASM, we
420
+ can ignore it. *)
421
+ bprintf buf " \t ALIGN\t %d" bytes
394
422
| Bytes { str; comment } ->
395
423
buf_bytes_directive buf ~directive: " BYTE" str;
396
424
bprintf buf " %s" (masm_comment_opt comment)
@@ -436,6 +464,11 @@ module Directive = struct
436
464
| Uleb128 _ -> unsupported " Uleb128"
437
465
| Direct_assignment _ -> unsupported " Direct_assignment"
438
466
| Protected _ -> unsupported " Protected"
467
+ | Hidden _ -> unsupported " Hidden"
468
+ | Weak _ -> unsupported " Weak"
469
+ | External s -> bprintf buf " \t EXTRN\t %s: NEAR" s
470
+ (* The only supported "type" on EXTRN declarations i NEAR. *)
471
+ | Reloc _ -> unsupported " Reloc"
439
472
440
473
let print b t =
441
474
match TS. assembler () with
@@ -480,6 +513,13 @@ let const_variable var = Variable var
480
513
481
514
let const_int64 i : expr = Signed_int i
482
515
516
+ let const_with_offset const (offset : int64 ) =
517
+ if Int64. equal offset 0L
518
+ then const
519
+ else if Int64. compare offset 0L < 0
520
+ then Add (const, Signed_int (Int64. neg offset))
521
+ else Add (const, Signed_int offset)
522
+
483
523
let emit_ref = ref None
484
524
485
525
let emit (d : Directive.t ) =
@@ -492,7 +532,7 @@ let emit_non_masm (d : Directive.t) =
492
532
493
533
let section ~names ~flags ~args = emit (Section { names; flags; args })
494
534
495
- let align ~bytes = emit (Align { bytes })
535
+ let align ~data_section ~ bytes = emit (Align { bytes; data_section })
496
536
497
537
let should_generate_cfi () =
498
538
(* We generate CFI info even if we're not generating any other debugging
@@ -543,8 +583,16 @@ let indirect_symbol symbol = emit (Indirect_symbol (Asm_symbol.encode symbol))
543
583
544
584
let private_extern symbol = emit (Private_extern (Asm_symbol. encode symbol))
545
585
586
+ let extrn symbol = emit (External (Asm_symbol. encode symbol))
587
+
588
+ let hidden symbol = emit (Hidden (Asm_symbol. encode symbol))
589
+
590
+ let weak symbol = emit (Weak (Asm_symbol. encode symbol))
591
+
546
592
let size symbol cst = emit (Size (Asm_symbol. encode symbol, lower_expr cst))
547
593
594
+ let size_const sym n = emit (Size (Asm_symbol. encode sym, Signed_int n))
595
+
548
596
let type_ symbol ~type_ = emit (Type (symbol, type_))
549
597
550
598
let sleb128 ?comment i =
@@ -621,7 +669,7 @@ let label ?comment label = const_machine_width ?comment (Label label)
621
669
let label_plus_offset ?comment lab ~offset_in_bytes =
622
670
let offset_in_bytes = Targetint. to_int64 offset_in_bytes in
623
671
let lab = const_label lab in
624
- const_machine_width ?comment (const_add lab (const_int64 offset_in_bytes) )
672
+ const_machine_width ?comment (const_with_offset lab offset_in_bytes)
625
673
626
674
let define_label label =
627
675
let lbl_section = Asm_label. section label in
@@ -793,7 +841,7 @@ let symbol ?comment sym = const_machine_width ?comment (Symbol sym)
793
841
794
842
let symbol_plus_offset symbol ~offset_in_bytes =
795
843
let offset_in_bytes = Targetint. to_int64 offset_in_bytes in
796
- const_machine_width (Add (Symbol symbol, Signed_int offset_in_bytes) )
844
+ const_machine_width (const_with_offset (Symbol symbol) offset_in_bytes)
797
845
798
846
let int8 ?comment i =
799
847
const ?comment (Signed_int (Int64. of_int (Int8. to_int i))) Eight
@@ -884,9 +932,11 @@ let between_labels_16_bit ?comment:_ ~upper:_ ~lower:_ () =
884
932
(* CR poechsel: use the arguments *)
885
933
Misc. fatal_error " between_labels_16_bit not implemented yet"
886
934
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"
935
+ let between_labels_32_bit ?comment :_comment ~upper ~lower () =
936
+ let expr = const_sub (const_label upper) (const_label lower) in
937
+ (* CR sspies: Following the x86 implementation, we *do not* force an assembly
938
+ time constant here. *)
939
+ const expr Thirty_two
890
940
891
941
let between_labels_64_bit ?comment :_ ~upper:_ ~lower:_ () =
892
942
(* CR poechsel: use the arguments *)
@@ -1059,3 +1109,14 @@ let offset_into_dwarf_section_symbol ?comment:_comment
1059
1109
match width with
1060
1110
| Thirty_two -> const expr Thirty_two
1061
1111
| Sixty_four -> const expr Sixty_four
1112
+
1113
+ let reloc_x86_64_plt32 ~offset_from_this ~target_symbol ~rel_offset_from_next =
1114
+ emit
1115
+ (Reloc
1116
+ { offset = Sub (This , Signed_int offset_from_this);
1117
+ name = R_X86_64_PLT32 ;
1118
+ expr =
1119
+ Sub
1120
+ ( Named_thing (Asm_symbol. encode target_symbol),
1121
+ Signed_int rel_offset_from_next )
1122
+ })
0 commit comments