Skip to content

Conversation

petrhosek
Copy link
Member

In change #146863 we moved definitions of preinit/init/fini arrays to header but unintentionally moved outside of the namespace. Since the namespace also controls the visibility (through LIBC_NAMESPACE_DECL), as a consequence these symbols no longer have the hidden visibility which changes the codegen from:

 4: 4c11          ldr     r4, [pc, #0x44]         @ 0x4c <__libc_init_array+0x4c>
 6: 4812          ldr     r0, [pc, #0x48]         @ 0x50 <__libc_init_array+0x50>
 8: 447c          add     r4, pc
 a: 4478          add     r0, pc
 c: 1b00          subs    r0, r0, r4

to:

 4: 4813          ldr     r0, [pc, #0x4c]         @ 0x54 <__libc_init_array+0x54>
 6: 4914          ldr     r1, [pc, #0x50]         @ 0x58 <__libc_init_array+0x58>
 8: 4478          add     r0, pc
 a: 4479          add     r1, pc
 c: 6804          ldr     r4, [r0]
 e: 6808          ldr     r0, [r1]
10: 1b00          subs    r0, r0, r4

The ldr will trigger a fault in case where these symbols aren't pointing to a valid memory location which is sometimes the case when the array is empty.

In change llvm#146863 we moved definitions of preinit/init/fini arrays to
header but unintentionally moved outside of the namespace. Since the
namespace also controls the visibility (through LIBC_NAMESPACE_DECL),
as a consequence these symbols no longer have the hidden visibility
which changes the codegen from:

```
 4: 4c11          ldr     r4, [pc, #0x44]         @ 0x4c <__libc_init_array+0x4c>
 6: 4812          ldr     r0, [pc, #0x48]         @ 0x50 <__libc_init_array+0x50>
 8: 447c          add     r4, pc
 a: 4478          add     r0, pc
 c: 1b00          subs    r0, r0, r4
```

to:

```
 4: 4813          ldr     r0, [pc, #0x4c]         @ 0x54 <__libc_init_array+0x54>
 6: 4914          ldr     r1, [pc, #0x50]         @ 0x58 <__libc_init_array+0x58>
 8: 4478          add     r0, pc
 a: 4479          add     r1, pc
 c: 6804          ldr     r4, [r0]
 e: 6808          ldr     r0, [r1]
10: 1b00          subs    r0, r0, r4
```

The `ldr` will trigger a fault in case where these symbols aren't
pointing to a valid memory location which is sometimes the case when
the array is empty.
@llvmbot
Copy link
Member

llvmbot commented Sep 15, 2025

@llvm/pr-subscribers-libc

Author: Petr Hosek (petrhosek)

Changes

In change #146863 we moved definitions of preinit/init/fini arrays to header but unintentionally moved outside of the namespace. Since the namespace also controls the visibility (through LIBC_NAMESPACE_DECL), as a consequence these symbols no longer have the hidden visibility which changes the codegen from:

 4: 4c11          ldr     r4, [pc, #<!-- -->0x44]         @ 0x4c &lt;__libc_init_array+0x4c&gt;
 6: 4812          ldr     r0, [pc, #<!-- -->0x48]         @ 0x50 &lt;__libc_init_array+0x50&gt;
 8: 447c          add     r4, pc
 a: 4478          add     r0, pc
 c: 1b00          subs    r0, r0, r4

to:

 4: 4813          ldr     r0, [pc, #<!-- -->0x4c]         @ 0x54 &lt;__libc_init_array+0x54&gt;
 6: 4914          ldr     r1, [pc, #<!-- -->0x50]         @ 0x58 &lt;__libc_init_array+0x58&gt;
 8: 4478          add     r0, pc
 a: 4479          add     r1, pc
 c: 6804          ldr     r4, [r0]
 e: 6808          ldr     r0, [r1]
10: 1b00          subs    r0, r0, r4

The ldr will trigger a fault in case where these symbols aren't pointing to a valid memory location which is sometimes the case when the array is empty.


Full diff: https://github.com/llvm/llvm-project/pull/158746.diff

2 Files Affected:

  • (modified) libc/startup/baremetal/fini.h (+6)
  • (modified) libc/startup/baremetal/init.h (+5)
diff --git a/libc/startup/baremetal/fini.h b/libc/startup/baremetal/fini.h
index 74e9601983a33..681cbf954f94a 100644
--- a/libc/startup/baremetal/fini.h
+++ b/libc/startup/baremetal/fini.h
@@ -7,6 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "hdr/stdint_proxy.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
 
 extern "C" {
 extern uintptr_t __fini_array_start[];
@@ -14,3 +17,6 @@ extern uintptr_t __fini_array_end[];
 
 void __libc_fini_array(void);
 } // extern "C"
+
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/startup/baremetal/init.h b/libc/startup/baremetal/init.h
index 6b545db3976da..da20c7766fee6 100644
--- a/libc/startup/baremetal/init.h
+++ b/libc/startup/baremetal/init.h
@@ -7,6 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "hdr/stdint_proxy.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
 
 extern "C" {
 extern uintptr_t __preinit_array_start[];
@@ -16,3 +19,5 @@ extern uintptr_t __init_array_end[];
 
 void __libc_init_array(void);
 } // extern "C"
+
+} // namespace LIBC_NAMESPACE_DECL

Copy link

github-actions bot commented Sep 15, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {
Copy link

@JonathonReinhart JonathonReinhart Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the only declarations inside this namespace are extern "C", it would be easy to overlook this namespace as being unnecessary for correctness -- especially if you don't realize the gnu::visibility("hidden") magic behind it. This probably facilitated the bug being introduced in #146863.

Perhaps a comment here would be warranted (and same on init.h of course).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@petrhosek petrhosek merged commit 5bf399b into llvm:main Sep 16, 2025
19 checks passed
@saturn691
Copy link
Contributor

Good catch!

kimsh02 pushed a commit to kimsh02/llvm-project that referenced this pull request Sep 19, 2025
In change llvm#146863 we moved definitions of preinit/init/fini arrays to
header but unintentionally moved outside of the namespace. Since the
namespace also controls the visibility (through LIBC_NAMESPACE_DECL), as
a consequence these symbols no longer have the hidden visibility which
changes the codegen from:

```
 4: 4c11          ldr     r4, [pc, #0x44]         @ 0x4c <__libc_init_array+0x4c>
 6: 4812          ldr     r0, [pc, #0x48]         @ 0x50 <__libc_init_array+0x50>
 8: 447c          add     r4, pc
 a: 4478          add     r0, pc
 c: 1b00          subs    r0, r0, r4
```

to:

```
 4: 4813          ldr     r0, [pc, #0x4c]         @ 0x54 <__libc_init_array+0x54>
 6: 4914          ldr     r1, [pc, #0x50]         @ 0x58 <__libc_init_array+0x58>
 8: 4478          add     r0, pc
 a: 4479          add     r1, pc
 c: 6804          ldr     r4, [r0]
 e: 6808          ldr     r0, [r1]
10: 1b00          subs    r0, r0, r4
```

The `ldr` will trigger a fault in case where these symbols aren't
pointing to a valid memory location which is sometimes the case when the
array is empty.
itzexpoexpo pushed a commit to itzexpoexpo/llvm-project that referenced this pull request Sep 21, 2025
In change llvm#146863 we moved definitions of preinit/init/fini arrays to
header but unintentionally moved outside of the namespace. Since the
namespace also controls the visibility (through LIBC_NAMESPACE_DECL), as
a consequence these symbols no longer have the hidden visibility which
changes the codegen from:

```
 4: 4c11          ldr     r4, [pc, #0x44]         @ 0x4c <__libc_init_array+0x4c>
 6: 4812          ldr     r0, [pc, #0x48]         @ 0x50 <__libc_init_array+0x50>
 8: 447c          add     r4, pc
 a: 4478          add     r0, pc
 c: 1b00          subs    r0, r0, r4
```

to:

```
 4: 4813          ldr     r0, [pc, #0x4c]         @ 0x54 <__libc_init_array+0x54>
 6: 4914          ldr     r1, [pc, #0x50]         @ 0x58 <__libc_init_array+0x58>
 8: 4478          add     r0, pc
 a: 4479          add     r1, pc
 c: 6804          ldr     r4, [r0]
 e: 6808          ldr     r0, [r1]
10: 1b00          subs    r0, r0, r4
```

The `ldr` will trigger a fault in case where these symbols aren't
pointing to a valid memory location which is sometimes the case when the
array is empty.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants