Skip to content

Conversation

@quic-akaryaki
Copy link
Contributor

No description provided.

@quic-akaryaki quic-akaryaki force-pushed the riscv-apply-reloc-nfc branch 2 times, most recently from 5108c07 to f371760 Compare August 7, 2025 18:49
Base automatically changed from riscv-apply-reloc-nfc to main August 8, 2025 14:36
@quic-akaryaki
Copy link
Contributor Author

Looks like the build failed because upstream LLVM does not emit R_RISCV_ALIGN.

Signed-off-by: Alexey Karyakin <akaryaki@quicinc.com>
Add '.yaml' to config.suffixes and fix tests that had non-test yaml
files outside of their Inputs directory.

Signed-off-by: Alexey Karyakin <akaryaki@quicinc.com>
The RISC-V psABI is silent on where R_RISCV_RELAX has to be in the
relocation table relative to the affected relocation, as long as it
is "at the same position". It is also not clear where exactly `.reloc`
assembly directive must place the relocation.

Therefore, sort all the RISC-V relocations. They were already sorted,
but not always.

Signed-off-by: Alexey Karyakin <akaryaki@quicinc.com>
@quic-akaryaki quic-akaryaki marked this pull request as ready for review August 14, 2025 01:15
// adjacent to the relocation they affect. The psABI is not clear if
// R_RISCV_RELAX must be adjacent, but using `.reloc` in assembly may generate
// those that are not. Note that because of this, this function must not have
// earlier non-error exists.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit : exits

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure

@@ -1,3 +1,11 @@
# RUN: %yaml2obj %s -o %t.o
# RUN: %link %linkopts -march aarch64 -T %p/t.t %t.o -o %t.out
# RUN: llvm-objdump -s %t.out | %filecheck %s
Copy link
Contributor

Choose a reason for hiding this comment

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

%objdump

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure (it was the original code).

ELFObjectFile *Obj = llvm::dyn_cast<ELFObjectFile>(&pInputFile);

