[LLD] Support DWARF64, debug_info "sorting"

>
> I got replies from Nick Clifton and Michael Matz:
> How to sort mixed DWARF32 and DWARF64 .debug_*
> (and its reply).
> I have mentioned (a) the difficulty of the
> detecting-DWARF64-by-first-relocation approach and (b) the section
> type approach in my reply there
> How to sort mixed DWARF32 and DWARF64 .debug_*
>
> (a) My prototype has made me feel uneasy with this approach.
>
> <quote>
> In DWARF v4 or if .debug_str_offset is not used, it is a problem. A
> heuristic is: if an input section in a file is marked DWARF64, we mark
> all other .debug_* DWARF64. This makes me feel a bit uneasy because
> for an output section description
>
> .debug_str 0 : { *(.debug_str) }
>
> Now the behavior of `*` (or, if we invent a `SORT_*` keyword) is also
> dependent on other output sections.
> </quote>
>
> (b)
> * It needs a section type (either a gABI one or a SHT_GNU_* in GNU
> ABI). Seeking for a gABI one is not that I think this is particularly
> related to gABI but that I don't want Solaris (which LLVM also
> supports) uses a different section type to unnecessarily cause
> friction on our implementation

If I'm understawding you correrctly you're suggesting the sorting
behavior would only be implemented if the input object file had some
new attributes in it designating which sections are debug info
sections?

I don't think that's a viable solution to the problem at hand, then -
if someone is able to update their toolchain and rebuild objects with
new attributes, they can probably update the build configuration of
those objects to build them with DWARF64 instead, avoiding the mixed
32/64 problem. I think the solution we're looking for would have to
work with existing precompiled object files using DWARF32 that are in
the wild today, without modification.

I know the "no-modification" requirement:) The first paragraph of
https://sourceware.org/pipermail/binutils/2020-November/114125.html
mentioned this.

The section type approach is used this way (in another paragraph):

<quote>
If we invent a keyword (say, TYPE) to match sections by type, we could use

   .debug_info 0 : { *(TYPE (SHT_PROGBITS)
.debug_info${RELOCATING+ .gnu.linkonce.wi.*}) }
   .debug_info 0 : { *(TYPE (SHT_GNU_DWARF64) .debug_info) }

or

   .debug_info 0 : { *(TYPE (SHT_PROGBITS)
.debug_info${RELOCATING+ .gnu.linkonce.wi.*} TYPE (SHT_GNU_DWARF64)
.debug_info) }
</quote>

>
> >
> > I got replies from Nick Clifton and Michael Matz:
> > How to sort mixed DWARF32 and DWARF64 .debug_*
> > (and its reply).
> > I have mentioned (a) the difficulty of the
> > detecting-DWARF64-by-first-relocation approach and (b) the section
> > type approach in my reply there
> > How to sort mixed DWARF32 and DWARF64 .debug_*
> >
> > (a) My prototype has made me feel uneasy with this approach.
> >
> > <quote>
> > In DWARF v4 or if .debug_str_offset is not used, it is a problem. A
> > heuristic is: if an input section in a file is marked DWARF64, we mark
> > all other .debug_* DWARF64. This makes me feel a bit uneasy because
> > for an output section description
> >
> > .debug_str 0 : { *(.debug_str) }
> >
> > Now the behavior of `*` (or, if we invent a `SORT_*` keyword) is also
> > dependent on other output sections.
> > </quote>
> >
> > (b)
> > * It needs a section type (either a gABI one or a SHT_GNU_* in GNU
> > ABI). Seeking for a gABI one is not that I think this is particularly
> > related to gABI but that I don't want Solaris (which LLVM also
> > supports) uses a different section type to unnecessarily cause
> > friction on our implementation
>
> If I'm understawding you correrctly you're suggesting the sorting
> behavior would only be implemented if the input object file had some
> new attributes in it designating which sections are debug info
> sections?
>
> I don't think that's a viable solution to the problem at hand, then -
> if someone is able to update their toolchain and rebuild objects with
> new attributes, they can probably update the build configuration of
> those objects to build them with DWARF64 instead, avoiding the mixed
> 32/64 problem. I think the solution we're looking for would have to
> work with existing precompiled object files using DWARF32 that are in
> the wild today, without modification.

