Skip to content

Commit 939d9b3

Browse files
committed
En ocamlopt, les acces hors bornes levent Invalid_argument au lieu de planter le programme. Itou pour les fonctions C qui appellent invalid_argument. Teste sur Intel, a tester sur les autres
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@2165 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
1 parent 6c220cd commit 939d9b3

File tree

20 files changed

+206
-78
lines changed

20 files changed

+206
-78
lines changed

Diff for: asmcomp/alpha/emit.mlp

+2-2
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,8 @@ let emit_fundecl (fundecl, needs_gp) =
709709
List.iter emit_call_gc !call_gc_sites;
710710
if !range_check_trap > 0 then begin
711711
`{emit_label !range_check_trap}:\n`;
712-
` br $25, call_array_bound_error\n`
713-
(* Keep retaddr in $25 for debugging *)
712+
` br $26, caml_array_bound_error\n`
713+
(* Keep retaddr in $26 for debugging *)
714714
end;
715715
` .end {emit_symbol fundecl.fun_name}\n`;
716716
if !bigint_constants <> [] then begin

Diff for: asmcomp/arm/emit.mlp

+3-3
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ let emit_instr i =
382382
` mov{emit_string comp} {emit_reg i.res.(0)}, #1\n`; 3
383383
| Lop(Iintop(Icheckbound)) ->
384384
` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
385-
` blls array_bound_error\n`; 2
385+
` blls caml_array_bound_error\n`; 2
386386
| Lop(Iintop op) ->
387387
let instr = name_for_int_operation op in
388388
` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; 1
@@ -419,7 +419,7 @@ let emit_instr i =
419419
` mov{emit_string comp} {emit_reg i.res.(0)}, #1\n`; 3
420420
| Lop(Iintop_imm(Icheckbound, n)) ->
421421
` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`;
422-
` blls array_bound_error\n`; 2
422+
` blls caml_array_bound_error\n`; 2
423423
| Lop(Iintop_imm(op, n)) ->
424424
let instr = name_for_int_operation op in
425425
` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, #{emit_int n}\n`; 1
@@ -438,7 +438,7 @@ let emit_instr i =
438438
1
439439
| Lop(Ispecific(Ishiftcheckbound shift)) ->
440440
` cmp {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}, lsr #{emit_int shift}\n`;
441-
` blcs array_bound_error\n`; 2
441+
` blcs caml_array_bound_error\n`; 2
442442
| Lop(Ispecific(Irevsubimm n)) ->
443443
` rsb {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, #{emit_int n}\n`; 1
444444
| Lreloadretaddr ->

Diff for: asmcomp/hppa/emit.mlp

+3-3
Original file line numberDiff line numberDiff line change
@@ -972,11 +972,11 @@ let fundecl fundecl =
972972
if !range_check_trap > 0 then begin
973973
`{emit_label !range_check_trap}:\n`;
974974
if hpux then begin
975-
emit_call "array_bound_error" "%r31";
975+
emit_call "caml_array_bound_error" "%r31";
976976
` nop\n`
977977
end else begin
978-
` ldil L\`{emit_symbol "array_bound_error"}, %r1\n`;
979-
` ble,n {emit_symbol_low "array_bound_error"}(4, %r1)\n`
978+
` ldil L\`{emit_symbol "caml_array_bound_error"}, %r1\n`;
979+
` ble,n {emit_symbol_low "caml_array_bound_error"}(4, %r1)\n`
980980
end
981981
end;
982982
if hpux then begin

Diff for: asmcomp/liveness.ml

+5-4
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@ let rec live i finally =
8989
let across_after = Reg.diff_set_array (live i.next finally) i.res in
9090
let across =
9191
match i.desc with
92-
Iop(Icall_ind) | Iop(Icall_imm _) | Iop(Iextcall(_, _)) ->
92+
Iop(Icall_ind) | Iop(Icall_imm _) | Iop(Iextcall(_, _))
93+
| Iop(Iintop Icheckbound) | Iop(Iintop_imm(Icheckbound, _)) ->
9394
(* The function call may raise an exception, branching to the
94-
nearest enclosing try ... with. Hence, everything that must
95-
be live at the beginning of the exception handler must also
96-
be live across the call. *)
95+
nearest enclosing try ... with. Similarly for bounds checks.
96+
Hence, everything that must be live at the beginning of
97+
the exception handler must also be live across this instr. *)
9798
Reg.Set.union across_after !live_at_raise
9899
| _ ->
99100
across_after in

