Skip to content

Commit 692410e

Browse files
committed
Be a bit more consistent about using ErrorOr when constructing Binary objects.
The constructors of classes deriving from Binary normally take an error_code as an argument to the constructor. My original intent was to change them to have a trivial constructor and move the initial parsing logic to a static method returning an ErrorOr. I changed my mind because: * A constructor with an error_code out parameter is extremely convenient from the implementation side. We can incrementally construct the object and give up when we find an error. * It is very efficient when constructing on the stack or when there is no error. The only inefficient case is where heap allocating and an error is found (we have to free the memory). The result is that this is a much smaller patch. It just standardizes the create* helpers to return an ErrorOr. Almost no functionality change: The only difference is that this found that we were trying to read past the end of COFF import library but ignoring the error. llvm-svn: 199770
1 parent 902efc6 commit 692410e

File tree

11 files changed

+84
-81
lines changed

11 files changed

+84
-81
lines changed

llvm/include/llvm/Object/Archive.h

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/ADT/StringRef.h"
1818
#include "llvm/Object/Binary.h"
1919
#include "llvm/Support/ErrorHandling.h"
20+
#include "llvm/Support/ErrorOr.h"
2021
#include "llvm/Support/FileSystem.h"
2122
#include "llvm/Support/MemoryBuffer.h"
2223

@@ -163,6 +164,7 @@ class Archive : public Binary {
163164
};
164165

165166
Archive(MemoryBuffer *source, error_code &ec);
167+
static ErrorOr<Archive *> create(MemoryBuffer *Source);
166168

167169
enum Kind {
168170
K_GNU,

llvm/include/llvm/Object/MachOUniversal.h

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/ADT/StringRef.h"
1919
#include "llvm/ADT/Triple.h"
2020
#include "llvm/Object/Binary.h"
21+
#include "llvm/Support/ErrorOr.h"
2122
#include "llvm/Support/MachO.h"
2223

2324
namespace llvm {
@@ -77,6 +78,7 @@ class MachOUniversalBinary : public Binary {
7778
};
7879

7980
MachOUniversalBinary(MemoryBuffer *Source, error_code &ec);
81+
static ErrorOr<MachOUniversalBinary*> create(MemoryBuffer *Source);
8082

8183
object_iterator begin_objects() const {
8284
return ObjectForArch(this, 0);

llvm/include/llvm/Object/ObjectFile.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,9 @@ class ObjectFile : public Binary {
384384
}
385385

386386
public:
387-
static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
388-
static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
389-
static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
387+
static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object);
388+
static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object);
389+
static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object);
390390
};
391391

392392
// Inline function definitions.

llvm/lib/Object/Archive.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,14 @@ error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const {
194194
return object_error::success;
195195
}
196196

