From: egor duda <deo@logos-m.ru>
To: binutils@sources.redhat.com
Cc: Charles Wilson <cwilson@ece.gatech.edu>, cygwin-apps@sources.redhat.com
Subject: Re: --enable-auto-import extension
Date: Tue, 02 Jul 2002 08:39:00 -0000 [thread overview]
Message-ID: <903891375.20020702193614@logos-m.ru> (raw)
In-Reply-To: <3D20C981.8020407@ece.gatech.edu>
[-- Attachment #1: Type: text/plain, Size: 1471 bytes --]
Hi!
Tuesday, 02 July, 2002 Charles Wilson cwilson@ece.gatech.edu wrote:
>> What i was talking about is 64-bit versions of windows where addresses
>> (and so base symbol values and addends are 64-bit). Or if we want to
>> add some other types of relocations. Adding type field will make it
>> possible to add extensions to this feature.
CW> </sheepish> Yeah. What he said. <I'll be over here....>
Well, after thinking twice about it i concluded that such flexibility
may be not that good after all. Sure, it allows adding extensions, but
make it hard to check at link-time if runtime support for those
extensions is present. So i think we can stay with simple format of
pseudo relocations for now.
>> Of course. Luckily, all we have to check is that it doesn't change
>> binaries for existing code,
CW> Hard to do, really -- DLLs get a timestamp in their header, so even
CW> under ideal conditions you can't do a simple diff on two DLLs...I
CW> suppose you could make sure that two DLLs differ ONLY in "unimportant"
CW> ways, like timestamp.
Someone suggested that one can do 'cmp -i 150 old.dll new.dll', or
whatever offset timestamp is located at.
Ok, i've finalized patch and test. I suppose i have a copyright
assignment with FSF for this changes to get incorporated into official
sources. As far as i understand, i have to get an assignment form from
binutils maintainer, right?
Egor. mailto:deo@logos-m.ru ICQ 5165414 FidoNet 2:5020/496.19
[-- Attachment #2: include.ChangeLog --]
[-- Type: application/octet-stream, Size: 130 bytes --]
2002-07-01 Egor Duda <deo@logos-m.ru>
* bfdlink.h (struct bfd_link_info): Add new boolean
field pei386_runtime_pseudo_reloc.
[-- Attachment #3: include.diff --]
[-- Type: application/octet-stream, Size: 733 bytes --]
Index: bfdlink.h
===================================================================
RCS file: /cvs/uberbaum/include/bfdlink.h,v
retrieving revision 1.20
diff -u -p -2 -r1.20 bfdlink.h
--- bfdlink.h 1 Jul 2002 08:04:47 -0000 1.20
+++ bfdlink.h 2 Jul 2002 07:47:09 -0000
@@ -330,4 +330,9 @@ struct bfd_link_info
int pei386_auto_import;
+ /* Non-zero if runtime relocs for DATA items with non-zero addends
+ in pei386 DLLs should be generated. Set to 1 if this feature
+ is explicitly requested by the user, -1 if enabled by default. */
+ int pei386_runtime_pseudo_reloc;
+
/* True if non-PLT relocs should be merged into one reloc section
and sorted so that relocs against the same symbol come together. */
[-- Attachment #4: ld.ChangeLog --]
[-- Type: application/octet-stream, Size: 854 bytes --]
2002-07-01 Egor Duda <deo@logos-m.ru>
* ldmain.c (main): Make runtime relocs disabled by default. Remove
assignment which has no effect.
* pe-dll.h (pe_create_import_fixup): Change prototype.
* pe-dll.c (make_runtime_pseudo_reloc): New function.
(pe_create_runtime_relocator_reference): Ditto.
(pe_create_import_fixup): Handle relocations with non-zero addends.
* emultempl/pe.em: Add options --enable-runtime-pseudo-reloc and
--disable-runtime-pseudo-reloc.
(make_import_fixup): Handle relocations with non-zero addends. Create
an external reference to _pei386_runtime_relocator symbol if at least
one pseudo reloc was created.
* scripttempl/pe.sc: Handle .rdata_runtime_pseudo_reloc sections.
Add symbols for application to access them.
* ld.texinfo: Document --enable-runtime-pseudo-reloc and
--disable-runtime-pseudo-reloc options.
[-- Attachment #5: ld.diff --]
[-- Type: application/octet-stream, Size: 12184 bytes --]
Index: ld.texinfo
===================================================================
RCS file: /cvs/uberbaum/ld/ld.texinfo,v
retrieving revision 1.70
diff -u -p -2 -r1.70 ld.texinfo
--- ld.texinfo 20 Jun 2002 14:44:10 -0000 1.70
+++ ld.texinfo 2 Jul 2002 11:37:31 -0000
@@ -1794,5 +1794,9 @@ There are several ways to address this d
data type of the exported variable:
-One solution is to force one of the 'constants' to be a variable --
+One way is to use --enable-runtime-pseudo-reloc switch. This leaves the task
+of adjusting references in your client code for runtime environment, so
+this method works only when runtime environtment supports this feature.
+
+Second solution is to force one of the 'constants' to be a variable --
that is, unknown and un-optimizable at compile time. For arrays,
there are two possibilities: a) make the indexee (the array's address)
@@ -1830,5 +1834,5 @@ extern_ll -->
@end example
-A second method of dealing with this difficulty is to abandon
+A third method of dealing with this difficulty is to abandon
'auto-import' for the offending symbol and mark it with
@code{__declspec(dllimport)}. However, in practice that
@@ -1881,5 +1885,5 @@ void main(int argc, char **argv)@{
@end example
-A third way to avoid this problem is to re-code your
+A fouth way to avoid this problem is to re-code your
library to use a functional interface rather than a data interface
for the offending variables (e.g. set_foo() and get_foo() accessor
@@ -1890,4 +1894,15 @@ functions).
Do not attempt to do sophisticalted linking of @code{_symbol} to
@code{__imp__symbol} for DATA imports from DLLs.
+
+@kindex --enable-runtime-pseudo-reloc
+@item --enable-runtime-pseudo-reloc
+If your code contains expressions described in --enable-auto-import section,
+that is, DATA imports from DLL with non-zero offset, this switch will create
+a vector of 'runtime pseudo relocations' which can be used by runtime
+environment to adjust references to such data in your client code.
+
+@kindex --disable-runtime-pseudo-reloc
+@item --disable-runtime-pseudo-reloc
+Do not create pseudo relocations for non-zero offset DATA imports from DLLs.
@kindex --enable-extra-pe-debug
Index: ldmain.c
===================================================================
RCS file: /cvs/uberbaum/ld/ldmain.c,v
retrieving revision 1.49
diff -u -p -2 -r1.49 ldmain.c
--- ldmain.c 1 Jul 2002 08:07:29 -0000 1.49
+++ ldmain.c 2 Jul 2002 11:37:32 -0000
@@ -261,6 +261,6 @@ main (argc, argv)
link_info.flags = (bfd_vma) 0;
link_info.flags_1 = (bfd_vma) 0;
- link_info.pei386_auto_import = false;
link_info.pei386_auto_import = -1;
+ link_info.pei386_runtime_pseudo_reloc = false;
link_info.combreloc = true;
link_info.spare_dynamic_tags = 5;
Index: pe-dll.c
===================================================================
RCS file: /cvs/uberbaum/ld/pe-dll.c,v
retrieving revision 1.41
diff -u -p -2 -r1.41 pe-dll.c
--- pe-dll.c 25 May 2002 20:39:25 -0000 1.41
+++ pe-dll.c 2 Jul 2002 11:37:32 -0000
@@ -142,4 +142,5 @@ static struct sec *edata_s, *reloc_s;
static unsigned char *edata_d, *reloc_d;
static size_t edata_sz, reloc_sz;
+static int runtime_pseudo_relocs_created = 0;
typedef struct
@@ -302,4 +303,8 @@ static char *make_import_fixup_mark PARA
static bfd *make_import_fixup_entry
PARAMS ((const char *, const char *, const char *, bfd *));
+static bfd *make_runtime_pseudo_reloc
+ PARAMS ((const char *, const char *, int, bfd *));
+static bfd *pe_create_runtime_relocator_reference
+ PARAMS ((bfd *parent));
static unsigned int pe_get16 PARAMS ((bfd *, int));
static unsigned int pe_get32 PARAMS ((bfd *, int));
@@ -2068,7 +2073,103 @@ make_import_fixup_entry (name, fixup_nam
}
+/* .section .rdata_runtime_pseudo_reloc
+ .long addend
+ .rva __fuNN_SYM (pointer to reference (address) in text) */
+
+static bfd *
+make_runtime_pseudo_reloc (name, fixup_name, addend, parent)
+ const char *name ATTRIBUTE_UNUSED;
+ const char *fixup_name;
+ int addend;
+ bfd *parent;
+{
+ asection *rt_rel;
+ unsigned char *rt_rel_d;
+ char *oname;
+ bfd *abfd;
+
+ oname = (char *) xmalloc (20);
+ sprintf (oname, "rtr%06d.o", tmp_seq);
+ tmp_seq++;
+
+ abfd = bfd_create (oname, parent);
+ bfd_find_target (pe_details->object_target, abfd);
+ bfd_make_writable (abfd);
+
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
+
+ symptr = 0;
+ symtab = (asymbol **) xmalloc (2 * sizeof (asymbol *));
+ rt_rel = quick_section (abfd, ".rdata_runtime_pseudo_reloc", SEC_HAS_CONTENTS, 2);
+
+ quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
+
+ bfd_set_section_size (abfd, rt_rel, 8);
+ rt_rel_d = (unsigned char *) xmalloc (8);
+ rt_rel->contents = rt_rel_d;
+ memset (rt_rel_d, 0, 8);
+ bfd_put_32 (abfd, addend, rt_rel_d);
+
+ quick_reloc (abfd, 4, BFD_RELOC_RVA, 1);
+ save_relocs (rt_rel);
+
+ bfd_set_symtab (abfd, symtab, symptr);
+
+ bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, 8);
+
+ bfd_make_readable (abfd);
+ return abfd;
+}
+
+/* .section .rdata
+ .rva __pei386_runtime_relocator */
+
+static bfd *
+pe_create_runtime_relocator_reference (parent)
+ bfd *parent;
+{
+ asection *extern_rt_rel;
+ unsigned char *extern_rt_rel_d;
+ char *oname;
+ bfd *abfd;
+
+ oname = (char *) xmalloc (20);
+ sprintf (oname, "ertr%06d.o", tmp_seq);
+ tmp_seq++;
+
+ abfd = bfd_create (oname, parent);
+ bfd_find_target (pe_details->object_target, abfd);
+ bfd_make_writable (abfd);
+
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
+
+ symptr = 0;
+ symtab = (asymbol **) xmalloc (2 * sizeof (asymbol *));
+ extern_rt_rel = quick_section (abfd, ".rdata", SEC_HAS_CONTENTS, 2);
+
+ quick_symbol (abfd, "", "__pei386_runtime_relocator", "", UNDSEC, BSF_NO_FLAGS, 0);
+
+ bfd_set_section_size (abfd, extern_rt_rel, 4);
+ extern_rt_rel_d = (unsigned char *) xmalloc (4);
+ extern_rt_rel->contents = extern_rt_rel_d;
+
+ quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
+ save_relocs (extern_rt_rel);
+
+ bfd_set_symtab (abfd, symtab, symptr);
+
+ bfd_set_section_contents (abfd, extern_rt_rel, extern_rt_rel_d, 0, 4);
+
+ bfd_make_readable (abfd);
+ return abfd;
+}
+
void
-pe_create_import_fixup (rel)
+pe_create_import_fixup (rel, s, addend)
arelent *rel;
+ asection *s;
+ int addend;
{
char buf[300];
@@ -2077,4 +2178,5 @@ pe_create_import_fixup (rel)
const char *name = sym->name;
char *fixup_name = make_import_fixup_mark (rel);
+ bfd *b;
sprintf (buf, U ("_nm_thnk_%s"), name);
@@ -2091,12 +2193,36 @@ pe_create_import_fixup (rel)
}
- {
- extern char * pe_data_import_dll;
- char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
+ if (addend == 0 || link_info.pei386_runtime_pseudo_reloc)
+ {
+ extern char * pe_data_import_dll;
+ char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
- bfd *b = make_import_fixup_entry (name, fixup_name, dll_symname,
- output_bfd);
- add_bfd_to_link (b, b->filename, &link_info);
- }
+ b = make_import_fixup_entry (name, fixup_name, dll_symname, output_bfd);
+ add_bfd_to_link (b, b->filename, &link_info);
+ }
+
+ if (addend != 0)
+ {
+ if (link_info.pei386_runtime_pseudo_reloc)
+ {
+ if (pe_dll_extra_pe_debug)
+ printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
+ fixup_name, addend);
+ b = make_runtime_pseudo_reloc (name, fixup_name, addend, output_bfd);
+ add_bfd_to_link (b, b->filename, &link_info);
+ if (runtime_pseudo_relocs_created == 0)
+ {
+ b = pe_create_runtime_relocator_reference (output_bfd);
+ add_bfd_to_link (b, b->filename, &link_info);
+ }
+ runtime_pseudo_relocs_created++;
+ }
+ else
+ {
+ einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
+ s->owner, s, rel->address, sym->name);
+ einfo ("%X");
+ }
+ }
}
Index: pe-dll.h
===================================================================
RCS file: /cvs/uberbaum/ld/pe-dll.h,v
retrieving revision 1.8
diff -u -p -2 -r1.8 pe-dll.h
--- pe-dll.h 8 Jun 2002 07:39:45 -0000 1.8
+++ pe-dll.h 2 Jul 2002 11:37:32 -0000
@@ -51,4 +51,4 @@ extern void pe_walk_relocs_of_symbol PAR
int (*cb) (arelent *, asection *)));
-extern void pe_create_import_fixup PARAMS ((arelent * rel));
+extern void pe_create_import_fixup PARAMS ((arelent * rel, asection * s, int addend));
#endif /* PE_DLL_H */
Index: emultempl/pe.em
===================================================================
RCS file: /cvs/uberbaum/ld/emultempl/pe.em,v
retrieving revision 1.65
diff -u -p -2 -r1.65 pe.em
--- emultempl/pe.em 1 Jul 2002 08:07:31 -0000 1.65
+++ emultempl/pe.em 2 Jul 2002 11:37:37 -0000
@@ -175,4 +175,5 @@ gld_${EMULATION_NAME}_before_parse()
config.has_shared = 1;
link_info.pei386_auto_import = -1;
+ link_info.pei386_runtime_pseudo_reloc = false;
#if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
@@ -223,4 +224,8 @@ gld_${EMULATION_NAME}_before_parse()
#define OPTION_ENABLE_EXTRA_PE_DEBUG (OPTION_DLL_DISABLE_AUTO_IMPORT + 1)
#define OPTION_EXCLUDE_LIBS (OPTION_ENABLE_EXTRA_PE_DEBUG + 1)
+#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC \
+ (OPTION_EXCLUDE_LIBS + 1)
+#define OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC \
+ (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC + 1)
static struct option longopts[] = {
@@ -264,4 +269,6 @@ static struct option longopts[] = {
{"disable-auto-import", no_argument, NULL, OPTION_DLL_DISABLE_AUTO_IMPORT},
{"enable-extra-pe-debug", no_argument, NULL, OPTION_ENABLE_EXTRA_PE_DEBUG},
+ {"enable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC},
+ {"disable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC},
#endif
{NULL, no_argument, NULL, 0}
@@ -353,4 +360,8 @@ gld_${EMULATION_NAME}_list_options (file
__imp_sym for DATA references\n"));
fprintf (file, _(" --disable-auto-import Do not auto-import DATA items from DLLs\n"));
+ fprintf (file, _(" --enable-runtime-pseudo-reloc Work around auto-import limitations by\n\
+ adding pseudo-relocations resolved at runtime.\n"));
+ fprintf (file, _(" --disable-runtime-pseudo-reloc Do not add runtime pseudo-relocations for\n\
+ auto-imported DATA.\n"));
fprintf (file, _(" --enable-extra-pe-debug Enable verbose debug output when building\n\
or linking to DLLs (esp. auto-import)\n"));
@@ -634,4 +645,10 @@ gld_${EMULATION_NAME}_parse_args(argc, a
link_info.pei386_auto_import = 0;
break;
+ case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC:
+ link_info.pei386_runtime_pseudo_reloc = 1;
+ break;
+ case OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC:
+ link_info.pei386_runtime_pseudo_reloc = 0;
+ break;
case OPTION_ENABLE_EXTRA_PE_DEBUG:
pe_dll_extra_pe_debug = 1;
@@ -881,12 +898,5 @@ make_import_fixup (rel, s)
}
- if (addend == 0)
- pe_create_import_fixup (rel);
- else
- {
- einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
- s->owner, s, rel->address, sym->name);
- einfo ("%X");
- }
+ pe_create_import_fixup (rel, s, addend);
}
Index: scripttempl/pe.sc
===================================================================
RCS file: /cvs/uberbaum/ld/scripttempl/pe.sc,v
retrieving revision 1.5
diff -u -p -2 -r1.5 pe.sc
--- scripttempl/pe.sc 16 Jan 2002 01:48:43 -0000 1.5
+++ scripttempl/pe.sc 2 Jul 2002 11:37:37 -0000
@@ -86,4 +86,7 @@ SECTIONS
${R_RDATA}
*(.eh_frame)
+ ___RUNTIME_PSEUDO_RELOC_LIST__ = .; __RUNTIME_PSEUDO_RELOC_LIST__ = . ;
+ *(.rdata_runtime_pseudo_reloc)
+ ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; __RUNTIME_PSEUDO_RELOC_LIST_END__ = . ;
}
[-- Attachment #6: crtest.c --]
[-- Type: application/octet-stream, Size: 1499 bytes --]
#include <stdio.h>
#include <stdlib.h>
#include "crtest.h"
#if defined(__CYGWIN__)
# define HAVE_FORK
#endif
#if !defined(RUNTIME_PSEUDO_RELOC_SUPPORT)
#include <windows.h>
typedef struct
{
DWORD addend;
DWORD target;
}
runtime_pseudo_reloc;
extern runtime_pseudo_reloc __RUNTIME_PSEUDO_RELOC_LIST__;
extern runtime_pseudo_reloc __RUNTIME_PSEUDO_RELOC_LIST_END__;
extern void* _data_start__;
extern void* _image_base__;
void
_pei386_runtime_relocator (runtime_pseudo_reloc* start, runtime_pseudo_reloc* end)
{
DWORD reloc_target;
runtime_pseudo_reloc* r;
for (r = start; r < end; r++)
{
printf ("ptr=%x, addend=%d\n", (long)r->target, r->addend);
reloc_target = (DWORD) &_image_base__ + r->target;
printf ("reloc target=%x\n", reloc_target);
*((DWORD*) reloc_target) += r->addend;
}
}
#endif
void
print_data ()
{
printf ("data=%d %d %c\n", foo[0].x, foo[1].y[2], foo[1].z[1]);
}
int
main ()
{
int pid;
#if !defined(RUNTIME_PSEUDO_RELOC_SUPPORT)
_pei386_runtime_relocator (&__RUNTIME_PSEUDO_RELOC_LIST__,
&__RUNTIME_PSEUDO_RELOC_LIST_END__);
#endif
#if defined(RUNTIME_PSEUDO_RELOC_SUPPORT) && defined(HAVE_FORK)
switch (pid = fork ())
{
case -1:
perror ("fork");
break;
case 0:
printf ("child: ");
print_data ();
break;
default:
wait (NULL);
printf ("parent: ");
print_data ();
break;
}
#else
print_data ();
#endif
return 0;
}
[-- Attachment #7: crtest.h --]
[-- Type: application/octet-stream, Size: 92 bytes --]
typedef struct
{
int x;
int y[3];
char z[3];
}
foo_t;
extern foo_t foo[2];
[-- Attachment #8: crtest_dll.c --]
[-- Type: application/octet-stream, Size: 128 bytes --]
#include "crtest.h"
foo_t foo[2] = { {1, {11, 12, 13}, {'a', 'b', 'c'}},
{2, {21, 22, 23}, {'d', 'e', 'f'}}};
[-- Attachment #9: Makefile --]
[-- Type: application/octet-stream, Size: 867 bytes --]
# mingw
# CC=gcc -mno-cygwin
# CFLAGS=-g3 -I . -DNO_RUNTIME_PSEUDO_RELOC_SUPPORT
# cygwin w/o runtime pseudo reloc support
CC=gcc
CFLAGS=-g3 -I . -DNO_RUNTIME_PSEUDO_RELOC_SUPPORT
# cygwin with runtime pseudo reloc support
# CC=gcc
# CFLAGS=-g3 -I . -DRUNTIME_PSEUDO_RELOC_SUPPORT
DLL_LDFLAGS=-Wl,--export-all-symbols -Wl,--out-implib=libcrtest.dll.a
EXE_LDFLAGS=-Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc
# DEBUG_LDFLAGS=-Wl,--enable-extra-pe-debug -Wl,--verbose
all: crtest.exe crtest.dll
crtest_dll.o: crtest_dll.c
$(CC) $(CFLAGS) -c $<
crtest.o: crtest.c
$(CC) $(CFLAGS) -c $<
crtest.dll libcrtest.dll.a: crtest_dll.o
$(CC) -shared -o crtest.dll $(DLL_LDFLAGS) $<
crtest.exe: crtest.o libcrtest.dll.a
$(CC) $(EXE_LDFLAGS) $(DEBUG_LDFLAGS) -o crtest.exe crtest.o -L. -lcrtest
.PHONY: clean
clean:
rm -f *.o *.a crtest.exe crtest.dll
next prev parent reply other threads:[~2002-07-02 15:39 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-06-28 3:19 egor duda
2002-06-28 18:08 ` Charles Wilson
2002-06-30 23:47 ` egor duda
2002-07-01 14:28 ` Charles Wilson
2002-07-02 8:39 ` egor duda [this message]
2002-07-02 9:31 ` Christopher Faylor
2002-07-03 2:21 ` egor duda
2002-07-03 12:05 ` Charles Wilson
2002-07-04 3:43 ` egor duda
2002-08-15 10:49 ` Christopher Faylor
2002-08-15 23:21 ` egor duda
2002-07-07 18:20 ` David A. Cobb
2002-11-11 18:01 Charles Wilson
2002-11-14 10:07 ` Nick Clifton
2002-11-15 5:35 ` egor duda
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=903891375.20020702193614@logos-m.ru \
--to=deo@logos-m.ru \
--cc=binutils@sources.redhat.com \
--cc=cwilson@ece.gatech.edu \
--cc=cygwin-apps@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).