LLVM: lib/DebugInfo/LogicalView/LVReaderHandler.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
20
21using namespace llvm;
25
26#define DEBUG_TYPE "ReaderHandler"
27
29 if (Error Err = createReaders())
30 return Err;
31 if (Error Err = printReaders())
32 return Err;
33 if (Error Err = compareReaders())
34 return Err;
35
37}
38
42 auto CreateOneReader = [&]() -> std::unique_ptr {
45 if (Obj.isCOFF()) {
47 return std::make_unique(Filename, FileFormatName,
48 *COFF, W, ExePath);
49 }
50 if (Obj.isELF() || Obj.isMachO() || Obj.isWasm())
51 return std::make_unique(Filename, FileFormatName, Obj,
52 W);
53 }
56 return std::make_unique(Filename, FileFormatName, Pdb,
57 W, ExePath);
58 }
59 return nullptr;
60 };
61
62 std::unique_ptr ReaderObj = CreateOneReader();
63 if (!ReaderObj)
65 "unable to create reader for: '%s'",
67
68 LVReader *Reader = ReaderObj.get();
69 Readers.emplace_back(std::move(ReaderObj));
70 return Reader->doLoad();
71}
72
74 Archive &Arch) {
76 for (const Archive::Child &Child : Arch.children(Err)) {
77 Expected BuffOrErr = Child.getMemoryBufferRef();
81 Expected NameOrErr = Child.getName();
85 std::string Name = (Filename + "(" + NameOrErr.get() + ")").str();
86 if (Error Err = handleBuffer(Readers, Name, BuffOrErr.get()))
89 }
90
91 if (Err)
95}
96
97
102
103 std::unique_ptr Session;
106 return {};
107 }
108
110 if (!PdbPathOrErr) {
112 return {};
113 }
114
117 if (ConvertedPath == Path)
118 return std::string(ExePath);
119
120 return {};
121}
122
123
131 if (!BuffOrErr)
132 return {};
133 return std::string(ObjPath);
134 }
135
136 return {};
137}
138
140 MemoryBufferRef Buffer, StringRef ExePath) {
141
142
145 if (!ExePath.empty())
146 return handleObject(Readers, Filename, Buffer.getBuffer(), ExePath);
147
148
149
150
151
152 std::vector ExecutableExtensions = {"exe", "dll"};
153 for (StringRef Extension : ExecutableExtensions) {
155 if (ExecutableImage.empty())
156 continue;
158 ExecutableImage)) {
160 continue;
161 }
163 }
164
165 std::vector ObjectExtensions = {"o", "obj", "lib"};
166 for (StringRef Extension : ObjectExtensions) {
168 if (ObjectImage.empty())
169 continue;
170 if (Error Err = handleFile(Readers, ObjectImage)) {
172 continue;
173 }
175 }
176
177
178 return handleObject(Readers, Filename, Buffer.getBuffer(), ExePath);
179 }
181
186 "Binary object format in '%s' does not have debug info.",
188 }
189
190 return handleFile(Readers, PdbPath.get(), Filename);
191 }
192
193 Expected<std::unique_ptr> BinOrErr = createBinary(Buffer);
196 "Binary object format in '%s' is not supported.",
198 }
199 return handleObject(Readers, Filename, *BinOrErr.get());
200}
201
203 StringRef ExePath) {
204
205 std::string ConvertedPath =
207 ErrorOr<std::unique_ptr> BuffOrErr =
211 "File '%s' does not exist.",
212 ConvertedPath.c_str());
213 }
214 std::unique_ptr Buffer = std::move(BuffOrErr.get());
215 return handleBuffer(Readers, ConvertedPath, *Buffer, ExePath);
216}
217
219 MachOUniversalBinary &Mach) {
220 for (const MachOUniversalBinary::ObjectForArch &ObjForArch : Mach.objects()) {
221 std::string ObjName = (Twine(Filename) + Twine("(") +
222 Twine(ObjForArch.getArchFlagName()) + Twine(")"))
223 .str();
224 if (Expected<std::unique_ptr> MachOOrErr =
225 ObjForArch.getAsObjectFile()) {
226 MachOObjectFile &Obj = **MachOOrErr;
229 createReader(Filename, Readers, Input, Obj.getFileFormatName()))
230 return Err;
231 continue;
232 } else
234 if (Expected<std::unique_ptr> ArchiveOrErr =
235 ObjForArch.getAsArchive()) {
236 if (Error Err = handleArchive(Readers, ObjName, *ArchiveOrErr.get()))
237 return Err;
238 continue;
239 } else
241 }
243}
244
246 Binary &Binary) {
248 return createReader(Filename, Readers, Input,
250
252 return handleMach(Readers, Filename, *Fat);
253
255 return handleArchive(Readers, Filename, *Arch);
256
258 "Binary object format in '%s' is not supported.",
260}
261
263 StringRef Buffer, StringRef ExePath) {
264 std::unique_ptr Session;
268
269 std::unique_ptr PdbSession;
270 PdbSession.reset(static_cast<NativeSession *>(Session.release()));
271 PdbOrObj Input = &PdbSession->getPDBFile();
272 StringRef FileFormatName;
274 if (Pos)
275 FileFormatName = Buffer.substr(0, Pos - 1);
276 return createReader(Filename, Readers, Input, FileFormatName, ExePath);
277}
278
279Error LVReaderHandler::createReaders() {
281 for (std::string &Object : Objects) {
283 if (Error Err = createReader(Object, Readers))
284 return Err;
285 TheReaders.insert(TheReaders.end(),
286 std::make_move_iterator(Readers.begin()),
287 std::make_move_iterator(Readers.end()));
288 }
289
291}
292
293Error LVReaderHandler::printReaders() {
295 if (options().getPrintExecute())
296 for (const std::unique_ptr &Reader : TheReaders)
298 return Err;
299
301}
302
303Error LVReaderHandler::compareReaders() {
305 size_t ReadersCount = TheReaders.size();
306 if (options().getCompareExecute() && ReadersCount >= 2) {
307
308 size_t ViewPairs = ReadersCount / 2;
310 for (size_t Pair = 0, Index = 0; Pair < ViewPairs; ++Pair) {
311 if (Error Err = Compare.execute(TheReaders[Index].get(),
312 TheReaders[Index + 1].get()))
313 return Err;
315 }
316 }
317
319}
320
static std::string searchForObj(const StringRef Path, const StringRef Extension)
Definition LVReaderHandler.cpp:124
static std::string searchForExe(const StringRef Path, const StringRef Extension)
Definition LVReaderHandler.cpp:98
The Input class is used to parse a yaml document into in-memory structs and vectors.
Represents either an error or a value T.
std::error_code getError() const
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
StringRef getBuffer() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
LLVM_ABI void print(raw_ostream &OS) const
Definition LVReaderHandler.cpp:321
LLVM_ABI Error process()
Definition LVReaderHandler.cpp:28
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
iterator_range< object_iterator > objects() const
static Expected< std::string > searchForPdb(const PdbSearchOptions &Opts)
This class implements an extremely fast bulk output stream that can only output to a stream.
std::vector< std::unique_ptr< LVReader > > LVReaders
PointerUnion< object::ObjectFile *, pdb::PDBFile * > PdbOrObj
LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
LLVM_ABI Error loadDataForEXE(PDB_ReaderType Type, StringRef Path, std::unique_ptr< IPDBSession > &Session)
LLVM_ABI Error loadDataForPDB(PDB_ReaderType Type, StringRef Path, std::unique_ptr< IPDBSession > &Session)
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
LLVM_ABI void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
LLVM_ABI std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
void consumeError(Error Err)
Consume a Error without doing anything.
@ pdb
Windows PDB debug info file.
@ pecoff_executable
PECOFF executable file.