Repository navigation
edg: -C on the archive too, and the finalization pair EDG leaves open - #617
Merged
Merged
Conversation
The cmd/edg link is down to two things and only one of them is ours. lib/edg built libedg.a with CFLAGS=-c while cmd/edg has had -c -C since the round that found it. An archive takes duplicate members silently, so the archive looked clean; the clash arrives only when the link pulls two members defining one vague-linkage entity. 6l answered (295) DATA _ZTSv+0(SB)/1,$118 __tourite_needs_stdio_exit: multiple initialization for _ZTSv, _ZTIv, _ZTSDn and _ZTIDn -- the void and decltype(nullptr) type strings and type_info objects -- each of which throw.c and typeinfo.c both define, counted rather than guessed. asm.c:548 suppresses that on sym->dupok and obj.c:908 sets it from the AGLOBL's DUPOK bit, which -C is the only way to ask for. dupok is a property of the Sym, so one side carrying it would have been enough and neither did. (The symbol in that message is stale diag context and names nothing: read the DATA line above it.) The remaining undefined is __cxa_finalize, and it is a gap EDG leaves to the platform rather than one this tree opened: include_c++/cxxabi.h declares the finalization pair and lib_src defines neither, because everywhere else the C++ runtime supplies them. cxa_atexit.c and dso_handle.c are the two hand-written files in lib/edg, deliberately not in libap -- a C++ ABI name in the library every program links is the reject shape -- and compiled without -C, since marking a hand-written file's symbols dupok would turn a second definition of __cxa_atexit into first-wins silence. They follow Itanium 3.3.5.3 rather than approximating it: the entry is removed BEFORE it is called and the list re-scanned afterwards, because a destructor may register more. A plain descending for loop over the list passes the ordering test and fails both, which is measured rather than argued -- the naive version replicated beside the real one gives 4 failures naming sections 3, 4a, 4b and 5b. __dso_handle is its own file because glibc's crtbeginS.o already defines one, so with both in a single object the host cross-check does not link at all. That collision is the measurement: the handle belongs to the C startup and the finalizers to the C++ runtime, and the host says so by owning exactly one of the two. cpfe references neither -- __dso_handle appears in src/lower_init.c only as a string literal, because cpfe emits references to it in the C it generates. cxaatexit-test.c runs unchanged on both machines, 0 failures on gcc. And the bacon recipe recorded here was wrong in both halves. -c cc rather than -c pcc: bacon's generated Makefile names $stem.o, and pcc.c:75 is objext = (strcmp(prog,"cc")==0) ? "o" : ot->o while 9src/cc.c is one line including pcc.c -- cc and pcc are one binary and the name chooses the extension, so -c cc is the same compiler under the name whose output every Makefile expects. And BACON_IN_DOCKER=true rather than </dev/null: both prompt sites are already guarded by that variable, while closing stdin does not make the prompt take its default, it makes bacon die -- the generated __b2c__input calls getdelim, -1 at EOF falls into the arm that raises "Error opening file", and compiling those four lines verbatim on glibc with stdin on /dev/null gives the same arm. Upstream's, on every platform. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The cmd/edg link is down to two things and only one of them is ours.
lib/edg built libedg.a with CFLAGS=-c while cmd/edg has had -c -C since the round that found it. An archive takes duplicate members silently, so the archive looked clean; the clash arrives only when the link pulls two members defining one vague-linkage entity. 6l answered
(295) DATA _ZTSv+0(SB)/1,$118
__tourite_needs_stdio_exit: multiple initialization
for _ZTSv, _ZTIv, _ZTSDn and _ZTIDn -- the void and decltype(nullptr) type strings and type_info objects -- each of which throw.c and typeinfo.c both define, counted rather than guessed. asm.c:548 suppresses that on sym->dupok and obj.c:908 sets it from the AGLOBL's DUPOK bit, which -C is the only way to ask for. dupok is a property of the Sym, so one side carrying it would have been enough and neither did. (The symbol in that message is stale diag context and names nothing: read the DATA line above it.)
The remaining undefined is __cxa_finalize, and it is a gap EDG leaves to the platform rather than one this tree opened: include_c++/cxxabi.h declares the finalization pair and lib_src defines neither, because everywhere else the C++ runtime supplies them. cxa_atexit.c and dso_handle.c are the two hand-written files in lib/edg, deliberately not in libap -- a C++ ABI name in the library every program links is the reject shape -- and compiled without -C, since marking a hand-written file's symbols dupok would turn a second definition of __cxa_atexit into first-wins silence.
They follow Itanium 3.3.5.3 rather than approximating it: the entry is removed BEFORE it is called and the list re-scanned afterwards, because a destructor may register more. A plain descending for loop over the list passes the ordering test and fails both, which is measured rather than argued -- the naive version replicated beside the real one gives 4 failures naming sections 3, 4a, 4b and 5b.
__dso_handle is its own file because glibc's crtbeginS.o already defines one, so with both in a single object the host cross-check does not link at all. That collision is the measurement: the handle belongs to the C startup and the finalizers to the C++ runtime, and the host says so by owning exactly one of the two. cpfe references neither -- __dso_handle appears in src/lower_init.c only as a string literal, because cpfe emits references to it in the C it generates.
cxaatexit-test.c runs unchanged on both machines, 0 failures on gcc.
And the bacon recipe recorded here was wrong in both halves. -c cc rather than -c pcc: bacon's generated Makefile names $stem.o, and pcc.c:75 is objext = (strcmp(prog,"cc")==0) ? "o" : ot->o while 9src/cc.c is one line including pcc.c -- cc and pcc are one binary and the name chooses the extension, so -c cc is the same compiler under the name whose output every Makefile expects. And BACON_IN_DOCKER=true rather than </dev/null: both prompt sites are already guarded by that variable, while closing stdin does not make the prompt take its default, it makes bacon die -- the generated __b2c__input calls getdelim, -1 at EOF falls into the arm that raises "Error opening file", and compiling those four lines verbatim on glibc with stdin on /dev/null gives the same arm. Upstream's, on every platform.
Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs