Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2022-07

Smart-linking on linux/x86-64

12 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Joost van der Sluis

Hi all,

I have a very small application, see below. One procedure is not called at all.

But when I compile with

ppcx64 -XX -CX testcfi.pp

The P$TESTCFI_$$_NEVERCALLES symbol is still in the executable.

On Windows (internal linker) this code is omitted from the executable, but not on Linux.

Does anyone know why?

Regards,

Joost.

program testcfi;
{$mode objfpc}
   procedure JoJo;
   begin
     writeln('Tadaa');
   end;
   procedure NeverCalled;
   begin
     writeln('NeverCalled');
   end;
   procedure NoStackFrame;
   begin
     JoJo;
   end;
begin
   NoStackFrame;
end.

Reply by email

Michael Van Canneyt
to Joost van der Sluis
Joost van der Sluis wrote 13 lines
Hi all, I have a very small application, see below. One procedure is not called at all. But when I compile with ppcx64 -XX -CX testcfi.pp The P$TESTCFI_$$_NEVERCALLES symbol is still in the executable. On Windows (internal linker) this code is omitted from the executable, but not on Linux.

It's omitted here as well:

objdump -t a | grep -i TESTCFI_

00000000004010d0 g F .text 000000000000000e P$TESTCFI_$$_NOSTACKFRAME 0000000000401080 g F .text 0000000000000047 P$TESTCFI_$$_JOJO

Michael.

Reply by email

Martin Frb
to Michael Van Canneyt
Michael Van Canneyt wrote 19 lines
On Mon, 4 Jul 2022, Joost van der Sluis via fpc-devel wrote: > Hi all, > > I have a very small application, see below. One procedure is not > called at all. > > But when I compile with > > ppcx64 -XX -CX testcfi.pp > > The P$TESTCFI_$$_NEVERCALLES symbol is still in the executable. > > On Windows (internal linker) this code is omitted from the > executable, but not on Linux. It's omitted here as well:

Not 100% on topic (sorry) but talking about symbols that are (or are not) included/excluded from the exe...

There are cases were (imho) too many symbols are omitted, and it has gotten worse from 3.2.3 to 3.3.1.

https://gitlab.com/freepascal.org/fpc/source/-/issues/39824 There may not be a variable of the class in question, but the class is created. Therefore it exists in the app, and could be needed by a debugger.

Yet while both 2.3.2 and 3.3.1 omit the info itself, an effort was made in 3.3.1 to clean up the $$vmt info too, imho that should be reverted, and the full info included.

Reply by email

Sven Barth
to Joost van der Sluis: I have a very small application, see below. One procedure is not called at all. But when…
Joost van der Sluis wrote 15 lines
Hi all, I have a very small application, see below. One procedure is not called at all. But when I compile with ppcx64 -XX -CX testcfi.pp The P$TESTCFI_$$_NEVERCALLES symbol is still in the executable. On Windows (internal linker) this code is omitted from the executable, but not on Linux. Does anyone know why?

I can't reproduce this with main. But considering that you named the test file “testcfi”: do you by chance play around with DWARF data? Cause DWARF doesn't support smartlinking on non-Windows, at least not in the way FPC generates it...

Regards,
Sven

Reply by email

Joost van der Sluis
to Sven Barth

Op 04-07-2022 om 23:37 schreef Sven Barth via fpc-devel:

Show quoted text 21 lines
Am 04.07.2022 um 19:52 schrieb Joost van der Sluis via fpc-devel: > Hi all, > > I have a very small application, see below. One procedure is not > called at all. > > But when I compile with > > ppcx64 -XX -CX testcfi.pp > > The P$TESTCFI_$$_NEVERCALLES symbol is still in the executable. > > On Windows (internal linker) this code is omitted from the executable, > but not on Linux. > > Does anyone know why? I can't reproduce this with main. But considering that you named the test file “testcfi”: do you by chance play around with DWARF data? Cause DWARF doesn't support smartlinking on non-Windows, at least not in the way FPC generates it...