I know the "no-modification" requirement:) The first paragraph of
How to sort mixed DWARF32 and DWARF64 .debug_*
mentioned this.

OK - thanks for clarifying. I don't really know much/enough about
linker scripts to comment on the rest of the design, and was just
confused/misunderstanding what was being suggested.

>
> >
> > >
> > > I got replies from Nick Clifton and Michael Matz:
> > > How to sort mixed DWARF32 and DWARF64 .debug_*
> > > (and its reply).
> > > I have mentioned (a) the difficulty of the
> > > detecting-DWARF64-by-first-relocation approach and (b) the section
> > > type approach in my reply there
> > > How to sort mixed DWARF32 and DWARF64 .debug_*
> > >
> > > (a) My prototype has made me feel uneasy with this approach.
> > >
> > > <quote>
> > > In DWARF v4 or if .debug_str_offset is not used, it is a problem. A
> > > heuristic is: if an input section in a file is marked DWARF64, we mark
> > > all other .debug_* DWARF64. This makes me feel a bit uneasy because
> > > for an output section description
> > >
> > > .debug_str 0 : { *(.debug_str) }
> > >
> > > Now the behavior of `*` (or, if we invent a `SORT_*` keyword) is also
> > > dependent on other output sections.
> > > </quote>
> > >
> > > (b)
> > > * It needs a section type (either a gABI one or a SHT_GNU_* in GNU
> > > ABI). Seeking for a gABI one is not that I think this is particularly
> > > related to gABI but that I don't want Solaris (which LLVM also
> > > supports) uses a different section type to unnecessarily cause
> > > friction on our implementation
> >
> > If I'm understawding you correrctly you're suggesting the sorting
> > behavior would only be implemented if the input object file had some
> > new attributes in it designating which sections are debug info
> > sections?
> >
> > I don't think that's a viable solution to the problem at hand, then -
> > if someone is able to update their toolchain and rebuild objects with
> > new attributes, they can probably update the build configuration of
> > those objects to build them with DWARF64 instead, avoiding the mixed
> > 32/64 problem. I think the solution we're looking for would have to
> > work with existing precompiled object files using DWARF32 that are in
> > the wild today, without modification.
>
> I know the "no-modification" requirement:) The first paragraph of
> How to sort mixed DWARF32 and DWARF64 .debug_*
> mentioned this.

OK - thanks for clarifying. I don't really know much/enough about
linker scripts to comment on the rest of the design, and was just
confused/misunderstanding what was being suggested.

For .debug_* in object files:

DWARF32 -> SHT_PROGBITS (unchanged)
DWARF64 -> SHT_DWARF64 or SHT_GNU_DWARF64

In LLD, we will need to allow mixed SHT_PROGBITS and SHT_DWARF64. If
all input sections are SHT_DWARF64, the output section type probably
should also be SHT_DWARF64.
If mixed, SHT_PROGBITS.

FWIW I started a generic-abi thread
https://groups.google.com/g/generic-abi/c/i2Xio-47QdQ ("Reserve a
section type value for DWARF64") to give stakeholders from other ELF
operating systems a chance to participate in the design. I have paid
attention to my wording: a new section type is **not decided yet** on
LLVM/GNU binutils sides. Our discussions on llvm-dev/binutils will
benefit from agreement/disagreement from generic-abi.

Thanks for doing a diff and asking in other groups.

So if I understand your concern with using first reloc as it relates to .debug_str.

In DWARF4 for .debug_str is referenced from .debug_info, .debug_type using DW_FORM_strp. For DWARF32 it’s 32bit unsigned, for DWARF64 it’s 64bit unsigned. So in relocation section for some .debug_info section we will have a relocation entry to patch up DW_FORM_strp. Either R_X86_64_32, or R_X86_64_64, depending on DWARF format.

