Current status of my Linux porting

Attached is my current diff to the LLDB tree to allow a mostly
complete build on Linux (not including the Makefiles). I'm going
through all the changes in my tree to let other people possibly
comment, and also to simply keep it organized for myself:

source/Expression/ClangExpression.cpp:
Hack around API change in trunk clang

source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp:
Linux doesn't have a header for CPU_TYPE_*. (Extend/switch to
llvm/Support/MachO.h or llvm/ADT/Triple.h?)

source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp:
Linux doesn't have a header for CPU_TYPE_*. (Extend/switch to
llvm/Support/MachO.h or llvm/ADT/Triple.h?)

source/Interpreter/ScriptInterpreterPython.cpp:
My build doesn't define init_lldb anywhere; I have no idea where the
definition is supposed to be.

source/Symbol/Symtab.cpp:
qsort_r isn't quite portable (uses different argument order on Linux
and *BSD). Needs ifdeffery or switch to std::sort.

source/Symbol/ClangASTContext.cpp:
Update for API change in trunk clang; add missing include; fix include path

source/Core/Error.cpp:
Linux doesn't have kern_return_t or mach_error_string. Also, missing includes.

source/Core/DataExtractor.cpp:
Linux doesn't have _OSReadInt* or OSReadSwapInt*; replacements are stubs.

source/Core/ModuleList.cpp:
TODO port ./source/Host/macosx/Symbols.cpp to Linux

source/Core/Log.cpp:
Linux doesn't have mach_thread_self()

source/Core/ArchSpec.cpp:
Linux doesn't have a header for CPU_TYPE_*. (Extend/switch to
llvm/Support/MachO.h or llvm/ADT/Triple.h?)

source/Core/FileSpec.cpp:
st_mtimespec is BSD-only, st_mtim is Linux only AFAIK; maybe switch to
llvm/System/Path.h?

source/Core/Args.cpp:
optreset is BSD-only; needs ifdeffery or switching away from getopt()

source/API/SBTarget.cpp:
Symptom of large change; I moved all the files from source/Commands to
source/Interpreter to fix a circular dependency.

source/Host/linux/TimeValue.cpp:
Mostly copied from source/Host/macosx; why not just use llvm/System/TimeValue.h?

source/Host/linux/Host.cpp:
Nasty hacked port to get rid of OSX-specific stuff.

(source/Host/linux/Mutex.cpp and source/Host/linux/Condition.cpp are
copied unmodified; it'd be nice to contribute the condition variable
to core LLVM and get rid of the LLDB versions)

source/lldb.cpp:
The include paths here are a complete mess; perhaps the init functions
should be declared in a common lldb/Plugins/PluginInit.h

tools/driver/Driver.cpp:
optreset is BSD-only; needs ifdeffery or switching away from getopt()

include/lldb/Core/Error.h:
kern_return_t is OSX-only.

include/lldb/lldb-types.h:
Remove non-portable includes (needs testing on a Mac).

-Eli

lldbdiff.txt (23.5 KB)

Attached is my current diff to the LLDB tree to allow a mostly
complete build on Linux (not including the Makefiles). I’m going
through all the changes in my tree to let other people possibly
comment, and also to simply keep it organized for myself:

source/Expression/ClangExpression.cpp:
Hack around API change in trunk clang

I can update our stuff to top of tree LLVM/Clang tomorrow to get rid of this dependency.

source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp:
Linux doesn’t have a header for CPU_TYPE_*. (Extend/switch to
llvm/Support/MachO.h or llvm/ADT/Triple.h?)

We probably need to duplicate some of the CPU_TYPE and CPU_SUBTYPE definitions so we don’t require the header file. If llvm does have these defines we should start t include them from there.

The CPU type is much more important on the Mac due to us having 32 and 64 bit binaries that run on the same system.

These values get used in lldb_private::ArchSpec.

Currently lldb_private::ArchSpec contains the following members:

class ArchSpec {

protected:

uint32_t m_cpu; ///< The cpu type of the architecture
uint32_t m_sub; ///< The cpu subtype of the architecture
};

This is currently tailored for MachO, but it should be made more generic.

ArchSpec should be modified to take an arch type enum as well:

// This would go in lldb-enumerations.h
typedef enum ArchitectureType
{
eArchTypeMachO,
eArchTypeELF
};

class ArchSpec {

protected:
ArchitectureType m_type; ///< The architecture type
uint32_t m_cpu; ///< The cpu type of the architecture (cputype for macho, e_machine for ELF)
uint32_t m_sub; ///< The cpu subtype of the architecture (cpu_subtype for macho, anything for ELF??)
};

We would need to modify the ArchSpec class to deal with the new m_type field and do the right thing when printing.

source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp:
Linux doesn’t have a header for CPU_TYPE_*. (Extend/switch to
llvm/Support/MachO.h or llvm/ADT/Triple.h?)

See above ArchSpec comment.

source/Interpreter/ScriptInterpreterPython.cpp:
My build doesn’t define init_lldb anywhere; I have no idea where the
definition is supposed to be.

This comes from the file cpp file that is generated by swig when run on the ABI sources.

This is done by a shell script build phaes in the Xcode project that essentially does a:

cd scripts
sh ./build-swig-wrapper-classes.sh lldb.swig …/source/LLDBWrapPython.cpp

The init_lldb ends up being in the LLDBWrapPython.cpp

source/Symbol/Symtab.cpp:
qsort_r isn’t quite portable (uses different argument order on Linux
and *BSD). Needs ifdeffery or switch to std::sort.

std::sort bloats up to be quite large in code size and doesn’t perform as well on MacOSX. Feel free to test and use something appropriate on linux if #ifdeffery

source/Symbol/ClangASTContext.cpp:
Update for API change in trunk clang; add missing include; fix include path

I can update to top of tree llvm soon.

source/Core/Error.cpp:
Linux doesn’t have kern_return_t or mach_error_string. Also, missing includes.

#ifdef out should be fine for anything that doesn’t make sense in these files for linux. Any BSD based system might support this.

source/Core/DataExtractor.cpp:
Linux doesn’t have _OSReadInt* or OSReadSwapInt*; replacements are stubs.

Linux must have some sort of ultra efficient byte swapping macros, no? If so, plug then in with #ifdefs. We should probably add byte swapping macros to lldb_private::Host as static inline functions if possible.

source/Core/ModuleList.cpp:
TODO port ./source/Host/macosx/Symbols.cpp to Linux

source/Core/Log.cpp:
Linux doesn’t have mach_thread_self()

We already have this abstracted in the host layer, switch to using static Host::GetCurrentThreadID ();

source/Core/ArchSpec.cpp:
Linux doesn’t have a header for CPU_TYPE_*. (Extend/switch to
llvm/Support/MachO.h or llvm/ADT/Triple.h?)

llvm/support/macho.h and augment ArchSpec as stated above…

source/Core/FileSpec.cpp:
st_mtimespec is BSD-only, st_mtim is Linux only AFAIK; maybe switch to
llvm/System/Path.h?

As long as we don’t run into any RTTI issues, sure thing.

source/Core/Args.cpp:
optreset is BSD-only; needs ifdeffery or switching away from getopt()

As long as what ever gets used works on both systems, I don’t mind what happens here.

source/API/SBTarget.cpp:
Symptom of large change; I moved all the files from source/Commands to
source/Interpreter to fix a circular dependency.

Which circular dependency?

source/Host/linux/TimeValue.cpp:
Mostly copied from source/Host/macosx; why not just use llvm/System/TimeValue.h?

As long as there are no RTTI issues, that would work.

source/Host/linux/Host.cpp:
Nasty hacked port to get rid of OSX-specific stuff.

Hopefully we can contain all Host specific things into these Host.cpp files. Was anything particularily hard? Anything not make sense?

(source/Host/linux/Mutex.cpp and source/Host/linux/Condition.cpp are
copied unmodified; it’d be nice to contribute the condition variable
to core LLVM and get rid of the LLDB versions)

Works for me as long as there are no RTTI issues.