197+
ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
198+
error_code EC;
199+
OwningPtr<Archive> Ret(new Archive(Source, EC));
200+
if (EC)
201+
return EC;
202+
return Ret.take();
203+
}
204+
197205
Archive::Archive(MemoryBuffer *source, error_code &ec)
198206
: Binary(Binary::ID_Archive, source), SymbolTable(child_end()) {
199207
// Check for sufficient magic.

llvm/lib/Object/Binary.cpp

+10-35
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
// Include headers for createBinary.
2121
#include "llvm/Object/Archive.h"
22-
#include "llvm/Object/COFF.h"
2322
#include "llvm/Object/MachOUniversal.h"
2423
#include "llvm/Object/ObjectFile.h"
2524

@@ -45,24 +44,14 @@ StringRef Binary::getFileName() const {
4544
ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source) {
4645
OwningPtr<MemoryBuffer> scopedSource(Source);
4746
sys::fs::file_magic type = sys::fs::identify_magic(Source->getBuffer());
48-
error_code EC;
4947
switch (type) {
50-
case sys::fs::file_magic::archive: {
51-
OwningPtr<Binary> Ret(new Archive(scopedSource.take(), EC));
52-
if (EC)
53-
return EC;
54-
return Ret.take();
55-
}
48+
case sys::fs::file_magic::archive:
49+
return Archive::create(scopedSource.take());
5650
case sys::fs::file_magic::elf_relocatable:
5751
case sys::fs::file_magic::elf_executable:
5852
case sys::fs::file_magic::elf_shared_object:
59-
case sys::fs::file_magic::elf_core: {
60-
OwningPtr<Binary> Ret(
61-
ObjectFile::createELFObjectFile(scopedSource.take()));
62-
if (!Ret)
63-
return object_error::invalid_file_type;
64-
return Ret.take();
65-
}
53+
case sys::fs::file_magic::elf_core:
54+
return ObjectFile::createELFObjectFile(scopedSource.take());
6655
case sys::fs::file_magic::macho_object:
6756
case sys::fs::file_magic::macho_executable:
6857
case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
@@ -72,28 +61,14 @@ ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source) {
7261
case sys::fs::file_magic::macho_dynamic_linker:
7362
case sys::fs::file_magic::macho_bundle:
7463
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
75-
case sys::fs::file_magic::macho_dsym_companion: {
76-
OwningPtr<Binary> Ret(
77-
ObjectFile::createMachOObjectFile(scopedSource.take()));
78-
if (!Ret)
79-
return object_error::invalid_file_type;
80-
return Ret.take();
81-
}
82-
case sys::fs::file_magic::macho_universal_binary: {
83-
OwningPtr<Binary> Ret(new MachOUniversalBinary(scopedSource.take(), EC));
84-
if (EC)
85-
return EC;
86-
return Ret.take();
87-
}
64+
case sys::fs::file_magic::macho_dsym_companion:
65+
return ObjectFile::createMachOObjectFile(scopedSource.take());
66+
case sys::fs::file_magic::macho_universal_binary:
67+
return MachOUniversalBinary::create(scopedSource.take());
8868
case sys::fs::file_magic::coff_object:
8969
case sys::fs::file_magic::coff_import_library:
90-
case sys::fs::file_magic::pecoff_executable: {
91-
OwningPtr<Binary> Ret(
92-
ObjectFile::createCOFFObjectFile(scopedSource.take()));
93-
if (!Ret)
94-
return object_error::invalid_file_type;
95-
return Ret.take();
96-
}
70+
case sys::fs::file_magic::pecoff_executable:
71+
return ObjectFile::createCOFFObjectFile(scopedSource.take());
9772
case sys::fs::file_magic::unknown:
9873
case sys::fs::file_magic::bitcode:
9974
case sys::fs::file_magic::windows_resource: {

llvm/lib/Object/COFFObjectFile.cpp

+11-8
Original file line numberDiff line numberDiff line change
@@ -514,10 +514,12 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC)
514514
CurPtr += COFFHeader->SizeOfOptionalHeader;
515515
}
516516

517-
if (!COFFHeader->isImportLibrary())
518-
if ((EC = getObject(SectionTable, Data, base() + CurPtr,
519-
COFFHeader->NumberOfSections * sizeof(coff_section))))
520-
return;
517+
if (COFFHeader->isImportLibrary())
518+
return;
519+
520+
if ((EC = getObject(SectionTable, Data, base() + CurPtr,
521+
COFFHeader->NumberOfSections * sizeof(coff_section))))
522+
return;
521523

522524
// Initialize the pointer to the symbol table.
523525
if (COFFHeader->PointerToSymbolTable != 0)
@@ -1013,9 +1015,10 @@ error_code ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
10131015
return object_error::success;
10141016
}
10151017

1016-
namespace llvm {
1017-
ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
1018+
ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
10181019
error_code EC;
1019-
return new COFFObjectFile(Object, EC);
1020-
}
1020+
OwningPtr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
1021+
if (EC)
1022+
return EC;
1023+
return Ret.take();
10211024
}

llvm/lib/Object/ELFObjectFile.cpp

