* Git v2.46.0 and --allow-multiple-definition linker flag @ 2024-12-21 23:23 James Mills 2024-12-22 2:30 ` Junio C Hamano 0 siblings, 1 reply; 5+ messages in thread From: James Mills @ 2024-12-21 23:23 UTC (permalink / raw) To: git Hi Folks 👋 Been a while since I've emailed one of the large(r) open source lists, so please excuse me I may be a bit rusty. For some years now I've been building a very tiny custom LInux distribution called µLInux (micro Linux) over at https://git.mills.io/prologic/ulinux -- I primarily target the x86_64 architecture and its intended use is mostly as lightweight VM(s) that boot really quickly but are otherwise populated with "just enough" UNIX tools, a small package manager and few other bits to get interesting things going. Today I noticed that when upgrading the zlib (✅) and git (❌) ports that the latest version of Git v2.47.2 does not link and I observe the following linker error, mostly what looks like a missing capability/flag of the TinyC compiler that is used as the linker (LD=tcc): tcc: error: unsupported linker option '--allow-multiple-definition' I bisected the Git releases and traced the introduction of this new flag to v2.46.0 I can't find any details of this flag really or when this was introduced in the GNU binutils and so far I haven't asked if the Tiny C devs intend to support this option (yet). Just wondering, can we consider backing this out? From my very brief research on the web this seems to allow the linker to permit multiple definitions of a function. I'm not even sure why that would be desirable to be honest (but I haven't been a C/C++ developer basically ever, I know enough to be dangerous!) Kind regards James -- James Mills / prologic Join Yarn.social today! The only decentralised social media that respects your privacy and freedoms! E: prologic@shortcircuit.net.au W: prologic.shortcircuit.net.au Blog: Read my Blog Yarn: @prologic@twtxt.net ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Git v2.46.0 and --allow-multiple-definition linker flag 2024-12-21 23:23 Git v2.46.0 and --allow-multiple-definition linker flag James Mills @ 2024-12-22 2:30 ` Junio C Hamano 2024-12-22 2:47 ` Junio C Hamano 0 siblings, 1 reply; 5+ messages in thread From: Junio C Hamano @ 2024-12-22 2:30 UTC (permalink / raw) To: James Mills; +Cc: git James Mills <prologic@shortcircuit.net.au> writes: > tcc: error: unsupported linker option '--allow-multiple-definition' > > I bisected the Git releases and traced the introduction of this new > flag to v2.46.0 > > I can't find any details of this flag really or when this was > introduced in the GNU binutils and so far I haven't asked if the Tiny > C devs intend to support this option (yet). Would $ make LINK_FUZZ_PROGRAMS="" help? The platform-specific tweak defined in config.mak.uname file assumes that you have glibc plus gcc or clang with usual binutils niceties once you claim that you are Linux. It lumps all different variants of Linux into a single ball of wax and defines LINK_FUZZ_PROGRAMS Makefile macro, which is a bit unfortunate. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Git v2.46.0 and --allow-multiple-definition linker flag 2024-12-22 2:30 ` Junio C Hamano @ 2024-12-22 2:47 ` Junio C Hamano 2025-01-13 17:54 ` Josh Steadmon 0 siblings, 1 reply; 5+ messages in thread From: Junio C Hamano @ 2024-12-22 2:47 UTC (permalink / raw) To: Josh Steadmon; +Cc: git, James Mills Junio C Hamano <gitster@pobox.com> writes: > James Mills <prologic@shortcircuit.net.au> writes: > >> tcc: error: unsupported linker option '--allow-multiple-definition' >> >> I bisected the Git releases and traced the introduction of this new >> flag to v2.46.0 >> >> I can't find any details of this flag really or when this was >> introduced in the GNU binutils and so far I haven't asked if the Tiny >> C devs intend to support this option (yet). > > Would > > $ make LINK_FUZZ_PROGRAMS="" > > help? > > The platform-specific tweak defined in config.mak.uname file assumes > that you have glibc plus gcc or clang with usual binutils niceties > once you claim that you are Linux. It lumps all different variants > of Linux into a single ball of wax and defines LINK_FUZZ_PROGRAMS > Makefile macro, which is a bit unfortunate. Having said that, I am not sure if the commit that introduced the fuzz-all linkage rules, which is 8b9a42bf (fuzz: fix fuzz test build rules, 2024-01-19), needed to do so in the first place. With this trivial patch at the end of the message applied on top of 8b9a42bf (or more recent 'master', for that matter), "make fuzz-all" seems to link things just fine. Note that "make CC=clang fuzz-all" in the older code used to fail due to something else from gcc+ (which recent build no longer makes mandatory), but in today's code with gcc/clang/ld available locally, the linker flag does not seem to be needed for "make fuzz-all". Josh, do you offhand know what made us add the option? Thanks. diff --git c/Makefile w/Makefile index c0cbed69d8..5af8935968 100644 --- c/Makefile +++ w/Makefile @@ -3848,7 +3848,6 @@ FUZZ_CXXFLAGS ?= $(ALL_CFLAGS) $(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS $(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) -o $@ $(ALL_LDFLAGS) \ - -Wl,--allow-multiple-definition \ $(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE) fuzz-all: $(FUZZ_PROGRAMS) ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: Git v2.46.0 and --allow-multiple-definition linker flag 2024-12-22 2:47 ` Junio C Hamano @ 2025-01-13 17:54 ` Josh Steadmon 2025-01-14 11:03 ` Jeff King 0 siblings, 1 reply; 5+ messages in thread From: Josh Steadmon @ 2025-01-13 17:54 UTC (permalink / raw) To: Junio C Hamano; +Cc: git, James Mills On 2024.12.21 18:47, Junio C Hamano wrote: > Junio C Hamano <gitster@pobox.com> writes: > > > James Mills <prologic@shortcircuit.net.au> writes: > > > >> tcc: error: unsupported linker option '--allow-multiple-definition' > >> > >> I bisected the Git releases and traced the introduction of this new > >> flag to v2.46.0 > >> > >> I can't find any details of this flag really or when this was > >> introduced in the GNU binutils and so far I haven't asked if the Tiny > >> C devs intend to support this option (yet). > > > > Would > > > > $ make LINK_FUZZ_PROGRAMS="" > > > > help? > > > > The platform-specific tweak defined in config.mak.uname file assumes > > that you have glibc plus gcc or clang with usual binutils niceties > > once you claim that you are Linux. It lumps all different variants > > of Linux into a single ball of wax and defines LINK_FUZZ_PROGRAMS > > Makefile macro, which is a bit unfortunate. > > Having said that, I am not sure if the commit that introduced the > fuzz-all linkage rules, which is 8b9a42bf (fuzz: fix fuzz test build > rules, 2024-01-19), needed to do so in the first place. With this > trivial patch at the end of the message applied on top of 8b9a42bf > (or more recent 'master', for that matter), "make fuzz-all" seems to > link things just fine. > > Note that "make CC=clang fuzz-all" in the older code used to fail > due to something else from gcc+ (which recent build no longer makes > mandatory), but in today's code with gcc/clang/ld available locally, > the linker flag does not seem to be needed for "make fuzz-all". > > Josh, do you offhand know what made us add the option? > > Thanks. > > diff --git c/Makefile w/Makefile > index c0cbed69d8..5af8935968 100644 > --- c/Makefile > +++ w/Makefile > @@ -3848,7 +3848,6 @@ FUZZ_CXXFLAGS ?= $(ALL_CFLAGS) > > $(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS > $(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) -o $@ $(ALL_LDFLAGS) \ > - -Wl,--allow-multiple-definition \ > $(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE) > > fuzz-all: $(FUZZ_PROGRAMS) Sorry for the delayed response, I'm finally back to work after holidays / sick leave. Unfortunately, the --allow-multiple-definitions flag is still required. When simply running "make fuzz-all" with no other args (with or without the patch above), we do not actually produce a working fuzzer: $ make clean $ make fuzz-all $ ./oss-fuzz/fuzz-date BUG: oss-fuzz/dummy-cmd-main.c:12: We should not execute cmd_main() from a fuzz target zsh: IOT instruction ./oss-fuzz/fuzz-date This is because we're linking with common-main.o and oss-fuzz/dummy-cmd-main.o. commain-main.o:main() calls cmd_main(), which it finds in oss-fuzz/dummy-cmd-main.o. If we instead build with a fuzzing engine enabled: $ make clean $ make CC=clang FUZZ_CXX=clang++ \ CFLAGS="-fsanitize=fuzzer-no-link,address" \ LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \ fuzz-all $ ./oss-fuzz/fuzz-date INFO: Running with entropic power schedule (0xFF, 100). INFO: Seed: 2884061060 INFO: Loaded 1 modules (55020 inline 8-bit counters): 55020 [0x562aff0d2840, 0x562aff0dff2c), INFO: Loaded 1 PC tables (55020 PCs): 55020 [0x562aff0dff30,0x562aff1b6df0), INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes INFO: A corpus is not provided, starting from an empty corpus [...] This works because the fuzzing engine provides its own main() which overrides ours, and so we never end up calling dummy-cmd-main.o:cmd_main(). However, that build will fail if we remove the --allow-multiple-definition flag: $ make clean $ make CC=clang FUZZ_CXX=clang++ \ CFLAGS="-fsanitize=fuzzer-no-link,address" \ LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \ fuzz-all [...] LINK oss-fuzz/fuzz-commit-graph /usr/bin/ld: common-main.o: in function `main': common-main.c:(.text.main[main]+0x0): multiple definition of `main'; /usr/lib/llvm-16/lib/clang/16/lib/linux/libclang_rt.fuzzer-x86_64.a(FuzzerMain.cpp.o):(.text.main+0x0): first defined here clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [Makefile:3890: oss-fuzz/fuzz-commit-graph] Error 1 As Junio says, a short term fix would be to build with LINK_FUZZ_PROGRAMS="". A better solution would be to make config.mak.uname smarter about whether to enable this by default. I see that we use "detect-compiler" in config.mak.dev, would it make sense to check this in config.mak.uname as well? ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Git v2.46.0 and --allow-multiple-definition linker flag 2025-01-13 17:54 ` Josh Steadmon @ 2025-01-14 11:03 ` Jeff King 0 siblings, 0 replies; 5+ messages in thread From: Jeff King @ 2025-01-14 11:03 UTC (permalink / raw) To: Josh Steadmon; +Cc: Junio C Hamano, git, James Mills On Mon, Jan 13, 2025 at 09:54:07AM -0800, Josh Steadmon wrote: > As Junio says, a short term fix would be to build with > LINK_FUZZ_PROGRAMS="". A better solution would be to make > config.mak.uname smarter about whether to enable this by default. I see > that we use "detect-compiler" in config.mak.dev, would it make sense to > check this in config.mak.uname as well? It feels like the original sin here is defining main() in our library in the first place, if there are programs that may not want it. But we don't actually put it into libgit.a; the object file is just mentioned in the $(GITLIBS) variable of the Makefile. We could split that out like this: diff --git a/Makefile b/Makefile index 97e8385b66..f098ca5a5c 100644 --- a/Makefile +++ b/Makefile @@ -1371,7 +1371,8 @@ UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-oid.o UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-reftable.o # xdiff and reftable libs may in turn depend on what is in libgit.a -GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE) +GITLIBS = $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE) +PROGRAM_GITLIBS = common-main.o $(GITLIBS) EXTLIBS = GIT_USER_AGENT = git/$(GIT_VERSION) and then depend on $(PROGRAM_GITLIBS) as appropriate. Or if oss-fuzz is the only special case here, then perhaps we could just teach it to suppress the extra main: diff --git a/Makefile b/Makefile index 97e8385b66..06431170de 100644 --- a/Makefile +++ b/Makefile @@ -3852,9 +3852,8 @@ FUZZ_CXXFLAGS ?= $(ALL_CFLAGS) .PHONY: fuzz-all fuzz-all: $(FUZZ_PROGRAMS) -$(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS +$(FUZZ_PROGRAMS): %: %.o $(filter-out common-main.o,$(GITLIBS)) GIT-LDFLAGS $(QUIET_LINK)$(FUZZ_CXX) $(FUZZ_CXXFLAGS) -o $@ $(ALL_LDFLAGS) \ - -Wl,--allow-multiple-definition \ $(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE) $(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_OBJS) \ You'd need two fixes to go with that: 1. common-main was originally supposed to just be about overriding main(). But it has since grown common_exit(), which does not have the same linking properties (we override exit() calls at the macro layer instead). That should be defined in libgit.a somewhere. 2. When building the test-compile fuzzers, now you'll need to provide an actual main() function. I guess we can determine that by the presence of LIB_FUZZING_ENGINE? So maybe: diff --git a/Makefile b/Makefile index 97e8385b66..ba3faf9b9e 100644 --- a/Makefile +++ b/Makefile @@ -3852,9 +3852,15 @@ FUZZ_CXXFLAGS ?= $(ALL_CFLAGS) .PHONY: fuzz-all fuzz-all: $(FUZZ_PROGRAMS) -$(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS +ifdef LIB_FUZZING_ENGINE +# assume the fuzzing engine supplies main() +FUZZ_GITLIBS = $(filter-out common-main.o, $(GITLIBS)) +else +FUZZ_GITLIBS = oss-fuzz/dummy-cmd-main.o $(GITLIBS) +endif + +$(FUZZ_PROGRAMS): %: %.o $(FUZZ_GITLIBS) GIT-LDFLAGS $(QUIET_LINK)$(FUZZ_CXX) $(FUZZ_CXXFLAGS) -o $@ $(ALL_LDFLAGS) \ - -Wl,--allow-multiple-definition \ $(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE) $(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_OBJS) \ -Peff ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-01-14 11:03 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-12-21 23:23 Git v2.46.0 and --allow-multiple-definition linker flag James Mills 2024-12-22 2:30 ` Junio C Hamano 2024-12-22 2:47 ` Junio C Hamano 2025-01-13 17:54 ` Josh Steadmon 2025-01-14 11:03 ` Jeff King
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 NNTP newsgroup(s).