@@ -86,38 +86,41 @@ module Directive = struct
86
86
| Add of t * t
87
87
| Sub of t * t
88
88
89
- (* The [force_digits ] option is for supporting .sleb128 directives. See the
89
+ (* The [force_decimal ] option is for supporting .sleb128 directives. See the
90
90
comment in [print] below. *)
91
- let rec print ~ force_digits buf t =
91
+ let rec print_aux ~ force_decimal buf t =
92
92
match t with
93
93
| (Named_thing _ | Signed_int _ | Unsigned_int _ | This ) as c ->
94
- print_subterm ~force_digits buf c
94
+ print_aux_subterm ~force_decimal buf c
95
95
| Add (c1 , c2 ) ->
96
96
bprintf buf " %a + %a"
97
- (print_subterm ~force_digits )
97
+ (print_aux_subterm ~force_decimal )
98
98
c1
99
- (print_subterm ~force_digits )
99
+ (print_aux_subterm ~force_decimal )
100
100
c2
101
101
| Sub (c1 , c2 ) ->
102
102
bprintf buf " %a - %a"
103
- (print_subterm ~force_digits )
103
+ (print_aux_subterm ~force_decimal )
104
104
c1
105
- (print_subterm ~force_digits )
105
+ (print_aux_subterm ~force_decimal )
106
106
c2
107
107
108
- and print_subterm ~ force_digits buf t =
108
+ and print_aux_subterm ~ force_decimal buf t =
109
109
match t with
110
110
| This -> (
111
111
match TS. assembler () with
112
112
| MacOS | GAS_like -> Buffer. add_string buf " ."
113
113
| MASM -> Buffer. add_string buf " THIS BYTE" )
114
114
| Named_thing name -> Buffer. add_string buf name
115
115
| Signed_int n -> (
116
- match TS. assembler () , force_digits with
116
+ match TS. assembler () , force_decimal with
117
117
| _ , true -> Buffer. add_string buf (Int64. to_string n)
118
118
| MASM , _ ->
119
119
if Int64. compare n 0x7FFF_FFFFL < = 0
120
120
&& Int64. compare n (- 0x8000_0000L ) > = 0
121
+ (* This constant was changed from 0x8000_0000L (in the original
122
+ code for these directives) to -0x8000_0000L, matching what we do
123
+ for GAS below. See #3948. *)
121
124
then Buffer. add_string buf (Int64. to_string n)
122
125
else bprintf buf " 0%LxH" n
123
126
| _ , false ->
@@ -128,19 +131,23 @@ module Directive = struct
128
131
| Unsigned_int n ->
129
132
(* We can use the printer for [Signed_int] since we always print as an
130
133
unsigned hex representation. *)
131
- print_subterm ~force_digits buf (Signed_int (Uint64. to_int64 n))
134
+ print_aux_subterm ~force_decimal buf (Signed_int (Uint64. to_int64 n))
132
135
| Add (c1 , c2 ) ->
133
136
bprintf buf " (%a + %a)"
134
- (print_subterm ~force_digits )
137
+ (print_aux_subterm ~force_decimal )
135
138
c1
136
- (print_subterm ~force_digits )
139
+ (print_aux_subterm ~force_decimal )
137
140
c2
138
141
| Sub (c1 , c2 ) ->
139
142
bprintf buf " (%a - %a)"
140
- (print_subterm ~force_digits )
143
+ (print_aux_subterm ~force_decimal )
141
144
c1
142
- (print_subterm ~force_digits )
145
+ (print_aux_subterm ~force_decimal )
143
146
c2
147
+
148
+ let print = print_aux ~force_decimal: false
149
+
150
+ let print_using_decimals = print_aux ~force_decimal: true
144
151
end
145
152
146
153
module Constant_with_width = struct
@@ -251,6 +258,14 @@ module Directive = struct
251
258
let between x low high =
252
259
Char. compare x low > = 0 && Char. compare x high < = 0
253
260
in
261
+ if k + n > String. length s
262
+ then
263
+ Misc. fatal_errorf
264
+ " Attempting to extract a substring that is too long: range %d..<%d \
265
+ goes beyond the string %S of length %d."
266
+ k (k + n) s (String. length s);
267
+ if n < 0 || k < 0
268
+ then Misc. fatal_errorf " Negative substring length %d or start index %d" n k;
254
269
let b = Buffer. create (n + 2 ) in
255
270
let last_was_escape = ref false in
256
271
for i = k to k + n - 1 do
@@ -349,19 +364,18 @@ module Directive = struct
349
364
| Sixty_four -> " 8byte"
350
365
in
351
366
let comment = gas_comment_opt comment in
352
- bprintf buf " \t .%s\t %a%s" directive
353
- (Constant. print ~force_digits: false )
367
+ bprintf buf " \t .%s\t %a%s" directive Constant. print
354
368
(Constant_with_width. constant constant)
355
369
comment
356
370
| Bytes { str; comment } ->
357
371
(match TS. system () , TS. architecture () with
358
372
| Solaris , _ | _ , POWER ->
359
373
buf_bytes_directive buf ~directive: " .byte" str
360
- (* Very long lines can cause gas to be extremely slow so split up large
374
+ (* Very long lines can cause gas to be extremely slow, so split up large
361
375
string literals. It turns out that gas reads files in 32kb chunks so
362
376
splitting the string into blocks of 25k characters should be close to
363
377
the sweet spot even with a lot of escapes. *)
364
- | _ , X86_64 -> print_ascii_string_gas ~chunk_size: 25000 buf str
378
+ | _ , X86_64 -> print_ascii_string_gas ~chunk_size: 25_000 buf str
365
379
| _ , AArch64 -> print_ascii_string_gas ~chunk_size: 80 buf str
366
380
| _ , _ -> print_ascii_string_gas ~chunk_size: 80 buf str);
367
381
bprintf buf " %s" (gas_comment_opt comment)
@@ -412,16 +426,15 @@ module Directive = struct
412
426
print_discriminator discriminator
413
427
| Private_extern s -> bprintf buf " \t .private_extern %s" s
414
428
| Size (s , c ) ->
415
- bprintf buf " \t .size %s,%a" s ( Constant. print ~force_digits: false ) c
429
+ bprintf buf " \t .size %s,%a" s Constant. print c
416
430
(* We use %Ld and not %Lx on Unix-like platforms to ensure that ".sleb128"
417
431
directives do not end up with hex arguments (since this denotes a
418
432
variable-length encoding it would not be clear where the sign bit
419
433
is). *)
420
434
| Sleb128 { constant; comment } ->
421
435
let comment = gas_comment_opt comment in
422
- bprintf buf " \t .sleb128\t %a%s"
423
- (Constant. print ~force_digits: true )
424
- constant comment
436
+ bprintf buf " \t .sleb128\t %a%s" Constant. print_using_decimals constant
437
+ comment
425
438
| Type (s , typ ) ->
426
439
let typ = symbol_type_to_string typ in
427
440
(* CR sspies: Technically, ",STT_OBJECT" violates the assembler syntax
@@ -431,15 +444,11 @@ module Directive = struct
431
444
bprintf buf " \t .type %s,%s" s typ
432
445
| Uleb128 { constant; comment } ->
433
446
let comment = gas_comment_opt comment in
434
- bprintf buf " \t .uleb128\t %a%s"
435
- (Constant. print ~force_digits: true )
436
- constant comment
447
+ bprintf buf " \t .uleb128\t %a%s" Constant. print_using_decimals constant
448
+ comment
437
449
| Direct_assignment (var , const ) -> (
438
450
match TS. assembler () with
439
- | MacOS ->
440
- bprintf buf " \t .set %s, %a" var
441
- (Constant. print ~force_digits: false )
442
- const
451
+ | MacOS -> bprintf buf " \t .set %s, %a" var Constant. print const
443
452
| _ ->
444
453
Misc. fatal_error
445
454
" Cannot emit [Direct_assignment] except on macOS-like assemblers" )
@@ -449,12 +458,9 @@ module Directive = struct
449
458
(* masm only *)
450
459
| External _ -> assert false
451
460
| Reloc { offset; name; expr } ->
452
- bprintf buf " \t .reloc\t %a, %s, %a"
453
- (Constant. print ~force_digits: false )
454
- offset
461
+ bprintf buf " \t .reloc\t %a, %s, %a" Constant. print offset
455
462
(reloc_type_to_string name)
456
- (Constant. print ~force_digits: false )
457
- expr
463
+ Constant. print expr
458
464
459
465
let print_masm buf t =
460
466
let unsupported name =
@@ -486,8 +492,7 @@ module Directive = struct
486
492
| Sixty_four -> " QWORD"
487
493
in
488
494
let comment = masm_comment_opt comment in
489
- bprintf buf " \t %s\t %a%s" directive
490
- (Constant. print ~force_digits: false )
495
+ bprintf buf " \t %s\t %a%s" directive Constant. print
491
496
(Constant_with_width. constant constant)
492
497
comment
493
498
| Global s -> bprintf buf " \t PUBLIC\t %s" s
0 commit comments