Re: Problems with startup code symbols (Copious warnings)

Jim Blandy
2006-06-15T00:12:21Z

Jim Blandy <jimb@codesourcery.com> writes:
> Steven Johnson <sjohnson@sakuraindustries.com> writes:
>> Will post an app tomorrow that does this, once I've made one.
>
> I see your post in the archive, but for some reason it didn't reach
> me. I'll take a look.

Okay. I think I understand part of the problem.

If you run 'readelf -wi' on your executable, you should see two
DW_TAG_compile_unit entries. Each has DW_AT_high_pc and DW_AT_low_pc
attributes. The DWARF data claims that the crt0.c compilation unit
covers addresses zero to zero, and that the vectors.S compilation unit
covers addresses from zero to 0x104.

Then, each of them has a DW_AT_stmt_list that points to line number
information, which you can dump with 'readelf -wl'. The crt0.c line
number info definitely seems to cover addresses outside the range
given in the crt0.c DW_TAG_compile_unit entry. Which is odd. Where
did the code from crt0.c really go?

Is there some reason relocs against the debugging information aren't
getting applied? I didn't quite get everything that was going on in
your link line.

The other part of the problem is that GDB distrusts DW_AT_low_pc
attributes whose values are zero, presuming that they refer to a
discarded 'linkonce' section. Here's the code:

/* When using the GNU linker, .gnu.linkonce. sections are used to
eliminate duplicate copies of functions and vtables and such.
The linker will arbitrarily choose one and discard the others.
The AT_*_pc values for such functions refer to local labels in
these sections. If the section from that file was discarded, the
labels are not in the output, so the relocs get a value of 0.
If this is a discarded function, mark the pc bounds as invalid,
so that GDB will ignore it. */
if (low == 0 && (bfd_get_file_flags (obfd) & HAS_RELOC) == 0)
return 0;

(Linkonce sections are a crock: if a section of code is discarded, the
debug info should be discarded along with it, but there's no way to do
that with linkonce sections.) But in your case, you really have a
compilation unit at address zero.

That crock is very important for debugging C++ code. But I don't see
any way to distinguish between debug info for a discarded linkonce
section and debug info for a CU that is actually linked at address
zero. They look the same.

But the effect is that GDB creates a symtab structure whose address
range is from zero to zero, built from a partial symtab whose address
range is from zero to 0x104, which is what produces the warnings: the
psymtab promises to cover a given range of code, but when it's
expanded into a full symtab, it doesn't. It would be more consistent
for GDB to never construct the psymtab in the first place, on the
grounds that it looks like debug info for a discarded linkonce
section, but that wouldn't help you at all.

For now, I think a patch that uses complaints instead of warnings is
the best way to get GDB out of your hair. But you're still going to
have problems.

If anyone can see a way to handle discarded linkonce sections better,
I'd love to hear it.