English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System

 
 
Thread Tools
Old 01 March 2023, 22:22   #1
Krashan
Hardware Designer
 
Join Date: Aug 2018
Location: Bialystok/Poland
Age: 50
Posts: 178
Implementation details of taglist variadic functions

I have looked into implementation of functions like OpenWindowTags(). We know that only OpenWindowTagList() is really in intuition.library, variadic version is created by include files. I use native GCC 2.95.3 and it implements variadic taglist functions as variadic macros, where named version of __VA_ARGS__ is used as content of local array initializer.
Code:
ULONG _tags = {tags};
where tags is "variadic argument" of the macro, then address of _tags is passed to OpenWindowTagList().

Compiled code looks weird. Compiler allocates space on stack using LINK instruction, twice the size of the taglist. It fills the taglist with tags and values in the first half on the space, then calls bcopy() to copy the taglist to the second half of the space. Finally it passes address of the copy to OpenWindowTagList(). What is the point of this copy? It also creates a minor problem when linking with -nostdlib, as bcopy() has to be delivered somehow.

I have to admit that using variadic function (instead of macro) and just passing address of the first tag argument creates smaller, cleaner and faster code. For example:
Code:
struct Window* OpenWindowTags(struct NewWindow *nwin, ULONG tag, ...)
{
  struct TagItem *tags = (struct TagItem*)&tag;
  return OpenWindowTagList(nwin, tags);
}
In this case taglist is built on the stack and is right away passed to the "real" function. I've heard that it is a "dirty hack" and is not portable, but it works + I do not care that much about portability beyond M68k Amiga. Or maybe I'm missing something else?
Krashan is offline  
Old 02 March 2023, 11:33   #2
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by Krashan View Post
I have looked into implementation of functions like OpenWindowTags(). We know that only OpenWindowTagList() is really in intuition.library, variadic version is created by include files.
No. The variadic version is in
amiga.lib
.

An optional version using compiler-specific pragmas or inlines may be in some compiler-specific header file, when including
<proto/intuition.h>
. If you include
<clib/intuition_protos.h>
instead, you can be sure that the version from
amiga.lib
is used.

Quote:
I use native GCC 2.95.3 and it implements variadic taglist functions as variadic macros, where named version of __VA_ARGS__ is used as content of local array initializer.
__VA_ARGS__
is C99, but a named version with
{tags}
is gcc-specific.

Quote:
I have to admit that using variadic function (instead of macro) and just passing address of the first tag argument creates smaller, cleaner and faster code.
The version in
amiga.lib
looks the same as your example. Just link with it.
Maybe later gcc code generators create better code, but using macros might not be the best approach here.

Quote:
I've heard that it is a "dirty hack" and is not portable
It is only portable among architectures which pass all function arguments on the stack. Which m68k does, when using the default ABI. PPC doesn't, as it passes up to eight(?) arguments in registers.

At least it would be more portable than your macro using gcc-specific extensions.

When linking with
amiga.lib
you also eliminate any "dirty hacks", as you only call
OpenWindowTags()
following the default ABI, the rest is handled there, as your compiler's
amiga.lib
knows the ABI.

Maybe it is possible to exclude only the macros for variadic OS-calls from your includes? Don't know about gcc, but at least with vbcc can define
-DNO_INLINE_STDARG
for that.
phx is offline  
Old 02 March 2023, 14:53   #3
Krashan
Hardware Designer
 
Join Date: Aug 2018
Location: Bialystok/Poland
Age: 50
Posts: 178
Quote:
Originally Posted by phx View Post
At least it would be more portable than your macro using gcc-specific extensions.
This is not my macro. It is generated with
fd2pragma
tool and resides in
<inline/intuition.h>
, which is included from
<proto/intuition.h>


