blob: 855e032417fde77c985db8aff697cf538dd01c90 [file] [log] [blame]
Eugene Zelenko1df42fa2017-04-24 23:21:38 +00001//===- ELFObjectFile.cpp - ELF object file implementation -----------------===//
Michael J. Spencerb60a18d2011-01-20 06:38:47 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Michael J. Spencerb60a18d2011-01-20 06:38:47 +00006//
7//===----------------------------------------------------------------------===//
8//
Eli Benderskyc7d23dd2012-02-12 06:12:10 +00009// Part of the ELFObjectFile class implementation.
Michael J. Spencerb60a18d2011-01-20 06:38:47 +000010//
11//===----------------------------------------------------------------------===//
12
Chandler Carruth6bda14b2017-06-06 11:49:48 +000013#include "llvm/Object/ELFObjectFile.h"
Eugene Zelenko1df42fa2017-04-24 23:21:38 +000014#include "llvm/ADT/Triple.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000015#include "llvm/BinaryFormat/ELF.h"
Joel Galensond36fb482018-08-24 15:21:56 +000016#include "llvm/MC/MCInstrAnalysis.h"
Eugene Zelenko1df42fa2017-04-24 23:21:38 +000017#include "llvm/MC/SubtargetFeature.h"
18#include "llvm/Object/ELF.h"
Eugene Zelenko1df42fa2017-04-24 23:21:38 +000019#include "llvm/Object/ELFTypes.h"
20#include "llvm/Object/Error.h"
Sam Parkerb0de00d2017-01-18 15:52:11 +000021#include "llvm/Support/ARMAttributeParser.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000022#include "llvm/Support/ARMBuildAttributes.h"
Eugene Zelenko1df42fa2017-04-24 23:21:38 +000023#include "llvm/Support/Endian.h"
24#include "llvm/Support/ErrorHandling.h"
Michael J. Spencerbae14ce2013-01-04 20:36:28 +000025#include "llvm/Support/MathExtras.h"
Joel Galensond36fb482018-08-24 15:21:56 +000026#include "llvm/Support/TargetRegistry.h"
Eugene Zelenko1df42fa2017-04-24 23:21:38 +000027#include <algorithm>
28#include <cstddef>
29#include <cstdint>
30#include <memory>
31#include <string>
32#include <system_error>
33#include <utility>
Eli Benderskyc3c80f02012-01-22 09:01:03 +000034
Eugene Zelenko1df42fa2017-04-24 23:21:38 +000035using namespace llvm;
Eli Benderskyc7d23dd2012-02-12 06:12:10 +000036using namespace object;
Eli Benderskyc3c80f02012-01-22 09:01:03 +000037
Sunil Srivastavaae8fe4e2019-03-08 22:00:50 +000038const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = {
39 {"None", "NOTYPE", ELF::STT_NOTYPE},
40 {"Object", "OBJECT", ELF::STT_OBJECT},
41 {"Function", "FUNC", ELF::STT_FUNC},
42 {"Section", "SECTION", ELF::STT_SECTION},
43 {"File", "FILE", ELF::STT_FILE},
44 {"Common", "COMMON", ELF::STT_COMMON},
45 {"TLS", "TLS", ELF::STT_TLS},
Sunil Srivastava27f6f2f2019-08-09 16:54:51 +000046 {"Unknown", "<unknown>: 7", 7},
47 {"Unknown", "<unknown>: 8", 8},
48 {"Unknown", "<unknown>: 9", 9},
49 {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC},
50 {"OS Specific", "<OS specific>: 11", 11},
51 {"OS Specific", "<OS specific>: 12", 12},
52 {"Proc Specific", "<processor specific>: 13", 13},
53 {"Proc Specific", "<processor specific>: 14", 14},
54 {"Proc Specific", "<processor specific>: 15", 15}
55};
Sunil Srivastavaae8fe4e2019-03-08 22:00:50 +000056
Rafael Espindola48af1c22014-08-19 18:44:46 +000057ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
58 : ObjectFile(Type, Source) {}
Rafael Espindolaab737742014-08-17 17:52:10 +000059
Rafael Espindolaef421f92017-10-10 21:21:16 +000060template <class ELFT>
61static Expected<std::unique_ptr<ELFObjectFile<ELFT>>>
62createPtr(MemoryBufferRef Object) {
63 auto Ret = ELFObjectFile<ELFT>::create(Object);
64 if (Error E = Ret.takeError())
Bill Wendlingc55cf4a2020-02-10 07:06:45 -080065 return std::move(E);
Jonas Devlieghere0eaee542019-08-15 15:54:37 +000066 return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
Rafael Espindolaef421f92017-10-10 21:21:16 +000067}
68
Rafael Espindola12db3832017-10-10 20:00:07 +000069Expected<std::unique_ptr<ObjectFile>>
Rafael Espindola48af1c22014-08-19 18:44:46 +000070ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
Rafael Espindolad5a8efe2014-07-05 11:38:52 +000071 std::pair<unsigned char, unsigned char> Ident =
Rafael Espindola48af1c22014-08-19 18:44:46 +000072 getElfArchType(Obj.getBuffer());
Michael J. Spencerbae14ce2013-01-04 20:36:28 +000073 std::size_t MaxAlignment =
Rafael Espindola48af1c22014-08-19 18:44:46 +000074 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
Michael J. Spencerbae14ce2013-01-04 20:36:28 +000075
Rafael Espindolaac729b42015-06-02 12:05:27 +000076 if (MaxAlignment < 2)
Rafael Espindola12db3832017-10-10 20:00:07 +000077 return createError("Insufficient alignment");
Rafael Espindolaac729b42015-06-02 12:05:27 +000078
Rafael Espindolaac729b42015-06-02 12:05:27 +000079 if (Ident.first == ELF::ELFCLASS32) {
80 if (Ident.second == ELF::ELFDATA2LSB)
Rafael Espindolaef421f92017-10-10 21:21:16 +000081 return createPtr<ELF32LE>(Obj);
Rafael Espindolaac729b42015-06-02 12:05:27 +000082 else if (Ident.second == ELF::ELFDATA2MSB)
Rafael Espindolaef421f92017-10-10 21:21:16 +000083 return createPtr<ELF32BE>(Obj);
Michael J. Spencer39678d82013-02-03 10:48:31 +000084 else
Rafael Espindola12db3832017-10-10 20:00:07 +000085 return createError("Invalid ELF data");
Alexey Samsonov49179dd2015-06-04 23:14:43 +000086 } else if (Ident.first == ELF::ELFCLASS64) {
Rafael Espindolaac729b42015-06-02 12:05:27 +000087 if (Ident.second == ELF::ELFDATA2LSB)
Rafael Espindolaef421f92017-10-10 21:21:16 +000088 return createPtr<ELF64LE>(Obj);
Rafael Espindolaac729b42015-06-02 12:05:27 +000089 else if (Ident.second == ELF::ELFDATA2MSB)
Rafael Espindolaef421f92017-10-10 21:21:16 +000090 return createPtr<ELF64BE>(Obj);
Michael J. Spencerbae14ce2013-01-04 20:36:28 +000091 else
Rafael Espindola12db3832017-10-10 20:00:07 +000092 return createError("Invalid ELF data");
Eli Benderskyc7d23dd2012-02-12 06:12:10 +000093 }
Rafael Espindolaef421f92017-10-10 21:21:16 +000094 return createError("Invalid ELF class");
Eli Benderskyc7d23dd2012-02-12 06:12:10 +000095}
Michael J. Spencerb60a18d2011-01-20 06:38:47 +000096
Sam Parkerb0de00d2017-01-18 15:52:11 +000097SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {
98 SubtargetFeatures Features;
Rafael Espindolad5f76ad2018-01-29 18:27:30 +000099 unsigned PlatformFlags = getPlatformFlags();
Sam Parkerb0de00d2017-01-18 15:52:11 +0000100
101 switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
102 case ELF::EF_MIPS_ARCH_1:
103 break;
104 case ELF::EF_MIPS_ARCH_2:
105 Features.AddFeature("mips2");
106 break;
107 case ELF::EF_MIPS_ARCH_3:
108 Features.AddFeature("mips3");
109 break;
110 case ELF::EF_MIPS_ARCH_4:
111 Features.AddFeature("mips4");
112 break;
113 case ELF::EF_MIPS_ARCH_5:
114 Features.AddFeature("mips5");
115 break;
116 case ELF::EF_MIPS_ARCH_32:
117 Features.AddFeature("mips32");
118 break;
119 case ELF::EF_MIPS_ARCH_64:
120 Features.AddFeature("mips64");
121 break;
122 case ELF::EF_MIPS_ARCH_32R2:
123 Features.AddFeature("mips32r2");
124 break;
125 case ELF::EF_MIPS_ARCH_64R2:
126 Features.AddFeature("mips64r2");
127 break;
128 case ELF::EF_MIPS_ARCH_32R6:
129 Features.AddFeature("mips32r6");
130 break;
131 case ELF::EF_MIPS_ARCH_64R6:
132 Features.AddFeature("mips64r6");
133 break;
134 default:
135 llvm_unreachable("Unknown EF_MIPS_ARCH value");
136 }
137
138 switch (PlatformFlags & ELF::EF_MIPS_MACH) {
139 case ELF::EF_MIPS_MACH_NONE:
140 // No feature associated with this value.
141 break;
142 case ELF::EF_MIPS_MACH_OCTEON:
143 Features.AddFeature("cnmips");
144 break;
145 default:
146 llvm_unreachable("Unknown EF_MIPS_ARCH value");
147 }
148
149 if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
150 Features.AddFeature("mips16");
151 if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
152 Features.AddFeature("micromips");
153
154 return Features;
155}
156
157SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
158 SubtargetFeatures Features;
159 ARMAttributeParser Attributes;
Fangrui Song791efb12020-02-21 11:32:33 -0800160 if (Error E = getBuildAttributes(Attributes)) {
161 consumeError(std::move(E));
Sam Parkerb0de00d2017-01-18 15:52:11 +0000162 return SubtargetFeatures();
Fangrui Song791efb12020-02-21 11:32:33 -0800163 }
Sam Parkerb0de00d2017-01-18 15:52:11 +0000164
165 // both ARMv7-M and R have to support thumb hardware div
166 bool isV7 = false;
167 if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
168 isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
169 == ARMBuildAttrs::v7;
170
171 if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) {
172 switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) {
173 case ARMBuildAttrs::ApplicationProfile:
174 Features.AddFeature("aclass");
175 break;
176 case ARMBuildAttrs::RealTimeProfile:
177 Features.AddFeature("rclass");
178 if (isV7)
179 Features.AddFeature("hwdiv");
180 break;
181 case ARMBuildAttrs::MicroControllerProfile:
182 Features.AddFeature("mclass");
183 if (isV7)
184 Features.AddFeature("hwdiv");
185 break;
186 }
187 }
188
189 if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
190 switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
191 default:
192 break;
193 case ARMBuildAttrs::Not_Allowed:
194 Features.AddFeature("thumb", false);
195 Features.AddFeature("thumb2", false);
196 break;
197 case ARMBuildAttrs::AllowThumb32:
198 Features.AddFeature("thumb2");
199 break;
200 }
201 }
202
203 if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
204 switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
205 default:
206 break;
207 case ARMBuildAttrs::Not_Allowed:
Eli Friedmanddf5e862019-09-17 21:42:38 +0000208 Features.AddFeature("vfp2sp", false);
Simon Tatham760df472019-05-28 16:13:20 +0000209 Features.AddFeature("vfp3d16sp", false);
210 Features.AddFeature("vfp4d16sp", false);
Sam Parkerb0de00d2017-01-18 15:52:11 +0000211 break;
212 case ARMBuildAttrs::AllowFPv2:
213 Features.AddFeature("vfp2");
214 break;
215 case ARMBuildAttrs::AllowFPv3A:
216 case ARMBuildAttrs::AllowFPv3B:
217 Features.AddFeature("vfp3");
218 break;
219 case ARMBuildAttrs::AllowFPv4A:
220 case ARMBuildAttrs::AllowFPv4B:
221 Features.AddFeature("vfp4");
222 break;
223 }
224 }
225
226 if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) {
227 switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) {
228 default:
229 break;
230 case ARMBuildAttrs::Not_Allowed:
231 Features.AddFeature("neon", false);
232 Features.AddFeature("fp16", false);
233 break;
234 case ARMBuildAttrs::AllowNeon:
235 Features.AddFeature("neon");
236 break;
237 case ARMBuildAttrs::AllowNeon2:
238 Features.AddFeature("neon");
239 Features.AddFeature("fp16");
240 break;
241 }
242 }
243
Sjoerd Meijer930dee22019-05-30 12:57:04 +0000244 if (Attributes.hasAttribute(ARMBuildAttrs::MVE_arch)) {
245 switch(Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch)) {
246 default:
247 break;
248 case ARMBuildAttrs::Not_Allowed:
249 Features.AddFeature("mve", false);
250 Features.AddFeature("mve.fp", false);
251 break;
252 case ARMBuildAttrs::AllowMVEInteger:
253 Features.AddFeature("mve.fp", false);
254 Features.AddFeature("mve");
255 break;
256 case ARMBuildAttrs::AllowMVEIntegerAndFloat:
257 Features.AddFeature("mve.fp");
258 break;
259 }
260 }
261
Sam Parkerb0de00d2017-01-18 15:52:11 +0000262 if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
263 switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
264 default:
265 break;
266 case ARMBuildAttrs::DisallowDIV:
267 Features.AddFeature("hwdiv", false);
268 Features.AddFeature("hwdiv-arm", false);
269 break;
270 case ARMBuildAttrs::AllowDIVExt:
271 Features.AddFeature("hwdiv");
272 Features.AddFeature("hwdiv-arm");
273 break;
274 }
275 }
276
277 return Features;
278}
279
Shiva Chen53489ad2018-02-02 06:01:02 +0000280SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const {
281 SubtargetFeatures Features;
282 unsigned PlatformFlags = getPlatformFlags();
283
284 if (PlatformFlags & ELF::EF_RISCV_RVC) {
285 Features.AddFeature("c");
286 }
287
288 return Features;
289}
290
Daniel Sanders1d148642016-06-16 09:17:03 +0000291SubtargetFeatures ELFObjectFileBase::getFeatures() const {
292 switch (getEMachine()) {
Sam Parkerb0de00d2017-01-18 15:52:11 +0000293 case ELF::EM_MIPS:
294 return getMIPSFeatures();
295 case ELF::EM_ARM:
296 return getARMFeatures();
Shiva Chen53489ad2018-02-02 06:01:02 +0000297 case ELF::EM_RISCV:
298 return getRISCVFeatures();
Daniel Sanders1d148642016-06-16 09:17:03 +0000299 default:
300 return SubtargetFeatures();
301 }
302}
303
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000304// FIXME Encode from a tablegen description or target parser.
305void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
306 if (TheTriple.getSubArch() != Triple::NoSubArch)
307 return;
308
309 ARMAttributeParser Attributes;
Fangrui Song791efb12020-02-21 11:32:33 -0800310 if (Error E = getBuildAttributes(Attributes)) {
311 // TODO Propagate Error.
312 consumeError(std::move(E));
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000313 return;
Fangrui Song791efb12020-02-21 11:32:33 -0800314 }
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000315
316 std::string Triple;
317 // Default to ARM, but use the triple if it's been set.
Florian Hahna5ba4ee2017-08-12 17:40:18 +0000318 if (TheTriple.isThumb())
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000319 Triple = "thumb";
320 else
321 Triple = "arm";
322
323 if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
324 switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
325 case ARMBuildAttrs::v4:
326 Triple += "v4";
327 break;
328 case ARMBuildAttrs::v4T:
329 Triple += "v4t";
330 break;
331 case ARMBuildAttrs::v5T:
332 Triple += "v5t";
333 break;
334 case ARMBuildAttrs::v5TE:
335 Triple += "v5te";
336 break;
337 case ARMBuildAttrs::v5TEJ:
338 Triple += "v5tej";
339 break;
340 case ARMBuildAttrs::v6:
341 Triple += "v6";
342 break;
343 case ARMBuildAttrs::v6KZ:
344 Triple += "v6kz";
345 break;
346 case ARMBuildAttrs::v6T2:
347 Triple += "v6t2";
348 break;
349 case ARMBuildAttrs::v6K:
350 Triple += "v6k";
351 break;
352 case ARMBuildAttrs::v7:
353 Triple += "v7";
354 break;
355 case ARMBuildAttrs::v6_M:
356 Triple += "v6m";
357 break;
358 case ARMBuildAttrs::v6S_M:
359 Triple += "v6sm";
360 break;
361 case ARMBuildAttrs::v7E_M:
362 Triple += "v7em";
363 break;
Yi Kongb9d87b92019-08-28 06:37:22 +0000364 case ARMBuildAttrs::v8_A:
365 Triple += "v8a";
366 break;
367 case ARMBuildAttrs::v8_R:
368 Triple += "v8r";
369 break;
370 case ARMBuildAttrs::v8_M_Base:
371 Triple += "v8m.base";
372 break;
373 case ARMBuildAttrs::v8_M_Main:
374 Triple += "v8m.main";
375 break;
376 case ARMBuildAttrs::v8_1_M_Main:
377 Triple += "v8.1m.main";
378 break;
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000379 }
380 }
381 if (!isLittleEndian())
382 Triple += "eb";
383
384 TheTriple.setArchName(Triple);
385}
Joel Galensond36fb482018-08-24 15:21:56 +0000386
387std::vector<std::pair<DataRefImpl, uint64_t>>
388ELFObjectFileBase::getPltAddresses() const {
389 std::string Err;
390 const auto Triple = makeTriple();
391 const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err);
392 if (!T)
393 return {};
394 uint64_t JumpSlotReloc = 0;
395 switch (Triple.getArch()) {
396 case Triple::x86:
397 JumpSlotReloc = ELF::R_386_JUMP_SLOT;
398 break;
399 case Triple::x86_64:
400 JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;
401 break;
402 case Triple::aarch64:
403 JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
404 break;
405 default:
406 return {};
407 }
Vitaly Buka96cbeff2018-08-24 21:03:35 +0000408 std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo());
Joel Galenson90f976a2018-08-24 19:40:35 +0000409 std::unique_ptr<const MCInstrAnalysis> MIA(
Vitaly Buka96cbeff2018-08-24 21:03:35 +0000410 T->createMCInstrAnalysis(MII.get()));
Joel Galensond36fb482018-08-24 15:21:56 +0000411 if (!MIA)
412 return {};
413 Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None;
414 for (const SectionRef &Section : sections()) {
George Rimarbcc00e12019-08-14 11:10:11 +0000415 Expected<StringRef> NameOrErr = Section.getName();
416 if (!NameOrErr) {
417 consumeError(NameOrErr.takeError());
Joel Galensond36fb482018-08-24 15:21:56 +0000418 continue;
George Rimarbcc00e12019-08-14 11:10:11 +0000419 }
420 StringRef Name = *NameOrErr;
421
Joel Galensond36fb482018-08-24 15:21:56 +0000422 if (Name == ".plt")
423 Plt = Section;
424 else if (Name == ".rela.plt" || Name == ".rel.plt")
425 RelaPlt = Section;
426 else if (Name == ".got.plt")
427 GotPlt = Section;
428 }
429 if (!Plt || !RelaPlt || !GotPlt)
430 return {};
Fangrui Songe1833402019-05-16 13:24:04 +0000431 Expected<StringRef> PltContents = Plt->getContents();
432 if (!PltContents) {
433 consumeError(PltContents.takeError());
Joel Galensond36fb482018-08-24 15:21:56 +0000434 return {};
Fangrui Songe1833402019-05-16 13:24:04 +0000435 }
436 auto PltEntries = MIA->findPltEntries(Plt->getAddress(),
437 arrayRefFromStringRef(*PltContents),
Joel Galensond36fb482018-08-24 15:21:56 +0000438 GotPlt->getAddress(), Triple);
439 // Build a map from GOT entry virtual address to PLT entry virtual address.
440 DenseMap<uint64_t, uint64_t> GotToPlt;
441 for (const auto &Entry : PltEntries)
442 GotToPlt.insert(std::make_pair(Entry.second, Entry.first));
443 // Find the relocations in the dynamic relocation table that point to
444 // locations in the GOT for which we know the corresponding PLT entry.
445 std::vector<std::pair<DataRefImpl, uint64_t>> Result;
446 for (const auto &Relocation : RelaPlt->relocations()) {
447 if (Relocation.getType() != JumpSlotReloc)
448 continue;
449 auto PltEntryIter = GotToPlt.find(Relocation.getOffset());
450 if (PltEntryIter != GotToPlt.end())
451 Result.push_back(std::make_pair(
452 Relocation.getSymbol()->getRawDataRefImpl(), PltEntryIter->second));
453 }
454 return Result;
455}