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.