Anyway I have defined NO_INLINE_STDARG, downloaded latest NDK, extracted
amiga.lib
, changed name to
libamiga.a
, so the linker recognizes it, all fine but...
Code:
hunk_drelx not supported yet
hunk_drelx not supported yet
main.o(.text_0x102): undefined reference to `OpenWindowTags'
NDK 3.9 version does not trigger warnings about "hunk_drelx", but the final result is the same, symbol is not found. Maybe the library itself should be recompiled with GCC, who knows.
Krashan is offline  
Old 02 March 2023, 17:04   #4
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by Krashan View Post
Code:
hunk_drelx not supported yet
That's interesting! My first thought was: ok, your GNU-ld does not support small-data references. But on the other hand the official NDK 3.2
amiga.lib
should not contain any small data code at all. So I scanned it for any
HUNK_DREL32
,
HUNK_DREL16
or
HUNK_DREL8
hunks. And I found one
HUNK_DREL32
in the last unit of the library: "Acrypt.c".

HUNK_DREL32
is very strange, as there are usually only 16-bit small-data references generated by most Amiga compilers. Don't know if Olaf reads this, otherwise I have to contact him. I don't think this is intended.

Quote:
Code:
main.o(.text_0x102): undefined reference to `OpenWindowTags'
NDK 3.9 version does not trigger warnings about "hunk_drelx", but the final result is the same, symbol is not found.
Can it resolve any library function name with this library? This looks like a problem with your compiler's ABI. It may be configured for m68k V.4/ELF, which doesn't use a leading underscore in global C symbol names. This is common for most other m68k ABIs (Unix-a.out, AmigaOS, Atari-TOS, etc.).

In other words: the library defines
_OpenWindowTags
.

Quote:
Maybe the library itself should be recompiled with GCC, who knows.
Yes. This might remove the leading underscores as well.
phx is offline  
Old 02 March 2023, 19:45   #5
Krashan
Hardware Designer
 
Join Date: Aug 2018
Location: Bialystok/Poland
Age: 50
Posts: 178
Quote:
Originally Posted by phx View Post
Can it resolve any library function name with this library?
No, because
nm
chokes on this unknown hunk and reports no symbols found. I've also noticed that IRA refuses to disassemble the library for the very same reason.

Quote:
Originally Posted by phx View Post
This looks like a problem with your compiler's ABI. It may be configured for m68k V.4/ELF, which doesn't use a leading underscore in global C symbol names.
Don't think so. Functions in all my object files and linklibs have leading underscores.
gcc -dumpmachine
shows "m68k-amigaos".
I guess I can write a Python script (to be run on PC) which will parse FD files and generate variadic stubs code. Then I can compile it and have not complete, but working
libamiga.a
.
Krashan is offline  
Old 04 March 2023, 14:44   #6
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by Krashan View Post
No, because
nm
chokes on this unknown hunk and reports no symbols found.
You can also try with an older amiga.lib from NDK3.1 or 3.9.
Or remove the Acrypt.c unit from the 3.2 amiga.lib. In my version it is the last unit (HUNK_UNIT $000003e7, named "ACrypt.c") starting at offset $36534. The last 320 bytes of amiga.lib. Who needs Acrypt anyway...

Quote:
I've also noticed that IRA refuses to disassemble the library for the very same reason.
Indeed. That's a bug. It uses the same code to parse DREL32 as in executables. But in executables (only) HUNK_DREL32 has the same meaning as HUNK_RELOC32SHORT.

Quote:
Don't think so. Functions in all my object files and linklibs have leading underscores.
Hmm. But your error message was
undefined reference to `OpenWindowTags'
. Does the linker automatically translate the symbol names? Does your gcc generate hunk-format, a.out or ELF object files?

Quote:
I guess I can write a Python script (to be run on PC) which will parse FD files and generate variadic stubs code. Then I can compile it and have not complete, but working
libamiga.a
.
I'm sure somebody already did that before.
I would use fd2pragma to generate the assembler source for all the stubs (including variadic ones).
Code:
fd2pragma -s 90 -t /tmp/ -n .text -i /path/to/NDK_3.2/SFD/intuition_lib.sfd
Then assemble all sources into the object file format you need (ELF? a.out?) and put them into a gcc library:
ar q libamiga.a *.o
phx is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
non-constant TagList values and SASC6.58 alancfrancis Coders. C/C++ 5 31 May 2021 17:59
Calling assembler functions from C Nosferax Coders. C/C++ 41 25 March 2020 12:55
Calling OS Functions? nocash Coders. System 5 03 February 2016 09:27
functions benchmark wawa Coders. System 2 15 April 2013 18:55
How do the non-i/o functions work? mikro project.WHDLoad 3 03 November 2011 14:33

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 00:35.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.09391 seconds with 13 queries