A situation we might have is that an input .debug_info section is DWARF32 so it gets ordered apropriatly within output .debug_info section, but the input .debug_str section can be put in the output .debug_str section that is above 4GB. In which case we still hit overflow. So we also need to oder the .debug_str section, except in DWARF4 there is no real clear link, besides looking through .debug_info relocs.

Is that a correct summary?

Also I don’t quite understand what the issue is with linker script.

My understanding is that:

.debug_str 0 : { *(.debug_str) }

Just stays that all .debug_str input sections should go in to .debug_str output section. It doesn’t really specify the ordering within the output .debug_str section.

Thank You
Alex

For .debug_* in object files:

DWARF32 -> SHT_PROGBITS (unchanged)
DWARF64 -> SHT_DWARF64 or SHT_GNU_DWARF64

In LLD, we will need to allow mixed SHT_PROGBITS and SHT_DWARF64. If
all input sections are SHT_DWARF64, the output section type probably
should also be SHT_DWARF64.
If mixed, SHT_PROGBITS.

I am not really sure that we need a new section type. This gets a small simplification in one part of the linker but adds much more burden of supporting that to all tools and specs around. And that support would be required for a rarely used feature, which certainly results that support to be partial and sometimes erroneous.

If we aim for clarity and not ambiguity, I would suggest considering the following. The DWARF specs designed so that the data of DWARF32 and DWARF64 formats can be intermixed together in one section. What section type should be used for that combination? Should it be another new section type, something like SHT_DWARF32_DWARF64? Probably not, that should be a regular SHT_PROGBITS. That means that DWARF64 data can be contained in a SHT_PROGBITS section. Consequently, the section which contains DWARF64 data without DWARF32 data should also be SHT_PROGBITS, because the latter is just a special case of the former.

FWIW I started a generic-abi thread
https://groups.google.com/g/generic-abi/c/i2Xio-47QdQ ("Reserve a
section type value for DWARF64") to give stakeholders from other ELF
operating systems a chance to participate in the design. I have paid
attention to my wording: a new section type is **not decided yet** on
LLVM/GNU binutils sides. Our discussions on llvm-dev/binutils will
benefit from agreement/disagreement from generic-abi.

Thank you for conducting all these discussions. I hope we will finally find a way to bring the feature alive.

Thanks for doing a diff and asking in other groups.

So if I understand your concern with using first reloc as it relates to .debug_str.

In DWARF4 for .debug_str is referenced from .debug_info, .debug_type using DW_FORM_strp. For DWARF32 it's 32bit unsigned, for DWARF64 it's 64bit unsigned. So in relocation section for some .debug_info section we will have a relocation entry to patch up DW_FORM_strp. Either R_X86_64_32, or R_X86_64_64, depending on DWARF format.

A situation we might have is that an input .debug_info section is DWARF32 so it gets ordered apropriatly within output .debug_info section, but the input .debug_str section can be put in the output .debug_str section that is above 4GB. In which case we still hit overflow. So we also need to oder the .debug_str section, except in DWARF4 there is no real clear link, besides looking through .debug_info relocs.

Yes. For most other .debug_*, we can check whether the section has an 64-bit
absolute relocation to decide whether it is DWARF64. .debug_str is different in
that we need to check relocations referencing it. This makes its behavior
dependent on other sections, which is why I feel lost with the relocation
approach: when we write .debug_str 0 : { *(.debug_str) }, we really want the
output section .debug_str can be made up with just information from the input
section descriptions, not random information from other .debug_*

LLD -O1 (default) and GNU ld -O0 enable constant string merge within
SHF_MERGE&&SHF_STRINGS sections. We need to pay attention as if a DWARF32
string gets folded into a DWARF64 string, the section referencing the DWARF32
string can still trigger a relocation overflow.

If we order DWARF32 components before DWARF64 components, with the
llvm::StringTableBuilder usage in LLD, we can make sure DWARF64 strings can get
folded into DWARF32 strings, not the other way around.

Is that a correct summary?

Also I don't quite understand what the issue is with linker script.

My understanding is that:

.debug_str 0 : { *(.debug_str) }

Just stays that all .debug_str input sections should go in to .debug_str output section. It doesn't really specify the ordering within the output .debug_str section.

