Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit ed89275c authored by Xavier Leroy's avatar Xavier Leroy Committed by Xavier Leroy
Browse files

Section handling: finer control of variable initialization

Distinguish between:
- uninitialized variables, which can go in COMM if supported
- variables initialized with fixed, numeric quantities,
  which can go in a readonly section if "const"
- variables initialized with symbol addresses which may need relocation,
  which cannot go in a readonly section even if "const",
  but can go in a special "const_data" section.

Also: on macOS, use ".const" instead of ".literal8" for literals,
as not all literals have size 8.
parent 30feb31c
......@@ -226,7 +226,7 @@ module MacOS_System : SYSTEM =
| Section_data i | Section_small_data i ->
variable_section ~sec:".data" i
| Section_const i | Section_small_const i ->
variable_section ~sec:".section __DATA,__CONST" i
variable_section ~sec:".const" ~reloc:".const_data" i
| Section_string -> ".const"
| Section_literal -> ".const"
| Section_jumptable -> ".text"
......
......@@ -21,14 +21,22 @@ open Sections
let pp_storage pp static =
pp_jstring pp (if static then "Static" else "Extern")
let pp_init pp init =
pp_jstring pp
(match init with
| Uninit -> "Uninit"
| Init -> "Init"
| Init_reloc -> "Init_reloc")
let pp_section pp sec =
let pp_simple name =
pp_jsingle_object pp "Section Name" pp_jstring name
and pp_complex name init =
pp_jobject_start pp;
pp_jmember ~first:true pp "Section Name" pp_jstring name;
pp_jmember pp "Init" pp_jbool init;
pp_jmember pp "Init" pp_init init;
pp_jobject_end pp in
match sec with
| Section_text -> pp_simple "Text"
| Section_data init -> pp_complex "Data" init
......
......@@ -121,7 +121,7 @@ module Printer(Target:TARGET) =
let sec =
match C2C.atom_sections name with
| [s] -> s
| _ -> Section_data true
| _ -> Section_data Init
and align =
match C2C.atom_alignof name with
| Some a -> a
......
......@@ -305,14 +305,21 @@ let print_version_and_options oc comment =
fprintf oc "\n"
(** Determine the name of the section to use for a variable.
[i] says whether the variable is initialized (true) or not (false).
[sec] is the name of the section to use if initialized or if
no other cases apply.
[bss] is the name of the section to use if uninitialized and
- [i] is the initialization status of the variable.
- [sec] is the name of the section to use if initialized (with no
relocations) or if no other cases apply.
- [reloc] is the name of the section to use if initialized and
containing relocations. If not provided, [sec] is used.
- [bss] is the name of the section to use if uninitialized and
common declarations are not used. If not provided, [sec] is used.
*)
let variable_section ~sec ?bss i =
if i then sec
else if !Clflags.option_fcommon then "COMM"
else match bss with None -> sec | Some b -> b
let variable_section ~sec ?bss ?reloc i =
match i with
| Uninit ->
if !Clflags.option_fcommon
then "COMM"
else begin match bss with Some s -> s | None -> sec end
| Init -> sec
| Init_reloc ->
begin match reloc with Some s -> s | None -> sec end
......@@ -1333,8 +1333,13 @@ let convertGlobvar loc env (sto, id, ty, optinit) =
if sto = C.Storage_extern then [] else [AST.Init_space sz]
| Some i ->
convertInitializer env ty i in
let initialized =
if optinit = None then Sections.Uninit else
if List.exists (function AST.Init_addrof _ -> true | _ -> false) init'
then Sections.Init_reloc
else Sections.Init in
let (section, access) =
Sections.for_variable env loc id' ty (optinit <> None) in
Sections.for_variable env loc id' ty initialized in
if Z.gt sz (Z.of_uint64 0xFFFF_FFFFL) then
error "'%s' is too big (%s bytes)"
id.name (Z.to_string sz);
......
......@@ -15,12 +15,17 @@
(* Handling of linker sections *)
type initialized =
| Uninit (* uninitialized data area *)
| Init (* initialized with fixed, non-relocatable data *)
| Init_reloc (* initialized with relocatable data (symbol addresses) *)
type section_name =
| Section_text
| Section_data of bool (* true = init data, false = uninit data *)
| Section_small_data of bool
| Section_const of bool
| Section_small_const of bool
| Section_data of initialized
| Section_small_data of initialized
| Section_const of initialized
| Section_small_const of initialized
| Section_string
| Section_literal
| Section_jumptable
......@@ -40,6 +45,7 @@ type access_mode =
type section_info = {
sec_name_init: section_name;
sec_name_init_reloc: section_name;
sec_name_uninit: section_name;
sec_writable: bool;
sec_executable: bool;
......@@ -47,8 +53,9 @@ type section_info = {
}
let default_section_info = {
sec_name_init = Section_data true;
sec_name_uninit = Section_data false;
sec_name_init = Section_data Init;
sec_name_init_reloc = Section_data Init_reloc;
sec_name_uninit = Section_data Uninit;
sec_writable = true;
sec_executable = false;
sec_access = Access_default
......@@ -59,41 +66,49 @@ let default_section_info = {
let builtin_sections = [
"CODE",
{sec_name_init = Section_text;
sec_name_init_reloc = Section_text;
sec_name_uninit = Section_text;
sec_writable = false; sec_executable = true;
sec_access = Access_default};
"DATA",
{sec_name_init = Section_data true;
sec_name_uninit = Section_data false;
{sec_name_init = Section_data Init;
sec_name_init_reloc = Section_data Init_reloc;
sec_name_uninit = Section_data Uninit;
sec_writable = true; sec_executable = false;
sec_access = Access_default};
"SDATA",
{sec_name_init = Section_small_data true;
sec_name_uninit = Section_small_data false;
{sec_name_init = Section_small_data Init;
sec_name_init_reloc = Section_small_data Init_reloc;
sec_name_uninit = Section_small_data Uninit;
sec_writable = true; sec_executable = false;
sec_access = Access_near};
"CONST",
{sec_name_init = Section_const true;
sec_name_uninit = Section_const false;
{sec_name_init = Section_const Init;
sec_name_init_reloc = Section_const Init_reloc;
sec_name_uninit = Section_const Uninit;
sec_writable = false; sec_executable = false;
sec_access = Access_default};
"SCONST",
{sec_name_init = Section_small_const true;
sec_name_uninit = Section_small_const false;
{sec_name_init = Section_small_const Init;
sec_name_init_reloc = Section_small_const Init_reloc;
sec_name_uninit = Section_small_const Uninit;
sec_writable = false; sec_executable = false;
sec_access = Access_near};
"STRING",
{sec_name_init = Section_string;
sec_name_init_reloc = Section_string;
sec_name_uninit = Section_string;
sec_writable = false; sec_executable = false;
sec_access = Access_default};
"LITERAL",
{sec_name_init = Section_literal;
sec_name_init_reloc = Section_literal;
sec_name_uninit = Section_literal;
sec_writable = false; sec_executable = false;
sec_access = Access_default};
"JUMPTABLE",
{sec_name_init = Section_jumptable;
sec_name_init_reloc = Section_jumptable;
sec_name_uninit = Section_jumptable;
sec_writable = false; sec_executable = false;
sec_access = Access_default}
......@@ -128,15 +143,19 @@ let define_section name ?iname ?uname ?writable ?executable ?access () =
match executable with Some b -> b | None -> si.sec_executable
and access =
match access with Some b -> b | None -> si.sec_access in
let iname =
let i =
match iname with Some s -> Section_user(s, writable, executable)
| None -> si.sec_name_init in
let uname =
let ir =
match iname with Some s -> Section_user(s, writable, executable)
| None -> si.sec_name_init_reloc in
let u =
match uname with Some s -> Section_user(s, writable, executable)
| None -> si.sec_name_uninit in
let new_si =
{ sec_name_init = iname;
sec_name_uninit = uname;
{ sec_name_init = i;
sec_name_init_reloc = ir;
sec_name_uninit = u;
sec_writable = writable;
sec_executable = executable;
sec_access = access } in
......@@ -156,7 +175,7 @@ let use_section_for id name =
let gcc_section name readonly exec =
let sn = Section_user(name, not readonly, exec) in
{ sec_name_init = sn; sec_name_uninit = sn;
{ sec_name_init = sn; sec_name_init_reloc = sn; sec_name_uninit = sn;
sec_writable = not readonly; sec_executable = exec;
sec_access = Access_default }
......@@ -199,7 +218,12 @@ let for_variable env loc id ty init =
Hashtbl.find current_section_table name
with Not_found ->
assert false in
((if init then si.sec_name_init else si.sec_name_uninit), si.sec_access)
let secname =
match init with
| Uninit -> si.sec_name_uninit
| Init -> si.sec_name_init
| Init_reloc -> si.sec_name_init_reloc in
(secname, si.sec_access)
(* Determine sections for a function definition *)
......
......@@ -16,12 +16,17 @@
(* Handling of linker sections *)
type initialized =
| Uninit (* uninitialized data area *)
| Init (* initialized with fixed, non-relocatable data *)
| Init_reloc (* initialized with relocatable data (symbol addresses) *)
type section_name =
| Section_text
| Section_data of bool (* true = init data, false = uninit data *)
| Section_small_data of bool
| Section_const of bool
| Section_small_const of bool
| Section_data of initialized
| Section_small_data of initialized
| Section_const of initialized
| Section_small_const of initialized
| Section_string
| Section_literal
| Section_jumptable
......@@ -46,7 +51,7 @@ val define_section:
-> ?writable:bool -> ?executable:bool -> ?access:access_mode -> unit -> unit
val use_section_for: AST.ident -> string -> bool
val for_variable: Env.t -> C.location -> AST.ident -> C.typ -> bool ->
val for_variable: Env.t -> C.location -> AST.ident -> C.typ -> initialized ->
section_name * access_mode
val for_function: Env.t -> C.location -> AST.ident -> C.attributes -> section_name list
val for_stringlit: unit -> section_name
......@@ -213,7 +213,7 @@ module Diab_System : SYSTEM =
let name_of_section = function
| Section_text -> ".text"
| Section_data i -> variable_section ~sec:".data" ~bss:".bss" i
| Section_small_data i -> if i then ".sdata" else ".sbss"
| Section_small_data i -> variable_section ~sec:".sdata" ~bss:".sbss" i
| Section_const _ -> ".text"
| Section_small_const _ -> ".sdata2"
| Section_string -> ".text"
......
......@@ -194,9 +194,9 @@ module MacOS_System : SYSTEM =
| Section_data i | Section_small_data i ->
variable_section ~sec:".data" i
| Section_const i | Section_small_const i ->
variable_section ~sec:".const" i
variable_section ~sec:".const" ~reloc:".const_data" i
| Section_string -> ".const"
| Section_literal -> ".literal8"
| Section_literal -> ".const"
| Section_jumptable -> ".text"
| Section_user(s, wr, ex) ->
sprintf ".section \"%s\", %s, %s"
......@@ -914,8 +914,7 @@ module Target(System: SYSTEM):TARGET =
let print_epilogue oc =
if !need_masks then begin
section oc (Section_const true);
(* not Section_literal because not 8-bytes *)
section oc Section_literal;
print_align oc 16;
fprintf oc "%a: .quad 0x8000000000000000, 0\n"
raw_symbol "__negd_mask";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment