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 <[email protected]<mailto:[email protected]>> Date: Wednesday, 15 May, 2013 3:53 PM To: Michael Sartain <[email protected]<mailto:[email protected]>> Cc: Daniel Malea <[email protected]<mailto:[email protected]>>, "[email protected]<mailto:[email protected]>" <[email protected]<mailto:[email protected]>> Subject: Re: [lldb-dev] PATCH for REVIEW: Implement Linux Host::FindProcesses() On Wed, May 15, 2013 at 11:10 AM, Michael Sartain <[email protected]<mailto:[email protected]>> wrote: On Wed, May 15, 2013 at 10:57 AM, Malea, Daniel <[email protected]<mailto:[email protected]>> 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 [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