+18-15
Original file line numberDiff line numberDiff line change
@@ -17,57 +17,60 @@
1717
namespace llvm {
1818
using namespace object;
1919

20-
// Creates an in-memory object-file by default: createELFObjectFile(Buffer)
21-
ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
22-
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
23-
error_code ec;
24-
20+
ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj) {
21+
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj);
2522
std::size_t MaxAlignment =
26-
1ULL << countTrailingZeros(uintptr_t(Object->getBufferStart()));
23+
1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
2724

25+
error_code EC;
26+
OwningPtr<ObjectFile> R;
2827
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
2928
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
3029
if (MaxAlignment >= 4)
31-
return new ELFObjectFile<ELFType<support::little, 4, false> >(Object, ec);
30+
R.reset(new ELFObjectFile<ELFType<support::little, 4, false> >(Obj, EC));
3231
else
3332
#endif
3433
if (MaxAlignment >= 2)
35-
return new ELFObjectFile<ELFType<support::little, 2, false> >(Object, ec);
34+
R.reset(new ELFObjectFile<ELFType<support::little, 2, false> >(Obj, EC));
3635
else
3736
llvm_unreachable("Invalid alignment for ELF file!");
3837
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
3938
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
4039
if (MaxAlignment >= 4)
41-
return new ELFObjectFile<ELFType<support::big, 4, false> >(Object, ec);
40+
R.reset(new ELFObjectFile<ELFType<support::big, 4, false> >(Obj, EC));
4241
else
4342
#endif
4443
if (MaxAlignment >= 2)
45-
return new ELFObjectFile<ELFType<support::big, 2, false> >(Object, ec);
44+
R.reset(new ELFObjectFile<ELFType<support::big, 2, false> >(Obj, EC));
4645
else
4746
llvm_unreachable("Invalid alignment for ELF file!");
4847
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
4948
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
5049
if (MaxAlignment >= 8)
51-
return new ELFObjectFile<ELFType<support::big, 8, true> >(Object, ec);
50+
R.reset(new ELFObjectFile<ELFType<support::big, 8, true> >(Obj, EC));
5251
else
5352
#endif
5453
if (MaxAlignment >= 2)
55-
return new ELFObjectFile<ELFType<support::big, 2, true> >(Object, ec);
54+
R.reset(new ELFObjectFile<ELFType<support::big, 2, true> >(Obj, EC));
5655
else
5756
llvm_unreachable("Invalid alignment for ELF file!");
5857
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
5958
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
6059
if (MaxAlignment >= 8)
61-
return new ELFObjectFile<ELFType<support::little, 8, true> >(Object, ec);
60+
R.reset(new ELFObjectFile<ELFType<support::little, 8, true> >(Obj, EC));
6261
else
6362
#endif
6463
if (MaxAlignment >= 2)
65-
return new ELFObjectFile<ELFType<support::little, 2, true> >(Object, ec);
64+
R.reset(new ELFObjectFile<ELFType<support::little, 2, true> >(Obj, EC));
6665
else
6766
llvm_unreachable("Invalid alignment for ELF file!");
6867
}
68+
else
69+
report_fatal_error("Buffer is not an ELF object file!");
6970

70-
report_fatal_error("Buffer is not an ELF object file!");
71+
if (EC)
72+
return EC;
73+
return R.take();
7174
}
7275

7376
} // end namespace llvm

llvm/lib/Object/MachOObjectFile.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -1582,25 +1582,25 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index,
15821582
}
15831583
}
15841584

1585-
ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
1585+
ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
15861586
StringRef Magic = Buffer->getBuffer().slice(0, 4);
1587-
error_code ec;
1588-
OwningPtr<ObjectFile> Ret;
1587+
error_code EC;
1588+
OwningPtr<MachOObjectFile> Ret;
15891589
if (Magic == "\xFE\xED\xFA\xCE")
1590-
Ret.reset(new MachOObjectFile(Buffer, false, false, ec));
1590+
Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
15911591
else if (Magic == "\xCE\xFA\xED\xFE")
1592-
Ret.reset(new MachOObjectFile(Buffer, true, false, ec));
1592+
Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
15931593
else if (Magic == "\xFE\xED\xFA\xCF")
1594-
Ret.reset(new MachOObjectFile(Buffer, false, true, ec));
1594+
Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
15951595
else if (Magic == "\xCF\xFA\xED\xFE")
1596-
Ret.reset(new MachOObjectFile(Buffer, true, true, ec));
1596+
Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
15971597
else {
15981598
delete Buffer;
1599-
return NULL;
1599+
return object_error::parse_failed;
16001600
}
16011601

