Re: [RFC] An idea for general kernel post-processing automation in FreeBSD

Mark Millard <[email protected]>
Newsgroups gmane.os.freebsd.architechture
Message-ID <[email protected]>
On May 24, 2023, at 09:52, Mark Millard <[email protected]> wrote:

> On May 22, 2023, at 13:16, Mark Millard <[email protected]> wrote:
> 
>> On May 22, 2023, at 03:00, Hans Petter Selasky <[email protected]> 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.