* Moved Array.h to new directory "types".
* Added StringUtils with string hash functions.
* Added Locatable{Entry,File,Directory} and FileManager classes to manage the
mapping from debug info/target file names to local file names.
* Image does now have a LocatableFile referring to the image's shared object
file. Added listening to location changes of these files to TeamDebugger. No
action is taken yet (should trigger reloading the debug info).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31368 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -11,9 +11,11 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) arch x86 ] ;
|
|||||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_info ] ;
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_info ] ;
|
||||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface ] ;
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface ] ;
|
||||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) elf ] ;
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) elf ] ;
|
||||||
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) files ] ;
|
||||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) gui team_window ] ;
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) gui team_window ] ;
|
||||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) model ] ;
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) model ] ;
|
||||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) types ] ;
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) types ] ;
|
||||||
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) util ] ;
|
||||||
|
|
||||||
local debugAnalyzerSources
|
local debugAnalyzerSources
|
||||||
= [ FDirName $(HAIKU_TOP) src apps debuganalyzer ] ;
|
= [ FDirName $(HAIKU_TOP) src apps debuganalyzer ] ;
|
||||||
@@ -68,6 +70,12 @@ Application Debugger :
|
|||||||
# elf
|
# elf
|
||||||
ElfFile.cpp
|
ElfFile.cpp
|
||||||
|
|
||||||
|
# files
|
||||||
|
FileManager.cpp
|
||||||
|
LocatableDirectory.cpp
|
||||||
|
LocatableEntry.cpp
|
||||||
|
LocatableFile.cpp
|
||||||
|
|
||||||
# gui/team_window
|
# gui/team_window
|
||||||
ImageFunctionsView.cpp
|
ImageFunctionsView.cpp
|
||||||
ImageListView.cpp
|
ImageListView.cpp
|
||||||
@@ -96,6 +104,9 @@ Application Debugger :
|
|||||||
# types
|
# types
|
||||||
TargetAddressRangeList.cpp
|
TargetAddressRangeList.cpp
|
||||||
|
|
||||||
|
# util
|
||||||
|
StringUtils.cpp
|
||||||
|
|
||||||
:
|
:
|
||||||
<nogrist>Debugger_demangler.o
|
<nogrist>Debugger_demangler.o
|
||||||
<nogrist>Debugger_disasm_x86.o
|
<nogrist>Debugger_disasm_x86.o
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ LoadImageDebugInfoJob::Do()
|
|||||||
// create the debug info
|
// create the debug info
|
||||||
ImageDebugInfo* debugInfo;
|
ImageDebugInfo* debugInfo;
|
||||||
status_t error = fImage->GetTeam()->DebugInfo()->LoadImageDebugInfo(
|
status_t error = fImage->GetTeam()->DebugInfo()->LoadImageDebugInfo(
|
||||||
imageInfo, debugInfo);
|
imageInfo, fImage->ImageFile(), debugInfo);
|
||||||
|
|
||||||
// set the result
|
// set the result
|
||||||
locker.Lock();
|
locker.Lock();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ enum {
|
|||||||
MSG_THREAD_CPU_STATE_CHANGED = 'tcsc',
|
MSG_THREAD_CPU_STATE_CHANGED = 'tcsc',
|
||||||
MSG_THREAD_STACK_TRACE_CHANGED = 'tstc',
|
MSG_THREAD_STACK_TRACE_CHANGED = 'tstc',
|
||||||
MSG_IMAGE_DEBUG_INFO_CHANGED = 'idic',
|
MSG_IMAGE_DEBUG_INFO_CHANGED = 'idic',
|
||||||
|
MSG_IMAGE_FILE_CHANGED = 'ifch',
|
||||||
MSG_FUNCTION_SOURCE_CODE_CHANGED = 'fnsc',
|
MSG_FUNCTION_SOURCE_CODE_CHANGED = 'fnsc',
|
||||||
MSG_USER_BREAKPOINT_CHANGED = 'ubrc',
|
MSG_USER_BREAKPOINT_CHANGED = 'ubrc',
|
||||||
MSG_DEBUGGER_EVENT = 'dbge',
|
MSG_DEBUGGER_EVENT = 'dbge',
|
||||||
|
|||||||
@@ -20,12 +20,93 @@
|
|||||||
#include "BreakpointManager.h"
|
#include "BreakpointManager.h"
|
||||||
#include "CpuState.h"
|
#include "CpuState.h"
|
||||||
#include "DebuggerInterface.h"
|
#include "DebuggerInterface.h"
|
||||||
|
#include "FileManager.h"
|
||||||
#include "Jobs.h"
|
#include "Jobs.h"
|
||||||
|
#include "LocatableFile.h"
|
||||||
#include "MessageCodes.h"
|
#include "MessageCodes.h"
|
||||||
#include "Statement.h"
|
#include "Statement.h"
|
||||||
#include "TeamDebugInfo.h"
|
#include "TeamDebugInfo.h"
|
||||||
#include "TeamDebugModel.h"
|
#include "TeamDebugModel.h"
|
||||||
|
|
||||||
|
// #pragma mark - ImageHandler
|
||||||
|
|
||||||
|
|
||||||
|
struct TeamDebugger::ImageHandler : public Referenceable,
|
||||||
|
public HashTableLink<ImageHandler>, private LocatableFile::Listener {
|
||||||
|
public:
|
||||||
|
ImageHandler(TeamDebugger* teamDebugger, Image* image)
|
||||||
|
:
|
||||||
|
fTeamDebugger(teamDebugger),
|
||||||
|
fImage(image)
|
||||||
|
{
|
||||||
|
fImage->AcquireReference();
|
||||||
|
if (fImage->ImageFile() != NULL)
|
||||||
|
fImage->ImageFile()->AddListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ImageHandler()
|
||||||
|
{
|
||||||
|
if (fImage->ImageFile() != NULL)
|
||||||
|
fImage->ImageFile()->RemoveListener(this);
|
||||||
|
fImage->ReleaseReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
Image* GetImage() const
|
||||||
|
{
|
||||||
|
return fImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
image_id ImageID() const
|
||||||
|
{
|
||||||
|
return fImage->ID();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// LocatableFile::Listener
|
||||||
|
virtual void LocatableFileChanged(LocatableFile* file)
|
||||||
|
{
|
||||||
|
BMessage message(MSG_IMAGE_FILE_CHANGED);
|
||||||
|
message.AddInt32("image", fImage->ID());
|
||||||
|
fTeamDebugger->PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TeamDebugger* fTeamDebugger;
|
||||||
|
Image* fImage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ImageHandlerHashDefinition
|
||||||
|
|
||||||
|
|
||||||
|
struct TeamDebugger::ImageHandlerHashDefinition {
|
||||||
|
typedef image_id KeyType;
|
||||||
|
typedef ImageHandler ValueType;
|
||||||
|
|
||||||
|
size_t HashKey(image_id key) const
|
||||||
|
{
|
||||||
|
return (size_t)key;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Hash(const ImageHandler* value) const
|
||||||
|
{
|
||||||
|
return HashKey(value->ImageID());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compare(image_id key, const ImageHandler* value) const
|
||||||
|
{
|
||||||
|
return value->ImageID() == key;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashTableLink<ImageHandler>* GetLink(ImageHandler* value) const
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - TeamDebugger
|
||||||
|
|
||||||
|
|
||||||
TeamDebugger::TeamDebugger(Listener* listener)
|
TeamDebugger::TeamDebugger(Listener* listener)
|
||||||
:
|
:
|
||||||
@@ -34,7 +115,9 @@ TeamDebugger::TeamDebugger(Listener* listener)
|
|||||||
fTeam(NULL),
|
fTeam(NULL),
|
||||||
fDebugModel(NULL),
|
fDebugModel(NULL),
|
||||||
fTeamID(-1),
|
fTeamID(-1),
|
||||||
|
fImageHandlers(NULL),
|
||||||
fDebuggerInterface(NULL),
|
fDebuggerInterface(NULL),
|
||||||
|
fFileManager(NULL),
|
||||||
fWorker(NULL),
|
fWorker(NULL),
|
||||||
fBreakpointManager(NULL),
|
fBreakpointManager(NULL),
|
||||||
fDebugEventListener(-1),
|
fDebugEventListener(-1),
|
||||||
@@ -73,15 +156,25 @@ TeamDebugger::~TeamDebugger()
|
|||||||
ThreadHandler* threadHandler = fThreadHandlers.Clear(true);
|
ThreadHandler* threadHandler = fThreadHandlers.Clear(true);
|
||||||
while (threadHandler != NULL) {
|
while (threadHandler != NULL) {
|
||||||
ThreadHandler* next = threadHandler->fNext;
|
ThreadHandler* next = threadHandler->fNext;
|
||||||
threadHandler->RemoveReference();
|
threadHandler->ReleaseReference();
|
||||||
threadHandler = next;
|
threadHandler = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageHandler* imageHandler = fImageHandlers->Clear(true);
|
||||||
|
while (imageHandler != NULL) {
|
||||||
|
ImageHandler* next = imageHandler->fNext;
|
||||||
|
imageHandler->ReleaseReference();
|
||||||
|
imageHandler = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete fImageHandlers;
|
||||||
|
|
||||||
delete fBreakpointManager;
|
delete fBreakpointManager;
|
||||||
delete fDebuggerInterface;
|
delete fDebuggerInterface;
|
||||||
delete fWorker;
|
delete fWorker;
|
||||||
delete fDebugModel;
|
delete fDebugModel;
|
||||||
delete fTeam;
|
delete fTeam;
|
||||||
|
delete fFileManager;
|
||||||
|
|
||||||
fListener->TeamDebuggerQuit(this);
|
fListener->TeamDebuggerQuit(this);
|
||||||
}
|
}
|
||||||
@@ -90,6 +183,9 @@ TeamDebugger::~TeamDebugger()
|
|||||||
status_t
|
status_t
|
||||||
TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
||||||
{
|
{
|
||||||
|
bool targetIsLocal = true;
|
||||||
|
// TODO: Support non-local targets!
|
||||||
|
|
||||||
fTeamID = teamID;
|
fTeamID = teamID;
|
||||||
|
|
||||||
// create debugger interface
|
// create debugger interface
|
||||||
@@ -101,6 +197,15 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
// create file manager
|
||||||
|
fFileManager = new(std::nothrow) FileManager;
|
||||||
|
if (fFileManager == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
error = fFileManager->Init(targetIsLocal);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
// create team debug info
|
// create team debug info
|
||||||
TeamDebugInfo* teamDebugInfo = new(std::nothrow) TeamDebugInfo(
|
TeamDebugInfo* teamDebugInfo = new(std::nothrow) TeamDebugInfo(
|
||||||
fDebuggerInterface, fDebuggerInterface->GetArchitecture());
|
fDebuggerInterface, fDebuggerInterface->GetArchitecture());
|
||||||
@@ -137,6 +242,15 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
// create image handler table
|
||||||
|
fImageHandlers = new(std::nothrow) ImageHandlerTable;
|
||||||
|
if (fImageHandlers == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
error = fImageHandlers->Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
// create our worker
|
// create our worker
|
||||||
fWorker = new(std::nothrow) Worker;
|
fWorker = new(std::nothrow) Worker;
|
||||||
if (fWorker == NULL)
|
if (fWorker == NULL)
|
||||||
@@ -198,7 +312,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
|||||||
BObjectList<ImageInfo> imageInfos(20, true);
|
BObjectList<ImageInfo> imageInfos(20, true);
|
||||||
status_t error = fDebuggerInterface->GetImageInfos(imageInfos);
|
status_t error = fDebuggerInterface->GetImageInfos(imageInfos);
|
||||||
for (int32 i = 0; ImageInfo* info = imageInfos.ItemAt(i); i++) {
|
for (int32 i = 0; ImageInfo* info = imageInfos.ItemAt(i); i++) {
|
||||||
error = fTeam->AddImage(*info);
|
error = _AddImage(*info);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -320,6 +434,16 @@ TeamDebugger::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MSG_IMAGE_FILE_CHANGED:
|
||||||
|
{
|
||||||
|
int32 imageID;
|
||||||
|
if (message->FindInt32("image", &imageID) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
_HandleImageFileChanged(imageID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MSG_DEBUGGER_EVENT:
|
case MSG_DEBUGGER_EVENT:
|
||||||
{
|
{
|
||||||
DebugEvent* event;
|
DebugEvent* event;
|
||||||
@@ -663,7 +787,7 @@ bool
|
|||||||
TeamDebugger::_HandleImageCreated(ImageCreatedEvent* event)
|
TeamDebugger::_HandleImageCreated(ImageCreatedEvent* event)
|
||||||
{
|
{
|
||||||
AutoLocker< ::Team> locker(fTeam);
|
AutoLocker< ::Team> locker(fTeam);
|
||||||
fTeam->AddImage(event->GetImageInfo());
|
_AddImage(event->GetImageInfo());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,10 +797,26 @@ TeamDebugger::_HandleImageDeleted(ImageDeletedEvent* event)
|
|||||||
{
|
{
|
||||||
AutoLocker< ::Team> locker(fTeam);
|
AutoLocker< ::Team> locker(fTeam);
|
||||||
fTeam->RemoveImage(event->GetImageInfo().ImageID());
|
fTeam->RemoveImage(event->GetImageInfo().ImageID());
|
||||||
|
|
||||||
|
ImageHandler* imageHandler = fImageHandlers->Lookup(
|
||||||
|
event->GetImageInfo().ImageID());
|
||||||
|
if (imageHandler != NULL) {
|
||||||
|
fImageHandlers->Remove(imageHandler);
|
||||||
|
imageHandler->ReleaseReference();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamDebugger::_HandleImageFileChanged(image_id imageID)
|
||||||
|
{
|
||||||
|
printf("TeamDebugger::_HandleImageFileChanged(%ld)\n", imageID);
|
||||||
|
// TODO: Reload the debug info!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TeamDebugger::_HandleSetUserBreakpoint(target_addr_t address, bool enabled)
|
TeamDebugger::_HandleSetUserBreakpoint(target_addr_t address, bool enabled)
|
||||||
{
|
{
|
||||||
@@ -710,6 +850,27 @@ TeamDebugger::_GetThreadHandler(thread_id threadID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TeamDebugger::_AddImage(const ImageInfo& imageInfo)
|
||||||
|
{
|
||||||
|
LocatableFile* file = NULL;
|
||||||
|
if (strchr(imageInfo.Name(), '/') != NULL)
|
||||||
|
file = fFileManager->GetTargetFile(imageInfo.Name());
|
||||||
|
Reference<LocatableFile> imageFileReference(file, true);
|
||||||
|
|
||||||
|
Image* image;
|
||||||
|
status_t error = fTeam->AddImage(imageInfo, file, &image);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
ImageHandler* imageHandler = new(std::nothrow) ImageHandler(this, image);
|
||||||
|
if (imageHandler != NULL)
|
||||||
|
fImageHandlers->Insert(imageHandler);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TeamDebugger::_NotifyUser(const char* title, const char* text,...)
|
TeamDebugger::_NotifyUser(const char* title, const char* text,...)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class DebuggerInterface;
|
class DebuggerInterface;
|
||||||
|
class FileManager;
|
||||||
class TeamDebugInfo;
|
class TeamDebugInfo;
|
||||||
class TeamDebugModel;
|
class TeamDebugModel;
|
||||||
|
|
||||||
@@ -64,6 +65,11 @@ private:
|
|||||||
virtual void ThreadStackTraceChanged(
|
virtual void ThreadStackTraceChanged(
|
||||||
const ::Team::ThreadEvent& event);
|
const ::Team::ThreadEvent& event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ImageHandler;
|
||||||
|
struct ImageHandlerHashDefinition;
|
||||||
|
typedef OpenHashTable<ImageHandlerHashDefinition> ImageHandlerTable;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static status_t _DebugEventListenerEntry(void* data);
|
static status_t _DebugEventListenerEntry(void* data);
|
||||||
status_t _DebugEventListener();
|
status_t _DebugEventListener();
|
||||||
@@ -79,14 +85,17 @@ private:
|
|||||||
bool _HandleImageDeleted(
|
bool _HandleImageDeleted(
|
||||||
ImageDeletedEvent* event);
|
ImageDeletedEvent* event);
|
||||||
|
|
||||||
|
void _HandleImageFileChanged(image_id imageID);
|
||||||
|
|
||||||
void _HandleSetUserBreakpoint(target_addr_t address,
|
void _HandleSetUserBreakpoint(target_addr_t address,
|
||||||
bool enabled);
|
bool enabled);
|
||||||
void _HandleClearUserBreakpoint(
|
void _HandleClearUserBreakpoint(
|
||||||
target_addr_t address);
|
target_addr_t address);
|
||||||
|
|
||||||
|
|
||||||
ThreadHandler* _GetThreadHandler(thread_id threadID);
|
ThreadHandler* _GetThreadHandler(thread_id threadID);
|
||||||
|
|
||||||
|
status_t _AddImage(const ImageInfo& imageInfo);
|
||||||
|
|
||||||
void _NotifyUser(const char* title,
|
void _NotifyUser(const char* title,
|
||||||
const char* text,...);
|
const char* text,...);
|
||||||
|
|
||||||
@@ -97,8 +106,10 @@ private:
|
|||||||
team_id fTeamID;
|
team_id fTeamID;
|
||||||
ThreadHandlerTable fThreadHandlers;
|
ThreadHandlerTable fThreadHandlers;
|
||||||
// protected by the team lock
|
// protected by the team lock
|
||||||
|
ImageHandlerTable* fImageHandlers;
|
||||||
DebuggerInterface* fDebuggerInterface;
|
DebuggerInterface* fDebuggerInterface;
|
||||||
TeamDebugInfo* fTeamDebugInfo;
|
TeamDebugInfo* fTeamDebugInfo;
|
||||||
|
FileManager* fFileManager;
|
||||||
Worker* fWorker;
|
Worker* fWorker;
|
||||||
BreakpointManager* fBreakpointManager;
|
BreakpointManager* fBreakpointManager;
|
||||||
thread_id fDebugEventListener;
|
thread_id fDebugEventListener;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ DebuggerTeamDebugInfo::Init()
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
DebuggerTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo,
|
DebuggerTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo,
|
||||||
SpecificImageDebugInfo*& _imageDebugInfo)
|
LocatableFile* imageFile, SpecificImageDebugInfo*& _imageDebugInfo)
|
||||||
{
|
{
|
||||||
DebuggerImageDebugInfo* debuggerInfo
|
DebuggerImageDebugInfo* debuggerInfo
|
||||||
= new(std::nothrow) DebuggerImageDebugInfo(imageInfo,
|
= new(std::nothrow) DebuggerImageDebugInfo(imageInfo,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public:
|
|||||||
status_t Init();
|
status_t Init();
|
||||||
|
|
||||||
virtual status_t CreateImageDebugInfo(const ImageInfo& imageInfo,
|
virtual status_t CreateImageDebugInfo(const ImageInfo& imageInfo,
|
||||||
|
LocatableFile* imageFile,
|
||||||
SpecificImageDebugInfo*& _imageDebugInfo);
|
SpecificImageDebugInfo*& _imageDebugInfo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "DwarfImageDebugInfo.h"
|
#include "DwarfImageDebugInfo.h"
|
||||||
#include "DwarfManager.h"
|
#include "DwarfManager.h"
|
||||||
|
#include "LocatableFile.h"
|
||||||
|
|
||||||
|
|
||||||
DwarfTeamDebugInfo::DwarfTeamDebugInfo(Architecture* architecture)
|
DwarfTeamDebugInfo::DwarfTeamDebugInfo(Architecture* architecture)
|
||||||
@@ -44,15 +45,16 @@ DwarfTeamDebugInfo::Init()
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo,
|
DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo,
|
||||||
SpecificImageDebugInfo*& _imageDebugInfo)
|
LocatableFile* imageFile, SpecificImageDebugInfo*& _imageDebugInfo)
|
||||||
{
|
{
|
||||||
// We only want images that belong to shared objects.
|
// We only like images whose file we can play with.
|
||||||
if (strchr(imageInfo.Name(), '/') == NULL)
|
BString filePath;
|
||||||
|
if (imageFile == NULL || !imageFile->GetLocatedPath(filePath))
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
// try to load the DWARF file
|
// try to load the DWARF file
|
||||||
DwarfFile* file;
|
DwarfFile* file;
|
||||||
status_t error = fManager->LoadFile(imageInfo.Name(), file);
|
status_t error = fManager->LoadFile(filePath, file);
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = fManager->FinishLoading();
|
error = fManager->FinishLoading();
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public:
|
|||||||
status_t Init();
|
status_t Init();
|
||||||
|
|
||||||
virtual status_t CreateImageDebugInfo(const ImageInfo& imageInfo,
|
virtual status_t CreateImageDebugInfo(const ImageInfo& imageInfo,
|
||||||
|
LocatableFile* imageFile,
|
||||||
SpecificImageDebugInfo*& _imageDebugInfo);
|
SpecificImageDebugInfo*& _imageDebugInfo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class ImageInfo;
|
class ImageInfo;
|
||||||
|
class LocatableFile;
|
||||||
class SpecificImageDebugInfo;
|
class SpecificImageDebugInfo;
|
||||||
|
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ public:
|
|||||||
virtual ~SpecificTeamDebugInfo();
|
virtual ~SpecificTeamDebugInfo();
|
||||||
|
|
||||||
virtual status_t CreateImageDebugInfo(const ImageInfo& imageInfo,
|
virtual status_t CreateImageDebugInfo(const ImageInfo& imageInfo,
|
||||||
|
LocatableFile* imageFile,
|
||||||
SpecificImageDebugInfo*& _imageDebugInfo)
|
SpecificImageDebugInfo*& _imageDebugInfo)
|
||||||
= 0;
|
= 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ TeamDebugInfo::Init()
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
TeamDebugInfo::LoadImageDebugInfo(const ImageInfo& imageInfo,
|
TeamDebugInfo::LoadImageDebugInfo(const ImageInfo& imageInfo,
|
||||||
ImageDebugInfo*& _imageDebugInfo)
|
LocatableFile* imageFile, ImageDebugInfo*& _imageDebugInfo)
|
||||||
{
|
{
|
||||||
ImageDebugInfo* imageDebugInfo = new(std::nothrow) ImageDebugInfo(
|
ImageDebugInfo* imageDebugInfo = new(std::nothrow) ImageDebugInfo(
|
||||||
imageInfo);
|
imageInfo);
|
||||||
@@ -79,7 +79,7 @@ TeamDebugInfo::LoadImageDebugInfo(const ImageInfo& imageInfo,
|
|||||||
= fSpecificInfos.ItemAt(i); i++) {
|
= fSpecificInfos.ItemAt(i); i++) {
|
||||||
SpecificImageDebugInfo* specificImageInfo;
|
SpecificImageDebugInfo* specificImageInfo;
|
||||||
status_t error = specificTeamInfo->CreateImageDebugInfo(imageInfo,
|
status_t error = specificTeamInfo->CreateImageDebugInfo(imageInfo,
|
||||||
specificImageInfo);
|
imageFile, specificImageInfo);
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
if (!imageDebugInfo->AddSpecificInfo(specificImageInfo)) {
|
if (!imageDebugInfo->AddSpecificInfo(specificImageInfo)) {
|
||||||
delete specificImageInfo;
|
delete specificImageInfo;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class Architecture;
|
|||||||
class DebuggerInterface;
|
class DebuggerInterface;
|
||||||
class ImageDebugInfo;
|
class ImageDebugInfo;
|
||||||
class ImageInfo;
|
class ImageInfo;
|
||||||
|
class LocatableFile;
|
||||||
class SpecificTeamDebugInfo;
|
class SpecificTeamDebugInfo;
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +29,7 @@ public:
|
|||||||
status_t Init();
|
status_t Init();
|
||||||
|
|
||||||
status_t LoadImageDebugInfo(const ImageInfo& imageInfo,
|
status_t LoadImageDebugInfo(const ImageInfo& imageInfo,
|
||||||
|
LocatableFile* imageFile,
|
||||||
ImageDebugInfo*& _imageDebugInfo);
|
ImageDebugInfo*& _imageDebugInfo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ UsePrivateSystemHeaders ;
|
|||||||
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
|
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
|
||||||
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) elf ] ;
|
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) elf ] ;
|
||||||
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) types ] ;
|
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) types ] ;
|
||||||
|
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) util ] ;
|
||||||
|
|
||||||
|
|
||||||
MergeObject Debugger_dwarf.o
|
MergeObject Debugger_dwarf.o
|
||||||
|
|||||||
@@ -0,0 +1,541 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FileManager.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <AutoLocker.h>
|
||||||
|
|
||||||
|
#include "LocatableDirectory.h"
|
||||||
|
#include "LocatableFile.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - EntryPath
|
||||||
|
|
||||||
|
|
||||||
|
struct FileManager::EntryPath {
|
||||||
|
const char* directory;
|
||||||
|
const char* name;
|
||||||
|
|
||||||
|
EntryPath(const char* directory, const char* name)
|
||||||
|
:
|
||||||
|
directory(directory),
|
||||||
|
name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryPath(const BString& directory, const BString& name)
|
||||||
|
:
|
||||||
|
directory(directory.Length() > 0 ? directory.String() : NULL),
|
||||||
|
name(name.String())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryPath(const LocatableEntry* entry)
|
||||||
|
:
|
||||||
|
directory(entry->Parent() != NULL ? entry->Parent()->Path() : NULL),
|
||||||
|
name(entry->Name())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryPath(const EntryPath& other)
|
||||||
|
:
|
||||||
|
directory(other.directory),
|
||||||
|
name(other.name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HashValue() const
|
||||||
|
{
|
||||||
|
return StringUtils::HashValue(directory)
|
||||||
|
^ StringUtils::HashValue(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const EntryPath& other) const
|
||||||
|
{
|
||||||
|
if (directory != other.directory
|
||||||
|
&& (directory == NULL || other.directory == NULL
|
||||||
|
|| strcmp(directory, other.directory) != 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strcmp(name, other.name) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - EntryHashDefinition
|
||||||
|
|
||||||
|
|
||||||
|
struct FileManager::EntryHashDefinition {
|
||||||
|
typedef EntryPath KeyType;
|
||||||
|
typedef LocatableEntry ValueType;
|
||||||
|
|
||||||
|
size_t HashKey(const EntryPath& key) const
|
||||||
|
{
|
||||||
|
return key.HashValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Hash(const LocatableEntry* value) const
|
||||||
|
{
|
||||||
|
return HashKey(EntryPath(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compare(const EntryPath& key, const LocatableEntry* value) const
|
||||||
|
{
|
||||||
|
return EntryPath(value) == key;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashTableLink<LocatableEntry>* GetLink(LocatableEntry* value) const
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - Domain
|
||||||
|
|
||||||
|
|
||||||
|
class FileManager::Domain : private LocatableEntryOwner {
|
||||||
|
public:
|
||||||
|
Domain(FileManager* manager, bool isLocal)
|
||||||
|
:
|
||||||
|
fManager(manager),
|
||||||
|
fIsLocal(isLocal)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Domain()
|
||||||
|
{
|
||||||
|
LocatableEntry* entry = fEntries.Clear(true);
|
||||||
|
while (entry != NULL) {
|
||||||
|
LocatableEntry* next = entry->fNext;
|
||||||
|
entry->RemoveReference();
|
||||||
|
entry = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t Init()
|
||||||
|
{
|
||||||
|
status_t error = fEntries.Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocatableFile* GetFile(const BString& directoryPath, const BString& name)
|
||||||
|
{
|
||||||
|
BString normalizedDirectoryPath;
|
||||||
|
_NormalizePath(directoryPath, normalizedDirectoryPath);
|
||||||
|
LocatableFile* file = _GetFile(normalizedDirectoryPath, name);
|
||||||
|
if (file == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// try to auto-locate the file
|
||||||
|
if (LocatableDirectory* directory = file->Parent()) {
|
||||||
|
if (directory->State() == LOCATABLE_ENTRY_UNLOCATED) {
|
||||||
|
// parent not yet located -- try locate with the entry's path
|
||||||
|
BString path;
|
||||||
|
file->GetPath(path);
|
||||||
|
_LocateEntry(file, path, true, true);
|
||||||
|
} else {
|
||||||
|
// parent already located -- locate the entry in the parent
|
||||||
|
BString locatedDirectoryPath;
|
||||||
|
if (directory->GetLocatedPath(locatedDirectoryPath))
|
||||||
|
_LocateEntryInParentDir(file, locatedDirectoryPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocatableFile* GetFile(const BString& path)
|
||||||
|
{
|
||||||
|
BString directoryPath;
|
||||||
|
BString name;
|
||||||
|
_SplitPath(path, directoryPath, name);
|
||||||
|
return _GetFile(directoryPath, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntryLocated(const BString& path, const BString& locatedPath)
|
||||||
|
{
|
||||||
|
BString directory;
|
||||||
|
BString name;
|
||||||
|
_SplitPath(path, directory, name);
|
||||||
|
|
||||||
|
LocatableEntry* entry = fEntries.Lookup(EntryPath(directory, name));
|
||||||
|
if (entry == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_LocateEntry(entry, locatedPath, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool Lock()
|
||||||
|
{
|
||||||
|
return fManager->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Unlock()
|
||||||
|
{
|
||||||
|
fManager->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool LocatableEntryUnused(LocatableEntry* entry)
|
||||||
|
{
|
||||||
|
fEntries.Remove(entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _LocateDirectory(LocatableDirectory* directory,
|
||||||
|
const BString& locatedPath)
|
||||||
|
{
|
||||||
|
if (directory == NULL
|
||||||
|
|| directory->State() != LOCATABLE_ENTRY_UNLOCATED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// locate the parent, if possible, otherwise this directory
|
||||||
|
BString locatedDirectory;
|
||||||
|
BString locatedName;
|
||||||
|
_SplitNormalizedPath(locatedPath, locatedDirectory, locatedName);
|
||||||
|
if (locatedName != directory->Name()
|
||||||
|
|| !_LocateDirectory(directory->Parent(), locatedDirectory)) {
|
||||||
|
directory->SetLocatedPath(locatedPath, true);
|
||||||
|
_LocateEntries(directory, locatedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _LocateEntry(LocatableEntry* entry, const BString& locatedPath,
|
||||||
|
bool implicit, bool locateAncestors)
|
||||||
|
{
|
||||||
|
if (implicit && entry->State() == LOCATABLE_ENTRY_LOCATED_EXPLICITLY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (stat(locatedPath, &st) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
LocatableDirectory* directory
|
||||||
|
= dynamic_cast<LocatableDirectory*>(entry);
|
||||||
|
if (directory == NULL)
|
||||||
|
return false;
|
||||||
|
entry->SetLocatedPath(locatedPath, implicit);
|
||||||
|
} else if (S_ISREG(st.st_mode)) {
|
||||||
|
LocatableFile* file = dynamic_cast<LocatableFile*>(entry);
|
||||||
|
if (file == NULL)
|
||||||
|
return false;
|
||||||
|
entry->SetLocatedPath(locatedPath, implicit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// locate the ancestor directories, if requested
|
||||||
|
if (locateAncestors) {
|
||||||
|
BString locatedDirectory;
|
||||||
|
BString locatedName;
|
||||||
|
_SplitPath(locatedPath, locatedDirectory, locatedName);
|
||||||
|
if (locatedName == entry->Name())
|
||||||
|
_LocateDirectory(entry->Parent(), locatedDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _LocateEntryInParentDir(LocatableEntry* entry,
|
||||||
|
const BString& locatedDirectoryPath)
|
||||||
|
{
|
||||||
|
// construct the located entry path
|
||||||
|
BString locatedEntryPath(locatedDirectoryPath);
|
||||||
|
int32 pathLength = locatedEntryPath.Length();
|
||||||
|
if (pathLength >= 1 && locatedEntryPath.ByteAt(pathLength - 1) != '/')
|
||||||
|
locatedEntryPath << '/';
|
||||||
|
locatedEntryPath << entry->Name();
|
||||||
|
|
||||||
|
return _LocateEntry(entry, locatedEntryPath, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _LocateEntries(LocatableDirectory* directory,
|
||||||
|
const BString& locatedPath)
|
||||||
|
{
|
||||||
|
for (LocatableEntryList::ConstIterator it
|
||||||
|
= directory->Entries().GetIterator();
|
||||||
|
LocatableEntry* entry = it.Next();) {
|
||||||
|
if (entry->State() == LOCATABLE_ENTRY_LOCATED_EXPLICITLY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_LocateEntryInParentDir(entry, locatedPath)) {
|
||||||
|
// recurse for directories
|
||||||
|
if (LocatableDirectory* subDir
|
||||||
|
= dynamic_cast<LocatableDirectory*>(entry)) {
|
||||||
|
BString locatedEntryPath;
|
||||||
|
if (subDir->GetLocatedPath(locatedEntryPath))
|
||||||
|
_LocateEntries(subDir, locatedEntryPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocatableFile* _GetFile(const BString& directoryPath, const BString& name)
|
||||||
|
{
|
||||||
|
// if already know return the file
|
||||||
|
LocatableEntry* entry = fEntries.Lookup(EntryPath(directoryPath, name));
|
||||||
|
if (entry != NULL) {
|
||||||
|
LocatableFile* file = dynamic_cast<LocatableFile*>(entry);
|
||||||
|
if (file == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
file->AcquireReference();
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no such file yet -- create it
|
||||||
|
BString normalizedDirPath;
|
||||||
|
_NormalizePath(directoryPath, normalizedDirPath);
|
||||||
|
LocatableDirectory* directory = _GetDirectory(normalizedDirPath);
|
||||||
|
if (directory == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
LocatableFile* file = new(std::nothrow) LocatableFile(this, directory,
|
||||||
|
name);
|
||||||
|
if (file == NULL) {
|
||||||
|
directory->ReleaseReference();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fEntries.Insert(file);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocatableDirectory* _GetDirectory(const BString& path)
|
||||||
|
{
|
||||||
|
BString directoryPath;
|
||||||
|
BString fileName;
|
||||||
|
_SplitNormalizedPath(path, directoryPath, fileName);
|
||||||
|
|
||||||
|
// if already know return the directory
|
||||||
|
LocatableEntry* entry
|
||||||
|
= fEntries.Lookup(EntryPath(directoryPath, fileName));
|
||||||
|
if (entry != NULL) {
|
||||||
|
LocatableDirectory* directory
|
||||||
|
= dynamic_cast<LocatableDirectory*>(entry);
|
||||||
|
if (directory == NULL)
|
||||||
|
return NULL;
|
||||||
|
directory->AcquireReference();
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the parent directory
|
||||||
|
LocatableDirectory* parentDirectory = NULL;
|
||||||
|
if (directoryPath.Length() > 0) {
|
||||||
|
parentDirectory = _GetDirectory(directoryPath);
|
||||||
|
if (parentDirectory == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new directory
|
||||||
|
LocatableDirectory* directory = new(std::nothrow) LocatableDirectory(
|
||||||
|
this, parentDirectory, path);
|
||||||
|
if (directory == NULL) {
|
||||||
|
parentDirectory->ReleaseReference();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto-locate, if possible
|
||||||
|
if (fIsLocal) {
|
||||||
|
BString dirPath;
|
||||||
|
directory->GetPath(dirPath);
|
||||||
|
directory->SetLocatedPath(dirPath, false);
|
||||||
|
} else if (parentDirectory != NULL
|
||||||
|
&& parentDirectory->State() != LOCATABLE_ENTRY_UNLOCATED) {
|
||||||
|
// TODO:...
|
||||||
|
}
|
||||||
|
|
||||||
|
fEntries.Insert(directory);
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _NormalizePath(const BString& path, BString& _normalizedPath)
|
||||||
|
{
|
||||||
|
BString normalizedPath;
|
||||||
|
char* buffer = normalizedPath.LockBuffer(path.Length());
|
||||||
|
int32 outIndex = 0;
|
||||||
|
const char* remaining = path.String();
|
||||||
|
|
||||||
|
while (*remaining != '\0') {
|
||||||
|
// collapse repeated slashes
|
||||||
|
if (*remaining == '/') {
|
||||||
|
buffer[outIndex++] = '/';
|
||||||
|
remaining++;
|
||||||
|
while (*remaining == '/')
|
||||||
|
remaining++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*remaining == '\0') {
|
||||||
|
// remove trailing slash (unless it's "/" only)
|
||||||
|
if (outIndex > 1)
|
||||||
|
outIndex--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip "." components
|
||||||
|
if (*remaining == '.') {
|
||||||
|
if (remaining[1] == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (remaining[1] == '/') {
|
||||||
|
remaining += 2;
|
||||||
|
while (*remaining == '/')
|
||||||
|
remaining++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy path component
|
||||||
|
while (*remaining != '\0' && *remaining != '/')
|
||||||
|
buffer[outIndex++] = *(remaining++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the path didn't change, use the original path (BString's copy on
|
||||||
|
// write mechanism) rather than the new string.
|
||||||
|
if (outIndex == path.Length()) {
|
||||||
|
_normalizedPath = path;
|
||||||
|
} else {
|
||||||
|
normalizedPath.UnlockBuffer(outIndex);
|
||||||
|
_normalizedPath = normalizedPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _SplitPath(const BString& path, BString& _directory, BString& _name)
|
||||||
|
{
|
||||||
|
BString normalized;
|
||||||
|
_NormalizePath(path, normalized);
|
||||||
|
_SplitNormalizedPath(normalized, _directory, _name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _SplitNormalizedPath(const BString& path, BString& _directory,
|
||||||
|
BString& _name)
|
||||||
|
{
|
||||||
|
// handle single component (including root dir) cases
|
||||||
|
int32 lastSlash = path.FindLast('/');
|
||||||
|
if (lastSlash < 0 || path.Length() == 1) {
|
||||||
|
_directory = (const char*)NULL;
|
||||||
|
_name = path;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle root dir + one component and multi component cases
|
||||||
|
if (lastSlash == 0)
|
||||||
|
_directory = "/";
|
||||||
|
else
|
||||||
|
_directory.SetTo(path, lastSlash);
|
||||||
|
_name = path.String() + (lastSlash + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileManager* fManager;
|
||||||
|
LocatableEntryTable fEntries;
|
||||||
|
bool fIsLocal;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - FileManager
|
||||||
|
|
||||||
|
|
||||||
|
FileManager::FileManager()
|
||||||
|
:
|
||||||
|
fLock("file manager"),
|
||||||
|
fTargetDomain(NULL),
|
||||||
|
fSourceDomain(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FileManager::~FileManager()
|
||||||
|
{
|
||||||
|
delete fTargetDomain;
|
||||||
|
delete fSourceDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FileManager::Init(bool targetIsLocal)
|
||||||
|
{
|
||||||
|
status_t error = fLock.InitCheck();
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// create target domain
|
||||||
|
fTargetDomain = new(std::nothrow) Domain(this, targetIsLocal);
|
||||||
|
if (fTargetDomain == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
error = fTargetDomain->Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// create source domain
|
||||||
|
fSourceDomain = new(std::nothrow) Domain(this, false);
|
||||||
|
if (fSourceDomain == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
error = fSourceDomain->Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LocatableFile*
|
||||||
|
FileManager::GetTargetFile(const BString& directory, const BString& name)
|
||||||
|
{
|
||||||
|
AutoLocker<FileManager> locker(this);
|
||||||
|
return fTargetDomain->GetFile(directory, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LocatableFile*
|
||||||
|
FileManager::GetTargetFile(const BString& path)
|
||||||
|
{
|
||||||
|
AutoLocker<FileManager> locker(this);
|
||||||
|
return fTargetDomain->GetFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FileManager::TargetEntryLocated(const BString& path, const BString& locatedPath)
|
||||||
|
{
|
||||||
|
AutoLocker<FileManager> locker(this);
|
||||||
|
fTargetDomain->EntryLocated(path, locatedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LocatableFile*
|
||||||
|
FileManager::GetSourceFile(const BString& directory, const BString& name)
|
||||||
|
{
|
||||||
|
AutoLocker<FileManager> locker(this);
|
||||||
|
return fSourceDomain->GetFile(directory, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LocatableFile*
|
||||||
|
FileManager::GetSourceFile(const BString& path)
|
||||||
|
{
|
||||||
|
AutoLocker<FileManager> locker(this);
|
||||||
|
return fSourceDomain->GetFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FileManager::SourceEntryLocated(const BString& path, const BString& locatedPath)
|
||||||
|
{
|
||||||
|
AutoLocker<FileManager> locker(this);
|
||||||
|
fSourceDomain->EntryLocated(path, locatedPath);
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef FILE_MANAGER_H
|
||||||
|
#define FILE_MANAGER_H
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
|
||||||
|
class LocatableFile;
|
||||||
|
|
||||||
|
|
||||||
|
class FileManager {
|
||||||
|
public:
|
||||||
|
FileManager();
|
||||||
|
~FileManager();
|
||||||
|
|
||||||
|
status_t Init(bool targetIsLocal);
|
||||||
|
|
||||||
|
bool Lock() { return fLock.Lock(); }
|
||||||
|
void Unlock() { fLock.Unlock(); }
|
||||||
|
|
||||||
|
LocatableFile* GetTargetFile(const BString& directory,
|
||||||
|
const BString& name);
|
||||||
|
// returns a reference
|
||||||
|
LocatableFile* GetTargetFile(const BString& path);
|
||||||
|
// returns a reference
|
||||||
|
void TargetEntryLocated(const BString& path,
|
||||||
|
const BString& locatedPath);
|
||||||
|
|
||||||
|
LocatableFile* GetSourceFile(const BString& directory,
|
||||||
|
const BString& name);
|
||||||
|
// returns a reference
|
||||||
|
LocatableFile* GetSourceFile(const BString& path);
|
||||||
|
// returns a reference
|
||||||
|
void SourceEntryLocated(const BString& path,
|
||||||
|
const BString& locatedPath);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct EntryPath;
|
||||||
|
struct EntryHashDefinition;
|
||||||
|
class Domain;
|
||||||
|
|
||||||
|
typedef OpenHashTable<EntryHashDefinition> LocatableEntryTable;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BLocker fLock;
|
||||||
|
Domain* fTargetDomain;
|
||||||
|
Domain* fSourceDomain;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FILE_MANAGER_H
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "LocatableDirectory.h"
|
||||||
|
|
||||||
|
|
||||||
|
LocatableDirectory::LocatableDirectory(LocatableEntryOwner* owner,
|
||||||
|
LocatableDirectory* parent, const BString& path)
|
||||||
|
:
|
||||||
|
LocatableEntry(owner, parent),
|
||||||
|
fPath(path),
|
||||||
|
fLocatedPath()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LocatableDirectory::~LocatableDirectory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
LocatableDirectory::Name() const
|
||||||
|
{
|
||||||
|
int32 lastSlash = fPath.FindLast('/');
|
||||||
|
// return -1, if not found
|
||||||
|
return fPath.String() + (lastSlash + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
LocatableDirectory::Path() const
|
||||||
|
{
|
||||||
|
return fPath.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableDirectory::GetPath(BString& _path) const
|
||||||
|
{
|
||||||
|
_path = fPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocatableDirectory::GetLocatedPath(BString& _path) const
|
||||||
|
{
|
||||||
|
if (fLocatedPath.Length() == 0)
|
||||||
|
return false;
|
||||||
|
_path = fLocatedPath;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableDirectory::SetLocatedPath(const BString& path, bool implicit)
|
||||||
|
{
|
||||||
|
fLocatedPath = path;
|
||||||
|
fState = implicit
|
||||||
|
? LOCATABLE_ENTRY_LOCATED_IMPLICITLY
|
||||||
|
: LOCATABLE_ENTRY_LOCATED_EXPLICITLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableDirectory::AddEntry(LocatableEntry* entry)
|
||||||
|
{
|
||||||
|
fEntries.Add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableDirectory::RemoveEntry(LocatableEntry* entry)
|
||||||
|
{
|
||||||
|
fEntries.Remove(entry);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef LOCATABLE_DIRECTORY_H
|
||||||
|
#define LOCATABLE_DIRECTORY_H
|
||||||
|
|
||||||
|
#include "LocatableEntry.h"
|
||||||
|
|
||||||
|
|
||||||
|
class LocatableDirectory : public LocatableEntry {
|
||||||
|
public:
|
||||||
|
LocatableDirectory(LocatableEntryOwner* owner,
|
||||||
|
LocatableDirectory* parent,
|
||||||
|
const BString& path);
|
||||||
|
~LocatableDirectory();
|
||||||
|
|
||||||
|
virtual const char* Name() const;
|
||||||
|
const char* Path() const;
|
||||||
|
void GetPath(BString& _path) const;
|
||||||
|
|
||||||
|
// mutable (requires locking)
|
||||||
|
virtual bool GetLocatedPath(BString& _path) const;
|
||||||
|
virtual void SetLocatedPath(const BString& path,
|
||||||
|
bool implicit);
|
||||||
|
|
||||||
|
void AddEntry(LocatableEntry* entry);
|
||||||
|
void RemoveEntry(LocatableEntry* entry);
|
||||||
|
const LocatableEntryList& Entries() const { return fEntries; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BString fPath;
|
||||||
|
BString fLocatedPath;
|
||||||
|
LocatableEntryList fEntries;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // LOCATABLE_DIRECTORY_H
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "LocatableEntry.h"
|
||||||
|
|
||||||
|
#include "AutoLocker.h"
|
||||||
|
|
||||||
|
#include "LocatableDirectory.h"
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - LocatableEntryOwner
|
||||||
|
|
||||||
|
|
||||||
|
LocatableEntryOwner::~LocatableEntryOwner()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - LocatableEntry
|
||||||
|
|
||||||
|
|
||||||
|
LocatableEntry::LocatableEntry(LocatableEntryOwner* owner,
|
||||||
|
LocatableDirectory* parent)
|
||||||
|
:
|
||||||
|
fOwner(owner),
|
||||||
|
fParent(parent),
|
||||||
|
fState(LOCATABLE_ENTRY_UNLOCATED)
|
||||||
|
{
|
||||||
|
if (fParent != NULL)
|
||||||
|
fParent->AcquireReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LocatableEntry::~LocatableEntry()
|
||||||
|
{
|
||||||
|
if (fParent != NULL)
|
||||||
|
fParent->ReleaseReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableEntry::LastReferenceReleased()
|
||||||
|
{
|
||||||
|
AutoLocker<LocatableEntryOwner> locker(fOwner);
|
||||||
|
if (CountReferences() == 0 && fOwner->LocatableEntryUnused(this))
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef LOCATABLE_ENTRY_H
|
||||||
|
#define LOCATABLE_ENTRY_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include <Referenceable.h>
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
|
||||||
|
enum locatable_entry_state {
|
||||||
|
LOCATABLE_ENTRY_UNLOCATED,
|
||||||
|
LOCATABLE_ENTRY_LOCATED_IMPLICITLY,
|
||||||
|
LOCATABLE_ENTRY_LOCATED_EXPLICITLY
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LocatableDirectory;
|
||||||
|
class LocatableEntry;
|
||||||
|
|
||||||
|
|
||||||
|
class LocatableEntryOwner {
|
||||||
|
public:
|
||||||
|
virtual ~LocatableEntryOwner();
|
||||||
|
|
||||||
|
virtual bool Lock() = 0;
|
||||||
|
virtual void Unlock() = 0;
|
||||||
|
|
||||||
|
virtual bool LocatableEntryUnused(LocatableEntry* entry) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LocatableEntry : public Referenceable,
|
||||||
|
public DoublyLinkedListLinkImpl<LocatableEntry>,
|
||||||
|
public HashTableLink<LocatableEntry> {
|
||||||
|
public:
|
||||||
|
LocatableEntry(LocatableEntryOwner* owner,
|
||||||
|
LocatableDirectory* parent);
|
||||||
|
~LocatableEntry();
|
||||||
|
|
||||||
|
LocatableDirectory* Parent() const { return fParent; }
|
||||||
|
virtual const char* Name() const = 0;
|
||||||
|
|
||||||
|
// mutable (requires locking)
|
||||||
|
locatable_entry_state State() const { return fState; }
|
||||||
|
virtual bool GetLocatedPath(BString& _path) const = 0;
|
||||||
|
virtual void SetLocatedPath(const BString& path,
|
||||||
|
bool implicit) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void LastReferenceReleased();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LocatableEntryOwner* fOwner;
|
||||||
|
LocatableDirectory* fParent;
|
||||||
|
locatable_entry_state fState;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<LocatableEntry> LocatableEntryList;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // LOCATABLE_ENTRY_H
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "LocatableFile.h"
|
||||||
|
|
||||||
|
#include <AutoLocker.h>
|
||||||
|
|
||||||
|
#include "LocatableDirectory.h"
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - LocatableFile
|
||||||
|
|
||||||
|
|
||||||
|
LocatableFile::LocatableFile(LocatableEntryOwner* owner,
|
||||||
|
LocatableDirectory* directory, const BString& name)
|
||||||
|
:
|
||||||
|
LocatableEntry(owner, directory),
|
||||||
|
fName(name),
|
||||||
|
fLocatedPath(),
|
||||||
|
fListeners(8)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LocatableFile::~LocatableFile()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
LocatableFile::Name() const
|
||||||
|
{
|
||||||
|
return fName.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableFile::GetPath(BString& _path) const
|
||||||
|
{
|
||||||
|
fParent->GetPath(_path);
|
||||||
|
_path << '/' << fName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocatableFile::GetLocatedPath(BString& _path) const
|
||||||
|
{
|
||||||
|
AutoLocker<LocatableEntryOwner> locker(fOwner);
|
||||||
|
|
||||||
|
if (fLocatedPath.Length() > 0) {
|
||||||
|
_path = fLocatedPath;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fParent->GetLocatedPath(_path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_path << '/' << fName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableFile::SetLocatedPath(const BString& path, bool implicit)
|
||||||
|
{
|
||||||
|
// called with owner already locked
|
||||||
|
|
||||||
|
if (implicit) {
|
||||||
|
fLocatedPath = (const char*)NULL;
|
||||||
|
fState = LOCATABLE_ENTRY_LOCATED_IMPLICITLY;
|
||||||
|
} else {
|
||||||
|
fLocatedPath = path;
|
||||||
|
fState = LOCATABLE_ENTRY_LOCATED_EXPLICITLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
_NotifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocatableFile::AddListener(Listener* listener)
|
||||||
|
{
|
||||||
|
AutoLocker<LocatableEntryOwner> locker(fOwner);
|
||||||
|
return fListeners.AddItem(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableFile::RemoveListener(Listener* listener)
|
||||||
|
{
|
||||||
|
AutoLocker<LocatableEntryOwner> locker(fOwner);
|
||||||
|
fListeners.RemoveItem(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LocatableFile::_NotifyListeners()
|
||||||
|
{
|
||||||
|
for (int32 i = fListeners.CountItems() - 1; i >= 0; i--)
|
||||||
|
fListeners.ItemAt(i)->LocatableFileChanged(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - Listener
|
||||||
|
|
||||||
|
|
||||||
|
LocatableFile::Listener::~Listener()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef LOCATABLE_FILE_H
|
||||||
|
#define LOCATABLE_FILE_H
|
||||||
|
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
#include "LocatableEntry.h"
|
||||||
|
|
||||||
|
|
||||||
|
class LocatableFile : public LocatableEntry {
|
||||||
|
public:
|
||||||
|
class Listener;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LocatableFile(LocatableEntryOwner* owner,
|
||||||
|
LocatableDirectory* directory,
|
||||||
|
const BString& name);
|
||||||
|
~LocatableFile();
|
||||||
|
|
||||||
|
virtual const char* Name() const;
|
||||||
|
void GetPath(BString& _path) const;
|
||||||
|
|
||||||
|
// mutable (requires/does locking)
|
||||||
|
virtual bool GetLocatedPath(BString& _path) const;
|
||||||
|
virtual void SetLocatedPath(const BString& path,
|
||||||
|
bool implicit);
|
||||||
|
|
||||||
|
bool AddListener(Listener* listener);
|
||||||
|
void RemoveListener(Listener* listener);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef BObjectList<Listener> ListenerList;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _NotifyListeners();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BString fName;
|
||||||
|
BString fLocatedPath;
|
||||||
|
ListenerList fListeners;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LocatableFile::Listener {
|
||||||
|
public:
|
||||||
|
virtual ~Listener();
|
||||||
|
|
||||||
|
virtual void LocatableFileChanged(LocatableFile* file) = 0;
|
||||||
|
// called with lock held
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // LOCATABLE_FILE_H
|
||||||
@@ -6,23 +6,29 @@
|
|||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
|
|
||||||
#include "ImageDebugInfo.h"
|
#include "ImageDebugInfo.h"
|
||||||
|
#include "LocatableFile.h"
|
||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
|
|
||||||
|
|
||||||
Image::Image(Team* team,const ImageInfo& imageInfo)
|
Image::Image(Team* team,const ImageInfo& imageInfo, LocatableFile* imageFile)
|
||||||
:
|
:
|
||||||
fTeam(team),
|
fTeam(team),
|
||||||
fInfo(imageInfo),
|
fInfo(imageInfo),
|
||||||
|
fImageFile(imageFile),
|
||||||
fDebugInfo(NULL),
|
fDebugInfo(NULL),
|
||||||
fDebugInfoState(IMAGE_DEBUG_INFO_NOT_LOADED)
|
fDebugInfoState(IMAGE_DEBUG_INFO_NOT_LOADED)
|
||||||
{
|
{
|
||||||
|
if (fImageFile != NULL)
|
||||||
|
fImageFile->AcquireReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Image::~Image()
|
Image::~Image()
|
||||||
{
|
{
|
||||||
if (fDebugInfo != NULL)
|
if (fDebugInfo != NULL)
|
||||||
fDebugInfo->RemoveReference();
|
fDebugInfo->ReleaseReference();
|
||||||
|
if (fImageFile != NULL)
|
||||||
|
fImageFile->ReleaseReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ enum image_debug_info_state {
|
|||||||
|
|
||||||
|
|
||||||
class ImageDebugInfo;
|
class ImageDebugInfo;
|
||||||
|
class LocatableFile;
|
||||||
class Team;
|
class Team;
|
||||||
|
|
||||||
|
|
||||||
class Image : public Referenceable, public DoublyLinkedListLinkImpl<Image> {
|
class Image : public Referenceable, public DoublyLinkedListLinkImpl<Image> {
|
||||||
public:
|
public:
|
||||||
Image(Team* team, const ImageInfo& imageInfo);
|
Image(Team* team, const ImageInfo& imageInfo,
|
||||||
|
LocatableFile* imageFile);
|
||||||
~Image();
|
~Image();
|
||||||
|
|
||||||
status_t Init();
|
status_t Init();
|
||||||
@@ -37,6 +39,7 @@ public:
|
|||||||
image_id ID() const { return fInfo.ImageID(); }
|
image_id ID() const { return fInfo.ImageID(); }
|
||||||
const char* Name() const { return fInfo.Name(); }
|
const char* Name() const { return fInfo.Name(); }
|
||||||
const ImageInfo& Info() const { return fInfo; }
|
const ImageInfo& Info() const { return fInfo; }
|
||||||
|
LocatableFile* ImageFile() const { return fImageFile; }
|
||||||
|
|
||||||
bool ContainsAddress(target_addr_t address) const;
|
bool ContainsAddress(target_addr_t address) const;
|
||||||
|
|
||||||
@@ -50,6 +53,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
Team* fTeam;
|
Team* fTeam;
|
||||||
ImageInfo fInfo;
|
ImageInfo fInfo;
|
||||||
|
LocatableFile* fImageFile;
|
||||||
// mutable
|
// mutable
|
||||||
ImageDebugInfo* fDebugInfo;
|
ImageDebugInfo* fDebugInfo;
|
||||||
image_debug_info_state fDebugInfoState;
|
image_debug_info_state fDebugInfoState;
|
||||||
|
|||||||
@@ -123,18 +123,11 @@ Team::Threads() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Team::AddImage(Image* image)
|
|
||||||
{
|
|
||||||
fImages.Add(image);
|
|
||||||
_NotifyImageAdded(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Team::AddImage(const ImageInfo& imageInfo, Image** _image)
|
Team::AddImage(const ImageInfo& imageInfo, LocatableFile* imageFile,
|
||||||
|
Image** _image)
|
||||||
{
|
{
|
||||||
Image* image = new(std::nothrow) Image(this, imageInfo);
|
Image* image = new(std::nothrow) Image(this, imageInfo, imageFile);
|
||||||
if (image == NULL)
|
if (image == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -144,7 +137,8 @@ Team::AddImage(const ImageInfo& imageInfo, Image** _image)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddImage(image);
|
fImages.Add(image);
|
||||||
|
_NotifyImageAdded(image);
|
||||||
|
|
||||||
if (_image != NULL)
|
if (_image != NULL)
|
||||||
*_image = image;
|
*_image = image;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LocatableFile;
|
||||||
class TeamDebugInfo;
|
class TeamDebugInfo;
|
||||||
|
|
||||||
|
|
||||||
@@ -58,8 +59,8 @@ public:
|
|||||||
Thread* ThreadByID(thread_id threadID) const;
|
Thread* ThreadByID(thread_id threadID) const;
|
||||||
const ThreadList& Threads() const;
|
const ThreadList& Threads() const;
|
||||||
|
|
||||||
void AddImage(Image* image);
|
|
||||||
status_t AddImage(const ImageInfo& imageInfo,
|
status_t AddImage(const ImageInfo& imageInfo,
|
||||||
|
LocatableFile* imageFile,
|
||||||
Image** _image = NULL);
|
Image** _image = NULL);
|
||||||
void RemoveImage(Image* image);
|
void RemoveImage(Image* image);
|
||||||
bool RemoveImage(image_id imageID);
|
bool RemoveImage(image_id imageID);
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
|
||||||
|
// from the Dragon Book: a slightly modified hashpjw()
|
||||||
|
/*static*/ uint32
|
||||||
|
StringUtils::HashValue(const char* string)
|
||||||
|
{
|
||||||
|
if (string == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint32 h = 0;
|
||||||
|
|
||||||
|
for (; *string; string++) {
|
||||||
|
uint32 g = h & 0xf0000000;
|
||||||
|
if (g)
|
||||||
|
h ^= g >> 24;
|
||||||
|
h = (h << 4) + *string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef STRING_UTILS_H
|
||||||
|
#define STRING_UTILS_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
class StringUtils {
|
||||||
|
public:
|
||||||
|
static uint32 HashValue(const char* string);
|
||||||
|
static uint32 HashValue(const BString& string);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ inline uint32
|
||||||
|
StringUtils::HashValue(const BString& string)
|
||||||
|
{
|
||||||
|
return HashValue(string.String());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STRING_UTILS_H
|
||||||
Reference in New Issue
Block a user