Diff for: asmcomp/m68k/emit.mlp

+1-1
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ let fundecl fundecl =
667667
`{emit_label !tailrec_entry_point}:\n`;
668668
emit_all fundecl.fun_body;
669669
if !range_check_trap > 0 then
670-
`{emit_label !range_check_trap}: jbsr {emit_symbol "array_bound_error"}\n`
670+
`{emit_label !range_check_trap}: jbsr {emit_symbol "caml_array_bound_error"}\n`
671671

672672
(* Emission of data *)
673673

Diff for: asmcomp/mips/emit.mlp

+1-1
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ let fundecl fundecl =
551551
end;
552552
if !range_check_trap > 0 then begin
553553
`{emit_label !range_check_trap}:\n`;
554-
emit_branch_symbol "array_bound_error"
554+
emit_branch_symbol "caml_array_bound_error"
555555
end;
556556
` .end {emit_symbol fundecl.fun_name}\n`
557557

Diff for: asmrun/alpha.S

+7-6
Original file line numberDiff line numberDiff line change
@@ -418,16 +418,17 @@ callback3:
418418
br $107
419419
.end callback3
420420

421-
/* Glue code to call array_bound_error after reinitializing $gp */
421+
/* Glue code to call array_bound_error */
422422

423-
.globl call_array_bound_error
424-
.ent call_array_bound_error
423+
.globl caml_array_bound_error
424+
.ent caml_array_bound_error
425425
.align 3
426-
call_array_bound_error:
426+
caml_array_bound_error:
427427
br $27, $111
428428
$111: ldgp $gp, 0($27)
429-
jsr array_bound_error /* never returns */
430-
.end call_array_bound_error
429+
lda $25, array_bound_error
430+
br caml_c_call /* never returns */
431+
.end caml_array_bound_error
431432

432433
#ifdef SYS_digital
433434
.rdata

Diff for: asmrun/arm.S

+13
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,18 @@ callback3:
312312
ldr r10, .Lcaml_apply3
313313
b .Ljump_to_caml
314314

