[PATCH] gas: support for .pushsection and .popsection pseudo ops for coff
Johannes Khoshnazar-Thoma <[email protected]> Sat, 18 Jul 2026 18:22:02 +0200
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <[email protected]> |
Current Linux kernels make heavy use of the .pushsection and .popsection pseudo ops. Normally, the Linux kernel is built as an ELF object, where the assembler supports those pseudo ops. When compiling the Linux kernel as a Windows/ReactOS driver however, it must be compiled as a COFF object, since the Windows/ReactOS kernel does not know how to load ELF binaries. In order to be able to compile the Linux kernel as a COFF object (and further on as a PE32 native executable) the implementation of those pseudo ops has been copiied from the obj-elf.c support code to the obj-coff.c support code. It has been verified that the Linux kernel works without assembler errors when using an assembler with this patch. Signed-off-by: Johannes Khoshnazar-Thoma <[email protected]> --- gas/config/obj-coff.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 7732c0af911..73c571b71de 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -1536,6 +1536,32 @@ obj_coff_finalize_section_relocs (asection *sec, arelent **relocs, return true; } +struct section_stack +{ + struct section_stack *next; + segT seg; + int subseg; +}; + +static struct section_stack *section_stack; + +static void +obj_coff_popsection (int xxx ATTRIBUTE_UNUSED) +{ + struct section_stack *top = section_stack; + + if (top == NULL) + { + as_warn (_(".popsection without corresponding .pushsection; ignored")); + return; + } + + section_stack = top->next; + subseg_set (top->seg, top->subseg); + free (top); +} + + /* Implement the .section pseudo op: .section name {, "flags"} ^ ^ @@ -1559,7 +1585,7 @@ obj_coff_finalize_section_relocs (asection *sec, arelent **relocs, .section directive to be parsed in both ELF and COFF formats. */ void -obj_coff_section (int ignore ATTRIBUTE_UNUSED) +obj_coff_section (int push) { /* Strip out the section name. */ char *section_name; @@ -1691,6 +1717,17 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED) } } + /* .pushsection implementation */ + if (push) + { + struct section_stack *elt; + elt = XNEW (struct section_stack); + elt->next = section_stack; + elt->seg = now_seg; + elt->subseg = now_subseg; + section_stack = elt; + } + sec = subseg_new (name, exp); if (is_bss) @@ -1903,6 +1940,8 @@ static const pseudo_typeS coff_pseudo_table[] = {"sect.s", obj_coff_section, 0}, {"section", obj_coff_section, 0}, {"section.s", obj_coff_section, 0}, + {"pushsection", obj_coff_section, 1}, + {"popsection", obj_coff_popsection, 0}, /* FIXME: We ignore the MRI short attribute. */ {"size", obj_coff_size, 0}, {"tag", obj_coff_tag, 0}, -- 2.55.0