aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@college-de-france.fr>2020-12-30 11:00:22 +0100
committerXavier Leroy <xavierleroy@users.noreply.github.com>2021-02-23 11:33:14 +0100
commited89275cb820bb7ab283c51e461d852d1c8bec63 (patch)
treee076d92145806c6de92194dfa816e9944c2d27f2
parent30feb31c6d6e9235acad42ec5d09d14f3919cc36 (diff)
downloadcompcert-ed89275cb820bb7ab283c51e461d852d1c8bec63.tar.gz
compcert-ed89275cb820bb7ab283c51e461d852d1c8bec63.zip
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.
-rw-r--r--aarch64/TargetPrinter.ml2
-rw-r--r--backend/JsonAST.ml10
-rw-r--r--backend/PrintAsm.ml2
-rw-r--r--backend/PrintAsmaux.ml23
-rw-r--r--cfrontend/C2C.ml7
-rw-r--r--common/Sections.ml64
-rw-r--r--common/Sections.mli15
-rw-r--r--powerpc/TargetPrinter.ml2
-rw-r--r--x86/TargetPrinter.ml7
9 files changed, 90 insertions, 42 deletions
diff --git a/aarch64/TargetPrinter.ml b/aarch64/TargetPrinter.ml
index e31abf71..a9d47bdd 100644
--- a/aarch64/TargetPrinter.ml
+++ b/aarch64/TargetPrinter.ml
@@ -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"
diff --git a/backend/JsonAST.ml b/backend/JsonAST.ml
index 8905e252..d218e567 100644
--- a/backend/JsonAST.ml
+++ b/backend/JsonAST.ml
@@ -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
diff --git a/backend/PrintAsm.ml b/backend/PrintAsm.ml
index 155f5e55..22df68ae 100644
--- a/backend/PrintAsm.ml
+++ b/backend/PrintAsm.ml
@@ -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
diff --git a/backend/PrintAsmaux.ml b/backend/PrintAsmaux.ml
index 82621010..7a692d20 100644
--- a/backend/PrintAsmaux.ml
+++ b/backend/PrintAsmaux.ml
@@ -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
diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml
index 186c3155..fee3d86e 100644
--- a/cfrontend/C2C.ml
+++ b/cfrontend/C2C.ml
@@ -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);
diff --git a/common/Sections.ml b/common/Sections.ml
index 839128a5..9858f957 100644
--- a/common/Sections.ml
+++ b/common/Sections.ml
@@ -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 *)
diff --git a/common/Sections.mli b/common/Sections.mli
index d9fd9239..a3dad3be 100644
--- a/common/Sections.mli
+++ b/common/Sections.mli
@@ -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
diff --git a/powerpc/TargetPrinter.ml b/powerpc/TargetPrinter.ml
index cf00e659..e32348a3 100644
--- a/powerpc/TargetPrinter.ml
+++ b/powerpc/TargetPrinter.ml
@@ -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"
diff --git a/x86/TargetPrinter.ml b/x86/TargetPrinter.ml
index 102edce4..1b27ee73 100644
--- a/x86/TargetPrinter.ml
+++ b/x86/TargetPrinter.ml
@@ -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";