Skip to content

ELF module not loading PublicSymbols for function name resolution #45

@dedmen

Description

@dedmen

When you load a ELF module that doesn't have Dwarf debug information, but does have exported public functions
(Like for example libpthread that you load when trying to analyze a core dump)
These functions are not considered when trying to look up a function name by instruction pointer.

But it works perfectly fine if you consider them.

I know this is not the proper way to do it, but I want to note it here in case someone who can do it properly comes along.

Add

        public PublicSymbol(string name, ulong address, ELFSharp.ELF.Sections.SymbolType type, ulong size)
        {
            Name = name;
            Address = address;
            demangledName = SimpleCache.Create(() => Demangle(name));
            Type = type;
            Size = size;
        }

        public ELFSharp.ELF.Sections.SymbolType Type { get; private set; }

        public ulong Size { get; private set; }

here https://github.com/southpolenator/SharpDebug/blob/next/Source/SharpDebug.DwarfSymbolProvider/IDwarfImage.cs#L39

and

publicSymbols.Add(new PublicSymbol(symbol.Name, symbol.Value - CodeSegmentOffset,symbol.Type, symbol.Size));

here: https://github.com/southpolenator/SharpDebug/blob/next/Source/SharpDebug.DwarfSymbolProvider/ElfImage.cs#L60

and (this is the most hacky part)

 functionsCache.AddRange(
                            publicSymbols
                                .Where(x => x.Type == SymbolType.Function && x.Size != 0 && x.Address != 0)
                                .Where(x =>
                                    functionsCache.All(f =>
                                        f.GetConstantAttribute(DwarfAttribute.LowPc) != x.Address) // #TODO binary search
                            ).Select(publicSymbol =>
                            {

                                Dictionary<DwarfAttribute, DwarfAttributeValue> attributes = new Dictionary<DwarfAttribute, DwarfAttributeValue>();
                                attributes.Add(DwarfAttribute.Name, new DwarfAttributeValue() { Type = DwarfAttributeValueType.String, Value = publicSymbol.Name });
                                // LowPC is function start
                                attributes.Add(DwarfAttribute.LowPc, new DwarfAttributeValue() { Type = DwarfAttributeValueType.Address, Value = publicSymbol.Address });
                                // HighPc can either be address (end address) or constant (offset after start address, function size)
                                attributes.Add(DwarfAttribute.HighPc, new DwarfAttributeValue() { Type = DwarfAttributeValueType.Constant, Value = publicSymbol.Size });
                                attributes.Add(DwarfAttribute.ByteSize, new DwarfAttributeValue() { Type = DwarfAttributeValueType.Constant, Value = publicSymbol.Size });
                                attributes.Add(DwarfAttribute.Type, new DwarfAttributeValue() { Type = DwarfAttributeValueType.Constant, Value = publicSymbol.Size });

                                return new DwarfSymbol { Tag = DwarfTag.Subprogram, Attributes = attributes };
                            })
                        );

here: https://github.com/southpolenator/SharpDebug/blob/next/Source/SharpDebug.DwarfSymbolProvider/DwarfSymbolProviderModule.cs#L1697

After these changes you will be able to resolve function names in libraries without debugging info.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions