[lldb-dev] PATCH for REVIEW: Implement Linux Host::FindProcesses()
Greg Clayton
gclayton at apple.com
Wed May 15 14:03:20 PDT 2013
The correct fix for this is to fill in the GetModuleSpecifications() in ObjectFileELF:
size_t
ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
lldb::DataBufferSP& data_sp,
lldb::offset_t data_offset,
lldb::offset_t file_offset,
lldb::offset_t length,
lldb_private::ModuleSpecList &specs)
{
return 0;
}
Then, given a file, you can then call:
size_t
ObjectFile::GetModuleSpecifications (const FileSpec &file, lldb::offset_t file_offset, ModuleSpecList &specs);
With "file_offset" set to zero. It will return a ModuleSpecList with 1 entry and this will contain a ModuleSpec with the file and arch filled in. You can grab the arch from there, and also prepare for new executable types in the future.
Greg
On May 15, 2013, at 12:53 PM, Michael Sartain <mikesart at valvesoftware.com> wrote:
> 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;
> }
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
More information about the lldb-dev
mailing list