comparison lib/Object/ELFObjectFile.cpp @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
comparison
equal deleted inserted replaced
146:3fc4d5c3e21e 148:63bd29f05246
1 //===- ELFObjectFile.cpp - ELF object file implementation -----------------===// 1 //===- ELFObjectFile.cpp - ELF object file implementation -----------------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // 4 // See https://llvm.org/LICENSE.txt for license information.
5 // This file is distributed under the University of Illinois Open Source 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 // License. See LICENSE.TXT for details.
7 // 6 //
8 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
9 // 8 //
10 // Part of the ELFObjectFile class implementation. 9 // Part of the ELFObjectFile class implementation.
11 // 10 //
12 //===----------------------------------------------------------------------===// 11 //===----------------------------------------------------------------------===//
13 12
14 #include "llvm/Object/ELFObjectFile.h" 13 #include "llvm/Object/ELFObjectFile.h"
15 #include "llvm/ADT/Triple.h" 14 #include "llvm/ADT/Triple.h"
16 #include "llvm/BinaryFormat/ELF.h" 15 #include "llvm/BinaryFormat/ELF.h"
16 #include "llvm/MC/MCInstrAnalysis.h"
17 #include "llvm/MC/SubtargetFeature.h" 17 #include "llvm/MC/SubtargetFeature.h"
18 #include "llvm/Object/ELF.h" 18 #include "llvm/Object/ELF.h"
19 #include "llvm/Object/ELFTypes.h" 19 #include "llvm/Object/ELFTypes.h"
20 #include "llvm/Object/Error.h" 20 #include "llvm/Object/Error.h"
21 #include "llvm/Support/ARMAttributeParser.h" 21 #include "llvm/Support/ARMAttributeParser.h"
22 #include "llvm/Support/ARMBuildAttributes.h" 22 #include "llvm/Support/ARMBuildAttributes.h"
23 #include "llvm/Support/Endian.h" 23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/MathExtras.h" 25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/Support/TargetRegistry.h"
26 #include <algorithm> 27 #include <algorithm>
27 #include <cstddef> 28 #include <cstddef>
28 #include <cstdint> 29 #include <cstdint>
29 #include <memory> 30 #include <memory>
30 #include <string> 31 #include <string>
31 #include <system_error> 32 #include <system_error>
32 #include <utility> 33 #include <utility>
33 34
34 using namespace llvm; 35 using namespace llvm;
35 using namespace object; 36 using namespace object;
37
38 const 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},
46 {"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 };
36 56
37 ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) 57 ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
38 : ObjectFile(Type, Source) {} 58 : ObjectFile(Type, Source) {}
39 59
40 template <class ELFT> 60 template <class ELFT>
135 } 155 }
136 156
137 SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { 157 SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
138 SubtargetFeatures Features; 158 SubtargetFeatures Features;
139 ARMAttributeParser Attributes; 159 ARMAttributeParser Attributes;
140 std::error_code EC = getBuildAttributes(Attributes); 160 if (Error E = getBuildAttributes(Attributes))
141 if (EC)
142 return SubtargetFeatures(); 161 return SubtargetFeatures();
143 162
144 // both ARMv7-M and R have to support thumb hardware div 163 // both ARMv7-M and R have to support thumb hardware div
145 bool isV7 = false; 164 bool isV7 = false;
146 if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) 165 if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
182 if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) { 201 if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
183 switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) { 202 switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
184 default: 203 default:
185 break; 204 break;
186 case ARMBuildAttrs::Not_Allowed: 205 case ARMBuildAttrs::Not_Allowed:
187 Features.AddFeature("vfp2", false); 206 Features.AddFeature("vfp2d16sp", false);
188 Features.AddFeature("vfp3", false); 207 Features.AddFeature("vfp3d16sp", false);
189 Features.AddFeature("vfp4", false); 208 Features.AddFeature("vfp4d16sp", false);
190 break; 209 break;
191 case ARMBuildAttrs::AllowFPv2: 210 case ARMBuildAttrs::AllowFPv2:
192 Features.AddFeature("vfp2"); 211 Features.AddFeature("vfp2");
193 break; 212 break;
194 case ARMBuildAttrs::AllowFPv3A: 213 case ARMBuildAttrs::AllowFPv3A:
214 Features.AddFeature("neon"); 233 Features.AddFeature("neon");
215 break; 234 break;
216 case ARMBuildAttrs::AllowNeon2: 235 case ARMBuildAttrs::AllowNeon2:
217 Features.AddFeature("neon"); 236 Features.AddFeature("neon");
218 Features.AddFeature("fp16"); 237 Features.AddFeature("fp16");
238 break;
239 }
240 }
241
242 if (Attributes.hasAttribute(ARMBuildAttrs::MVE_arch)) {
243 switch(Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch)) {
244 default:
245 break;
246 case ARMBuildAttrs::Not_Allowed:
247 Features.AddFeature("mve", false);
248 Features.AddFeature("mve.fp", false);
249 break;
250 case ARMBuildAttrs::AllowMVEInteger:
251 Features.AddFeature("mve.fp", false);
252 Features.AddFeature("mve");
253 break;
254 case ARMBuildAttrs::AllowMVEIntegerAndFloat:
255 Features.AddFeature("mve.fp");
219 break; 256 break;
220 } 257 }
221 } 258 }
222 259
223 if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) { 260 if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
266 void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { 303 void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
267 if (TheTriple.getSubArch() != Triple::NoSubArch) 304 if (TheTriple.getSubArch() != Triple::NoSubArch)
268 return; 305 return;
269 306
270 ARMAttributeParser Attributes; 307 ARMAttributeParser Attributes;
271 std::error_code EC = getBuildAttributes(Attributes); 308 if (Error E = getBuildAttributes(Attributes))
272 if (EC)
273 return; 309 return;
274 310
275 std::string Triple; 311 std::string Triple;
276 // Default to ARM, but use the triple if it's been set. 312 // Default to ARM, but use the triple if it's been set.
277 if (TheTriple.isThumb()) 313 if (TheTriple.isThumb())
325 if (!isLittleEndian()) 361 if (!isLittleEndian())
326 Triple += "eb"; 362 Triple += "eb";
327 363
328 TheTriple.setArchName(Triple); 364 TheTriple.setArchName(Triple);
329 } 365 }
366
367 std::vector<std::pair<DataRefImpl, uint64_t>>
368 ELFObjectFileBase::getPltAddresses() const {
369 std::string Err;
370 const auto Triple = makeTriple();
371 const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err);
372 if (!T)
373 return {};
374 uint64_t JumpSlotReloc = 0;
375 switch (Triple.getArch()) {
376 case Triple::x86:
377 JumpSlotReloc = ELF::R_386_JUMP_SLOT;
378 break;
379 case Triple::x86_64:
380 JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;
381 break;
382 case Triple::aarch64:
383 JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
384 break;
385 default:
386 return {};
387 }
388 std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo());
389 std::unique_ptr<const MCInstrAnalysis> MIA(
390 T->createMCInstrAnalysis(MII.get()));
391 if (!MIA)
392 return {};
393 Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None;
394 for (const SectionRef &Section : sections()) {
395 StringRef Name;
396 if (Section.getName(Name))
397 continue;
398 if (Name == ".plt")
399 Plt = Section;
400 else if (Name == ".rela.plt" || Name == ".rel.plt")
401 RelaPlt = Section;
402 else if (Name == ".got.plt")
403 GotPlt = Section;
404 }
405 if (!Plt || !RelaPlt || !GotPlt)
406 return {};
407 Expected<StringRef> PltContents = Plt->getContents();
408 if (!PltContents) {
409 consumeError(PltContents.takeError());
410 return {};
411 }
412 auto PltEntries = MIA->findPltEntries(Plt->getAddress(),
413 arrayRefFromStringRef(*PltContents),
414 GotPlt->getAddress(), Triple);
415 // Build a map from GOT entry virtual address to PLT entry virtual address.
416 DenseMap<uint64_t, uint64_t> GotToPlt;
417 for (const auto &Entry : PltEntries)
418 GotToPlt.insert(std::make_pair(Entry.second, Entry.first));
419 // Find the relocations in the dynamic relocation table that point to
420 // locations in the GOT for which we know the corresponding PLT entry.
421 std::vector<std::pair<DataRefImpl, uint64_t>> Result;
422 for (const auto &Relocation : RelaPlt->relocations()) {
423 if (Relocation.getType() != JumpSlotReloc)
424 continue;
425 auto PltEntryIter = GotToPlt.find(Relocation.getOffset());
426 if (PltEntryIter != GotToPlt.end())
427 Result.push_back(std::make_pair(
428 Relocation.getSymbol()->getRawDataRefImpl(), PltEntryIter->second));
429 }
430 return Result;
431 }