[PATCH 2/3] include: Emit assembly function debug line info.

Rémi Bernon rbernon at codeweavers.com
Mon Nov 30 03:30:20 CST 2020


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

This is a little bit ugly, but I don't think there is any other way.

The idea here is that we need .file and .loc pseudo-op be generated for
the assembly functions. We cannot output them ourselves, as .file op
requires a uniquely increasing file number, which varies depending on
what has been previously emitted already.

We use the dummy wrapper to benefit from its automatically emitted
instructions, however even when using naked function, GCC still emits
cfi/seh pseudo-ops too, and it gets confused with our own. The trick
here is to fake the function end before emitting our assembly, and fake
another function start before ending the dummy wrapper.

 include/wine/asm.h | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/include/wine/asm.h b/include/wine/asm.h
index 7975e377341..f1e358f13d8 100644
--- a/include/wine/asm.h
+++ b/include/wine/asm.h
@@ -21,6 +21,12 @@
 #ifndef __WINE_WINE_ASM_H
 #define __WINE_WINE_ASM_H
 
+#define __ASM_STR_I(x) #x
+#define __ASM_STR(x) __ASM_STR_I(x)
+
+#define __ASM_CAT_I(x,y) x ## y
+#define __ASM_CAT(x,y) __ASM_CAT_I(x, y)
+
 #if defined(__APPLE__) || (defined(_WIN32) && defined(__i386__))
 # define __ASM_NAME(name) "_" name
 #else
@@ -74,18 +80,31 @@
 #endif
 
 #if !defined(__GNUC__) && !defined(__clang__)
-# define __ASM_BLOCK_BEGIN(name) void __asm_dummy_##name(void) {
+# define __ASM_BLOCK_BEGIN(name) void __ASM_CAT(__asm_dummy_,name)(void) {
 # define __ASM_BLOCK_END         }
 #else
 # define __ASM_BLOCK_BEGIN(name)
 # define __ASM_BLOCK_END
 #endif
 
+#if !defined(__GNUC__)
+# define __ASM_FUNC_BEGIN(line) __ASM_BLOCK_BEGIN(line)
+# define __ASM_FUNC_END(line)   __ASM_BLOCK_END
+#else
+# define __ASM_FUNC_BEGIN(line) \
+    static void __attribute__((naked,used)) __ASM_CAT(__asm_dummy_,line)(void) { \
+        asm(__ASM_CFI("\n\t.cfi_endproc") __ASM_SEH("\n\t.seh_endproc"));
+# define __ASM_FUNC_END(line) \
+        asm(__ASM_SEH("\n\t.seh_proc .L__asm_dummy_" __ASM_STR(line) "\n.L__asm_dummy_" __ASM_STR(line) ":") \
+            __ASM_CFI("\n\t.cfi_startproc")); \
+    }
+#endif
+
 #define __ASM_DEFINE_FUNC(name,code)  \
-    __ASM_BLOCK_BEGIN(__LINE__) \
+    __ASM_FUNC_BEGIN(__LINE__) \
     asm(".text\n\t.align 4\n\t.globl " name "\n\t" __ASM_FUNC_TYPE(name) __ASM_SEH("\n\t.seh_proc " name) "\n" name ":\n\t" \
         __ASM_CFI(".cfi_startproc\n\t") code __ASM_CFI("\n\t.cfi_endproc") __ASM_SEH("\n\t.seh_endproc") "\n\t" __ASM_FUNC_SIZE(name) "\n" ); \
-    __ASM_BLOCK_END
+    __ASM_FUNC_END(__LINE__)
 
 #define __ASM_GLOBAL_FUNC(name,code) __ASM_DEFINE_FUNC(__ASM_NAME(#name),code)
 #define __ASM_STDCALL_FUNC(name,args,code) __ASM_DEFINE_FUNC(__ASM_STDCALL(#name,args),code)
-- 
2.29.2




More information about the wine-devel mailing list