blob: cf63b89adc122a516d69a8adc37f368b8b027404 [file] [log] [blame]
Eugene Zelenko86bfc782017-04-19 23:02:10 +00001//===- ObjectFile.cpp - File format independent object file ---------------===//
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a file format independent ObjectFile class.
11//
12//===----------------------------------------------------------------------===//
13
Chandler Carruthe3e43d92017-06-06 11:49:48 +000014#include "llvm/Object/ObjectFile.h"
Eugene Zelenko86bfc782017-04-19 23:02:10 +000015#include "llvm/ADT/StringRef.h"
Zachary Turner19ca2b02017-06-07 03:48:56 +000016#include "llvm/BinaryFormat/Magic.h"
Eugene Zelenko86bfc782017-04-19 23:02:10 +000017#include "llvm/Object/Binary.h"
Rafael Espindola79002da2014-07-31 03:12:45 +000018#include "llvm/Object/COFF.h"
Eugene Zelenko86bfc782017-04-19 23:02:10 +000019#include "llvm/Object/Error.h"
Rafael Espindola79002da2014-07-31 03:12:45 +000020#include "llvm/Object/MachO.h"
Derek Schuff7a578c92016-11-30 16:49:11 +000021#include "llvm/Object/Wasm.h"
Eugene Zelenko86bfc782017-04-19 23:02:10 +000022#include "llvm/Support/Error.h"
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +000023#include "llvm/Support/ErrorHandling.h"
Eugene Zelenko86bfc782017-04-19 23:02:10 +000024#include "llvm/Support/ErrorOr.h"
Rafael Espindolad27a9782013-06-11 15:19:04 +000025#include "llvm/Support/FileSystem.h"
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +000026#include "llvm/Support/MemoryBuffer.h"
Aaron Ballman100aba22014-02-21 20:42:18 +000027#include "llvm/Support/raw_ostream.h"
Eugene Zelenko86bfc782017-04-19 23:02:10 +000028#include <algorithm>
29#include <cstdint>
30#include <memory>
Rafael Espindolad5132f92014-06-12 17:38:55 +000031#include <system_error>
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +000032
Michael J. Spencer88af6b92010-11-16 01:06:51 +000033using namespace llvm;
34using namespace object;
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +000035
Eugene Zelenko86bfc782017-04-19 23:02:10 +000036void ObjectFile::anchor() {}
David Blaikie2d24e2a2011-12-20 02:50:00 +000037
Rafael Espindola548f2b62014-08-19 18:44:46 +000038ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source)
39 : SymbolicFile(Type, Source) {}
Rafael Espindola91f86b72014-02-21 20:10:59 +000040
Rafael Espindolad2313062015-06-30 20:18:49 +000041bool SectionRef::containsSymbol(SymbolRef S) const {
Kevin Enderbya486dca2016-05-02 20:28:12 +000042 Expected<section_iterator> SymSec = S.getSection();
43 if (!SymSec) {
44 // TODO: Actually report errors helpfully.
45 consumeError(SymSec.takeError());
Rafael Espindolad2313062015-06-30 20:18:49 +000046 return false;
Kevin Enderbya486dca2016-05-02 20:28:12 +000047 }
Rafael Espindolae84d8c12015-08-07 23:27:14 +000048 return *this == **SymSec;
Rafael Espindolad2313062015-06-30 20:18:49 +000049}
50
Rafael Espindola7b7c81c2015-07-07 17:12:59 +000051uint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const {
52 uint32_t Flags = getSymbolFlags(Ref);
53 if (Flags & SymbolRef::SF_Undefined)
54 return 0;
55 if (Flags & SymbolRef::SF_Common)
56 return getCommonSymbolSize(Ref);
57 return getSymbolValueImpl(Ref);
58}
59
Rafael Espindola4e2b9222014-06-13 02:24:39 +000060std::error_code ObjectFile::printSymbolName(raw_ostream &OS,
61 DataRefImpl Symb) const {
Kevin Enderby813e0cf2016-04-20 21:24:34 +000062 Expected<StringRef> Name = getSymbolName(Symb);
63 if (!Name)
64 return errorToErrorCode(Name.takeError());
Rafael Espindola8a806412015-07-02 20:55:21 +000065 OS << *Name;
Rui Ueyamaeae46732015-06-09 15:20:42 +000066 return std::error_code();
Rafael Espindola91f86b72014-02-21 20:10:59 +000067}
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +000068
Rafael Espindola64afb832015-05-31 23:52:50 +000069uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; }
Rafael Espindola59a0e792013-04-29 22:24:22 +000070
Steven Wub9de1972016-02-29 19:40:10 +000071bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const {
72 StringRef SectName;
73 if (!getSectionName(Sec, SectName))
74 return SectName == ".llvmbc";
75 return false;
76}
77
Jonas Devlieghereac9a5002017-09-26 14:22:35 +000078bool ObjectFile::isSectionStripped(DataRefImpl Sec) const { return false; }
79
Jordan Rupprecht91c68852018-12-13 19:40:12 +000080bool ObjectFile::isBerkeleyText(DataRefImpl Sec) const {
81 return isSectionText(Sec);
82}
83
84bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {
85 return isSectionData(Sec);
86}
87
Rafael Espindola7486d922013-05-30 03:05:14 +000088section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
89 return section_iterator(SectionRef(Sec, this));
90}
91
Vlad Tsyrklevichb261c462017-09-19 02:22:48 +000092Triple ObjectFile::makeTriple() const {
93 Triple TheTriple;
94 auto Arch = getArch();
95 TheTriple.setArch(Triple::ArchType(Arch));
96
97 // For ARM targets, try to use the build attributes to build determine
98 // the build target. Target features are also added, but later during
99 // disassembly.
100 if (Arch == Triple::arm || Arch == Triple::armeb)
101 setARMSubArch(TheTriple);
102
103 // TheTriple defaults to ELF, and COFF doesn't have an environment:
104 // the best we can do here is indicate that it is mach-o.
105 if (isMachO())
106 TheTriple.setObjectFormat(Triple::MachO);
107
108 if (isCOFF()) {
109 const auto COFFObj = dyn_cast<COFFObjectFile>(this);
110 if (COFFObj->getArch() == Triple::thumb)
111 TheTriple.setTriple("thumbv7-windows");
112 }
113
114 return TheTriple;
115}
116
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +0000117Expected<std::unique_ptr<ObjectFile>>
Zachary Turner19ca2b02017-06-07 03:48:56 +0000118ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type) {
Rafael Espindola548f2b62014-08-19 18:44:46 +0000119 StringRef Data = Object.getBuffer();
Zachary Turner19ca2b02017-06-07 03:48:56 +0000120 if (Type == file_magic::unknown)
121 Type = identify_magic(Data);
Rafael Espindola825fc312014-01-22 00:14:49 +0000122
Rafael Espindolad27a9782013-06-11 15:19:04 +0000123 switch (Type) {
Zachary Turner19ca2b02017-06-07 03:48:56 +0000124 case file_magic::unknown:
125 case file_magic::bitcode:
126 case file_magic::coff_cl_gl_object:
127 case file_magic::archive:
128 case file_magic::macho_universal_binary:
129 case file_magic::windows_resource:
Zachary Turnera896ada2018-03-07 18:58:33 +0000130 case file_magic::pdb:
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +0000131 return errorCodeToError(object_error::invalid_file_type);
Zachary Turner19ca2b02017-06-07 03:48:56 +0000132 case file_magic::elf:
133 case file_magic::elf_relocatable:
134 case file_magic::elf_executable:
135 case file_magic::elf_shared_object:
136 case file_magic::elf_core:
Rafael Espindolae2d20cb2017-10-10 20:00:07 +0000137 return createELFObjectFile(Object);
Zachary Turner19ca2b02017-06-07 03:48:56 +0000138 case file_magic::macho_object:
139 case file_magic::macho_executable:
140 case file_magic::macho_fixed_virtual_memory_shared_lib:
141 case file_magic::macho_core:
142 case file_magic::macho_preload_executable:
143 case file_magic::macho_dynamically_linked_shared_lib:
144 case file_magic::macho_dynamic_linker:
145 case file_magic::macho_bundle:
146 case file_magic::macho_dynamically_linked_shared_lib_stub:
147 case file_magic::macho_dsym_companion:
148 case file_magic::macho_kext_bundle:
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +0000149 return createMachOObjectFile(Object);
Zachary Turner19ca2b02017-06-07 03:48:56 +0000150 case file_magic::coff_object:
151 case file_magic::coff_import_library:
152 case file_magic::pecoff_executable:
Rafael Espindolae2d20cb2017-10-10 20:00:07 +0000153 return createCOFFObjectFile(Object);
Zachary Turner19ca2b02017-06-07 03:48:56 +0000154 case file_magic::wasm_object:
Derek Schuff7a578c92016-11-30 16:49:11 +0000155 return createWasmObjectFile(Object);
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +0000156 }
Rafael Espindolad27a9782013-06-11 15:19:04 +0000157 llvm_unreachable("Unexpected Object File Type");
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +0000158}
159
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +0000160Expected<OwningBinary<ObjectFile>>
Rafael Espindola79002da2014-07-31 03:12:45 +0000161ObjectFile::createObjectFile(StringRef ObjectPath) {
Rafael Espindola7cba2a92014-07-06 17:43:13 +0000162 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
163 MemoryBuffer::getFile(ObjectPath);
164 if (std::error_code EC = FileOrErr.getError())
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +0000165 return errorCodeToError(EC);
Rafael Espindola548f2b62014-08-19 18:44:46 +0000166 std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get());
167
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +0000168 Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
Rafael Espindola548f2b62014-08-19 18:44:46 +0000169 createObjectFile(Buffer->getMemBufferRef());
Justin Bognerb3c2bab2016-10-18 05:17:23 +0000170 if (Error Err = ObjOrErr.takeError())
171 return std::move(Err);
Rafael Espindola548f2b62014-08-19 18:44:46 +0000172 std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
173
174 return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer));
Michael J. Spencer68b3f0c2010-11-15 03:21:41 +0000175}