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

Michael Sartain mikesart at valvesoftware.com
Wed May 15 12:53:51 PDT 2013


On Wed, May 15, 2013 at 11:10 AM, Michael Sartain <
mikesart at valvesoftware.com> wrote:

> On Wed, May 15, 2013 at 10:57 AM, Malea, Daniel <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;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20130515/2951c267/attachment.html>


More information about the lldb-dev mailing list