There is an assumption that linkers concatenate input sections in input order,
which is required by the ELF specification. There are options which can change
the semantics of `*`: --sort-section, (gold specific) --section-ordering-file,
(LLD specific) --symbol-ordering-file. Like the other options, we should
justify the `*` ordering by assigning appropriate semantics.

> For .debug_* in object files:
>
> DWARF32 -> SHT_PROGBITS (unchanged)
> DWARF64 -> SHT_DWARF64 or SHT_GNU_DWARF64
>
> In LLD, we will need to allow mixed SHT_PROGBITS and SHT_DWARF64. If
> all input sections are SHT_DWARF64, the output section type probably
> should also be SHT_DWARF64.
> If mixed, SHT_PROGBITS.

I am not really sure that we need a new section type. This gets a small
simplification in one part of the linker but adds much more burden of
supporting that to all tools and specs around. And that support would be
required for a rarely used feature, which certainly results that support
to be partial and sometimes erroneous.

This is not a small simplification. If we consider how we would
address .debug_str with the relocation approach,
it would be quite contrived. A reply I just made
https://lists.llvm.org/pipermail/llvm-dev/2020-November/146673.html
detailed why I don't like the conceptual model: the behavior is
dependent on other sections.
I also felt bad as I had to do string comparison on ".debug_"
(⚙ D91404 RFC: [ELF] Add --dwarf32-before-dwarf64 to place DWARF32 input sections before DWARF64)

I've chatted with gdb folks: gdb (gdb/dwarf2/read.c) is agnostic about
the section type. (They just cannot handle multiple .debug_info
sections.)
SHT_PROGBITS is a default (or "use this if nothing more specific
exists") section type that probably no tool will specifically check
the type.
For many tools, they don't understand DWARF64 yet - there is little
they need to adapt when they add DWARF64 support.
Currently the only problem I can think of is readelf -S (from my
understanding of
How to sort mixed DWARF32 and DWARF64 .debug_* ,
Nick will be happy if I write a GNU readelf patch to make the section
header table dump look good:) )

If we aim for clarity and not ambiguity, I would suggest considering the
following. The DWARF specs designed so that the data of DWARF32 and
DWARF64 formats can be intermixed together in one section. What section
type should be used for that combination? Should it be another new
section type, something like SHT_DWARF32_DWARF64? Probably not, that
should be a regular SHT_PROGBITS. That means that DWARF64 data can be
contained in a SHT_PROGBITS section. Consequently, the section which
contains DWARF64 data without DWARF32 data should also be SHT_PROGBITS,
because the latter is just a special case of the former.

I suggest we follow the `canMergeToProgbits` logic in LLD: mixed
SHT_DWARF64 and SHT_PROGBITS get SHT_PROGBITS. This is the existing
rule for many other section types.
Conceptually, the combined section should impose the rigid restriction
when it is further combined with other sections.
This is probably an extra argument that we don't need SHT_DWARF32.

> FWIW I started a generic-abi thread
> https://groups.google.com/g/generic-abi/c/i2Xio-47QdQ ("Reserve a
> section type value for DWARF64") to give stakeholders from other ELF
> operating systems a chance to participate in the design. I have paid
> attention to my wording: a new section type is **not decided yet** on
> LLVM/GNU binutils sides. Our discussions on llvm-dev/binutils will
> benefit from agreement/disagreement from generic-abi.

Thank you for conducting all these discussions. I hope we will finally
find a way to bring the feature alive.

Thanks to James and Pavel for quoting the standard.
https://groups.google.com/g/generic-abi/c/i2Xio-47QdQ
It seems that we've made progress on the thread and may be able to get
a generic value.
I am following up with binutils folks
https://sourceware.org/pipermail/binutils/2020-November/
I hope we can get to a design which satisfies all parties.

Thinking about it, it would probably be wise to raise this discussion on the DWARF mailing list too. They might want to put an addendum in the spec/DWARF wiki/somewhere appropriate along the lines of “ELF support for DWARF64”, which can be retroactively applied to existing standards. The committee may also have some thoughts on how tools are expected to work with DWARF64 and DWARF32 mixtures.

