Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocamlopt 4.08.1 triggers ld relocation warnings on i386 with binutils 2.35 #9800

Closed
glondu opened this issue Jul 27, 2020 · 21 comments
Closed

Comments

@glondu
Copy link
Contributor

glondu commented Jul 27, 2020

When compiled in current Debian unstable (2020-07-27), ocamlopt 4.08.1 on an empty file gives on i386:

/usr/bin/ld: /tmp/ocaml-4.08.1/stdlib/stdlib.a(camlinternalFormatBasics.o): warning: relocation in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE

These warnings seem to be triggered on any file. Because of this, the test suite does not pass and is messy. I suspect this is due to a new version of binutils (2.35).

@glondu
Copy link
Contributor Author

glondu commented Jul 27, 2020

The same warnings are triggered with 4.11.0+beta2.

@xavierleroy
Copy link
Contributor

xavierleroy commented Jul 27, 2020

It is quite possible that PIE needs to be turned off for i386 and perhaps other 32-bit platforms. We already do it for musl-based systems, see da12974 . This, or the warning needs to be silenced.

@glondu
Copy link
Contributor Author

glondu commented Jul 27, 2020

Adding -no-pie indeed reduces the amount of noise in the test suite. However, there remains:

Running tests from 'tests/tool-ocamlobjinfo' ...
 ... testing 'question.ml' with 1 (shared-libraries) => passed
 ... testing 'question.ml' with 1.1 (script) => passed
 ... testing 'question.ml' with 1.1.1 (setup-ocamlopt.byte-build-env) => passed
 ... testing 'question.ml' with 1.1.1.1 (ocamlopt.byte) => passed
 ... testing 'question.ml' with 1.1.1.1.1 (check-ocamlopt.byte-output) => failed (The file /tmp/ocaml-4.11.0+beta2/testsuite/_ocamltest/tests/tool-ocamlobjinfo/question/ocamlopt.byte/ocamlopt.byte.output was expected to be empty because there is no reference file /tmp/ocaml-4.11.0+beta2/testsuite/tests/tool-ocamlobjinfo/question.compilers.reference but it is not:
========================================
/usr/bin/ld: question.o: warning: relocation against `camlQuestion' in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a shared object
========================================

)
 ... testing 'question.ml' with 1.1.1.1.1.1 (ocamlobjinfo) => n/a
 ... testing 'question.ml' with 1.1.1.1.1.1.1 (check-program-output) => n/a

@glondu
Copy link
Contributor Author

glondu commented Jul 29, 2020

There are also dynlink tests that still fail with -no-pie:

Running tests from 'tests/lib-dynlink-pr4839' ...
 ... testing 'test.ml' with 1 (shared-libraries) => passed
 ... testing 'test.ml' with 1.1 (setup-ocamlc.byte-build-env) => passed
 ... testing 'test.ml' with 1.1.1 (script) => passed
 ... testing 'test.ml' with 1.1.2 (script) => passed
 ... testing 'test.ml' with 1.1.3 (script) => passed
 ... testing 'test.ml' with 1.1.4 (script) => passed
 ... testing 'test.ml' with 1.1.5 (script) => passed
 ... testing 'test.ml' with 1.1.6 (script) => passed
 ... testing 'test.ml' with 1.1.7 (cd) => passed
 ... testing 'test.ml' with 1.1.8 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.9 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.10 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.11 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.12 (cd) => passed
 ... testing 'test.ml' with 1.1.13 (cd) => passed
 ... testing 'test.ml' with 1.1.14 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.15 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.16 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.17 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.18 (cd) => passed
 ... testing 'test.ml' with 1.1.19 (cd) => passed
 ... testing 'test.ml' with 1.1.20 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.21 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.22 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.23 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.24 (cd) => passed
 ... testing 'test.ml' with 1.1.25 (cd) => passed
 ... testing 'test.ml' with 1.1.26 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.27 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.28 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.29 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.30 (cd) => passed
 ... testing 'test.ml' with 1.1.31 (cd) => passed
 ... testing 'test.ml' with 1.1.32 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.33 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.34 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.35 (ocamlc.byte) => passed
 ... testing 'test.ml' with 1.1.35.1 (run) => passed
 ... testing 'test.ml' with 1.1.35.1.1 (check-program-output) => passed
 ... testing 'test.ml' with 1.1.35.2 (run) => passed
 ... testing 'test.ml' with 1.1.35.2.1 (check-program-output) => passed
 ... testing 'test.ml' with 1.1.35.3 (run) => passed
 ... testing 'test.ml' with 1.1.35.3.1 (check-program-output) => passed
 ... testing 'test.ml' with 1.1.35.4 (run) => passed
 ... testing 'test.ml' with 1.1.35.4.1 (check-program-output) => passed
 ... testing 'test.ml' with 1.1.36 (cd) => passed
 ... testing 'test.ml' with 1.2 (native-dynlink) => passed
 ... testing 'test.ml' with 1.2.1 (setup-ocamlopt.byte-build-env) => passed
 ... testing 'test.ml' with 1.2.1.1 (script) => passed
 ... testing 'test.ml' with 1.2.1.2 (script) => passed
 ... testing 'test.ml' with 1.2.1.3 (script) => passed
 ... testing 'test.ml' with 1.2.1.4 (script) => passed
 ... testing 'test.ml' with 1.2.1.5 (script) => passed
 ... testing 'test.ml' with 1.2.1.6 (script) => passed
 ... testing 'test.ml' with 1.2.1.7 (cd) => passed
 ... testing 'test.ml' with 1.2.1.8 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.1.9 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.1.10 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.1.11 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.1.12 (cd) => passed
 ... testing 'test.ml' with 1.2.1.13 (cd) => passed
 ... testing 'test.ml' with 1.2.1.14 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.1.15 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.1.16 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.1.17 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2 (cd) => passed
 ... testing 'test.ml' with 1.2.2.1 (cd) => passed
 ... testing 'test.ml' with 1.2.2.2 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.3 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.4 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.5 (ocamlopt.byte) => /usr/bin/ld: plugin.o: warning: relocation in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a shared object
passed
 ... testing 'test.ml' with 1.2.2.6 (cd) => passed
 ... testing 'test.ml' with 1.2.2.7 (cd) => passed
 ... testing 'test.ml' with 1.2.2.8 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.9 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.10 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.11 (ocamlopt.byte) => /usr/bin/ld: plugin.o: warning: relocation in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a shared object
passed
 ... testing 'test.ml' with 1.2.2.12 (cd) => passed
 ... testing 'test.ml' with 1.2.2.13 (cd) => passed
 ... testing 'test.ml' with 1.2.2.14 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.15 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.16 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.17 (ocamlopt.byte) => passed
 ... testing 'test.ml' with 1.2.2.17.1 (run) => passed
 ... testing 'test.ml' with 1.2.2.17.1.1 (check-program-output) => passed
 ... testing 'test.ml' with 1.2.2.17.2 (run) => passed
 ... testing 'test.ml' with 1.2.2.17.2.1 (check-program-output) => passed
 ... testing 'test.ml' with 1.2.2.17.3 (run) => passed
 ... testing 'test.ml' with 1.2.2.17.3.1 (check-program-output) => passed
 ... testing 'test.ml' with 1.2.2.17.4 (run) => passed
 ... testing 'test.ml' with 1.2.2.17.4.1 (check-program-output) => passed
 ... testing 'test.ml' with 1.2.2.18 (cd) => passed

@glondu
Copy link
Contributor Author

glondu commented Jul 30, 2020

If I understand correctly, emitting PIC code would solve this issue. Unfortunately, ocamlopt does not seem to support emitting PIC code on i386.

@glondu
Copy link
Contributor Author

glondu commented Jul 30, 2020

The new behavior is triggered by this commit. I didn't find any rationale for this.

@hjl-tools
Copy link

If ocaml doesn't support PIC, please pass "-z notext" to ld in your driver.

@glondu
Copy link
Contributor Author

glondu commented Jul 30, 2020

I've applied this patch (disabling the warnings) to the Debian package.

@glondu
Copy link
Contributor Author

glondu commented Jul 31, 2020

I've applied this patch (disabling the warnings) to the Debian package.

Note that this change breaks the compiler-libs ABI (the option ends up in a string that is exposed in config.cmx). Hence, it needs recompilation of all reverse-dependencies :-(

@fweimer
Copy link

fweimer commented Aug 5, 2020

The new behavior is triggered by this commit. I didn't find any rationale for this.

Text relocations are almost always created by accident. This is also what seems to be happening here, so the warning has already served its purpose.

@xavierleroy
Copy link
Contributor

The patch is the best solution to the issue, I believe.

Just to document what's going on:

  • On 32-bit targets (x86-32, arm, powerpc-32) ocamlopt cannot generate position-independent code (PIC), and never will, in all likelihood, because 32-bit processors are less and less relevant. (ocamlopt supports PIC on 64-bit targets.)
  • Under Linux with Glibc, we can still make shared libraries and PIE executables from non-PIC code, because the Glibc dynamic loader is able to relocate non-PIC code. For that it needs to update the "text" ELF section, which is inefficient and slightly insecure, but that's better than failing or sliently crashing (like the Musl dynamic loader does).
  • The new ld warning is probably appropriate in general, but here it needs to be turned off.

raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Aug 12, 2020
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0008-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Nov 7, 2020
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0006-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Nov 7, 2020
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0006-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Nov 9, 2020
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0006-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
@JasonGross
Copy link

For some reason, this patch does not seem to work when building on groovy, see this log. Despite the host system type being picked up as i686-pc-linux-gnu, the extra flags don't seem to be added. @glondu (or others), do you have any idea what's going on here?

@JasonGross
Copy link

Ah, I've figured out what's going on. The patch is inadequate because it updates configure.ac without updating configure.

@JasonGross
Copy link

samoht added a commit to samoht/mirage that referenced this issue Oct 7, 2021
samoht added a commit to samoht/mirage that referenced this issue Oct 7, 2021
samoht added a commit to samoht/mirage that referenced this issue Oct 7, 2021
samoht added a commit to samoht/mirage that referenced this issue Oct 7, 2021
@alexfanqi
Copy link
Contributor

alexfanqi commented Oct 10, 2021

Hi, on riscv64 and ocaml 4.12.1, I also got this warning in some tests, causing a few tests failure (expect empty output). Does ocamlopt currently support generating PIC for riscv64?

for example:

... testing 'np1.ml' with 2 (native) => failed (The file /var/tmp/portage/dev-lang/ocaml-4.12.1/work/ocaml-4.12.1/t
estsuite/_ocamltest/tests/runtime-naked-pointers/np1/ocamlopt.byte/ocamlopt.byte.output was expected to be empty bec
ause there is no reference file /var/tmp/portage/dev-lang/ocaml-4.12.1/work/ocaml-4.12.1/testsuite/tests/runtime-nak
ed-pointers/np1.compilers.reference but it is not:                                                                  
========================================       
/usr/lib/gcc/riscv64-unknown-linux-gnu/11.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: warning: creating DT_TEX
TREL in a PIE
========================================

@nojb
Copy link
Contributor

nojb commented Oct 10, 2021

Hi, on riscv64 and ocaml 4.12.1, I also got this warning in some tests, causing a few tests failure (expect empty output). Does ocamlopt currently support generating PIC for riscv64?

It should. The testsuite passes on our test server, but it uses gcc 9.2.1 which is older than the one you are using 11.2.0... perhaps that has something to do with it.

@alexfanqi
Copy link
Contributor

alexfanqi commented Oct 11, 2021

Maybe it is gcc version. I noticed in your test server, flambda is set false for riscv. so I disabled it, but the warnings are still there plus 3 unexpected errors. Should I open an issue for this?

@nojb
Copy link
Contributor

nojb commented Oct 11, 2021

Should I open an issue for this?

OK, but as we don't currently have an easy way to reproduce the issue, it may not get looked at immediately. We should look into maybe upgrading the VM we use for testing. Which distribution are you using by the way?

@alexfanqi
Copy link
Contributor

Which distribution are you using by the way?

I use Gentoo and tested on it.

it may not get looked at immediately

Not a problem for me. Thanks for the comments. I am just testing packages for Gentoo. not pushing for anything.

@mseri
Copy link
Member

mseri commented Nov 9, 2021

We seem to have hit this issue on x86 in the opam-repository CI on ocaml/opam-repository#19949 and ocaml/opam-repository#19943

raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Dec 2, 2021
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0006-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Feb 3, 2022
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0004-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
@kit-ty-kate
Copy link
Member

Just for information for distribution maintainers out-there: the patch for this has been upstreamed in #10835

It would probably be good to use this one instead to detect outdated patches in future releases.

raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Feb 28, 2023
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0004-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
tmcgilchrist added a commit to tmcgilchrist/opam-dune-lint that referenced this issue Jun 13, 2023
Disable cram tests on i386 due to relocation warnings.
ocaml/ocaml#9800
raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Sep 14, 2023
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0004-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Sep 14, 2023
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0004-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Sep 21, 2023
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0004-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
raspbian-autopush pushed a commit to raspbian-packages/ocaml that referenced this issue Sep 28, 2023
Bug: ocaml/ocaml#9800

Gbp-Pq: Name 0004-Disable-DT_TEXTREL-warnings-on-Linux-i386.patch
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

No branches or pull requests

9 participants