I’d like to propose that LLVM IR have a mechanism to describe sections in a more explicit way than we can today.
Currently, we provide an attribute called “section” on GlobalVariables and Functions. This attribute will choose which section the Value will end up in.
However, it does not describe the attributes of the section.
Without a way of describing the section, we try to infer the section’s attribute from the first Value from that section that MC comes across.
This means that if the first value is constant, the rest of the values
will end up in .rodata even if the intention was for them to be mutable.
Equally problematic is our inability to verify the appropriate use of sections, consider the following:
- One global value is defined to be thread_local and in section “.foo”
- Another value is not defined to be thread_local and in section “.foo”
The IR verifier does not catch this nonsensical arrangement of IR.
Further motivation stems from being able to represent the MS ABI’s RTTI data:
- A single COMDAT section is created which holds both the RTTI data and the vftable for a type.
- If there is no vftable, the section will start with just the vftable.
- The entire section is marked with a linkage that indicates the linker to pick the largest.
I think LLVM needs new IR to represent these semantics properly.
I propose that we do the following:
- Sections are represented at module scope and have an identifier that starts with ‘$’
- Sections have linkage, all Values inside of a section must agree with the section’s linkage.
- Sections don’t have visibility, Values may disagree with one another about how visible they are.
- Sections have attributes annotating what semantics they provide (read, write, execute, etc.)
A concrete example of a const variable inside of a read-only section:
$.my_section = appending read
@my_var = constant float 1.0, section $.my_section, align 4
The following is how I imagine MS RTTI would look like if we had this IR construct:
$.vdata_for_type = pick_largest read
@my_rtti_for_type = pick_largest unnamed_addr constant %rtti_ptr_ty @rtti_complete_object_locator, section $.vdata_for_type, align 4
@vftable_for_type = pick_largest unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.S*)* @"\01?fun@S@@UAEXXZ" to i8*)], section $.vdata_for_type, align 4
Attached is a patch to the LangRef.
Thanks for reading!
SectionIRLangRef.patch (2.19 KB)