James

For .debug_* in object files:

DWARF32 -> SHT_PROGBITS (unchanged)
DWARF64 -> SHT_DWARF64 or SHT_GNU_DWARF64

In LLD, we will need to allow mixed SHT_PROGBITS and SHT_DWARF64. If
all input sections are SHT_DWARF64, the output section type probably
should also be SHT_DWARF64.
If mixed, SHT_PROGBITS.

I am not really sure that we need a new section type. This gets a small
simplification in one part of the linker but adds much more burden of
supporting that to all tools and specs around. And that support would be
required for a rarely used feature, which certainly results that support
to be partial and sometimes erroneous.

This is not a small simplification. If we consider how we would
address .debug_str with the relocation approach,
it would be quite contrived. A reply I just made
[llvm-dev] [LLD] Support DWARF64, debug_info "sorting"
detailed why I don't like the conceptual model: the behavior is
dependent on other sections.

I do not see real issues in the dependency on other sections. Section 7.4, p. 198, DWARFv5 states: "The 32-bit and 64-bit DWARF format conventions must not be intermixed within a single compilation unit." From this, we can conclude that if a ".debug_info" section contains only 64-bit relocations, all other debug info sections in the object file are in the 64-bit DWARF format. This can be simplified to checking just the first relocation of this section, as you have made in ⚙ D91404 RFC: [ELF] Add --dwarf32-before-dwarf64 to place DWARF32 input sections before DWARF64, and then spreading the assessment to all other debug sections in the object file. Sure, this heuristic will not work for some clumsy partially linked relocatable objects with a mixture of DWARF64 and DWARF32 data, but I guess they can be ignored for the first shot, because, firstly, their creation is usually under full control of the user and, secondly, the heuristic can be extended to check all the relocations if that will be ever necessary.

I also felt bad as I had to do string comparison on ".debug_"
(⚙ D91404 RFC: [ELF] Add --dwarf32-before-dwarf64 to place DWARF32 input sections before DWARF64)

Well, that is a common way to find sections with debugging information, no?

I've chatted with gdb folks: gdb (gdb/dwarf2/read.c) is agnostic about
the section type. (They just cannot handle multiple .debug_info
sections.)
SHT_PROGBITS is a default (or "use this if nothing more specific
exists") section type that probably no tool will specifically check
the type.
For many tools, they don't understand DWARF64 yet - there is little
they need to adapt when they add DWARF64 support.
Currently the only problem I can think of is readelf -S (from my
understanding of
How to sort mixed DWARF32 and DWARF64 .debug_* ,
Nick will be happy if I write a GNU readelf patch to make the section
header table dump look good:) )

My main concern is that the new type is mostly useless for everyone, except that it provides a small hint for the linker, which is not very important because the same information can be easily and reliably gathered in place. Is that hint really so useful that deserves special support on the ELF specs level?

From: Fāng-ruì Sòng <maskray@google.com>
Sent: Tuesday, November 17, 2020 1:51 AM
To: Alexander Yermolovich <ayermolo@fb.com>
Cc: David Blaikie <dblaikie@gmail.com>; Wenlei He <wenlei@fb.com>; llvm-
dev@lists.llvm.org; Robinson, Paul <paul.robinson@sony.com>; James
Henderson <jh7370.2008@my.bristol.ac.uk>; Eric Christopher
<echristo@gmail.com>; Igor Kudrin <ikudrin@accesssoftek.com>
Subject: Re: [llvm-dev] [LLD] Support DWARF64, debug_info "sorting"

>Thanks for doing a diff and asking in other groups.
>
>So if I understand your concern with using first reloc as it relates to
.debug_str.
>
>In DWARF4 for .debug_str is referenced from .debug_info, .debug_type
using DW_FORM_strp. For DWARF32 it's 32bit unsigned, for DWARF64 it's
64bit unsigned. So in relocation section for some .debug_info section we
will have a relocation entry to patch up DW_FORM_strp. Either R_X86_64_32,
or R_X86_64_64, depending on DWARF format.
>
>A situation we might have is that an input .debug_info section is DWARF32
so it gets ordered apropriatly within output .debug_info section, but the
input .debug_str section can be put in the output .debug_str section that
is above 4GB. In which case we still hit overflow. So we also need to oder
the .debug_str section, except in DWARF4 there is no real clear link,
besides looking through .debug_info relocs.

