1//===- ObjectFile.cpp - File format independent object file ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines a file format independent ObjectFile class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Object/ObjectFile.h"
14#include "llvm/Object/COFF.h"
15#include "llvm/Support/Format.h"
16#include "llvm/Support/raw_ostream.h"
17
18using namespace llvm;
19using namespace object;
20
21raw_ostream &object::operator<<(raw_ostream &OS, const SectionedAddress &Addr) {
22 OS << "SectionedAddress{" << format_hex(N: Addr.Address, Width: 10);
23 if (Addr.SectionIndex != SectionedAddress::UndefSection)
24 OS << ", " << Addr.SectionIndex;
25 return OS << "}";
26}
27
28void ObjectFile::anchor() {}
29
30ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source)
31 : SymbolicFile(Type, Source) {}
32
33bool SectionRef::containsSymbol(SymbolRef S) const {
34 Expected<section_iterator> SymSec = S.getSection();
35 if (!SymSec) {
36 // TODO: Actually report errors helpfully.
37 consumeError(Err: SymSec.takeError());
38 return false;
39 }
40 return *this == **SymSec;
41}
42
43Expected<uint64_t> ObjectFile::getSymbolValue(DataRefImpl Ref) const {
44 uint32_t Flags;
45 if (Error E = getSymbolFlags(Symb: Ref).moveInto(Value&: Flags))
46 // TODO: Test this error.
47 return std::move(E);
48
49 if (Flags & SymbolRef::SF_Undefined)
50 return 0;
51 if (Flags & SymbolRef::SF_Common)
52 return getCommonSymbolSize(Symb: Ref);
53 return getSymbolValueImpl(Symb: Ref);
54}
55
56Error ObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const {
57 Expected<StringRef> Name = getSymbolName(Symb);
58 if (!Name)
59 return Name.takeError();
60 OS << *Name;
61 return Error::success();
62}
63
64uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; }
65
66bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const {
67 Expected<StringRef> NameOrErr = getSectionName(Sec);
68 if (NameOrErr)
69 return *NameOrErr == ".llvm.lto";
70 consumeError(Err: NameOrErr.takeError());
71 return false;
72}
73
74bool ObjectFile::isSectionStripped(DataRefImpl Sec) const { return false; }
75
76bool ObjectFile::isBerkeleyText(DataRefImpl Sec) const {
77 return isSectionText(Sec);
78}
79
80bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {
81 return isSectionData(Sec);
82}
83
84bool ObjectFile::isDebugSection(DataRefImpl Sec) const { return false; }
85
86bool ObjectFile::hasDebugInfo() const {
87 return any_of(Range: sections(),
88 P: [](SectionRef Sec) { return Sec.isDebugSection(); });
89}
90
91Expected<section_iterator>
92ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
93 return section_iterator(SectionRef(Sec, this));
94}
95
96Triple ObjectFile::makeTriple() const {
97 Triple TheTriple;
98 auto Arch = getArch();
99 TheTriple.setArch(Kind: Triple::ArchType(Arch));
100
101 auto OS = getOS();
102 if (OS != Triple::UnknownOS)
103 TheTriple.setOS(OS);
104
105 // For ARM targets, try to use the build attributes to build determine
106 // the build target. Target features are also added, but later during
107 // disassembly.
108 if (Arch == Triple::arm || Arch == Triple::armeb)
109 setARMSubArch(TheTriple);
110
111 // TheTriple defaults to ELF, and COFF doesn't have an environment:
112 // something we can do here is indicate that it is mach-o.
113 if (isMachO()) {
114 TheTriple.setObjectFormat(Triple::MachO);
115 } else if (isCOFF()) {
116 const auto COFFObj = cast<COFFObjectFile>(Val: this);
117 if (COFFObj->getArch() == Triple::thumb)
118 TheTriple.setTriple("thumbv7-windows");
119 } else if (isXCOFF()) {
120 // XCOFF implies AIX.
121 TheTriple.setOS(Triple::AIX);
122 TheTriple.setObjectFormat(Triple::XCOFF);
123 } else if (isGOFF()) {
124 TheTriple.setOS(Triple::ZOS);
125 TheTriple.setObjectFormat(Triple::GOFF);
126 } else if (TheTriple.isAMDGPU()) {
127 TheTriple.setVendor(Triple::AMD);
128 } else if (TheTriple.isNVPTX()) {
129 TheTriple.setVendor(Triple::NVIDIA);
130 }
131
132 return TheTriple;
133}
134
135bool ObjectFile::isReflectionSectionStrippable(
136 llvm::binaryformat::Swift5ReflectionSectionKind ReflectionSectionKind)
137 const {
138 using llvm::binaryformat::Swift5ReflectionSectionKind;
139 return ReflectionSectionKind == Swift5ReflectionSectionKind::fieldmd ||
140 ReflectionSectionKind == Swift5ReflectionSectionKind::reflstr ||
141 ReflectionSectionKind == Swift5ReflectionSectionKind::assocty;
142}
143