// Common relocation processing for both local and global symbols.
switch (pReloc.type()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

probably making this to be a function and calling this from local and global reloc would make it easy since its a common pattern that we follow across targets.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I wanted to merge local/global functions because there is a lot duplication between them. We have had bugs in one of the branches because it's written a little different than the other.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure

// Non-preemptible symbols in executables will be optimized or relaxed,
// no GOT needed.
if (!m_Target.isSymbolPreemptible(*rsym))
return;
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like we dont do anything for hidden symbols / protected symbols that may get resolved as HIDDEN/PROTECTED across modules ?

cat > 1.c << !
__thread int tls_var = 0;
int foo() { return tls_var; }
!

cat > 2.c << !
extern __thread int tls_var;
int bar() { return tls_var; }
!

clang -c -target riscv32 1.c -fPIC -mtls-dialect=desc -fvisibility=hidden
clang -c -target riscv32 2.c -fPIC -mtls-dialect=desc
riscv-ld 1.o 2.o

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They should not work differently because the code does not check for it. If there is a bug in isSymbolPreemptible(), then the symbol will be wrongly preemptible or not but TLS DESC code will still work correctly.

RUN: %llvm-mc -filetype=obj --defsym PAD=0 -mattr=+c,+relax %p/Inputs/riscv-tlsdesc-relax/a.s -o %t.a.o
RUN: %llvm-mc -filetype=obj --defsym PAD=5000 -mattr=+c,+relax %p/Inputs/riscv-tlsdesc-relax/a.s -o %t.aa.o
RUN: %llvm-mc -filetype=obj -mattr=+c,+relax %p/Inputs/riscv-tlsdesc-relax/c.s -o %t.c.o
RUN: %link %linkopts -shared %t.c.o -o %t.c.so
Copy link
Contributor

Choose a reason for hiding this comment

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

May be useful to add tests using 'C' code to make it easy to debug ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The test check for particular instruction at particular offsets which C compiler will not guarantee. Also, some tests have interleave patterns that compiler probably can never generate.

@quic-seaswara
Copy link
Contributor

@lenary please review

@quic-seaswara
Copy link
Contributor

quic-seaswara commented Aug 15, 2025

I would like to see tests using 'C' code as well. You can still keep the asm test.

I would like to see more detailed testing mentioned below :

  • Basic TLSDESC tests without relaxation (Executable, Shared library, PIE, static linking, symbol visibility tests)
    • Probably we want to have a flag --no-tlsdesc-relax
  • TLSDESC tests with relaxation for the cases above
  • Please add what relaxations is supported right now, and what is punted for later
    • It is not clear from the commit message on what TLS relaxationare included in this patch
  • Any addition to map file for TLS relaxations will be useful
  • Test cases with mno-relax as needed
  • Documentation should follow as a seperate subtask (to know what the linker did for our users)

Please create subtasks as needed and totally I am ok to see the limited support that we add for 21.0 but my focus is to build this feature with more clarity.

cat > 1.c << \!
__attribute__((visibility("hidden"))) __thread int tls_var = 10;
int foo() { return tls_var; }
!

cat > 2.c << \!
extern __thread int tls_var;
int bar() { return tls_var; }
!

clang -c -target riscv32 1.c -fPIC -mtls-dialect=desc
clang -c -target riscv32 2.c -fPIC
# case 1
ld.eld -march riscv32 1.o 2.o -shared -o 1.so
llvm-readelf --dyn-syms 1.so | grep tls_var && echo BADIMAGE
llvm-readelf -r 1.so | grep tls_var && echo BADIMAGE
# case 2 (partial link)
ld.eld -march riscv32 1.o 2.o -r -o r.o
ld.eld -march riscv32 r.o -shared -o 1.so
llvm-readelf --dyn-syms 1.so | grep tls_var && echo BADIMAGE
llvm-readelf -r 1.so | grep tls_var && echo BADIMAGE
# case 3 (no relax)
clang -c -target riscv32 1.c -fPIC -mtls-dialect=desc -mno-relax
clang -c -target riscv32 2.c -fPIC -mno-relax
ld.eld -march riscv32 1.o 2.o -shared -o 1.so
llvm-readelf --dyn-syms 1.so | grep tls_var && echo BADIMAGE
llvm-readelf -r 1.so | grep tls_var && echo BADIMAGE

@quic-akaryaki
Copy link
Contributor Author

I would like to see tests using 'C' code as well. You can still keep the asm test.

I would like to see more detailed testing mentioned below :

  • Basic TLSDESC tests without relaxation (Executable, Shared library, PIE, static linking, symbol visibility tests)

    • Probably we want to have a flag --no-tlsdesc-relax
  • TLSDESC tests with relaxation for the cases above

  • Please add what relaxations is supported right now, and what is punted for later

    • It is not clear from the commit message on what TLS relaxationare included in this patch
  • Any addition to map file for TLS relaxations will be useful

  • Test cases with mno-relax as needed

  • Documentation should follow as a seperate subtask (to know what the linker did for our users)

Please create subtasks as needed and totally I am ok to see the limited support that we add for 21.0 but my focus is to build this feature with more clarity.

cat > 1.c << \!
__attribute__((visibility("hidden"))) __thread int tls_var = 10;
int foo() { return tls_var; }
!

cat > 2.c << \!
extern __thread int tls_var;
int bar() { return tls_var; }
!

clang -c -target riscv32 1.c -fPIC -mtls-dialect=desc
clang -c -target riscv32 2.c -fPIC
# case 1
ld.eld -march riscv32 1.o 2.o -shared -o 1.so
llvm-readelf --dyn-syms 1.so | grep tls_var && echo BADIMAGE
llvm-readelf -r 1.so | grep tls_var && echo BADIMAGE
# case 2 (partial link)
ld.eld -march riscv32 1.o 2.o -r -o r.o
ld.eld -march riscv32 r.o -shared -o 1.so
llvm-readelf --dyn-syms 1.so | grep tls_var && echo BADIMAGE
llvm-readelf -r 1.so | grep tls_var && echo BADIMAGE
# case 3 (no relax)
clang -c -target riscv32 1.c -fPIC -mtls-dialect=desc -mno-relax
clang -c -target riscv32 2.c -fPIC -mno-relax
ld.eld -march riscv32 1.o 2.o -shared -o 1.so
llvm-readelf --dyn-syms 1.so | grep tls_var && echo BADIMAGE
llvm-readelf -r 1.so | grep tls_var && echo BADIMAGE

Just to clarify, this patch has full support for TLSDESC, including all 4 types of static relocations, linker optimizations (replacing instructions with nops) and relaxations (removing instructions). Of course, it may have bugs, which is the case with existing code, which could be fixed before the 21 releases. Since new requirements come 1 day before the 21.x feature deadline, it won't go into the release.

Also, please clarify:
-- if --no-tlsdesc-relax is needed
-- which addition to map file for TLS relaxations will be useful

Thank you

@quic-seaswara
Copy link
Contributor

Just to clarify, this patch has full support for TLSDESC, including all 4 types of static relocations, linker optimizations (replacing instructions with nops) and relaxations (removing instructions). Of course, it may have bugs, which is the case with existing code, which could be fixed before the 21 releases. Since new requirements come 1 day before the 21.x feature deadline, it won't go into the release.

Yes, sorry!.

My point was to make TLSDESC without relaxation work before relaxations are added.

Also cases such as TLSDESC with symbol visibility is something users typically do. We should look into those cases to make sure that we have tests that show functionality.

Also, please clarify: -- if --no-tlsdesc-relax is needed -- which addition to map file for TLS relaxations will be useful

I think it will be useful to have --no-tlsdesc-relax like --no-gp-relax or --no-relax-c to have a workaround if any.

Map file can be annotated to point out what relaxations were applied.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants