• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

The MinGW.org Windows System Libraries


Commit MetaInfo

修订版7b37e9a66a0faf14dc59b7f3bc7dda51db1e9703 (tree)
时间2021-05-24 04:54:29
作者Keith Marshall <keith@user...>
CommiterKeith Marshall

Log Message

Implement a generic legacy platform support infrastructure.

更改概述

差异

--- a/mingwrt/ChangeLog
+++ b/mingwrt/ChangeLog
@@ -1,3 +1,10 @@
1+2021-05-23 Keith Marshall <keith@users.osdn.me>
2+
3+ Add a makefile clarification comment.
4+
5+ * Makefile.in (msvcrt_repl_funcs): Explain inclusion...
6+ (free, realloc): ...these.
7+
18 2021-04-11 Keith Marshall <keith@users.osdn.me>
29
310 Prepare and publish MinGW.org WSL-5.4.2 release.
--- a/mingwrt/Makefile.in
+++ b/mingwrt/Makefile.in
@@ -270,6 +270,12 @@ $(addsuffix .def,$(all_msvcrt)): %.def: msvcrt.def.in
270270 #
271271 msvcrt_repl_prefix := __msvcrt
272272 msvcrt_repl_funcs := printf fprintf sprintf vprintf vfprintf vsprintf
273+
274+# Likewise, for the MinGW wrappers which allow free() and realloc()
275+# to operate on both regularly-aligned, and on over-aligned, blocks
276+# of heap memory; (Microsoft require distinct functions for their
277+# implementations of regularly-aligned and over-aligned allocation).
278+#
273279 msvcrt_repl_funcs += free realloc
274280
275281 # This is kludgey, but dlltool lacks the selectivity to do the job
--- a/w32api/ChangeLog
+++ b/w32api/ChangeLog
@@ -1,3 +1,24 @@
1+2021-05-23 Keith Marshall <keith@users.osdn.me>
2+
3+ Implement a generic legacy platform support infrastructure.
4+
5+ * lib/availapi.c: New file; it implements...
6+ (__kernel32_entry_point, __bound_dll_entry_point)
7+ (__unbound_dll_entry_point): ...these run-time link helper functions.
8+
9+ * include/legacy.h: New file.
10+ (__kernel32_entry_point, __bound_dll_entry_point)
11+ (__unbound_dll_entry_point): Declare them.
12+ (__legacy_support): New inline error notifier; implement it.
13+ (API_UNCHECKED, API_UNSUPPORTED): Define them.
14+ (ERROR_OLD_WIN_VERSION): Duplicate.
15+
16+ * Makefile.in (libkernel32.a): Integrate...
17+ (k32entry.$OBJEXT, bound.$OBJECT): ...these; they provide...
18+ (__kernel32_entry_point, __bound_dll_entry_point): ...these; add
19+ build rules, as appropriate, incorporating...
20+ (NO_ALIGN_FLAGS): ...this new macro.
21+
122 2021-05-09 Keith Marshall <keith@users.osdn.me>
223
324 Correct TreeView_GetItemRect() syntax; cf. MinGW-Issue #41041.
--- a/w32api/Makefile.in
+++ b/w32api/Makefile.in
@@ -7,7 +7,7 @@ PACKAGE_TARNAME := @PACKAGE_TARNAME@
77 PACKAGE_VERSION := @PACKAGE_VERSION@
88
99 # Written by Keith Marshall <keithmarshall@users.sourceforge.net>
10-# Copyright (C) 2014-2017, MinGW.org Project
10+# Copyright (C) 2014-2017, 2021, MinGW.org Project
1111 #
1212 #
1313 # Permission is hereby granted, free of charge, to any person obtaining a
@@ -125,6 +125,16 @@ lib%.a: %.def
125125 $(if $(filter-out $<,$^),$(AR) $(ARFLAGS) $@ $(filter-out $<,$^))
126126
127127 vpath %.c ${srcdir}/lib
128+libkernel32.a: k32entry.$(OBJEXT) bound.$(OBJEXT)
129+
130+NO_ALIGN_FLAGS := -fno-align-jumps -fno-align-functions
131+bound.$(OBJEXT) unbound.$(OBJEXT): %.$(OBJEXT): availapi.c
132+ $(CC) -c $(ALL_CFLAGS) $(NO_ALIGN_FLAGS) -D_$* $< -o $@
133+
134+bound_dll_api_list := k32entry
135+$(addsuffix .$(OBJEXT),$(bound_dll_api_list)): %.$(OBJEXT): availapi.c
136+ $(CC) -c $(ALL_CFLAGS) $(NO_ALIGN_FLAGS) -D_bound -D_lib=$* $< -o $@
137+
128138 libuuid.a: ativscp-uuid.$(OBJEXT) cguid-uuid.$(OBJEXT)
129139 libuuid.a: comcat-uuid.$(OBJEXT) devguid.$(OBJEXT) docobj-uuid.$(OBJEXT)
130140 libuuid.a: exdisp-uuid.$(OBJEXT) extras-uuid.$(OBJEXT) hlguids-uuid.$(OBJEXT)
--- /dev/null
+++ b/w32api/include/legacy.h
@@ -0,0 +1,98 @@
1+/*
2+ * legacy.h
3+ *
4+ * Run-time binding helper routines, to facilitate access to APIs which
5+ * may not be universally supported, while allowing for graceful fall-back
6+ * action, when running on legacy Windows versions.
7+ *
8+ * $Id$
9+ *
10+ * Written by Keith Marshall <keith@users.osdn.me>
11+ * Copyright (C) 2021, MinGW.org Project
12+ *
13+ *
14+ * Permission is hereby granted, free of charge, to any person obtaining a
15+ * copy of this software and associated documentation files (the "Software"),
16+ * to deal in the Software without restriction, including without limitation
17+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18+ * and/or sell copies of the Software, and to permit persons to whom the
19+ * Software is furnished to do so, subject to the following conditions:
20+ *
21+ * The above copyright notice and this permission notice (including the next
22+ * paragraph) shall be included in all copies or substantial portions of the
23+ * Software.
24+ *
25+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31+ * DEALINGS IN THE SOFTWARE.
32+ *
33+ */
34+#ifndef _LEGACY_H
35+#define _LEGACY_H
36+
37+/* Dynamic legacy support is dependent of standard Windows-API
38+ * features, which are declared in <winbase.h>, and implemented
39+ * in kernel32.dll; the supplementary API helper functions, which
40+ * are declared herein, are all implemented as extensions within
41+ * libkernel32.a, whence they will be statically linked.
42+ */
43+#include <winbase.h>
44+
45+_BEGIN_C_DECLS
46+
47+/* Manifest constants to represent the resolution state of any
48+ * DLL entry-point; this is assumed to be recorded in a static
49+ * "void *" pointer, specific to each entry-point, initialized
50+ * to "API_UNCHECKED", and passed to the resolver, whence the
51+ * return value, (which may be either an actual entry-point
52+ * function pointer, or "API_UNSUPPORTED"), should be assigned
53+ * in place of the initial "API_UNCHECKED" value.
54+ */
55+#define API_UNCHECKED (void *)(-1)
56+#define API_UNSUPPORTED (void *)(0)
57+
58+/* The following is a duplicate of the error code, as nominally
59+ * defined in <winerror.h>; DO NOT define it conditionally, since
60+ * that would deny the compiler an opportunity to verify that it
61+ * is a faithful duplicate, if <winerror.h> is included first.
62+ */
63+#define ERROR_OLD_WIN_VERSION 1150L
64+
65+/* DLL-specific entry-point resolvers; declare as "pure", to
66+ * avoid GCC's penchant for burdening the code with unnecessary
67+ * register saves, and restores of memory, at point of call.
68+ */
69+extern __attribute__((pure))
70+void *__kernel32_entry_point (void *, const char *);
71+
72+/* Entry-point resolvers for named DLLs, (explicitly bound at
73+ * link-time, or dynamically loaded, respectively); declared as
74+ * "pure" for same reason as above.
75+ */
76+extern __attribute__((pure))
77+void *__bound_dll_entry_point (void *, const char *, const char *);
78+
79+/* Whereas the preceding resolver assumes that the DLL named by
80+ * its first "const char *" argument has been explicitly bound at
81+ * link-time, (and will return "API_UNSUPPORTED" if it has not),
82+ * the following will load the DLL if necessary, (but it will NOT
83+ * increment the reference count, if the DLL is already mapped
84+ * into the process address space).
85+ */
86+extern __attribute__((pure))
87+void *__unbound_dll_entry_point (void *, const char *, const char *);
88+
89+/* The following helper function, which is ALWAYS expanded in-line,
90+ * provides a convenient mechanism for returning an error status code,
91+ * while also setting said code as Windows last error.
92+ */
93+__CRT_ALIAS int __legacy_support( int status )
94+{ SetLastError( status ); return status; }
95+
96+_END_C_DECLS
97+
98+#endif /* !_LEGACY_H: $RCSfile$: end of file */
--- /dev/null
+++ b/w32api/lib/availapi.c
@@ -0,0 +1,168 @@
1+/*
2+ * availapi.c
3+ *
4+ * Provides generic DLL entry-point lookup helper functions, to facilitate
5+ * run-time linking of API functions which may not be supported in legacy
6+ * versions of Windows.
7+ *
8+ * $Id$
9+ *
10+ * Written by Keith Marshall <keith@users.osdn.me>
11+ * Copyright (C) 2021, MinGW.org Project
12+ *
13+ *
14+ * Permission is hereby granted, free of charge, to any person obtaining a
15+ * copy of this software and associated documentation files (the "Software"),
16+ * to deal in the Software without restriction, including without limitation
17+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18+ * and/or sell copies of the Software, and to permit persons to whom the
19+ * Software is furnished to do so, subject to the following conditions:
20+ *
21+ * The above copyright notice and this permission notice (including the next
22+ * paragraph) shall be included in all copies or substantial portions of the
23+ * Software.
24+ *
25+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31+ * DEALINGS IN THE SOFTWARE.
32+ *
33+ *
34+ * Compile this module multiple times, once for each entry-point resolver
35+ * which is required; the specifics of the resolver are determined thus:
36+ *
37+ * $ gcc -c -D_bound availapi.c -o bound.o
38+ *
39+ * will create a generic resolver, named __bound_dll_entry_point(), which
40+ * will resolve entry-points ONLY within DLLs which have been explicitly
41+ * loaded beforehand. Conversely:
42+ *
43+ * $ gcc -c -D_unbound availapi.c -o unbound.o
44+ *
45+ * will create a generic resolver, named __unbound_dll_entry_point(); this
46+ * will attempt to load a named DLL, if it is not already mapped, before it
47+ * attempts to resolve a named entry-point within it. Finally:
48+ *
49+ * $ gcc -c -D_lib=DLLNAME [-D_bound] availapi.c -o dllentry.o
50+ *
51+ * will create a resolver specific to the DLL specified by DLLNAME, (the
52+ * file-name only part of the DLL name, WITHOUT either the ".dll" suffix,
53+ * or any preceding directory path qualification; this resolver will be
54+ * named __DLLNAME_entry_point(). If the "-D_lib=DLLNAME" specification
55+ * is accompanied by the optional "-D_bound" flag, this resolver will be
56+ * implemented as a thin wrapper around __bound_dll_entry_point(); OTOH,
57+ * if the "-D_bound" flag is not specified, it will be implemented as a
58+ * thin wrapper around __unbound_dll_entry_point().
59+ *
60+ */
61+#include "legacy.h"
62+
63+#if defined _lib
64+/* The entry-point resolver is to be associated with a specifically
65+ * named DLL; define a set of mappings between preferred object file
66+ * names (aliases), and their associated DLL names; (note that this
67+ * facility is primarily provided to accommodate makefile mapping of
68+ * resolver object file names to DLL names; the DLLNAME reference,
69+ * within the command line "-D_lib=DLLNAME" specification, is given
70+ * as the alias, but within the resolver FUNCTION name, it is ALWAYS
71+ * set to match the "DLL Name" entry from the following table):
72+ *
73+ * Alias DLL Name
74+ * -------- -------- */
75+# define k32entry kernel32
76+
77+/* Provide a set of macros, to derive the entry-point resolver name,
78+ * and its associated DLL name, from the command line assignment for
79+ * the object file's base name:
80+ */
81+# define _dll(_lib) _as_string(_lib) ".dll"
82+# define _entry(_lib) __##_lib##_entry_point
83+# define _entry_point(_lib) _entry(_lib)
84+# define _as_string(_name) #_name
85+
86+/* Implement the appropriately named entry-point resolver function...
87+ */
88+void *_entry_point(_lib) (void *hook, const char *procname)
89+# if defined _bound
90+{ /* ...in terms of the appropiate resolver for a DLL which is
91+ * expected to have been implicitly loaded, (i.e. explicitly
92+ * bound to the executable, at link-time)...
93+ */
94+ return __bound_dll_entry_point( hook, _dll(_lib), procname );
95+}
96+# else
97+{ /* ...or otherwise, for a DLL which MAY need to be explicitly
98+ * loaded, on demand.
99+ */
100+ return __unbound_dll_entry_point( hook, _dll(_lib), procname );
101+}
102+# endif
103+#elif defined _bound
104+/* This entry-point resolver is to be generic, w.r.t. the DLL name
105+ * with which it will be associated, but will require that the named
106+ * DLL has been explicitly bound to the application, at link-time.
107+ */
108+void *__bound_dll_entry_point
109+( void *hook, const char *dllname, const char *procname )
110+{
111+ /* If the passed entry-point hook has already been assigned, then
112+ * there is nothing more to do, other than to return it...
113+ */
114+ if( hook == API_UNCHECKED )
115+ { /* ...otherwise, we perform a DLL entry-point lookup, considering
116+ * only DLLs which are already mapped into the address space of the
117+ * calling process, and subsequently updating the hook to represent
118+ * the entry-point, or mark it as permanently unsupported.
119+ */
120+ HMODULE dll = GetModuleHandleA( dllname );
121+ hook = (dll == NULL) ? GetProcAddress( dll, procname ) : API_UNSUPPORTED;
122+ }
123+ /* In any case, we return the (possibly updated) hook, which should
124+ * then be recorded by the caller.
125+ */
126+ return hook;
127+}
128+#elif defined _unbound
129+/* This entry-point resolver performs a similar function to that above,
130+ * except that it will attempt to explicitly load any named DLL which is
131+ * not already mapped into the address space of the calling process.
132+ */
133+void *__unbound_dll_entry_point
134+( void *hook, const char *dllname, const char *procname )
135+{
136+ /* If the passed entry-point hook has already been assigned, then
137+ * there is nothing more to do, other than to return it...
138+ */
139+ if( hook == API_UNCHECKED )
140+ { /* ...otherwise, we perform a DLL entry-point lookup, loading
141+ * the named DLL, if it has not yet been mapped into the address
142+ * space of the calling process...
143+ */
144+ HMODULE dll = GetModuleHandleA( dllname );
145+ if( (dll == NULL) && ((dll = LoadLibraryA( dllname )) == NULL) )
146+ /*
147+ * ...marking the hook as permanently unsupported, in the
148+ * event of failure to map the DLL...
149+ */
150+ return hook = API_UNSUPPORTED;
151+
152+ /* ...otherwise, updating it to reflect the lookup result.
153+ */
154+ hook = GetProcAddress( dll, procname );
155+ }
156+ /* In any case, we return the (possibly updated) hook, which should
157+ * then be recorded by the caller.
158+ */
159+ return hook;
160+}
161+#else
162+/* None of the mandatory -D_spec arguments have been specified; we need
163+ * at least one of...
164+ */
165+# error "A -D_lib=DLLNAME, -D_bound, or -D_unbound argument is required."
166+#endif
167+
168+/* $RCSfile$: end of file */