Skip to content

Commit a9eaf48

Browse files
authored
More precise determination of small data accesses (#220)
We can get linker errors for addresses of the form "symbol + offset" where "symbol" is in the small data area and "offset" is large enough to overflow the relative displacement from the SDA base register. To avoid this, this commit enriches `C2C.atom_is_small_data`, which is the implementation of `Asm.symbol_is_small_data` in the PPC port, with a check that the offset is within the bounds of the symbol. If it is not, `Asm.symbol_is_small_data` returns `false` and Asmgen produces an absolute addressing instead of a SDA-relative addressing. To implement the check, we record the sizes of symbols in the atom table, just like we already record their alignments.
1 parent 7978290 commit a9eaf48

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

cfrontend/C2C.ml

+15-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type inline_status =
3333

3434
type atom_info =
3535
{ a_storage: C.storage; (* storage class *)
36+
a_size: int64 option; (* size in bytes *)
3637
a_alignment: int option; (* alignment *)
3738
a_sections: Sections.section_name list; (* in which section to put it *)
3839
(* 1 section for data, 3 sections (code/lit/jumptbl) for functions *)
@@ -72,9 +73,14 @@ let atom_sections a =
7273
with Not_found ->
7374
[]
7475

75-
let atom_is_small_data a ofs =
76+
let atom_is_small_data a ofs =
7677
try
77-
(Hashtbl.find decl_atom a).a_access = Sections.Access_near
78+
let info = Hashtbl.find decl_atom a in
79+
info.a_access = Sections.Access_near
80+
&& (match info.a_size with
81+
| None -> false
82+
| Some sz ->
83+
let ofs = camlint64_of_ptrofs ofs in 0L <= ofs && ofs < sz)
7884
with Not_found ->
7985
false
8086

@@ -352,6 +358,7 @@ let name_for_string_literal s =
352358
Hashtbl.add decl_atom id
353359
{ a_storage = C.Storage_static;
354360
a_alignment = Some 1;
361+
a_size = Some (Int64.of_int (String.length s + 1));
355362
a_sections = [Sections.for_stringlit()];
356363
a_access = Sections.Access_default;
357364
a_inline = No_specifier;
@@ -379,9 +386,12 @@ let name_for_wide_string_literal s =
379386
incr stringNum;
380387
let name = Printf.sprintf "__stringlit_%d" !stringNum in
381388
let id = intern_string name in
389+
let wchar_size = Machine.((!config).sizeof_wchar) in
382390
Hashtbl.add decl_atom id
383391
{ a_storage = C.Storage_static;
384-
a_alignment = Some Machine.((!config).sizeof_wchar);
392+
a_alignment = Some wchar_size;
393+
a_size = Some (Int64.(mul (of_int (List.length s + 1))
394+
(of_int wchar_size)));
385395
a_sections = [Sections.for_stringlit()];
386396
a_access = Sections.Access_default;
387397
a_inline = No_specifier;
@@ -1223,6 +1233,7 @@ let convertFundef loc env fd =
12231233
Hashtbl.add decl_atom id'
12241234
{ a_storage = fd.fd_storage;
12251235
a_alignment = None;
1236+
a_size = None;
12261237
a_sections = Sections.for_function env id' fd.fd_attrib;
12271238
a_access = Sections.Access_default;
12281239
a_inline = inline;
@@ -1309,6 +1320,7 @@ let convertGlobvar loc env (sto, id, ty, optinit) =
13091320
Hashtbl.add decl_atom id'
13101321
{ a_storage = sto;
13111322
a_alignment = Some (Z.to_int al);
1323+
a_size = Some (Z.to_int64 sz);
13121324
a_sections = [section];
13131325
a_access = access;
13141326
a_inline = No_specifier;

0 commit comments

Comments
 (0)