1 //===- ELFObjectFile.cpp - ELF object file implementation -----------------===// 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 // Part of the ELFObjectFile class implementation. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Object/ELFObjectFile.h" 14 #include "llvm/ADT/Triple.h" 15 #include "llvm/BinaryFormat/ELF.h" 16 #include "llvm/MC/MCInstrAnalysis.h" 17 #include "llvm/MC/SubtargetFeature.h" 18 #include "llvm/Object/ELF.h" 19 #include "llvm/Object/ELFTypes.h" 20 #include "llvm/Object/Error.h" 21 #include "llvm/Support/ARMAttributeParser.h" 22 #include "llvm/Support/ARMBuildAttributes.h" 23 #include "llvm/Support/Endian.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include "llvm/Support/MathExtras.h" 26 #include "llvm/Support/RISCVAttributeParser.h" 27 #include "llvm/Support/RISCVAttributes.h" 28 #include "llvm/Support/TargetRegistry.h" 29 #include <algorithm> 30 #include <cstddef> 31 #include <cstdint> 32 #include <memory> 33 #include <string> 34 #include <system_error> 35 #include <utility> 36 37 using namespace llvm; 38 using namespace object; 39 40 const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = { 41 {"None", "NOTYPE", ELF::STT_NOTYPE}, 42 {"Object", "OBJECT", ELF::STT_OBJECT}, 43 {"Function", "FUNC", ELF::STT_FUNC}, 44 {"Section", "SECTION", ELF::STT_SECTION}, 45 {"File", "FILE", ELF::STT_FILE}, 46 {"Common", "COMMON", ELF::STT_COMMON}, 47 {"TLS", "TLS", ELF::STT_TLS}, 48 {"Unknown", "<unknown>: 7", 7}, 49 {"Unknown", "<unknown>: 8", 8}, 50 {"Unknown", "<unknown>: 9", 9}, 51 {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}, 52 {"OS Specific", "<OS specific>: 11", 11}, 53 {"OS Specific", "<OS specific>: 12", 12}, 54 {"Proc Specific", "<processor specific>: 13", 13}, 55 {"Proc Specific", "<processor specific>: 14", 14}, 56 {"Proc Specific", "<processor specific>: 15", 15} 57 }; 58 59 ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) 60 : ObjectFile(Type, Source) {} 61 62 template <class ELFT> 63 static Expected<std::unique_ptr<ELFObjectFile<ELFT>>> 64 createPtr(MemoryBufferRef Object) { 65 auto Ret = ELFObjectFile<ELFT>::create(Object); 66 if (Error E = Ret.takeError()) 67 return std::move(E); 68 return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret)); 69 } 70 71 Expected<std::unique_ptr<ObjectFile>> 72 ObjectFile::createELFObjectFile(MemoryBufferRef Obj) { 73 std::pair<unsigned char, unsigned char> Ident = 74 getElfArchType(Obj.getBuffer()); 75 std::size_t MaxAlignment = 76 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart())); 77 78 if (MaxAlignment < 2) 79 return createError("Insufficient alignment"); 80 81 if (Ident.first == ELF::ELFCLASS32) { 82 if (Ident.second == ELF::ELFDATA2LSB) 83 return createPtr<ELF32LE>(Obj); 84 else if (Ident.second == ELF::ELFDATA2MSB) 85 return createPtr<ELF32BE>(Obj); 86 else 87 return createError("Invalid ELF data"); 88 } else if (Ident.first == ELF::ELFCLASS64) { 89 if (Ident.second == ELF::ELFDATA2LSB) 90 return createPtr<ELF64LE>(Obj); 91 else if (Ident.second == ELF::ELFDATA2MSB) 92 return createPtr<ELF64BE>(Obj); 93 else 94 return createError("Invalid ELF data"); 95 } 96 return createError("Invalid ELF class"); 97 } 98 99 SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const { 100 SubtargetFeatures Features; 101 unsigned PlatformFlags = getPlatformFlags(); 102 103 switch (PlatformFlags & ELF::EF_MIPS_ARCH) { 104 case ELF::EF_MIPS_ARCH_1: 105 break; 106 case ELF::EF_MIPS_ARCH_2: 107 Features.AddFeature("mips2"); 108 break; 109 case ELF::EF_MIPS_ARCH_3: 110 Features.AddFeature("mips3"); 111 break; 112 case ELF::EF_MIPS_ARCH_4: 113 Features.AddFeature("mips4"); 114 break; 115 case ELF::EF_MIPS_ARCH_5: 116 Features.AddFeature("mips5"); 117 break; 118 case ELF::EF_MIPS_ARCH_32: 119 Features.AddFeature("mips32"); 120 break; 121 case ELF::EF_MIPS_ARCH_64: 122 Features.AddFeature("mips64"); 123 break; 124 case ELF::EF_MIPS_ARCH_32R2: 125 Features.AddFeature("mips32r2"); 126 break; 127 case ELF::EF_MIPS_ARCH_64R2: 128 Features.AddFeature("mips64r2"); 129 break; 130 case ELF::EF_MIPS_ARCH_32R6: 131 Features.AddFeature("mips32r6"); 132 break; 133 case ELF::EF_MIPS_ARCH_64R6: 134 Features.AddFeature("mips64r6"); 135 break; 136 default: 137 llvm_unreachable("Unknown EF_MIPS_ARCH value"); 138 } 139 140 switch (PlatformFlags & ELF::EF_MIPS_MACH) { 141 case ELF::EF_MIPS_MACH_NONE: 142 // No feature associated with this value. 143 break; 144 case ELF::EF_MIPS_MACH_OCTEON: 145 Features.AddFeature("cnmips"); 146 break; 147 default: 148 llvm_unreachable("Unknown EF_MIPS_ARCH value"); 149 } 150 151 if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) 152 Features.AddFeature("mips16"); 153 if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) 154 Features.AddFeature("micromips"); 155 156 return Features; 157 } 158 159 SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { 160 SubtargetFeatures Features; 161 ARMAttributeParser Attributes; 162 if (Error E = getBuildAttributes(Attributes)) { 163 consumeError(std::move(E)); 164 return SubtargetFeatures(); 165 } 166 167 // both ARMv7-M and R have to support thumb hardware div 168 bool isV7 = false; 169 Optional<unsigned> Attr = 170 Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 171 if (Attr.hasValue()) 172 isV7 = Attr.getValue() == ARMBuildAttrs::v7; 173 174 Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile); 175 if (Attr.hasValue()) { 176 switch (Attr.getValue()) { 177 case ARMBuildAttrs::ApplicationProfile: 178 Features.AddFeature("aclass"); 179 break; 180 case ARMBuildAttrs::RealTimeProfile: 181 Features.AddFeature("rclass"); 182 if (isV7) 183 Features.AddFeature("hwdiv"); 184 break; 185 case ARMBuildAttrs::MicroControllerProfile: 186 Features.AddFeature("mclass"); 187 if (isV7) 188 Features.AddFeature("hwdiv"); 189 break; 190 } 191 } 192 193 Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use); 194 if (Attr.hasValue()) { 195 switch (Attr.getValue()) { 196 default: 197 break; 198 case ARMBuildAttrs::Not_Allowed: 199 Features.AddFeature("thumb", false); 200 Features.AddFeature("thumb2", false); 201 break; 202 case ARMBuildAttrs::AllowThumb32: 203 Features.AddFeature("thumb2"); 204 break; 205 } 206 } 207 208 Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch); 209 if (Attr.hasValue()) { 210 switch (Attr.getValue()) { 211 default: 212 break; 213 case ARMBuildAttrs::Not_Allowed: 214 Features.AddFeature("vfp2sp", false); 215 Features.AddFeature("vfp3d16sp", false); 216 Features.AddFeature("vfp4d16sp", false); 217 break; 218 case ARMBuildAttrs::AllowFPv2: 219 Features.AddFeature("vfp2"); 220 break; 221 case ARMBuildAttrs::AllowFPv3A: 222 case ARMBuildAttrs::AllowFPv3B: 223 Features.AddFeature("vfp3"); 224 break; 225 case ARMBuildAttrs::AllowFPv4A: 226 case ARMBuildAttrs::AllowFPv4B: 227 Features.AddFeature("vfp4"); 228 break; 229 } 230 } 231 232 Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch); 233 if (Attr.hasValue()) { 234 switch (Attr.getValue()) { 235 default: 236 break; 237 case ARMBuildAttrs::Not_Allowed: 238 Features.AddFeature("neon", false); 239 Features.AddFeature("fp16", false); 240 break; 241 case ARMBuildAttrs::AllowNeon: 242 Features.AddFeature("neon"); 243 break; 244 case ARMBuildAttrs::AllowNeon2: 245 Features.AddFeature("neon"); 246 Features.AddFeature("fp16"); 247 break; 248 } 249 } 250 251 Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch); 252 if (Attr.hasValue()) { 253 switch (Attr.getValue()) { 254 default: 255 break; 256 case ARMBuildAttrs::Not_Allowed: 257 Features.AddFeature("mve", false); 258 Features.AddFeature("mve.fp", false); 259 break; 260 case ARMBuildAttrs::AllowMVEInteger: 261 Features.AddFeature("mve.fp", false); 262 Features.AddFeature("mve"); 263 break; 264 case ARMBuildAttrs::AllowMVEIntegerAndFloat: 265 Features.AddFeature("mve.fp"); 266 break; 267 } 268 } 269 270 Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use); 271 if (Attr.hasValue()) { 272 switch (Attr.getValue()) { 273 default: 274 break; 275 case ARMBuildAttrs::DisallowDIV: 276 Features.AddFeature("hwdiv", false); 277 Features.AddFeature("hwdiv-arm", false); 278 break; 279 case ARMBuildAttrs::AllowDIVExt: 280 Features.AddFeature("hwdiv"); 281 Features.AddFeature("hwdiv-arm"); 282 break; 283 } 284 } 285 286 return Features; 287 } 288 289 SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const { 290 SubtargetFeatures Features; 291 unsigned PlatformFlags = getPlatformFlags(); 292 293 if (PlatformFlags & ELF::EF_RISCV_RVC) { 294 Features.AddFeature("c"); 295 } 296 297 // Add features according to the ELF attribute section. 298 // If there are any unrecognized features, ignore them. 299 RISCVAttributeParser Attributes; 300 if (Error E = getBuildAttributes(Attributes)) 301 return Features; // Keep "c" feature if there is one in PlatformFlags. 302 303 Optional<StringRef> Attr = Attributes.getAttributeString(RISCVAttrs::ARCH); 304 if (Attr.hasValue()) { 305 // The Arch pattern is [rv32|rv64][i|e]version(_[m|a|f|d|c]version)* 306 // Version string pattern is (major)p(minor). Major and minor are optional. 307 // For example, a version number could be 2p0, 2, or p92. 308 StringRef Arch = Attr.getValue(); 309 if (Arch.consume_front("rv32")) 310 Features.AddFeature("64bit", false); 311 else if (Arch.consume_front("rv64")) 312 Features.AddFeature("64bit"); 313 314 while (!Arch.empty()) { 315 switch (Arch[0]) { 316 default: 317 break; // Ignore unexpected features. 318 case 'i': 319 Features.AddFeature("e", false); 320 break; 321 case 'd': 322 Features.AddFeature("f"); // D-ext will imply F-ext. 323 LLVM_FALLTHROUGH; 324 case 'e': 325 case 'm': 326 case 'a': 327 case 'f': 328 case 'c': 329 Features.AddFeature(Arch.take_front()); 330 break; 331 } 332 333 // FIXME: Handle version numbers. 334 Arch = Arch.drop_until([](char c) { return c == '_' || c == '\0'; }); 335 Arch = Arch.drop_while([](char c) { return c == '_'; }); 336 } 337 } 338 339 return Features; 340 } 341 342 SubtargetFeatures ELFObjectFileBase::getFeatures() const { 343 switch (getEMachine()) { 344 case ELF::EM_MIPS: 345 return getMIPSFeatures(); 346 case ELF::EM_ARM: 347 return getARMFeatures(); 348 case ELF::EM_RISCV: 349 return getRISCVFeatures(); 350 default: 351 return SubtargetFeatures(); 352 } 353 } 354 355 // FIXME Encode from a tablegen description or target parser. 356 void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { 357 if (TheTriple.getSubArch() != Triple::NoSubArch) 358 return; 359 360 ARMAttributeParser Attributes; 361 if (Error E = getBuildAttributes(Attributes)) { 362 // TODO Propagate Error. 363 consumeError(std::move(E)); 364 return; 365 } 366 367 std::string Triple; 368 // Default to ARM, but use the triple if it's been set. 369 if (TheTriple.isThumb()) 370 Triple = "thumb"; 371 else 372 Triple = "arm"; 373 374 Optional<unsigned> Attr = 375 Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch); 376 if (Attr.hasValue()) { 377 switch (Attr.getValue()) { 378 case ARMBuildAttrs::v4: 379 Triple += "v4"; 380 break; 381 case ARMBuildAttrs::v4T: 382 Triple += "v4t"; 383 break; 384 case ARMBuildAttrs::v5T: 385 Triple += "v5t"; 386 break; 387 case ARMBuildAttrs::v5TE: 388 Triple += "v5te"; 389 break; 390 case ARMBuildAttrs::v5TEJ: 391 Triple += "v5tej"; 392 break; 393 case ARMBuildAttrs::v6: 394 Triple += "v6"; 395 break; 396 case ARMBuildAttrs::v6KZ: 397 Triple += "v6kz"; 398 break; 399 case ARMBuildAttrs::v6T2: 400 Triple += "v6t2"; 401 break; 402 case ARMBuildAttrs::v6K: 403 Triple += "v6k"; 404 break; 405 case ARMBuildAttrs::v7: 406 Triple += "v7"; 407 break; 408 case ARMBuildAttrs::v6_M: 409 Triple += "v6m"; 410 break; 411 case ARMBuildAttrs::v6S_M: 412 Triple += "v6sm"; 413 break; 414 case ARMBuildAttrs::v7E_M: 415 Triple += "v7em"; 416 break; 417 case ARMBuildAttrs::v8_A: 418 Triple += "v8a"; 419 break; 420 case ARMBuildAttrs::v8_R: 421 Triple += "v8r"; 422 break; 423 case ARMBuildAttrs::v8_M_Base: 424 Triple += "v8m.base"; 425 break; 426 case ARMBuildAttrs::v8_M_Main: 427 Triple += "v8m.main"; 428 break; 429 case ARMBuildAttrs::v8_1_M_Main: 430 Triple += "v8.1m.main"; 431 break; 432 } 433 } 434 if (!isLittleEndian()) 435 Triple += "eb"; 436 437 TheTriple.setArchName(Triple); 438 } 439 440 std::vector<std::pair<DataRefImpl, uint64_t>> 441 ELFObjectFileBase::getPltAddresses() const { 442 std::string Err; 443 const auto Triple = makeTriple(); 444 const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err); 445 if (!T) 446 return {}; 447 uint64_t JumpSlotReloc = 0; 448 switch (Triple.getArch()) { 449 case Triple::x86: 450 JumpSlotReloc = ELF::R_386_JUMP_SLOT; 451 break; 452 case Triple::x86_64: 453 JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT; 454 break; 455 case Triple::aarch64: 456 JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT; 457 break; 458 default: 459 return {}; 460 } 461 std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo()); 462 std::unique_ptr<const MCInstrAnalysis> MIA( 463 T->createMCInstrAnalysis(MII.get())); 464 if (!MIA) 465 return {}; 466 Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None; 467 for (const SectionRef &Section : sections()) { 468 Expected<StringRef> NameOrErr = Section.getName(); 469 if (!NameOrErr) { 470 consumeError(NameOrErr.takeError()); 471 continue; 472 } 473 StringRef Name = *NameOrErr; 474 475 if (Name == ".plt") 476 Plt = Section; 477 else if (Name == ".rela.plt" || Name == ".rel.plt") 478 RelaPlt = Section; 479 else if (Name == ".got.plt") 480 GotPlt = Section; 481 } 482 if (!Plt || !RelaPlt || !GotPlt) 483 return {}; 484 Expected<StringRef> PltContents = Plt->getContents(); 485 if (!PltContents) { 486 consumeError(PltContents.takeError()); 487 return {}; 488 } 489 auto PltEntries = MIA->findPltEntries(Plt->getAddress(), 490 arrayRefFromStringRef(*PltContents), 491 GotPlt->getAddress(), Triple); 492 // Build a map from GOT entry virtual address to PLT entry virtual address. 493 DenseMap<uint64_t, uint64_t> GotToPlt; 494 for (const auto &Entry : PltEntries) 495 GotToPlt.insert(std::make_pair(Entry.second, Entry.first)); 496 // Find the relocations in the dynamic relocation table that point to 497 // locations in the GOT for which we know the corresponding PLT entry. 498 std::vector<std::pair<DataRefImpl, uint64_t>> Result; 499 for (const auto &Relocation : RelaPlt->relocations()) { 500 if (Relocation.getType() != JumpSlotReloc) 501 continue; 502 auto PltEntryIter = GotToPlt.find(Relocation.getOffset()); 503 if (PltEntryIter != GotToPlt.end()) 504 Result.push_back(std::make_pair( 505 Relocation.getSymbol()->getRawDataRefImpl(), PltEntryIter->second)); 506 } 507 return Result; 508 } 509