Yes. For most other .debug_*, we can check whether the section has an 64-
bit
absolute relocation to decide whether it is DWARF64. .debug_str is
different in
that we need to check relocations referencing it. This makes its behavior
dependent on other sections, which is why I feel lost with the relocation
approach: when we write .debug_str 0 : { *(.debug_str) }, we really want
the
output section .debug_str can be made up with just information from the
input
section descriptions, not random information from other .debug_*

LLD -O1 (default) and GNU ld -O0 enable constant string merge within
SHF_MERGE&&SHF_STRINGS sections. We need to pay attention as if a DWARF32
string gets folded into a DWARF64 string, the section referencing the
DWARF32
string can still trigger a relocation overflow.

This is a problem only if the .debug_str section *by itself* exceeds 4GB;
are we anticipating that will happen IRL? The section is just a string
section, by itself it has no 32/64 format.

If the .debug_str section *by itself* exceeds 4GB, then yes any string
with a 32-bit reference to it must be in the first 4GB. Strings that
have only 64-bit references to them can be sorted to the end of the
section, if necessary. I wouldn't think anyone guarantees or cares
about the order of strings within a string section.

But I think this would be the very last thing to care about, with regard
to DWARF-64 concerns.
--paulr

For .debug_* in object files:

DWARF32 -> SHT_PROGBITS (unchanged)
DWARF64 -> SHT_DWARF64 or SHT_GNU_DWARF64

In LLD, we will need to allow mixed SHT_PROGBITS and SHT_DWARF64. If
all input sections are SHT_DWARF64, the output section type probably
should also be SHT_DWARF64.
If mixed, SHT_PROGBITS.

I am not really sure that we need a new section type. This gets a small
simplification in one part of the linker but adds much more burden of
supporting that to all tools and specs around. And that support would be
required for a rarely used feature, which certainly results that support
to be partial and sometimes erroneous.

This is not a small simplification. If we consider how we would
address .debug_str with the relocation approach,
it would be quite contrived. A reply I just made
[llvm-dev] [LLD] Support DWARF64, debug_info "sorting"
detailed why I don't like the conceptual model: the behavior is
dependent on other sections.

I do not see real issues in the dependency on other sections. Section 7.4, p. 198, DWARFv5 states: "The 32-bit and 64-bit DWARF format conventions must not be intermixed within a single compilation unit." From this, we can conclude that if a ".debug_info" section contains only 64-bit relocations, all other debug info sections in the object file are in the 64-bit DWARF format. This can be simplified to checking just the first relocation of this section, as you have made in ⚙ D91404 RFC: [ELF] Add --dwarf32-before-dwarf64 to place DWARF32 input sections before DWARF64, and then spreading the assessment to all other debug sections in the object file. Sure, this heuristic will not work for some clumsy partially linked relocatable objects with a mixture of DWARF64 and DWARF32 data, but I guess they can be ignored for the first shot, because, firstly, their creation is usually under full control of the user and, secondly, the heuristic can be extended to check all the relocations if that will be ever necessary.

I don't like the "if .debug_info looks like DWARF64, mark .debug_str
approach" because it makes a section's behavior dependent on other
sections in the input file, diverging a lot from the current way
existing output section descriptions/input section descriptions are
handled. This is about system consistency that I care a lot and really
don't want to break giving that we have compelling alternative designs.

I also felt bad as I had to do string comparison on ".debug_"
(⚙ D91404 RFC: [ELF] Add --dwarf32-before-dwarf64 to place DWARF32 input sections before DWARF64)

Well, that is a common way to find sections with debugging information, no?