source/lldb.cpp:
The include paths here are a complete mess; perhaps the init functions
should be declared in a common lldb/Plugins/PluginInit.h

The init routines are currently taking place of actually compiling separate plug-ins and loading them dynamically. Usually all plug-ins would be detected by searching a common set of machine and user paths for lldb plug-ins to load. We were initially doing this with objective C and Bundles (thus why some of the files had a “.mm” extension, they used to have objective C plug-in loading code in there). Once we finalized on the fact we were going to integrate with LLVM, we started slowly moving away from ObjC stuff and slowly got rid of all that stuff.

Plug-ins in LLDB reverse the roles where the plug-ins register themselves with LLDB instead of LLDB asking each plug-in what it supports. Some of the Initialize()/Terminate() calls in lldb.cpp are parts of the LLDB core initializing themselves, and others are the PLUGIN::Initialize() and PLUGIN::Terminate() functions being manually called to avoid doing plug-in loading dynamically for the time being.

So right now these Initialize()/Terminate() calls need to happen, tough it would be a good idea to segragate the plug-in implementations from the Core Initialize()/Terminate() routines.

tools/driver/Driver.cpp:
optreset is BSD-only; needs ifdeffery or switching away from getopt()

include/lldb/Core/Error.h:
kern_return_t is OSX-only.

#ifdef out for other non-BSD systems.

source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp:
Linux doesn't have a header for CPU_TYPE_*. (Extend/switch to
llvm/Support/MachO.h or llvm/ADT/Triple.h?)

We probably need to duplicate some of the CPU_TYPE and CPU_SUBTYPE
definitions so we don't require the header file. If llvm does have these
defines we should start t include them from there.
The CPU type is much more important on the Mac due to us having 32 and 64
bit binaries that run on the same system.
These values get used in lldb_private::ArchSpec.
Currently lldb_private::ArchSpec contains the following members:
class ArchSpec {
...
protected:
uint32_t m_cpu; ///< The cpu type of the architecture
uint32_t m_sub; ///< The cpu subtype of the architecture
};
This is currently tailored for MachO, but it should be made more generic.
ArchSpec should be modified to take an arch type enum as well:
// This would go in lldb-enumerations.h
typedef enum ArchitectureType
{
eArchTypeMachO,
eArchTypeELF
};

class ArchSpec {
...
protected:
ArchitectureType m_type; ///< The architecture type
uint32_t m_cpu; ///< The cpu type of the architecture (cputype for
macho, e_machine for ELF)
uint32_t m_sub; ///< The cpu subtype of the architecture (cpu_subtype
for macho, anything for ELF??)
};
We would need to modify the ArchSpec class to deal with the new m_type field
and do the right thing when printing.

Okay; I'll try to take a look at it in the next couple days.

source/Interpreter/ScriptInterpreterPython.cpp:
My build doesn't define init_lldb anywhere; I have no idea where the
definition is supposed to be.

This comes from the file cpp file that is generated by swig when run on the
ABI sources.
This is done by a shell script build phaes in the Xcode project that
essentially does a:
cd scripts
sh ./build-swig-wrapper-classes.sh lldb.swig ../source/LLDBWrapPython.cpp
The init_lldb ends up being in the LLDBWrapPython.cpp

Ah, okay; I'll adjust my in-progress build system to do that.

source/Symbol/Symtab.cpp:
qsort_r isn't quite portable (uses different argument order on Linux
and *BSD). Needs ifdeffery or switch to std::sort.

std::sort bloats up to be quite large in code size and doesn't perform as
well on MacOSX. Feel free to test and use something appropriate on linux if
#ifdeffery

Okay; I'll just use an ifdef __APPLE__ at the moment, and we can fix
it up later.

source/Core/Error.cpp:
Linux doesn't have kern_return_t or mach_error_string. Also, missing
includes.

#ifdef out should be fine for anything that doesn't make sense in these
files for linux. Any BSD based system might support this.

I'll just use an ifdef __APPLE__ at the moment, and we can fix it up later.

source/Core/DataExtractor.cpp:
Linux doesn't have _OSReadInt* or OSReadSwapInt*; replacements are stubs.

