1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2013, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include "CompilationUnit.h"
9
10#include <new>
11
12#include "DebugInfoEntries.h"
13#include "TargetAddressRangeList.h"
14
15
16struct CompilationUnit::File {
17	BString		fileName;
18	const char*	dirName;
19
20
21	File(const char* fileName, const char* dirName)
22		:
23		fileName(fileName),
24		dirName(dirName)
25	{
26	}
27};
28
29
30CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset,
31	off_t totalSize, off_t abbreviationOffset, uint8 addressSize,
32	bool isBigEndian, bool isDwarf64)
33	:
34	BaseUnit(headerOffset, contentOffset, totalSize, abbreviationOffset,
35		addressSize, isBigEndian, isDwarf64),
36	fUnitEntry(NULL),
37	fAddressRanges(NULL),
38	fDirectories(10, true),
39	fFiles(10, true),
40	fLineNumberProgram(addressSize, isBigEndian)
41{
42}
43
44
45CompilationUnit::~CompilationUnit()
46{
47	SetAddressRanges(NULL);
48}
49
50
51void
52CompilationUnit::SetUnitEntry(DIECompileUnitBase* entry)
53{
54	fUnitEntry = entry;
55}
56
57
58void
59CompilationUnit::SetAddressRanges(TargetAddressRangeList* ranges)
60{
61	if (fAddressRanges != NULL)
62		fAddressRanges->ReleaseReference();
63
64	fAddressRanges = ranges;
65
66	if (fAddressRanges != NULL)
67		fAddressRanges->AcquireReference();
68}
69
70
71target_addr_t
72CompilationUnit::AddressRangeBase() const
73{
74	return fUnitEntry != NULL ? fUnitEntry->LowPC() : 0;
75}
76
77
78bool
79CompilationUnit::AddDirectory(const char* directory)
80{
81	BString* directoryString = new(std::nothrow) BString(directory);
82	if (directoryString == NULL || directoryString->Length() == 0
83		|| !fDirectories.AddItem(directoryString)) {
84		delete directoryString;
85		return false;
86	}
87
88	return true;
89}
90
91
92int32
93CompilationUnit::CountDirectories() const
94{
95	return fDirectories.CountItems();
96}
97
98
99const char*
100CompilationUnit::DirectoryAt(int32 index) const
101{
102	BString* directory = fDirectories.ItemAt(index);
103	return directory != NULL ? directory->String() : NULL;
104}
105
106
107bool
108CompilationUnit::AddFile(const char* fileName, int32 dirIndex)
109{
110	File* file = new(std::nothrow) File(fileName, DirectoryAt(dirIndex));
111	if (file == NULL || file->fileName.Length() == 0 || !fFiles.AddItem(file)) {
112		delete file;
113		return false;
114	}
115
116	return true;
117}
118
119
120int32
121CompilationUnit::CountFiles() const
122{
123	return fFiles.CountItems();
124}
125
126
127const char*
128CompilationUnit::FileAt(int32 index, const char** _directory) const
129{
130	if (File* file = fFiles.ItemAt(index)) {
131		if (_directory != NULL)
132			*_directory = file->dirName;
133		return file->fileName.String();
134	}
135
136	return NULL;
137}
138
139
140dwarf_unit_kind
141CompilationUnit::Kind() const
142{
143	return dwarf_unit_kind_compilation;
144}
145