llvm.org GIT mirror llvm / 3d21815
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199770 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
11 changed file(s) with 88 addition(s) and 85 deletion(s). Raw diff Collapse all Expand all
1616 #include "llvm/ADT/StringRef.h"
1717 #include "llvm/Object/Binary.h"
1818 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/ErrorOr.h"
1920 #include "llvm/Support/FileSystem.h"
2021 #include "llvm/Support/MemoryBuffer.h"
2122
162163 };
163164
164165 Archive(MemoryBuffer *source, error_code &ec);
166 static ErrorOr create(MemoryBuffer *Source);
165167
166168 enum Kind {
167169 K_GNU,
1717 #include "llvm/ADT/StringRef.h"
1818 #include "llvm/ADT/Triple.h"
1919 #include "llvm/Object/Binary.h"
20 #include "llvm/Support/ErrorOr.h"
2021 #include "llvm/Support/MachO.h"
2122
2223 namespace llvm {
7677 };
7778
7879 MachOUniversalBinary(MemoryBuffer *Source, error_code &ec);
80 static ErrorOr create(MemoryBuffer *Source);
7981
8082 object_iterator begin_objects() const {
8183 return ObjectForArch(this, 0);
383383 }
384384
385385 public:
386 static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
387 static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
388 static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
386 static ErrorOr createCOFFObjectFile(MemoryBuffer *Object);
387 static ErrorOr createELFObjectFile(MemoryBuffer *Object);
388 static ErrorOr createMachOObjectFile(MemoryBuffer *Object);
389389 };
390390
391391 // Inline function definitions.
191191 return EC;
192192 Result.reset(BinaryOrErr.get());
193193 return object_error::success;
194 }
195
196 ErrorOr Archive::create(MemoryBuffer *Source) {
197 error_code EC;
198 OwningPtr Ret(new Archive(Source, EC));
199 if (EC)
200 return EC;
201 return Ret.take();
194202 }
195203
196204 Archive::Archive(MemoryBuffer *source, error_code &ec)
1818
1919 // Include headers for createBinary.
2020 #include "llvm/Object/Archive.h"
21 #include "llvm/Object/COFF.h"
2221 #include "llvm/Object/MachOUniversal.h"
2322 #include "llvm/Object/ObjectFile.h"
2423
4443 ErrorOr object::createBinary(MemoryBuffer *Source) {
4544 OwningPtr scopedSource(Source);
4645 sys::fs::file_magic type = sys::fs::identify_magic(Source->getBuffer());
47 error_code EC;
4846 switch (type) {
49 case sys::fs::file_magic::archive: {
50 OwningPtr Ret(new Archive(scopedSource.take(), EC));
51 if (EC)
52 return EC;
53 return Ret.take();
54 }
47 case sys::fs::file_magic::archive:
48 return Archive::create(scopedSource.take());
5549 case sys::fs::file_magic::elf_relocatable:
5650 case sys::fs::file_magic::elf_executable:
5751 case sys::fs::file_magic::elf_shared_object:
58 case sys::fs::file_magic::elf_core: {
59 OwningPtr Ret(
60 ObjectFile::createELFObjectFile(scopedSource.take()));
61 if (!Ret)
62 return object_error::invalid_file_type;
63 return Ret.take();
64 }
52 case sys::fs::file_magic::elf_core:
53 return ObjectFile::createELFObjectFile(scopedSource.take());
6554 case sys::fs::file_magic::macho_object:
6655 case sys::fs::file_magic::macho_executable:
6756 case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
7160 case sys::fs::file_magic::macho_dynamic_linker:
7261 case sys::fs::file_magic::macho_bundle:
7362 case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
74 case sys::fs::file_magic::macho_dsym_companion: {
75 OwningPtr Ret(
76 ObjectFile::createMachOObjectFile(scopedSource.take()));
77 if (!Ret)
78 return object_error::invalid_file_type;
79 return Ret.take();
80 }
81 case sys::fs::file_magic::macho_universal_binary: {
82 OwningPtr Ret(new MachOUniversalBinary(scopedSource.take(), EC));
83 if (EC)
84 return EC;
85 return Ret.take();
86 }
63 case sys::fs::file_magic::macho_dsym_companion:
64 return ObjectFile::createMachOObjectFile(scopedSource.take());
65 case sys::fs::file_magic::macho_universal_binary:
66 return MachOUniversalBinary::create(scopedSource.take());
8767 case sys::fs::file_magic::coff_object:
8868 case sys::fs::file_magic::coff_import_library:
89 case sys::fs::file_magic::pecoff_executable: {
90 OwningPtr Ret(
91 ObjectFile::createCOFFObjectFile(scopedSource.take()));
92 if (!Ret)
93 return object_error::invalid_file_type;
94 return Ret.take();
95 }
69 case sys::fs::file_magic::pecoff_executable:
70 return ObjectFile::createCOFFObjectFile(scopedSource.take());
9671 case sys::fs::file_magic::unknown:
9772 case sys::fs::file_magic::bitcode:
9873 case sys::fs::file_magic::windows_resource: {
513513 CurPtr += COFFHeader->SizeOfOptionalHeader;
514514 }
515515
516 if (!COFFHeader->isImportLibrary())
517 if ((EC = getObject(SectionTable, Data, base() + CurPtr,
518 COFFHeader->NumberOfSections * sizeof(coff_section))))
519 return;
516 if (COFFHeader->isImportLibrary())
517 return;
518
519 if ((EC = getObject(SectionTable, Data, base() + CurPtr,
520 COFFHeader->NumberOfSections * sizeof(coff_section))))
521 return;
520522
521523 // Initialize the pointer to the symbol table.
522524 if (COFFHeader->PointerToSymbolTable != 0)
10121014 return object_error::success;
10131015 }
10141016
1015 namespace llvm {
1016 ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
1017 ErrorOr ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
10171018 error_code EC;
1018 return new COFFObjectFile(Object, EC);
1019 }
1020 }
1019 OwningPtr Ret(new COFFObjectFile(Object, EC));
1020 if (EC)
1021 return EC;
1022 return Ret.take();
1023 }
1616 namespace llvm {
1717 using namespace object;
1818
19 // Creates an in-memory object-file by default: createELFObjectFile(Buffer)
20 ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
21 std::pair Ident = getElfArchType(Object);
22 error_code ec;
19 ErrorOr ObjectFile::createELFObjectFile(MemoryBuffer *Obj) {
20 std::pair Ident = getElfArchType(Obj);
21 std::size_t MaxAlignment =
22 1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
2323
24 std::size_t MaxAlignment =
25 1ULL << countTrailingZeros(uintptr_t(Object->getBufferStart()));
26
24 error_code EC;
25 OwningPtr R;
2726 if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
2827 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
2928 if (MaxAlignment >= 4)
30 return new ELFObjectFile >(Object, ec);
29 R.reset(new ELFObjectFile >(Obj, EC));
3130 else
3231 #endif
3332 if (MaxAlignment >= 2)
34 return new ELFObjectFile >(Object, ec);
33 R.reset(new ELFObjectFile >(Obj, EC));
3534 else
3635 llvm_unreachable("Invalid alignment for ELF file!");
3736 else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
3837 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
3938 if (MaxAlignment >= 4)
40 return new ELFObjectFile >(Object, ec);
39 R.reset(new ELFObjectFile >(Obj, EC));
4140 else
4241 #endif
4342 if (MaxAlignment >= 2)
44 return new ELFObjectFile >(Object, ec);
43 R.reset(new ELFObjectFile >(Obj, EC));
4544 else
4645 llvm_unreachable("Invalid alignment for ELF file!");
4746 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
4847 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
4948 if (MaxAlignment >= 8)
50 return new ELFObjectFile >(Object, ec);
49 R.reset(new ELFObjectFile >(Obj, EC));
5150 else
5251 #endif
5352 if (MaxAlignment >= 2)
54 return new ELFObjectFile >(Object, ec);
53 R.reset(new ELFObjectFile >(Obj, EC));
5554 else
5655 llvm_unreachable("Invalid alignment for ELF file!");
5756 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
5857 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
5958 if (MaxAlignment >= 8)
60 return new ELFObjectFile >(Object, ec);
59 R.reset(new ELFObjectFile >(Obj, EC));
6160 else
6261 #endif
6362 if (MaxAlignment >= 2)
64 return new ELFObjectFile >(Object, ec);
63 R.reset(new ELFObjectFile >(Obj, EC));
6564 else
6665 llvm_unreachable("Invalid alignment for ELF file!");
6766 }
67 else
68 report_fatal_error("Buffer is not an ELF object file!");
6869
69 report_fatal_error("Buffer is not an ELF object file!");
70 if (EC)
71 return EC;
72 return R.take();
7073 }
7174
7275 } // end namespace llvm
15811581 }
15821582 }
15831583
1584 ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
1584 ErrorOr ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
15851585 StringRef Magic = Buffer->getBuffer().slice(0, 4);
1586 error_code ec;
1587 OwningPtr Ret;
1586 error_code EC;
1587 OwningPtr Ret;
15881588 if (Magic == "\xFE\xED\xFA\xCE")
1589 Ret.reset(new MachOObjectFile(Buffer, false, false, ec));
1589 Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
15901590 else if (Magic == "\xCE\xFA\xED\xFE")
1591 Ret.reset(new MachOObjectFile(Buffer, true, false, ec));
1591 Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
15921592 else if (Magic == "\xFE\xED\xFA\xCF")
1593 Ret.reset(new MachOObjectFile(Buffer, false, true, ec));
1593 Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
15941594 else if (Magic == "\xCF\xFA\xED\xFE")
1595 Ret.reset(new MachOObjectFile(Buffer, true, true, ec));
1595 Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
15961596 else {
15971597 delete Buffer;
1598 return NULL;
1599 }
1600
1601 if (ec)
1602 return NULL;
1598 return object_error::parse_failed;
1599 }
1600
1601 if (EC)
1602 return EC;
16031603 return Ret.take();
16041604 }
16051605
8080 Triple::getArchTypeName(MachOObjectFile::getArch(Header.cputype));
8181 MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
8282 ObjectData, ObjectName, false);
83 if (ObjectFile *Obj = ObjectFile::createMachOObjectFile(ObjBuffer)) {
84 Result.reset(Obj);
85 return object_error::success;
86 }
83 ErrorOr Obj = ObjectFile::createMachOObjectFile(ObjBuffer);
84 if (error_code EC = Obj.getError())
85 return EC;
86 Result.reset(Obj.get());
87 return object_error::success;
8788 }
8889 return object_error::parse_failed;
8990 }
9091
9192 void MachOUniversalBinary::anchor() { }
93
94 ErrorOr
95 MachOUniversalBinary::create(MemoryBuffer *Source) {
96 error_code EC;
97 OwningPtr Ret(new MachOUniversalBinary(Source, EC));
98 if (EC)
99 return EC;
100 return Ret.take();
101 }
92102
93103 MachOUniversalBinary::MachOUniversalBinary(MemoryBuffer *Source,
94104 error_code &ec)
5555 case sys::fs::file_magic::elf_executable:
5656 case sys::fs::file_magic::elf_shared_object:
5757 case sys::fs::file_magic::elf_core:
58 return createELFObjectFile(Object);
58 return createELFObjectFile(Object).get();
5959 case sys::fs::file_magic::macho_object:
6060 case sys::fs::file_magic::macho_executable:
6161 case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
6666 case sys::fs::file_magic::macho_bundle:
6767 case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
6868 case sys::fs::file_magic::macho_dsym_companion:
69 return createMachOObjectFile(Object);
69 return createMachOObjectFile(Object).get();
7070 case sys::fs::file_magic::coff_object:
7171 case sys::fs::file_magic::coff_import_library:
7272 case sys::fs::file_magic::pecoff_executable:
73 return createCOFFObjectFile(Object);
73 return createCOFFObjectFile(Object).get();
7474 }
7575 llvm_unreachable("Unexpected Object File Type");
7676 }
206206 return;
207207 }
208208
209 OwningPtr MachOOF(static_cast(
210 ObjectFile::createMachOObjectFile(Buff.take())));
209 OwningPtr MachOOF(static_cast(
210 ObjectFile::createMachOObjectFile(Buff.take()).get()));
211211
212212 DisassembleInputMachO2(Filename, MachOOF.get());
213213 }
296296 errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
297297 return;
298298 }
299 DbgObj = ObjectFile::createMachOObjectFile(Buf.take());
299 DbgObj = ObjectFile::createMachOObjectFile(Buf.take()).get();
300300 }
301301
302302 // Setup the DIContext