diff options
author | Xavier Leroy <xavier.leroy@college-de-france.fr> | 2020-12-30 11:00:22 +0100 |
---|---|---|
committer | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2021-02-23 11:33:14 +0100 |
commit | ed89275cb820bb7ab283c51e461d852d1c8bec63 (patch) | |
tree | e076d92145806c6de92194dfa816e9944c2d27f2 | |
parent | 30feb31c6d6e9235acad42ec5d09d14f3919cc36 (diff) | |
download | compcert-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.ml | 2 | ||||
-rw-r--r-- | backend/JsonAST.ml | 10 | ||||
-rw-r--r-- | backend/PrintAsm.ml | 2 | ||||
-rw-r--r-- | backend/PrintAsmaux.ml | 23 | ||||
-rw-r--r-- | cfrontend/C2C.ml | 7 | ||||
-rw-r--r-- | common/Sections.ml | 64 | ||||
-rw-r--r-- | common/Sections.mli | 15 | ||||
-rw-r--r-- | powerpc/TargetPrinter.ml | 2 | ||||
-rw-r--r-- | x86/TargetPrinter.ml | 7 |
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"; |