https://github.com/madsmtm created 
https://github.com/llvm/llvm-project/pull/209167

LLVM implements logic in `llvm/lib/MC/MCSectionMachO.cpp` to parse the section 
name and split it into its components. The syntax for doing this seems to have 
been uplifted [from the old macOS 
assembler](https://github.com/apple-oss-distributions/cctools/blob/cctools-1010.6/as/read.c#L232-L279),
 and it is documented in the [Mac OS X Assembler 
Reference](https://leopard-adc.pepas.com/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html#//apple_ref/doc/uid/TP30000823-TPXREF102)

But that can be kinda hard to find, and it's quite outdated, so let's also 
document things in LLVM (since that is the source of truth for this nowadays).

>From 0c9e559164a0471fb0065114b6cbde4ed2f20f28 Mon Sep 17 00:00:00 2001
From: Mads Marquart <[email protected]>
Date: Mon, 13 Jul 2026 14:27:56 +0200
Subject: [PATCH] [docs] Document `section` attribute Mach-O format

LLVM implements logic in llvm/lib/MC/MCSectionMachO.cpp to parse the
section name and split it into its components. The syntax for doing this
seems to have been uplifted from the old macOS assembler:
https://github.com/apple-oss-distributions/cctools/blob/cctools-1010.6/as/read.c#L232-L279

And it is documented in the Mac OS X Assembler Reference:
https://leopard-adc.pepas.com/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html#//apple_ref/doc/uid/TP30000823-TPXREF102

But that can be kinda hard to find, and it's quite outdated, so let's
also document things in LLVM (since it is the source of truth for this
nowadays).
---
 clang/include/clang/Basic/AttrDocs.td |  15 +++-
 llvm/docs/LangRef.md                  | 119 +++++++++++++++++++++++---
 2 files changed, 122 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 05e4cb0870652..0c7b622b463eb 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -51,8 +51,19 @@ This page lists the attributes currently supported by Clang.
 def SectionDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{
-The ``section`` attribute allows you to specify a specific section a
-global variable or function should be in after translation.
+The ``section`` attribute allows you to specify a specific section a global
+variable or function should be in after translation.
+
+The format of the attribute is target-specific, see `LLVM documentation
+<https://llvm.org/docs/LangRef.html#sections>`_.
+
+Example usage:
+
+.. code-block:: c
+
+  __attribute__((section("foo")))
+  void bar(void) {}
+
   }];
   let Heading = "section, __declspec(allocate)";
 }
diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index aecc425538d65..d4c9c6e02d0d1 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -861,10 +861,10 @@ may affect how optimizations are performed and/or what 
target
 instructions are used to access the variable. The default address space
 is zero. The address space qualifier must precede any other attributes.
 
-LLVM allows an explicit section to be specified for globals. If the
-target supports it, it will emit globals to the section specified.
-Additionally, the global can be placed in a comdat if the target has the 
necessary
-support.
+LLVM allows an explicit {ref}`section <langref_sections>` to be specified for
+globals. If the target supports it, it will emit globals to the section
+specified. Additionally, the global can be placed in a
+{ref}`comdat <langref_comdats>` if the target has the necessary support.
 
 External declarations may have an explicit section specified. Section
 information is retained in LLVM IR for targets that make use of this
@@ -985,7 +985,9 @@ an optional `unnamed_addr` attribute, a return type, an 
optional
 {ref}`parameter attribute <paramattrs>` for the return type, a function
 name, a (possibly empty) argument list (each with optional {ref}`parameter
 attributes <paramattrs>`), optional {ref}`function attributes <fnattrs>`,
-an optional address space, an optional section, an optional partition,
+an optional address space,
+an optional {ref}`section <langref_sections>`,
+an optional partition,
 an optional minimum alignment,
 an optional preferred alignment,
 an optional {ref}`comdat <langref_comdats>`,