After your and Michael's response, I've tried it again and I can't reproduce it anymore either...

I'm still wondering what I did wrong.

But my real issue is this: on Windows, using the internal linker, this procedure is also omitted *with* Dwarf debug-data. As you implied.

The problem is, though, that the CFI-information (the FDE) is not omitted. This is 'solved' in the internal linker by replacing the address with 0. Gdb doesn't mind and I've adapted FpDebug so that it allows this too, but this is still invalid, imho.

But as the FDE is written now, as 'one block', without any sections, I don't see how the linker could omit the corresponding FDE.

Any suggestions? Is it possible to place every fde in it's own section to solve this?

Regards,

Joost.

Reply by email

Sven Barth
to Joost van der Sluis

Joost van der Sluis via fpc-devel schrieb
am Di., 5. Juli 2022, 00:17:

Show quoted text 15 lines
But my real issue is this: on Windows, using the internal linker, this procedure is also omitted *with* Dwarf debug-data. As you implied. The problem is, though, that the CFI-information (the FDE) is not omitted. This is 'solved' in the internal linker by replacing the address with 0. Gdb doesn't mind and I've adapted FpDebug so that it allows this too, but this is still invalid, imho. But as the FDE is written now, as 'one block', without any sections, I don't see how the linker could omit the corresponding FDE. Any suggestions? Is it possible to place every fde in it's own section to solve this?

The problem is that *something* would need to reference the debug sections otherwise they are stripped as well. But as soon as they're referenced whatever code or data *they* reference is kept as well. One of the better solutions might be to write these references as weak symbols (on systems that support this) so at least the data/function isn't kept around.
Or the section of the data/function would have to contain a reference to its corresponding debug entry so that it is kept around as long as the function/data is kept around...
How does GCC do this?

Regards,
Sven

Reply by email

Sergei Gorelkin
to Sven Barth
Sven Barth wrote 28 lines
Joost van der Sluis via fpc-devel < > schrieb am Di., 5. Juli 2022, 00:17: But my real issue is this: on Windows, using the internal linker, this procedure is also omitted *with* Dwarf debug-data. As you implied. The problem is, though, that the CFI-information (the FDE) is not omitted. This is 'solved' in the internal linker by replacing the address with 0. Gdb doesn't mind and I've adapted FpDebug so that it allows this too, but this is still invalid, imho. But as the FDE is written now, as 'one block', without any sections, I don't see how the linker could omit the corresponding FDE. Any suggestions? Is it possible to place every fde in it's own section to solve this? The problem is that *something* would need to reference the debug sections otherwise they are stripped as well. But as soon as they're referenced whatever code or data *they* reference is kept as well. One of the better solutions might be to write these references as weak symbols (on systems that support this) so at least the data/function isn't kept around. Or the section of the data/function would have to contain a reference to its corresponding debug entry so that it is kept around as long as the function/data is kept around... How does GCC do this?

As far as I had studied this issue, ld essentially "decompiles" the monolithic FDE's from object files into internal representation, and then "compiles" it back, omitting information for the code that won't go into executable due to smartlinking. It also optimizes for size by using 8- and 16-bit offsets instead of 32-bit ones when possible.

Regards,
Sergei

Reply by email

Joost van der Sluis
to Sven Barth: Joost van der Sluis via fpc-devel schrieb am Di., 5. Juli 2022, 00:17: The problem is…

Op 05-07-2022 om 08:39 schreef Sven Barth via fpc-devel:

Show quoted text 17 lines
Joost van der Sluis via fpc-devel < > schrieb am Di., 5. Juli 2022, 00:17: Any suggestions? Is it possible to place every fde in it's own section to solve this? The problem is that *something* would need to reference the debug sections otherwise they are stripped as well. But as soon as they're referenced whatever code or data *they* reference is kept as well. One of the better solutions might be to write these references as weak symbols (on systems that support this) so at least the data/function isn't kept around. Or the section of the data/function would have to contain a reference to its corresponding debug entry so that it is kept around as long as the function/data is kept around... How does GCC do this?

Apperently GCC does the exact same thing as fpc does on Windows. Replace the addresses with 0, and mixup the function-names.

(The link between the CFI and actual code consists of local labels. They do not reference the global labels/sections. I guess that is why the code is removed, as it's global label is not referenced)

I can adapt fpc so that it does the same on Linux also. So I think I'll leave it this way.

Thanks for the help.

Joost.

Reply by email

Sven Barth
to Joost van der Sluis

Joost van der Sluis via fpc-devel schrieb
am Di., 5. Juli 2022, 22:37:

Show quoted text 33 lines
Op 05-07-2022 om 08:39 schreef Sven Barth via fpc-devel: > Joost van der Sluis via fpc-devel < > > schrieb am Di., 5. Juli 2022, > 00:17: > Any suggestions? Is it possible to place every fde in it's own section > to solve this? > > > The problem is that *something* would need to reference the debug > sections otherwise they are stripped as well. But as soon as they're > referenced whatever code or data *they* reference is kept as well. > One of the better solutions might be to write these references as weak > symbols (on systems that support this) so at least the data/function > isn't kept around. > Or the section of the data/function would have to contain a reference to > its corresponding debug entry so that it is kept around as long as the > function/data is kept around... > How does GCC do this? Apperently GCC does the exact same thing as fpc does on Windows. Replace the addresses with 0, and mixup the function-names. (The link between the CFI and actual code consists of local labels. They do not reference the global labels/sections. I guess that is why the code is removed, as it's global label is not referenced) I can adapt fpc so that it does the same on Linux also. So I think I'll leave it this way.

I think many people would be glad if you'd solve the issue of smart linking with debug information when an external linker is used. :)

Regards,
Sven

Reply by email

Joost van der Sluis
to Sergei Gorelkin: As far as I had studied this issue, ld essentially "decompiles" the monolithic FDE's from…

Op 05-07-2022 om 11:51 schreef Sergei Gorelkin via fpc-devel:

Show quoted text 21 lines
05/07/2022 09:39, Sven Barth via fpc-devel wrote: > Joost van der Sluis via fpc-devel < > > schrieb am Di., 5. Juli 2022, > 00:17: > The problem is that *something* would need to reference the debug > sections otherwise they are stripped as well. But as soon as they're > referenced whatever code or data *they* reference is kept as well. > One of the better solutions might be to write these references as weak > symbols (on systems that support this) so at least the data/function > isn't kept around. > Or the section of the data/function would have to contain a reference > to its corresponding debug entry so that it is kept around as long as > the function/data is kept around... > How does GCC do this? > As far as I had studied this issue, ld essentially "decompiles" the monolithic FDE's from object files into internal representation, and then "compiles" it back, omitting information for the code that won't go into executable due to smartlinking. It also optimizes for size by using 8- and 16-bit offsets instead of 32-bit ones when possible.

Indeed, that is also what I have seen. ld Adapts the cfi-contents. (It also removed some mistakes in fpc's implementation)

Regards,

Joost.

Reply by email

Joost van der Sluis
to Sven Barth: Joost van der Sluis via fpc-devel schrieb am Di., 5. Juli 2022, 22:37: I think many…

Op 05-07-2022 om 23:45 schreef Sven Barth via fpc-devel:

Show quoted text 6 lines
Joost van der Sluis via fpc-devel < > schrieb am Di., 5. Juli 2022, 22:37: I think many people would be glad if you'd solve the issue of smart linking with debug information when an external linker is used. :)

That's easy. See the attachment (Linux only). The results are similar as gcc produces. Apparently ld does not regard references in debug-sections as real references, and replaces them with 0-addresses. Just like our internal linker on Windows does.

I don't dare to push it, though. Because:

1: Someone disabled this because some older version of LD cannot handle it. Maybe some version we use still use on some targets/systems?

2: Someone disabled this because of some corner-case we now don't know of anymore.

Does anyone have some more information?

Regards,

Joost

Reply by email