315+
.global caml_array_bound_error
316+
array_bound_error:
317+
/* Save the exception handler and alloc ptr */
318+
ldr r6, .Lyoung_ptr
319+
ldr r7, .Lcaml_exception_pointer
320+
str alloc_ptr, [r6, #0]
321+
str trap_ptr, [r7, #0]
322+
/* Load address of array_bound_error in r10 */
323+
ldr r10, .Larray_bound_error
324+
/* Call that function */
325+
b caml_c_call
326+
315327
/* Global references */
316328

317329
.Lcaml_last_return_address: .word caml_last_return_address
@@ -325,6 +337,7 @@ callback3:
325337
.Lcaml_apply2: .word caml_apply2
326338
.Lcaml_apply3: .word caml_apply3
327339
.Lcaml_requested_size: .word 0
340+
.Larray_bound_error: .word array_bound_error
328341

329342
/* GC roots for callback */
330343

Diff for: asmrun/fail.c

+31-9
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,9 @@ void failwith (char *msg)
107107
raise_with_string((value) Failure, msg);
108108
}
109109

110-
/* We chose to abort the program if a C primitive raises Invalid_argument.
111-
Rationale: nobody should trap Invalid_argument, and we're not running
112-
under a toplevel, so this will provide the same feedback to the user.
113-
Moreover, divisions by zero or out-of-bounds accesses also abort the
114-
program, and there's no way we can turn them into exceptions.
115-
Finally, this allows a number of C primitives to be declared "noalloc",
116-
and this makes calling them much more efficient. */
117-
118110
void invalid_argument (char *msg)
119111
{
120-
fatal_error_arg("Fatal_error: Invalid_argument \"%s\"\n", msg);
112+
raise_with_string((value) Invalid_argument, msg);
121113
}
122114

123115
/* To raise Out_of_memory, we can't use raise_constant,
@@ -157,3 +149,33 @@ void raise_not_found(void)
157149
{
158150
raise_constant((value) Not_found);
159151
}
152+
153+
/* We allocate statically the bucket for the exception because we can't
154+
do a GC before the exception is raised (lack of stack descriptors
155+
for the ccall to array_bound_error */
156+
157+
#define BOUND_MSG "out-of-bound array or string access"
158+
#define BOUND_MSG_LEN (sizeof(BOUND_MSG) - 1)
159+
160+
static struct {
161+
header_t hdr;
162+
value exn;
163+
value arg;
164+
} array_bound_error_bucket;
165+
166+
static struct {
167+
header_t hdr;
168+
char data[BOUND_MSG_LEN + sizeof(value)];
169+
} array_bound_error_msg = { 0, BOUND_MSG };
170+
171+
void array_bound_error(void)
172+
{
173+
mlsize_t wosize = (BOUND_MSG_LEN + sizeof(value)) / sizeof(value);
174+
mlsize_t offset_index = Bsize_wsize(wosize) - 1;
175+
array_bound_error_msg.hdr = Make_header(wosize, String_tag, White);
176+
array_bound_error_msg.data[offset_index] = offset_index - BOUND_MSG_LEN;
177+
array_bound_error_bucket.hdr = Make_header(2, 0, White);
178+
array_bound_error_bucket.exn = (value) Invalid_argument;
179+
array_bound_error_bucket.arg = (value) array_bound_error_msg.data;
180+
mlraise((value) &array_bound_error_bucket.exn);
181+
}

Diff for: asmrun/hppa.S

+22
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,28 @@ G(callback3):
523523
ldo LOW(G(caml_apply3))(%r1), %r22
524524
ENDPROC
525525

526+
.align CODE_ALIGN
527+
EXPORT_CODE(G(caml_array_bound_error))
528+
G(caml_array_bound_error):
529+
STARTPROC
530+
; Save the exception handler
531+
LOADHIGH(G(caml_exception_pointer))
532+
stw %r5, LOW(G(caml_exception_pointer))(%r1)
533+
; Save the allocation pointer
534+
LOADHIGH(G(young_ptr))
535+
stw %r3, LOW(G(young_ptr))(%r1)
536+
; Load address of array_bound_error in %r22
537+
#ifdef SYS_hpux
538+
ldil LP'array_bound_error, %r22
539+
ldo RP'array_bound_error(%r22), %r22
540+
#else
541+
ldil L`_array_bound_error, %r22
542+
ldo R`_array_bound_error(%r22), %r22
543+
#endif
544+
; Jump to caml_c_call
545+
b,n G(caml_c_call)
546+
ENDPROC
547+
526548
.data
527549
EXPORT_DATA(G(system_frametable))
528550
G(system_frametable):

Diff for: asmrun/m68k.S

+9
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,15 @@ _callback3:
230230
lea _caml_apply3, a5 | code pointer
231231
bra L106
232232

233+
.globl _caml_array_bound_error
234+
_caml_array_bound_error:
235+
| Save allocation pointer and exception pointer
236+
movel d6, _young_ptr
237+
movel d7, _caml_exception_pointer
238+
| Load address of array_bound_error in a0 and call it
239+
lea _array_bound_error, a0
240+
bra _caml_c_call
241+
233242
.data
234243
.globl _system_frametable
235244
_system_frametable:

Diff for: asmrun/mips.S

+15
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,21 @@ callback3:
426426

427427
.end callback3
428428

429+
/* Glue code to call array_bound_error */
430+
431+
.globl caml_array_bound_error
432+
.ent caml_array_bound_error
433+
434+
caml_array_bound_error:
435+
#ifdef PIC
436+
.set noreorder
437+
.cpload $25
438+
.set reorder
439+
#endif
440+
la $24, array_bound_error
441+
b caml_c_call /* never returns */
442+
.end caml_array_bound_error
443+
429444
.rdata
430445
.globl system_frametable
431446
system_frametable:

0 commit comments

Comments
 (0)