@@ -1159,6 +1161,103 @@ Syntax:
           [, partition "name"] (, !name !N)*
 ```
 
+(langref_sections)=
+
+### Sections
+
+The supported format in the `section` attribute is target-specific and varies
+depending on the object file format. On most targets, the section name is
+forwarded to and interpreted by the linker.
+
+#### Section Mach-O format
+
+In Mach-O, the section is parsed by the assembler as a string with five fields:
+the segment name, the section name, the section type, the section attributes
+and the stub size. The fields are separated by `,`. Whitespace is ignored.
+
+Segment name
+:   Sections are grouped together in segments. The segment name is limited to
+    16 characters. Common segment names include `__DATA` and `__TEXT`.
+
+Section name
+:   The segment name and section name together identifies the section. All
+    symbols in the binary with a given segment/section pair must have the same
+    type and attributes. The section name is limited to 16 characters.
+
+Section type
+:   The valid section type names are:
+    - `regular`
+    - `zerofill`
+    - `cstring_literals`
+    - `4byte_literals`
+    - `8byte_literals`
+    - `literal_pointers`
+    - `non_lazy_symbol_pointers`
+    - `lazy_symbol_pointers`
+    - `mod_init_funcs`
+    - `mod_term_funcs`
+    - `coalesced`
+    - `interposing`
+    - `16byte_literals`
+    - `thread_local_regular`
+    - `thread_local_zerofill`
+    - `thread_local_variables`
+    - `thread_local_variable_pointers`
+    - `thread_local_init_function_pointers`
+    - `symbol_stubs`
+
+    The section type is optional, and will default to `regular` if not set.
+
+    Most of these are documented further in [the Mac OS X Assembler 
Reference](https://leopard-adc.pepas.com/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html#//apple_ref/doc/uid/TP30000823-TPXREF105).
+
+Section attributes
+:   The valid section attribute names are:
+    - `pure_instructions`
+    - `no_toc`
+    - `strip_static_syms`
+    - `no_dead_strip`
+    - `live_support`
+    - `self_modifying_code`
+    - `debug`
+
+    Multiple section attributes can be set, these are separated by `+`.
+
+    Most of these are documented further in [the Mac OS X Assembler 
Reference](https://leopard-adc.pepas.com/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html#//apple_ref/doc/uid/TP30000823-TPXREF117).
+
+Section stub size
+:   The stub size must be specified if the `symbol_stubs` section type is used.
+    It is an error to specify otherwise.
+
+Here is an example of using a Mach-O section specifier to implement a
+{ref}`global constructor <gv_llvmglobalctors>`.
+
+```llvm
+define void @constructor() section "__DATA,__mod_init_func,mod_init_funcs" {
+  ret void
+}
+```
+
+And here is an example of using a Mach-O section specifier to tell the dynamic
+linker to replace the external symbol `foo` with the locally defined
+`replacement_foo`.
+
+```llvm
+declare void @foo()
+
+define void @replacement_foo() {
+  ret void
+}
+
+@interposers = global [2 x ptr] [
+  ptr @replacement_foo,
+  ptr @foo
+], section "__DATA, __interpose", align 8
+
[email protected] = appending global [1 x ptr] [
+  ptr @interposers
+], section "llvm.metadata"
+```
+
 (langref_comdats)=
 
 ### Comdats
@@ -13520,7 +13619,7 @@ This instruction requires several arguments:
    ```llvm
    declare void @take_byval(ptr byval(i64))
    declare void @take_ptr(ptr)
-   
+
    ; Invalid (assuming @take_ptr dereferences the pointer), because %local
    ; may be de-allocated before the call to @take_ptr.
    define void @invalid_alloca() {
@@ -13529,7 +13628,7 @@ This instruction requires several arguments:
      tail call void @take_ptr(ptr %local)
      ret void
    }
-   
+
    ; Valid, the byval attribute causes the memory allocated by %local to be
    ; copied into @take_byval's stack frame.
    define void @byval_alloca() {
@@ -13538,7 +13637,7 @@ This instruction requires several arguments:
      tail call void @take_byval(ptr byval(i64) %local)
      ret void
    }
-   
+
    ; Invalid, because @use_global_va_list uses the variadic arguments from
    ; @invalid_va_list.
    %struct.va_list = type { ptr }
@@ -13554,14 +13653,14 @@ This instruction requires several arguments:
      tail call void @use_global_va_list()
      ret void
    }
-   
+
    ; Valid, byval argument forwarded to tail call as another byval argument.
    define void @forward_byval(ptr byval(i64) %x) {
    entry:
      tail call void @take_byval(ptr byval(i64) %x)
      ret void
    }
-   
+
    ; Invalid (assuming @take_ptr dereferences the pointer), byval argument
    ; passed to tail callee as non-byval ptr.
    define void @invalid_byval(ptr byval(i64) %x) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to