Commit d267f0f968

Andrew Kelley <andrew@ziglang.org>
2022-08-10 23:08:09
LLVM: respect linksection for exported variables
1 parent e8d02c5
Changed files (3)
src/codegen/llvm/bindings.zig
@@ -126,6 +126,9 @@ pub const Value = opaque {
     pub const setThreadLocalMode = LLVMSetThreadLocalMode;
     extern fn LLVMSetThreadLocalMode(Global: *const Value, Mode: ThreadLocalMode) void;
 
+    pub const setSection = LLVMSetSection;
+    extern fn LLVMSetSection(Global: *const Value, Section: [*:0]const u8) void;
+
     pub const deleteGlobal = LLVMDeleteGlobal;
     extern fn LLVMDeleteGlobal(GlobalVar: *const Value) void;
 
src/codegen/llvm.zig
@@ -722,6 +722,10 @@ pub const Object = struct {
             dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
         }
 
+        if (decl.@"linksection") |section| {
+            llvm_func.setSection(section);
+        }
+
         // Remove all the basic blocks of a function in order to start over, generating
         // LLVM IR from an empty function body.
         while (llvm_func.getFirstBasicBlock()) |bb| {
@@ -1107,6 +1111,11 @@ pub const Object = struct {
                 .hidden => llvm_global.setVisibility(.Hidden),
                 .protected => llvm_global.setVisibility(.Protected),
             }
+            if (exports[0].options.section) |section| {
+                const section_z = try module.gpa.dupeZ(u8, section);
+                defer module.gpa.free(section_z);
+                llvm_global.setSection(section_z);
+            }
             if (decl.val.castTag(.variable)) |variable| {
                 if (variable.data.is_threadlocal) {
                     llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);
@@ -2183,6 +2192,7 @@ pub const DeclGen = struct {
             const target = dg.module.getTarget();
             var global = try dg.resolveGlobalDecl(decl_index);
             global.setAlignment(decl.getAlignment(target));
+            if (decl.@"linksection") |section| global.setSection(section);
             assert(decl.has_tv);
             const init_val = if (decl.val.castTag(.variable)) |payload| init_val: {
                 const variable = payload.data;
@@ -2216,6 +2226,7 @@ pub const DeclGen = struct {
                     new_global.setLinkage(global.getLinkage());
                     new_global.setUnnamedAddr(global.getUnnamedAddress());
                     new_global.setAlignment(global.getAlignment());
+                    if (decl.@"linksection") |section| new_global.setSection(section);
                     new_global.setInitializer(llvm_init);
                     // replaceAllUsesWith requires the type to be unchanged. So we bitcast
                     // the new global to the old type and use that as the thing to replace
src/Sema.zig
@@ -6351,6 +6351,7 @@ fn instantiateGenericCall(
         new_decl.is_exported = fn_owner_decl.is_exported;
         new_decl.has_align = fn_owner_decl.has_align;
         new_decl.has_linksection_or_addrspace = fn_owner_decl.has_linksection_or_addrspace;
+        new_decl.@"linksection" = fn_owner_decl.@"linksection";
         new_decl.@"addrspace" = fn_owner_decl.@"addrspace";
         new_decl.zir_decl_index = fn_owner_decl.zir_decl_index;
         new_decl.alive = true; // This Decl is called at runtime.