Re: [RFC] An idea for general kernel post-processing automation in FreeBSD
Date: Thu, 25 May 2023 00:00:55 UTC
On May 24, 2023, at 09:52, Mark Millard <marklmi@yahoo.com> wrote: > On May 22, 2023, at 13:16, Mark Millard <marklmi@yahoo.com> wrote: > >> On May 22, 2023, at 03:00, Hans Petter Selasky <hps@selasky.org> wrote: >> >>> On 5/22/23 01:07, Mark Millard wrote: >>>> In the C language standard, the original had a status of "no linkage" >>>> and "static storage duration". ("a block scope identifier >>>> for an object declared without the storage-class specifier >>>> extern" leads to the "no linkage" status.) >>>> The change still has "static storage duration" but now has "internal >>>> linkage" status instead. I'm being cautious about the distinction. >>>> (I'm looking at ISO/IEC 9899:2011 (E).) >>>> I've had trouble identifying the match of your wordings to the >>>> language standard, leaving me unsure of the interpretation to >>>> give your wording. >>>> I've yet to figure out why internal linkage could end up >>>> being required, given how the language specifies things. >>> >>> Hi, >>> >>> If you find something, let me know. I'll let the issue rest for some days. >> >> Okay. File the below for later. >> >> (Some detailed whitespace below might not survive.) >> >> >> I still find no reason in the C11 standard to change >> the code in question from: >> >> Block Scope, No Linkage, Static Storage Duration >> >> into: >> >> File Scope, Internal Linkage, Static Storage Duration >> >> I'll ponder the standard's text some more but I doubt >> that I'll find something that I've missed so far. >> >> >> I propose using 2 source files that I show below as >> the basis for terminology. I set them up based on >> text from the C11 standard. If you can explain why >> Internal Linkage would be required in terms of some >> similar example and terminology, it would help be >> sure I'm not missing something that you are >> referencing. >> >> (Part of the text was just me trying to make sure that >> I'd appropriately covered the allowed combinations of >> official language concepts that are involved.) >> >> >> # more NameScope_Linkage_StorageDuration_combinations.c >> // For -std=c99 or c11 or c17 or c2x (showing c99): >> >> // cc -std=c99 -pedantic -Wall -Wextra -c FileScope_ExternalLinkage_initialization.c >> // cc -std=c99 -pedantic -Wall -Wextra NameScope_Linkage_StorageDuration_combinations.c FileScope_ExternalLinkage_initialization.o >> // ./a.out >> >> // gcc13 -std=c99 -pedantic -Wall -Wextra -c FileScope_ExternalLinkage_initialization.c >> // gcc13 -std=c99 -pedantic -Wall -Wextra NameScope_Linkage_StorageDuration_combinations.c FileScope_ExternalLinkage_initialization.o >> // ./a.out >> >> >> // Indentification of contexts and the subset covered here: >> >> // Just objects (not macros, functions, tags, typedefs names, lables, etc.): >> // (Note: function prototype scope is not relevant here) >> // >> // Scopes (visibility): Block, File >> // Linkages: None (No), External, Internal >> // Storage durations: Automatic, Static (, Thread, Allocated) >> // Name space: Ordinary Identifiers (Note: no alternatives) >> >> // Note: I do not cover any thread-storage-duration related contexts here. >> // Note: I do not cover any allocated-storage-duration contexts here. >> >> // Note: I do not cover the special non-lvalue expression contexts here >> // that involve the combination: >> // temporary-lifetime and automatic-storage-duration >> >> // For reference: >> // Static Storage Duration: "Its lifetime is the entire execution of the >> // program and its storage value is initialized >> // only once, prior to program startup." >> // >> // It need not be tied to file scope or to external/internal linkage. >> >> // Covered here: >> // Block Scope, No Linkage, Automatic Storage Duration >> // Block Scope, No Linkage, Static Storage Duration >> // Block Scope, External Linkage, Static Storage Duration >> // File Scope, Internal Linkage, Static Storage Duration >> // File Scope, External Linkage, Static Storage Duration >> >> // Note: Only external linkage objects have a definition vs. >> // declaration distinction. >> >> // I count 4 distinct non-stack types of whole-program-lifetime >> // object contexts in that list: The static-storage-duration ones. >> // But: >> // >> // Block Scope, External Linkage, Static Storage Duration >> // >> // can only be used to declare access to an external-linkage >> // defined elsewhere (defined outside any block scope). >> >> // Note: There is no such thing as the combination: >> // Block Scope, Internal Linkage, Static Storage Duration >> >> // Note: "Each declaration of an identifier with no linkage >> // denotes a unique entity." This prevents various >> // forms of multiple declarations for the same >> // namespace and scope combination. >> >> #include <stdio.h> >> >> // Note: Only automatic storage duration is in a call stack. >> int Using_BlockScope_NoLinkage_AutomaticStorageDuration(void) >> { >> int BlockScope_NoLinkage_AutomaticStorageDuration = 1; >> return ++BlockScope_NoLinkage_AutomaticStorageDuration; >> } >> >> // Note: No direct notation for file scope access exists but >> // the storage duration spans when the function is not >> // in use. >> int Using_BlockScope_NoLinkage_StaticStorageDuration(void) >> { >> static int BlockScope_NoLinkage_StaticStorageDuration = 1; >> return ++BlockScope_NoLinkage_StaticStorageDuration; >> } >> >> int Using_BlockScope_ExternalLinkage_StaticStorageDuration(void) >> { >> // Note: Defined/initialized in FileScope_ExternalLinkage_initialization.c >> // Such an external definition is not allowed in block scope. >> extern int ExternalLinkage_StaticStorageDuration; // a declaration >> return ++ExternalLinkage_StaticStorageDuration; >> } >> >> // Note: To have internal linkage requires a file scope declaration. >> static int FileScope_InternalLinkage_StaticStorageDuration = 1; >> // Note: after such an internal linkage definition, the following >> // is allowed (not required) but does not change the status. >> // "extern" does not always mean external-storage-duration. >> extern int FileScope_InternalLinkage_StaticStorageDuration; >> int Using_FileScope_InternalLinkage_StaticStorageDuration(void) >> { >> // Note: after such an internal linkage definition, the following >> // is allowed (not required) but does not change the status. >> // "extern" does not always mean external-storage-duration. >> extern int FileScope_InternalLinkage_StaticStorageDuration; >> >> return ++FileScope_InternalLinkage_StaticStorageDuration; >> } >> >> // Note: Defined/initialized in FileScope_ExternalLinkage_initialization.c >> extern int FileScope_ExternalLinkage_StaticStorageDuration; // a declaration >> // Note: Without "extern", a definition would be allowed above, instead >> // of having one in FileScope_ExternalLinkage_initialization.c . >> int Using_FileScope_ExternalLinkage_StaticStorageDuration(void) >> { >> return ++FileScope_ExternalLinkage_StaticStorageDuration; >> } >> >> int main(void) >> { >> (void) Using_BlockScope_NoLinkage_AutomaticStorageDuration(); >> printf("Using_BlockScope_NoLinkage_AutomaticStorageDuration() : %d (expect 2)\n" >> , Using_BlockScope_NoLinkage_AutomaticStorageDuration()); >> >> (void) Using_BlockScope_NoLinkage_StaticStorageDuration(); >> printf("Using_BlockScope_NoLinkage_StaticStorageDuration() : %d (expect 3)\n" >> , Using_BlockScope_NoLinkage_StaticStorageDuration()); >> >> (void) Using_BlockScope_ExternalLinkage_StaticStorageDuration(); >> printf("Using_BlockScope_ExternalLinkage_StaticStorageDuration(): %d (expect 3)\n" >> , Using_BlockScope_ExternalLinkage_StaticStorageDuration()); >> >> (void) Using_FileScope_InternalLinkage_StaticStorageDuration(); >> printf("Using_FileScope_InternalLinkage_StaticStorageDuration() : %d (expect 3)\n" >> , Using_FileScope_InternalLinkage_StaticStorageDuration()); >> printf("Accessing FileScope_InternalLinkage_StaticStorageDuration : %d (expect 3 again)\n" >> , FileScope_InternalLinkage_StaticStorageDuration); >> } >> >> >> # more FileScope_ExternalLinkage_initialization.c >> // For -std=c99 or c11 or c17 or c2x (showing c99): >> >> // cc -std=c99 -pedantic -Wall -Wextra -c NameScope_Linkage_StorageDuration_combinations.c >> >> // gcc13 -std=c99 -pedantic -Wall -Wextra -c NameScope_Linkage_StorageDuration_combinations.c >> >> // Defined at file scope here. >> // Used separately at block scope elsewhere. >> // The definition can not be in block scope. >> int ExternalLinkage_StaticStorageDuration = 1; // a definition >> >> // Defined at file scope here. >> // Used separately at file scope elsewhere. >> int FileScope_ExternalLinkage_StaticStorageDuration = 1; // a definition >> > > It has been a few days. So I'll add the following. > > Stepping outside the language definition, in > case you are curious about an example of how: > > Block Scope, No Linkage, Static Storage Duration > > can be handled by a toolchain, in a FreeBSD > main aarch64 context I get: > > # nm a.out | grep Linkage > 0000000000410c7c d BlockScope_NoLinkage_StaticStorageDuration.0 > 0000000000410c80 D ExternalLinkage_StaticStorageDuration > 0000000000410c84 D FileScope_ExternalLinkage_StaticStorageDuration > 0000000000410c78 d FileScope_InternalLinkage_StaticStorageDuration > 00000000004005e4 T Using_BlockScope_ExternalLinkage_StaticStorageDuration > 0000000000400594 T Using_BlockScope_NoLinkage_AutomaticStorageDuration > 00000000004005b8 T Using_BlockScope_NoLinkage_StaticStorageDuration > 000000000040063c T Using_FileScope_ExternalLinkage_StaticStorageDuration > 0000000000400610 T Using_FileScope_InternalLinkage_StaticStorageDuration > > "BlockScope_NoLinkage_StaticStorageDuration.0" is not a valid > C identifier but has a structure allowing making each such: > > Block Scope, No Linkage, Static Storage Duration > > unique when the identifier part is not: replacing the 0 in .0 > with other numerals, incrementing values, say. The "d" status > avoids it being external. > > Overall, then there is nothing else having a possible linkage: > "linkage none" in the C11 standard's terms. I took a look at a . . ./sys/modules/mlx4/mlx4_main.o via nm and it showed a different convention for creating uniqueness for the type of context involved: static ssize_t set_port_type(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { . . . static DEFINE_MUTEX(set_port_type_mutex); . . . ended up with the static routine's name prefixed, with a "." separator: 0000000000006da0 t set_port_type 0000000000000018 d set_port_type.__set_sysinit_set_sym_set_port_type_mutex_sx_sysinit_sys_init 0000000000000008 d set_port_type.__set_sysuninit_set_sym_set_port_type_mutex_sx_sysuninit_sys_uninit 0000000000000020 b set_port_type.set_port_type_mutex 00000000000004a8 d set_port_type.set_port_type_mutex_args 00000000000004c0 d set_port_type.set_port_type_mutex_sx_sysinit_sys_init 00000000000004d8 d set_port_type.set_port_type_mutex_sx_sysuninit_sys_uninit This was based on: # uname -apKU # long output line manually split for readability FreeBSD CA72_16Gp_ZFS 14.0-CURRENT FreeBSD 14.0-CURRENT #94 main-n262658-b347c2284603-dirty: Fri Apr 28 19:57:23 PDT 2023 root@CA72_16Gp_ZFS:/usr/obj/BUILDs/main-CA72-nodbg-clang/usr/main-src/arm64.aarch64/sys/GENERIC-NODBG-CA72 arm64 aarch64 1400088 1400088 and so the context predates any changes. === Mark Millard marklmi at yahoo.com