I've chatted with gdb folks: gdb (gdb/dwarf2/read.c) is agnostic about
the section type. (They just cannot handle multiple .debug_info
sections.)
SHT_PROGBITS is a default (or "use this if nothing more specific
exists") section type that probably no tool will specifically check
the type.
For many tools, they don't understand DWARF64 yet - there is little
they need to adapt when they add DWARF64 support.
Currently the only problem I can think of is readelf -S (from my
understanding of
How to sort mixed DWARF32 and DWARF64 .debug_* ,
Nick will be happy if I write a GNU readelf patch to make the section
header table dump look good:) )

My main concern is that the new type is mostly useless for everyone, except that it provides a small hint for the linker, which is not very important because the same information can be easily and reliably gathered in place. Is that hint really so useful that deserves special support on the ELF specs level?

It is not useless. Avoiding string comparison on ".debug_" is one thing
(sometimes this can improve performance a bit). The linker complexity is
another. As I mentioned in my previous reply, "SHT_PROGBITS+SHT_DWARF64
=> SHT_DWARF64" makes the scheme automatically work with relocatable links.

There are 0x60000000 generic section type values and 0x10000000 OS
specific values. The resource is abundant.

On https://groups.google.com/g/generic-abi/c/i2Xio-47QdQ , Cary Coutant
has made an alternative proposal by adding a new section flag.
Personally I prefer a section type a section flag with reasons explained
by Ali Bahrami. People are still arguing but I appreciate that the theme
of the discussion is that people acknowledge the use cases and agree to
use an appropriate ELF-level thing, instead of adding ad-hoc rules to
the linker.

In https://groups.google.com/g/generic-abi/c/i2Xio-47QdQ (you need to
join the group before making a post)
Cary Coutant raised yet another idea: whether we can use ".debug64" as
the section prefix. I like the idea because of:

* It is immediately obvious whether DWARF64 is used and whether
DWARF32 is used along with DWARF64.
* In a relocatable link mixing DWARF32 and DWARF64 sections, DWARF32
and DWARF64 sections will naturally not get mixed. (For a relocation
based approach, if DWARF64 is the first input section, the output may
appear as a "DWARF64" because the proposed approach only checks the
first relocation)

On the other hand,

* It is (slightly) non-conformant because of the different section names.
* Tooling support. Some commonly used consumers have recognized
DWARF64. We'll have to teach these tools about new section names. The
number of sections to recognize has doubled. This may result in a fair
amount of complexity (DWARFContext/MCObjectFileInfo/llvm-dwarfdump
-debug* options/ld.lld --gdb-index are things I can immediately think
of).

On balance I think this is not as good as the section type idea.

I guess that the relative size of the ".debug_str" section may vary and depends on the source code, particular build environment, and lots of other circumstances. I've checked some fresh built samples and always see that the section is usually close in size to ".debug_info" and sometimes even bigger. So, this section must be ordered similarly as all other debugging info sections.

I was thinking about whether I liked the section name idea myself. I think a slight refinement could be to have linkers combine .debug and .debug64 sections into one output section (in non -r links), so that end consumers (debuggers etc) don’t have to worry about it. However, conformance is still a concern to me as we cannot really retrofit the existing standard versions, and the section names themselves are in the standard. That means that tools that otherwise would work might stop working when presented with a “new” DWARFv3/4/5 output that it in theory could otherwise handle. This applies to both debuggers who don’t know about the support and tools like llvm-dwarfdump which work on intermediate objects until they get updated. One final concern with the section name approach is that there are tools that look for the debug sections in general (e.g. llvm-objcopy --strip-debug), which use the prefix “.debug_” to identify such sections, rather than .debug, so .debug64 would be a bad name to use (although you could do .debug_64_info or .debug_info_64 probably safely).

I was just thinking about this as well, and I think that we should still have linkers merge the .debug_ and .debug64 sections in the final links (essentially replacing the section type-based matching in the original proposal with section name-based matching).

It's true that the .debug64 names are not really conforming, but otoh, the reason why the SHT_DWARF64 idea was conforming is that DWARF is very hand-wavy when it comes to how it interacts with linkers and object file formats.

pl