1602-
if (ec)
1603-
return NULL;
1602+
if (EC)
1603+
return EC;
16041604
return Ret.take();
16051605
}
16061606

llvm/lib/Object/MachOUniversal.cpp

+14-4
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,26 @@ error_code MachOUniversalBinary::ObjectForArch::getAsObjectFile(
8181
Triple::getArchTypeName(MachOObjectFile::getArch(Header.cputype));
8282
MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
8383
ObjectData, ObjectName, false);
84-
if (ObjectFile *Obj = ObjectFile::createMachOObjectFile(ObjBuffer)) {
85-
Result.reset(Obj);
86-
return object_error::success;
87-
}
84+
ErrorOr<ObjectFile *> Obj = ObjectFile::createMachOObjectFile(ObjBuffer);
85+
if (error_code EC = Obj.getError())
86+
return EC;
87+
Result.reset(Obj.get());
88+
return object_error::success;
8889
}
8990
return object_error::parse_failed;
9091
}
9192

9293
void MachOUniversalBinary::anchor() { }
9394

95+
ErrorOr<MachOUniversalBinary *>
96+
MachOUniversalBinary::create(MemoryBuffer *Source) {
97+
error_code EC;
98+
OwningPtr<MachOUniversalBinary> Ret(new MachOUniversalBinary(Source, EC));
99+
if (EC)
100+
return EC;
101+
return Ret.take();
102+
}
103+
94104
MachOUniversalBinary::MachOUniversalBinary(MemoryBuffer *Source,
95105
error_code &ec)
96106
: Binary(Binary::ID_MachOUniversalBinary, Source),

llvm/lib/Object/ObjectFile.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) {
5656
case sys::fs::file_magic::elf_executable:
5757
case sys::fs::file_magic::elf_shared_object:
5858
case sys::fs::file_magic::elf_core:
59-
return createELFObjectFile(Object);
59+
return createELFObjectFile(Object).get();
6060
case sys::fs::file_magic::macho_object:
6161
case sys::fs::file_magic::macho_executable:
6262
case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
@@ -67,11 +67,11 @@ ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) {
6767
case sys::fs::file_magic::macho_bundle:
6868
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
6969
case sys::fs::file_magic::macho_dsym_companion:
70-
return createMachOObjectFile(Object);
70+
return createMachOObjectFile(Object).get();
7171
case sys::fs::file_magic::coff_object:
7272
case sys::fs::file_magic::coff_import_library:
7373
case sys::fs::file_magic::pecoff_executable:
74-
return createCOFFObjectFile(Object);
74+
return createCOFFObjectFile(Object).get();
7575
}
7676
llvm_unreachable("Unexpected Object File Type");
7777
}

llvm/tools/llvm-objdump/MachODump.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
207207
return;
208208
}
209209

210-
OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(
211-
ObjectFile::createMachOObjectFile(Buff.take())));
210+
OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile *>(
211+
ObjectFile::createMachOObjectFile(Buff.take()).get()));
212212

213213
DisassembleInputMachO2(Filename, MachOOF.get());
214214
}
@@ -297,7 +297,7 @@ static void DisassembleInputMachO2(StringRef Filename,
297297
errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
298298
return;
299299
}
300-
DbgObj = ObjectFile::createMachOObjectFile(Buf.take());
300+
DbgObj = ObjectFile::createMachOObjectFile(Buf.take()).get();
301301
}
302302

303303
// Setup the DIContext

0 commit comments

Comments
 (0)