[lldb-dev] PATCH for REVIEW: Implement Linux Host::FindProcesses()

Malea, Daniel daniel.malea at intel.com
Wed May 15 13:24:46 PDT 2013


Hey Mike, looks good, but any reason to not put this implementation in ObjectFileELF (or re-use that class if possible)? I notice that ELFHeader::Parse() (see ELFHeader.cpp:108) seems to read some similar fields as your function below.  If we can improve the ObjectFile plugin and re-use it instead of replicating its functionality, I think that would be preferable.

OTOH, if it is not possible to initialize an ObjectFile at the point where the CPU type is needed, or that is otherwise undesirable, I'm OK with having some minimal ELF functionality in the Linux host plugin.

Cheers,
Dan



From: Michael Sartain <mikesart at valvesoftware.com<mailto:mikesart at valvesoftware.com>>
Date: Wednesday, 15 May, 2013 3:53 PM
To: Michael Sartain <mikesart at valvesoftware.com<mailto:mikesart at valvesoftware.com>>
Cc: Daniel Malea <daniel.malea at intel.com<mailto:daniel.malea at intel.com>>, "lldb-dev at cs.uiuc.edu<mailto:lldb-dev at cs.uiuc.edu>" <lldb-dev at cs.uiuc.edu<mailto:lldb-dev at cs.uiuc.edu>>
Subject: Re: [lldb-dev] PATCH for REVIEW: Implement Linux Host::FindProcesses()

On Wed, May 15, 2013 at 11:10 AM, Michael Sartain <mikesart at valvesoftware.com<mailto:mikesart at valvesoftware.com>> wrote:
On Wed, May 15, 2013 at 10:57 AM, Malea, Daniel <daniel.malea at intel.com<mailto:daniel.malea at intel.com>> wrote:
I verified the implementation works as expected on Linux (Ubuntu 12.10), but I notice you're not filling in the process architecture. I believe there's an existing comment about why it's better to determine the arch in a different place, so it's probably fine to omit for now, but unless someone has any qualms, I will file a bug to also list the process' architectures when the user does "platform process list"; currently that field just shows "0".

Ha! You are good. I'm actually about halfway through a GetELFProcessCPUType() function right now. It looks like I have to follow the exe link and read the elf header to get that data, but it's not too bad. Chris Lattner was kinda enough to get me commit access, so hopefully I'll have something for folks to review later today and then try to submit it myself if it looks ok.

The new function is down below. Running "platform process list" results in something like this now:

...
5919   5916   mikesart   6       x86_64-pc-linux tee
5920   5917   mikesart   6       x86_64-pc-linux tee
5923   1      mikesart   6       x86_64-pc-linux wineserver
5933   1      mikesart   6       x86_64-pc-linux wine64-preloader
5939   1      mikesart   6       x86_64-pc-linux wine64-preloader
5947   1      mikesart   6       x86_64-pc-linux wine64-preloader
6004   1      mikesart   6       x86_64-pc-linux wine64-preloader
6049   1      mikesart   4       i386-pc-linux wine-preloader
6181   2852   mikesart   6       x86_64-pc-linux dash

Please fire away with any feedback and if it looks ok I'll try to commit it later today.
Thanks much.
 -Mike

static bool
GetELFProcessCPUType (const char *exe_path, ProcessInstanceInfo &process_info)
{
    // First part of elf header structure copied from llvm/Support/ELF.h.
    // Read in just enough to get the machine type.
    struct Elf_Ehdr
    {
        unsigned char e_ident[llvm::ELF::EI_NIDENT];    // ELF Identification bytes
        uint16_t      e_type;                           // Type of file (see ET_* below)
        uint16_t      e_machine;                        // Required architecture for this file (see EM_*)

        bool checkMagic() const {
            return (memcmp(e_ident, llvm::ELF::ElfMagic, strlen(llvm::ELF::ElfMagic))) == 0;
        }
        unsigned char getFileClass() const { return e_ident[llvm::ELF::EI_CLASS]; }
        unsigned char getDataEncoding() const { return e_ident[llvm::ELF::EI_DATA]; }
    } elfhdr;
    bool success = false;

    // Clear the architecture.
    process_info.GetArchitecture().Clear();

    // Open the binary and read the elf header.
    int fd = open(exe_path, O_RDONLY, 0);
    if (fd >= 0)
    {
        // Check that we read in enough bytes and the magic header lines up.
        int ret = read(fd, &elfhdr, sizeof(elfhdr));
        if (ret == sizeof(elfhdr) && elfhdr.checkMagic())
        {
            // Check elf version.
            int elfversion = elfhdr.e_ident[llvm::ELF::EI_VERSION];
            if (elfversion == llvm::ELF::EV_CURRENT)
            {
                // Check elf class.
                int elfclass = elfhdr.getFileClass();
                if (elfclass == llvm::ELF::ELFCLASS32 || elfclass == llvm::ELF::ELFCLASS64)
                {
                    // Check elf data encoding.
                    int elfdataencoding = elfhdr.getDataEncoding();
                    if (elfdataencoding == llvm::ELF::ELFDATA2LSB || elfdataencoding == llvm::ELF::ELFDATA2MSB)
                    {
                        int byte_size = (elfclass == llvm::ELF::ELFCLASS32) ? 4 : 8;
                        lldb::ByteOrder byte_order = (elfdataencoding == llvm::ELF::ELFDATA2LSB) ? eByteOrderLittle : eByteOrderBig;
                        lldb_private::DataExtractor data(&elfhdr, sizeof(elfhdr), byte_order, byte_size);

                        uint16_t cpu;
                        lldb::offset_t offset = offsetof(Elf_Ehdr, e_machine);
                        if (data.GetU16 (&offset, &cpu, 1))
                        {
                            // Set the machine type.
                            process_info.GetArchitecture ().SetArchitecture (eArchTypeELF, cpu, LLDB_INVALID_CPUTYPE);
                            // SetArchitecture() in ArchSpec.cpp sets vendor and os to unknown. Reset them to PC and Linux.
                            process_info.GetArchitecture ().GetTriple().setVendor (llvm::Triple::PC);
                            process_info.GetArchitecture ().GetTriple().setOS (llvm::Triple::Linux);
                            success = true;
                        }
                    }
                }
            }
        }

        close (fd);
    }

    return success;
}




More information about the lldb-dev mailing list