Thinking about it, I wouldn’t expect an LTO generated object itself to have a mixture of DWARF32/64, although I guess the 32/64 bit state could be encoded in the IR (I am not familiar enough with it to know if it actually is or not). It might be necessary to find ways to configure LTO to generate DWARF64, possibly via a link-time option.

I don’t think we need to encode dwarf32/64 in IR as attribute for each module. We’re not going to emit mixed dwarf32/64 for merged LTO module anyways, so allowing each module to express its dwarf setting would only introduce burden for LTO to deal with inconsistency (warning?) among input modules. Having a linker switch to pass the setting from driver to LTO sounds better to me.

Usually the issue there is that existing build systems may be setup
only to pass such flags to the compilations, and not to the link
invocations - like DWARF version, we pass that down through IR, emit
warnings/errors when two IR modules with different DWARF versions are
linked together, and then emit only one (the higher, I believe) DWARF
version out the other end.

We aren’t 100% consistent on this “anything you could do without LTO,
you shuold be able to do with LTO/passing the same flags to the same
actions” kind of strategy (eg: type units and DWARF compression aren’t
passed down through IR - if you want those you have to pass them to
the link invocation (via the clang driver) yourself). So it’s more “is
there a systemic use of these flags already for the compilation and
would not supporting it there be a pain”? It’s probably not for
DWARF64, since we haven’t had any flag to support it at the moment
anyway.

Haven’t followed this whole discussion closely, but +1 on this. Sounds like a good use of module flags that automatically pick the “max” value on merge. For anything that in a non-LTO build would only need to be passed to the compile step and not affect the link, we should strive to do the same with LTO (there are some legacy things that are passed through the driver at link time, but want to avoid new cases).

Thanks,
Teresa

My concern with using section type, is that it does modify ELF format spec, and can break various tools that rely on this information. This sems somewhat of a heavy handed approach to solving this problem.

Alternatively, if we do want to go with something more official then just doing it in a linker using first reloc, why not use sh_info? Seems like it’s made for providing an extra information for each section_type. In this case .debug_*.

With it we have a current behavior of using names which as far as I can tell the default for figuring out debug sections. If producer provides this extra information the linker can improve layout to help with debug sections overflows, if producer doesn’t provide this information, then it’s a current behavior which also adheres to DWARF spec that says if DWARF32 and DWARF64 the onus is on the user.

Alex

My concern with using section type, is that it does modify ELF format spec, and can break various tools that rely on this information. This sems somewhat of a heavy handed approach to solving this problem.

Alternatively, if we do want to go with something more official then just doing it in a linker using first reloc, why not use sh_info? Seems like it's made for providing an extra information for each section_type. In this case .debug_*.

No, sh_info is a poor fit for this. Its usage is implied by the
sh_type, and, if used, always contains either a symbol table index or
a section table index. A section flag would be far more appropriate.

-cary

Thinking about it, it would probably be wise to raise this discussion on the DWARF mailing list too. They might want to put an addendum in the spec/DWARF wiki/somewhere appropriate along the lines of "ELF support for DWARF64", which can be retroactively applied to existing standards. The committee may also have some thoughts on how tools are expected to work with DWARF64 and DWARF32 mixtures.

Eric, Paul, and I are members of the DWARF committee, so you can be
assured that we will bring this issue up there!

-cary

-cary

> If the .debug_str section *by itself* exceeds 4GB, then yes any string
> with a 32-bit reference to it must be in the first 4GB. Strings that
> have only 64-bit references to them can be sorted to the end of the
> section, if necessary. I wouldn't think anyone guarantees or cares
> about the order of strings within a string section.
>
> But I think this would be the very last thing to care about, with regard
> to DWARF-64 concerns.

I guess that the relative size of the ".debug_str" section may vary and depends on the source code, particular build environment, and lots of other circumstances. I've checked some fresh built samples and always see that the section is usually close in size to ".debug_info" and sometimes even bigger. So, this section must be ordered similarly as all other debugging info sections.

I agree with Paul, and I'm surprised by your findings. Can you post
some actual numbers? In my experience, .debug_str is an order of
magnitude smaller than .debug_info. Perhaps the binaries you're
looking at haven't been string-merged?

-cary