Linux must have some sort of ultra efficient byte swapping macros, no? If
so, plug then in with #ifdefs. We should probably add byte swapping macros
to lldb_private::Host as static inline functions if possible.

I can use llvm/Support/MathExtras.h for bswap; it's just that these
functions have a funny signature, and I haven't gotten around to
writing it.

source/Core/Log.cpp:
Linux doesn't have mach_thread_self()

We already have this abstracted in the host layer, switch to using static
Host::GetCurrentThreadID ();

Okay, will do.

source/Core/FileSpec.cpp:
st_mtimespec is BSD-only, st_mtim is Linux only AFAIK; maybe switch to
llvm/System/Path.h?

As long as we don't run into any RTTI issues, sure thing.

Okay, or I might just use st_mtime. I'll have to take a look.

source/Core/Args.cpp:
optreset is BSD-only; needs ifdeffery or switching away from getopt()

As long as what ever gets used works on both systems, I don't mind what
happens here.

I'll just use an ifdef __APPLE__ at the moment, and we can fix it up later.

source/API/SBTarget.cpp:
Symptom of large change; I moved all the files from source/Commands to
source/Interpreter to fix a circular dependency.

Which circular dependency?

I managed to resolve it with the following smaller set of moves:
Move source/Commands/CommandObjectScript.cpp and
source/Commands/CommandObjectScript.h to source/Interpreter (they make
calls into Interpreter files)
Move source/Interpreter/CommandObjectMultiword.cpp,
source/Interpreter/CommandObjectCrossref.cpp, and
source/Interpreter/CommandCompletions.cpp to source/Commands (they are
called from other files in Commands)

source/Host/linux/Host.cpp:
Nasty hacked port to get rid of OSX-specific stuff.

Hopefully we can contain all Host specific things into these Host.cpp files.
Was anything particularily hard? Anything not make sense?

I didn't really spend much time on it; I'll take a closer look once
other stuff is resolved.

source/lldb.cpp:
The include paths here are a complete mess; perhaps the init functions
should be declared in a common lldb/Plugins/PluginInit.h

The init routines are currently taking place of actually compiling separate
plug-ins and loading them dynamically. Usually all plug-ins would be
detected by searching a common set of machine and user paths for lldb
plug-ins to load. We were initially doing this with objective C and Bundles
(thus why some of the files had a ".mm" extension, they used to have
objective C plug-in loading code in there). Once we finalized on the fact we
were going to integrate with LLVM, we started slowly moving away from ObjC
stuff and slowly got rid of all that stuff.
Plug-ins in LLDB reverse the roles where the plug-ins register themselves
with LLDB instead of LLDB asking each plug-in what it supports. Some of the
Initialize()/Terminate() calls in lldb.cpp are parts of the LLDB core
initializing themselves, and others are the PLUGIN::Initialize() and
PLUGIN::Terminate() functions being manually called to avoid doing plug-in
loading dynamically for the time being.
So right now these Initialize()/Terminate() calls need to happen, tough it
would be a good idea to segragate the plug-in implementations from the
Core Initialize()/Terminate() routines.

Mmm... I'll have to look at that again.

include/lldb/Core/Error.h:
kern_return_t is OSX-only.

#ifdef out for other non-BSD systems.

OK.

-Eli

There are a couple of things to be aware of in running those scripts. The first thing is that,
as written, they were intended to be run from Xcode, which means they contain references to
environment variables that Xcode defines in its build process, so they probably won’t work for
you ‘as is’. One of the next things on my to do list is to try to modify the scripts to take those
values as parameters instead. The other thing you should be aware of is that there are two sets of
scripts, the build-swig-… scripts and the finish-swig-… scripts. The build scripts need to be run fairly early
in the overall build process, because they cause SWIG to build the C++ file(s) for the scripting language API(s) that need to be compiled and linked with all the other source files to create lldb. The finish-swig… scripts
need to be run after it’s all been compiled, to generate links and copy files around to where they need to be
in order for the embedded scripting stuff in lldb to find them properly.

– Caroline
ctice@apple.com