public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/114984] New: asm() renaming of symbols inconsistent with dllimport
@ 2024-05-08 11:27 martin at martin dot st
  2024-05-08 11:30 ` [Bug target/114984] " martin at martin dot st
  2024-05-08 11:35 ` martin at martin dot st
  0 siblings, 2 replies; 3+ messages in thread
From: martin at martin dot st @ 2024-05-08 11:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114984

            Bug ID: 114984
           Summary: asm() renaming of symbols inconsistent with dllimport
           Product: gcc
           Version: 13.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: martin at martin dot st
  Target Milestone: ---

A function declaration can use asm("") to point out that the function actually
exists under a different symbol name. E.g. like this:

$ cat call-bar.c
extern void foo (void) asm("bar");
void call_bar(void)
{ foo(); }

$ x86_64-w64-mingw32-gcc -S -O2 -o - call-bar.c 
call_bar:
        jmp     bar

On i686, where symbols normally have an extra underscore prefix (signaled via
__USER_LABEL_PREFIX__), the symbol name in asm() is taken literally, so one has
to include the underscore prefix manually:

$ cat call-bar.c
extern void foo (void) asm("_bar");
void call_bar(void)
{ foo(); }
$ i686-w64-mingw32-gcc -S -O2 -o - call-bar.c
_call_bar:
        jmp     _bar


If the renamed function is declared with dllimport, however, GCC suddenly
treats the symbol name given with asm("") as an undecorated one, that gets the
extra implicit underscore added.

$ cat call-bar2.c 
extern __declspec(dllimport) void foo1 (void) asm("_bar");
extern __declspec(dllimport) void foo2 (void);
void call_bar(void)
{ foo1(); foo2(); }
$ /usr/bin/i686-w64-mingw32-gcc -S -O2 -o - call-bar2.c -O2
_call_bar:
        subl    $12, %esp
        call    *__imp___bar
        addl    $12, %esp
        jmp     *__imp__foo2

Regularly, when adding dllimport, it references a symbol named "__imp_"
followed by the symbol name used without dllimport, i.e. a non-dllimport call
to "foo2" would reference "_foo2", while a dllimport call references
"__imp__foo2".

Therefore, it is surprising and inconsistent that dllimport together with asm()
implicitly includes __USER_LABEL_PREFIX__, while asm() without dllimport
doesn't.

This issue was reported already in 2007 in
https://sourceware.org/pipermail/cygwin/2007-February/154845.html, with an
intent to send a patch, but I find no traces of such a patch.

To fully show off all combinations in one example, consider:

$ cat sym-asm.c 
void regular(void);
void __declspec(dllimport) imported(void);
void renamed(void) asm("newname");
void __declspec(dllimport) renamedimported(void) asm("newimportedname");

void call(void) {
  regular();
  imported();
  renamed();
  renamedimported();
}
$ i686-w64-mingw32-gcc -S -O2 -o - sym-asm.c 
_call:
        subl    $12, %esp
        call    _regular
        call    *__imp__imported
        call    newname
        addl    $12, %esp
        jmp     *__imp__newimportedname

Contrary, Clang does seem to handle this consistently:
$ clang -target i686-w64-mingw32 -S -O2 -o - sym-asm.c 
_call:
        calll   _regular
        calll   *__imp__imported
        calll   newname
        jmpl    *__imp_newimportedname

I.e., when naming the symbol asm("newimportedname"), this singifies the literal
string that would be included after "__imp_", i.e. the user need to include
__USER_LABEL_PREFIX__ within asm("").

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug target/114984] asm() renaming of symbols inconsistent with dllimport
  2024-05-08 11:27 [Bug target/114984] New: asm() renaming of symbols inconsistent with dllimport martin at martin dot st
@ 2024-05-08 11:30 ` martin at martin dot st
  2024-05-08 11:35 ` martin at martin dot st
  1 sibling, 0 replies; 3+ messages in thread
From: martin at martin dot st @ 2024-05-08 11:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114984

--- Comment #1 from Martin Storsjö <martin at martin dot st> ---
The suggestion in
https://sourceware.org/pipermail/cygwin/2007-February/154845.html was that for
dllimported symbols, the string passed in asm("") should be entirely literal,
i.e. no implicit "__imp_" prepended.

While I can agree that this would be reasonable, it would differ even more from
what Clang already does (which is self consistent). So I believe the most
consistent and straightforward fix would be to make GCC prepend "__imp_" before
the string from asm(""), for dllimport symbols, instead of "__imp__".

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug target/114984] asm() renaming of symbols inconsistent with dllimport
  2024-05-08 11:27 [Bug target/114984] New: asm() renaming of symbols inconsistent with dllimport martin at martin dot st
  2024-05-08 11:30 ` [Bug target/114984] " martin at martin dot st
@ 2024-05-08 11:35 ` martin at martin dot st
  1 sibling, 0 replies; 3+ messages in thread
From: martin at martin dot st @ 2024-05-08 11:35 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114984

--- Comment #2 from Martin Storsjö <martin at martin dot st> ---
To clarify the concern for changing whether "__imp_" is implied for asm("") on
dllimported symbols or not; on all other mingw architectures than i386, there's
no extra symbol prefix, so the current behaviour there works just fine and is
reasonably consistent.

Thus, by only fixing the extra underscore prefix, the only case that changes is
i386 + dllimport + asm(), while if we'd require the whole "__imp_" prefix to be
specified, we'd affect all other architectures as well (which are well off as
they are).

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-05-08 11:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-08 11:27 [Bug target/114984] New: asm() renaming of symbols inconsistent with dllimport martin at martin dot st
2024-05-08 11:30 ` [Bug target/114984] " martin at martin dot st
2024-05-08 11:35 ` martin at martin dot st

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).