1 //===- ELFObjcopy.cpp -----------------------------------------------------===// 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 #include "llvm/ObjCopy/ELF/ELFObjcopy.h" 10 #include "ELFObject.h" 11 #include "llvm/ADT/BitmaskEnum.h" 12 #include "llvm/ADT/DenseSet.h" 13 #include "llvm/ADT/SmallVector.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/ADT/Twine.h" 16 #include "llvm/BinaryFormat/ELF.h" 17 #include "llvm/MC/MCTargetOptions.h" 18 #include "llvm/ObjCopy/CommonConfig.h" 19 #include "llvm/ObjCopy/ELF/ELFConfig.h" 20 #include "llvm/Object/Binary.h" 21 #include "llvm/Object/ELFObjectFile.h" 22 #include "llvm/Object/ELFTypes.h" 23 #include "llvm/Object/Error.h" 24 #include "llvm/Option/Option.h" 25 #include "llvm/Support/Casting.h" 26 #include "llvm/Support/Compression.h" 27 #include "llvm/Support/Errc.h" 28 #include "llvm/Support/Error.h" 29 #include "llvm/Support/ErrorHandling.h" 30 #include "llvm/Support/Memory.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include <algorithm> 33 #include <cassert> 34 #include <cstdlib> 35 #include <functional> 36 #include <memory> 37 #include <string> 38 #include <system_error> 39 #include <utility> 40 41 using namespace llvm; 42 using namespace llvm::ELF; 43 using namespace llvm::objcopy; 44 using namespace llvm::objcopy::elf; 45 using namespace llvm::object; 46 47 using SectionPred = std::function<bool(const SectionBase &Sec)>; 48 49 static bool isDebugSection(const SectionBase &Sec) { 50 return StringRef(Sec.Name).starts_with(".debug") || Sec.Name == ".gdb_index"; 51 } 52 53 static bool isDWOSection(const SectionBase &Sec) { 54 return StringRef(Sec.Name).ends_with(".dwo"); 55 } 56 57 static bool onlyKeepDWOPred(const Object &Obj, const SectionBase &Sec) { 58 // We can't remove the section header string table. 59 if (&Sec == Obj.SectionNames) 60 return false; 61 // Short of keeping the string table we want to keep everything that is a DWO 62 // section and remove everything else. 63 return !isDWOSection(Sec); 64 } 65 66 static Expected<uint64_t> getNewShfFlags(SectionFlag AllFlags, 67 uint16_t EMachine) { 68 uint64_t NewFlags = 0; 69 if (AllFlags & SectionFlag::SecAlloc) 70 NewFlags |= ELF::SHF_ALLOC; 71 if (!(AllFlags & SectionFlag::SecReadonly)) 72 NewFlags |= ELF::SHF_WRITE; 73 if (AllFlags & SectionFlag::SecCode) 74 NewFlags |= ELF::SHF_EXECINSTR; 75 if (AllFlags & SectionFlag::SecMerge) 76 NewFlags |= ELF::SHF_MERGE; 77 if (AllFlags & SectionFlag::SecStrings) 78 NewFlags |= ELF::SHF_STRINGS; 79 if (AllFlags & SectionFlag::SecExclude) 80 NewFlags |= ELF::SHF_EXCLUDE; 81 if (AllFlags & SectionFlag::SecLarge) { 82 if (EMachine != EM_X86_64) 83 return createStringError(errc::invalid_argument, 84 "section flag SHF_X86_64_LARGE can only be used " 85 "with x86_64 architecture"); 86 NewFlags |= ELF::SHF_X86_64_LARGE; 87 } 88 return NewFlags; 89 } 90 91 static uint64_t getSectionFlagsPreserveMask(uint64_t OldFlags, 92 uint64_t NewFlags, 93 uint16_t EMachine) { 94 // Preserve some flags which should not be dropped when setting flags. 95 // Also, preserve anything OS/processor dependant. 96 const uint64_t PreserveMask = 97 (ELF::SHF_COMPRESSED | ELF::SHF_GROUP | ELF::SHF_LINK_ORDER | 98 ELF::SHF_MASKOS | ELF::SHF_MASKPROC | ELF::SHF_TLS | 99 ELF::SHF_INFO_LINK) & 100 ~ELF::SHF_EXCLUDE & 101 ~(EMachine == EM_X86_64 ? (uint64_t)ELF::SHF_X86_64_LARGE : 0UL); 102 return (OldFlags & PreserveMask) | (NewFlags & ~PreserveMask); 103 } 104 105 static void setSectionType(SectionBase &Sec, uint64_t Type) { 106 // If Sec's type is changed from SHT_NOBITS due to --set-section-flags, 107 // Offset may not be aligned. Align it to max(Align, 1). 108 if (Sec.Type == ELF::SHT_NOBITS && Type != ELF::SHT_NOBITS) 109 Sec.Offset = alignTo(Sec.Offset, std::max(Sec.Align, uint64_t(1))); 110 Sec.Type = Type; 111 } 112 113 static Error setSectionFlagsAndType(SectionBase &Sec, SectionFlag Flags, 114 uint16_t EMachine) { 115 Expected<uint64_t> NewFlags = getNewShfFlags(Flags, EMachine); 116 if (!NewFlags) 117 return NewFlags.takeError(); 118 Sec.Flags = getSectionFlagsPreserveMask(Sec.Flags, *NewFlags, EMachine); 119 120 // In GNU objcopy, certain flags promote SHT_NOBITS to SHT_PROGBITS. This rule 121 // may promote more non-ALLOC sections than GNU objcopy, but it is fine as 122 // non-ALLOC SHT_NOBITS sections do not make much sense. 123 if (Sec.Type == SHT_NOBITS && 124 (!(Sec.Flags & ELF::SHF_ALLOC) || 125 Flags & (SectionFlag::SecContents | SectionFlag::SecLoad))) 126 setSectionType(Sec, ELF::SHT_PROGBITS); 127 128 return Error::success(); 129 } 130 131 static ElfType getOutputElfType(const Binary &Bin) { 132 // Infer output ELF type from the input ELF object 133 if (isa<ELFObjectFile<ELF32LE>>(Bin)) 134 return ELFT_ELF32LE; 135 if (isa<ELFObjectFile<ELF64LE>>(Bin)) 136 return ELFT_ELF64LE; 137 if (isa<ELFObjectFile<ELF32BE>>(Bin)) 138 return ELFT_ELF32BE; 139 if (isa<ELFObjectFile<ELF64BE>>(Bin)) 140 return ELFT_ELF64BE; 141 llvm_unreachable("Invalid ELFType"); 142 } 143 144 static ElfType getOutputElfType(const MachineInfo &MI) { 145 // Infer output ELF type from the binary arch specified 146 if (MI.Is64Bit) 147 return MI.IsLittleEndian ? ELFT_ELF64LE : ELFT_ELF64BE; 148 else 149 return MI.IsLittleEndian ? ELFT_ELF32LE : ELFT_ELF32BE; 150 } 151 152 static std::unique_ptr<Writer> createELFWriter(const CommonConfig &Config, 153 Object &Obj, raw_ostream &Out, 154 ElfType OutputElfType) { 155 // Depending on the initial ELFT and OutputFormat we need a different Writer. 156 switch (OutputElfType) { 157 case ELFT_ELF32LE: 158 return std::make_unique<ELFWriter<ELF32LE>>(Obj, Out, !Config.StripSections, 159 Config.OnlyKeepDebug); 160 case ELFT_ELF64LE: 161 return std::make_unique<ELFWriter<ELF64LE>>(Obj, Out, !Config.StripSections, 162 Config.OnlyKeepDebug); 163 case ELFT_ELF32BE: 164 return std::make_unique<ELFWriter<ELF32BE>>(Obj, Out, !Config.StripSections, 165 Config.OnlyKeepDebug); 166 case ELFT_ELF64BE: 167 return std::make_unique<ELFWriter<ELF64BE>>(Obj, Out, !Config.StripSections, 168 Config.OnlyKeepDebug); 169 } 170 llvm_unreachable("Invalid output format"); 171 } 172 173 static std::unique_ptr<Writer> createWriter(const CommonConfig &Config, 174 Object &Obj, raw_ostream &Out, 175 ElfType OutputElfType) { 176 switch (Config.OutputFormat) { 177 case FileFormat::Binary: 178 return std::make_unique<BinaryWriter>(Obj, Out, Config); 179 case FileFormat::IHex: 180 return std::make_unique<IHexWriter>(Obj, Out, Config.OutputFilename); 181 case FileFormat::SREC: 182 return std::make_unique<SRECWriter>(Obj, Out, Config.OutputFilename); 183 default: 184 return createELFWriter(Config, Obj, Out, OutputElfType); 185 } 186 } 187 188 static Error dumpSectionToFile(StringRef SecName, StringRef Filename, 189 StringRef InputFilename, Object &Obj) { 190 for (auto &Sec : Obj.sections()) { 191 if (Sec.Name == SecName) { 192 if (Sec.Type == SHT_NOBITS) 193 return createFileError(InputFilename, object_error::parse_failed, 194 "cannot dump section '%s': it has no contents", 195 SecName.str().c_str()); 196 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 197 FileOutputBuffer::create(Filename, Sec.OriginalData.size()); 198 if (!BufferOrErr) 199 return createFileError(Filename, BufferOrErr.takeError()); 200 std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr); 201 std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), 202 Buf->getBufferStart()); 203 if (Error E = Buf->commit()) 204 return createFileError(Filename, std::move(E)); 205 return Error::success(); 206 } 207 } 208 209 return createFileError(InputFilename, object_error::parse_failed, 210 "section '%s' not found", SecName.str().c_str()); 211 } 212 213 Error Object::compressOrDecompressSections(const CommonConfig &Config) { 214 // Build a list of sections we are going to replace. 215 // We can't call `addSection` while iterating over sections, 216 // because it would mutate the sections array. 217 SmallVector<std::pair<SectionBase *, std::function<SectionBase *()>>, 0> 218 ToReplace; 219 for (SectionBase &Sec : sections()) { 220 std::optional<DebugCompressionType> CType; 221 for (auto &[Matcher, T] : Config.compressSections) 222 if (Matcher.matches(Sec.Name)) 223 CType = T; 224 // Handle --compress-debug-sections and --decompress-debug-sections, which 225 // apply to non-ALLOC debug sections. 226 if (!(Sec.Flags & SHF_ALLOC) && StringRef(Sec.Name).starts_with(".debug")) { 227 if (Config.CompressionType != DebugCompressionType::None) 228 CType = Config.CompressionType; 229 else if (Config.DecompressDebugSections) 230 CType = DebugCompressionType::None; 231 } 232 if (!CType) 233 continue; 234 235 if (Sec.ParentSegment) 236 return createStringError( 237 errc::invalid_argument, 238 "section '" + Sec.Name + 239 "' within a segment cannot be (de)compressed"); 240 241 if (auto *CS = dyn_cast<CompressedSection>(&Sec)) { 242 if (*CType == DebugCompressionType::None) 243 ToReplace.emplace_back( 244 &Sec, [=] { return &addSection<DecompressedSection>(*CS); }); 245 } else if (*CType != DebugCompressionType::None) { 246 ToReplace.emplace_back(&Sec, [=, S = &Sec] { 247 return &addSection<CompressedSection>( 248 CompressedSection(*S, *CType, Is64Bits)); 249 }); 250 } 251 } 252 253 DenseMap<SectionBase *, SectionBase *> FromTo; 254 for (auto [S, Func] : ToReplace) 255 FromTo[S] = Func(); 256 return replaceSections(FromTo); 257 } 258 259 static bool isAArch64MappingSymbol(const Symbol &Sym) { 260 if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE || 261 Sym.getShndx() == SHN_UNDEF) 262 return false; 263 StringRef Name = Sym.Name; 264 if (!Name.consume_front("$x") && !Name.consume_front("$d")) 265 return false; 266 return Name.empty() || Name.starts_with("."); 267 } 268 269 static bool isArmMappingSymbol(const Symbol &Sym) { 270 if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE || 271 Sym.getShndx() == SHN_UNDEF) 272 return false; 273 StringRef Name = Sym.Name; 274 if (!Name.consume_front("$a") && !Name.consume_front("$d") && 275 !Name.consume_front("$t")) 276 return false; 277 return Name.empty() || Name.starts_with("."); 278 } 279 280 // Check if the symbol should be preserved because it is required by ABI. 281 static bool isRequiredByABISymbol(const Object &Obj, const Symbol &Sym) { 282 switch (Obj.Machine) { 283 case EM_AARCH64: 284 // Mapping symbols should be preserved for a relocatable object file. 285 return Obj.isRelocatable() && isAArch64MappingSymbol(Sym); 286 case EM_ARM: 287 // Mapping symbols should be preserved for a relocatable object file. 288 return Obj.isRelocatable() && isArmMappingSymbol(Sym); 289 default: 290 return false; 291 } 292 } 293 294 static bool isUnneededSymbol(const Symbol &Sym) { 295 return !Sym.Referenced && 296 (Sym.Binding == STB_LOCAL || Sym.getShndx() == SHN_UNDEF) && 297 Sym.Type != STT_SECTION; 298 } 299 300 static Error updateAndRemoveSymbols(const CommonConfig &Config, 301 const ELFConfig &ELFConfig, Object &Obj) { 302 // TODO: update or remove symbols only if there is an option that affects 303 // them. 304 if (!Obj.SymbolTable) 305 return Error::success(); 306 307 Obj.SymbolTable->updateSymbols([&](Symbol &Sym) { 308 if (Config.SymbolsToSkip.matches(Sym.Name)) 309 return; 310 311 // Common and undefined symbols don't make sense as local symbols, and can 312 // even cause crashes if we localize those, so skip them. 313 if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF && 314 ((ELFConfig.LocalizeHidden && 315 (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) || 316 Config.SymbolsToLocalize.matches(Sym.Name))) 317 Sym.Binding = STB_LOCAL; 318 319 for (auto &[Matcher, Visibility] : ELFConfig.SymbolsToSetVisibility) 320 if (Matcher.matches(Sym.Name)) 321 Sym.Visibility = Visibility; 322 323 // Note: these two globalize flags have very similar names but different 324 // meanings: 325 // 326 // --globalize-symbol: promote a symbol to global 327 // --keep-global-symbol: all symbols except for these should be made local 328 // 329 // If --globalize-symbol is specified for a given symbol, it will be 330 // global in the output file even if it is not included via 331 // --keep-global-symbol. Because of that, make sure to check 332 // --globalize-symbol second. 333 if (!Config.SymbolsToKeepGlobal.empty() && 334 !Config.SymbolsToKeepGlobal.matches(Sym.Name) && 335 Sym.getShndx() != SHN_UNDEF) 336 Sym.Binding = STB_LOCAL; 337 338 if (Config.SymbolsToGlobalize.matches(Sym.Name) && 339 Sym.getShndx() != SHN_UNDEF) 340 Sym.Binding = STB_GLOBAL; 341 342 // SymbolsToWeaken applies to both STB_GLOBAL and STB_GNU_UNIQUE. 343 if (Config.SymbolsToWeaken.matches(Sym.Name) && Sym.Binding != STB_LOCAL) 344 Sym.Binding = STB_WEAK; 345 346 if (Config.Weaken && Sym.Binding != STB_LOCAL && 347 Sym.getShndx() != SHN_UNDEF) 348 Sym.Binding = STB_WEAK; 349 350 const auto I = Config.SymbolsToRename.find(Sym.Name); 351 if (I != Config.SymbolsToRename.end()) 352 Sym.Name = std::string(I->getValue()); 353 354 if (!Config.SymbolsPrefixRemove.empty() && Sym.Type != STT_SECTION) 355 if (StringRef(Sym.Name).starts_with(Config.SymbolsPrefixRemove)) 356 Sym.Name = Sym.Name.substr(Config.SymbolsPrefixRemove.size()); 357 358 if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION) 359 Sym.Name = (Config.SymbolsPrefix + Sym.Name).str(); 360 }); 361 362 // The purpose of this loop is to mark symbols referenced by sections 363 // (like GroupSection or RelocationSection). This way, we know which 364 // symbols are still 'needed' and which are not. 365 if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty() || 366 !Config.OnlySection.empty() || Config.DiscardMode != DiscardType::None) { 367 for (SectionBase &Sec : Obj.sections()) 368 Sec.markSymbols(); 369 } 370 371 auto RemoveSymbolsPred = [&](const Symbol &Sym) { 372 if (Config.SymbolsToKeep.matches(Sym.Name) || 373 (ELFConfig.KeepFileSymbols && Sym.Type == STT_FILE)) 374 return false; 375 376 if (Config.SymbolsToRemove.matches(Sym.Name)) 377 return true; 378 379 if (Config.StripAll || Config.StripAllGNU) 380 return true; 381 382 if (isRequiredByABISymbol(Obj, Sym)) 383 return false; 384 385 if (Config.StripDebug && Sym.Type == STT_FILE) 386 return true; 387 388 if ((Config.StripUnneeded || 389 Config.UnneededSymbolsToRemove.matches(Sym.Name)) && 390 (!Obj.isRelocatable() || isUnneededSymbol(Sym))) 391 return true; 392 393 if (!Sym.Referenced) { 394 if ((Config.DiscardMode == DiscardType::All || 395 (Config.DiscardMode == DiscardType::Locals && 396 StringRef(Sym.Name).starts_with(".L"))) && 397 Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF && 398 Sym.Type != STT_FILE && Sym.Type != STT_SECTION) 399 return true; 400 // We want to remove undefined symbols if all references have been 401 // stripped. 402 if (!Config.OnlySection.empty() && Sym.getShndx() == SHN_UNDEF) 403 return true; 404 } 405 406 return false; 407 }; 408 409 return Obj.removeSymbols(RemoveSymbolsPred); 410 } 411 412 static Error replaceAndRemoveSections(const CommonConfig &Config, 413 const ELFConfig &ELFConfig, Object &Obj) { 414 SectionPred RemovePred = [](const SectionBase &) { return false; }; 415 416 // Removes: 417 if (!Config.ToRemove.empty()) { 418 RemovePred = [&Config](const SectionBase &Sec) { 419 return Config.ToRemove.matches(Sec.Name); 420 }; 421 } 422 423 if (Config.StripDWO) 424 RemovePred = [RemovePred](const SectionBase &Sec) { 425 return isDWOSection(Sec) || RemovePred(Sec); 426 }; 427 428 if (Config.ExtractDWO) 429 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 430 return onlyKeepDWOPred(Obj, Sec) || RemovePred(Sec); 431 }; 432 433 if (Config.StripAllGNU) 434 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 435 if (RemovePred(Sec)) 436 return true; 437 if ((Sec.Flags & SHF_ALLOC) != 0) 438 return false; 439 if (&Sec == Obj.SectionNames) 440 return false; 441 switch (Sec.Type) { 442 case SHT_SYMTAB: 443 case SHT_REL: 444 case SHT_RELA: 445 case SHT_STRTAB: 446 return true; 447 } 448 return isDebugSection(Sec); 449 }; 450 451 if (Config.StripSections) { 452 RemovePred = [RemovePred](const SectionBase &Sec) { 453 return RemovePred(Sec) || Sec.ParentSegment == nullptr; 454 }; 455 } 456 457 if (Config.StripDebug || Config.StripUnneeded) { 458 RemovePred = [RemovePred](const SectionBase &Sec) { 459 return RemovePred(Sec) || isDebugSection(Sec); 460 }; 461 } 462 463 if (Config.StripNonAlloc) 464 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 465 if (RemovePred(Sec)) 466 return true; 467 if (&Sec == Obj.SectionNames) 468 return false; 469 return (Sec.Flags & SHF_ALLOC) == 0 && Sec.ParentSegment == nullptr; 470 }; 471 472 if (Config.StripAll) 473 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 474 if (RemovePred(Sec)) 475 return true; 476 if (&Sec == Obj.SectionNames) 477 return false; 478 if (StringRef(Sec.Name).starts_with(".gnu.warning")) 479 return false; 480 if (StringRef(Sec.Name).starts_with(".gnu_debuglink")) 481 return false; 482 // We keep the .ARM.attribute section to maintain compatibility 483 // with Debian derived distributions. This is a bug in their 484 // patchset as documented here: 485 // https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=943798 486 if (Sec.Type == SHT_ARM_ATTRIBUTES) 487 return false; 488 if (Sec.ParentSegment != nullptr) 489 return false; 490 return (Sec.Flags & SHF_ALLOC) == 0; 491 }; 492 493 if (Config.ExtractPartition || Config.ExtractMainPartition) { 494 RemovePred = [RemovePred](const SectionBase &Sec) { 495 if (RemovePred(Sec)) 496 return true; 497 if (Sec.Type == SHT_LLVM_PART_EHDR || Sec.Type == SHT_LLVM_PART_PHDR) 498 return true; 499 return (Sec.Flags & SHF_ALLOC) != 0 && !Sec.ParentSegment; 500 }; 501 } 502 503 // Explicit copies: 504 if (!Config.OnlySection.empty()) { 505 RemovePred = [&Config, RemovePred, &Obj](const SectionBase &Sec) { 506 // Explicitly keep these sections regardless of previous removes. 507 if (Config.OnlySection.matches(Sec.Name)) 508 return false; 509 510 // Allow all implicit removes. 511 if (RemovePred(Sec)) 512 return true; 513 514 // Keep special sections. 515 if (Obj.SectionNames == &Sec) 516 return false; 517 if (Obj.SymbolTable == &Sec || 518 (Obj.SymbolTable && Obj.SymbolTable->getStrTab() == &Sec)) 519 return false; 520 521 // Remove everything else. 522 return true; 523 }; 524 } 525 526 if (!Config.KeepSection.empty()) { 527 RemovePred = [&Config, RemovePred](const SectionBase &Sec) { 528 // Explicitly keep these sections regardless of previous removes. 529 if (Config.KeepSection.matches(Sec.Name)) 530 return false; 531 // Otherwise defer to RemovePred. 532 return RemovePred(Sec); 533 }; 534 } 535 536 // This has to be the last predicate assignment. 537 // If the option --keep-symbol has been specified 538 // and at least one of those symbols is present 539 // (equivalently, the updated symbol table is not empty) 540 // the symbol table and the string table should not be removed. 541 if ((!Config.SymbolsToKeep.empty() || ELFConfig.KeepFileSymbols) && 542 Obj.SymbolTable && !Obj.SymbolTable->empty()) { 543 RemovePred = [&Obj, RemovePred](const SectionBase &Sec) { 544 if (&Sec == Obj.SymbolTable || &Sec == Obj.SymbolTable->getStrTab()) 545 return false; 546 return RemovePred(Sec); 547 }; 548 } 549 550 if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred)) 551 return E; 552 553 if (Error E = Obj.compressOrDecompressSections(Config)) 554 return E; 555 556 return Error::success(); 557 } 558 559 // Add symbol to the Object symbol table with the specified properties. 560 static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo, 561 uint8_t DefaultVisibility) { 562 SectionBase *Sec = Obj.findSection(SymInfo.SectionName); 563 uint64_t Value = Sec ? Sec->Addr + SymInfo.Value : SymInfo.Value; 564 565 uint8_t Bind = ELF::STB_GLOBAL; 566 uint8_t Type = ELF::STT_NOTYPE; 567 uint8_t Visibility = DefaultVisibility; 568 569 for (SymbolFlag FlagValue : SymInfo.Flags) 570 switch (FlagValue) { 571 case SymbolFlag::Global: 572 Bind = ELF::STB_GLOBAL; 573 break; 574 case SymbolFlag::Local: 575 Bind = ELF::STB_LOCAL; 576 break; 577 case SymbolFlag::Weak: 578 Bind = ELF::STB_WEAK; 579 break; 580 case SymbolFlag::Default: 581 Visibility = ELF::STV_DEFAULT; 582 break; 583 case SymbolFlag::Hidden: 584 Visibility = ELF::STV_HIDDEN; 585 break; 586 case SymbolFlag::Protected: 587 Visibility = ELF::STV_PROTECTED; 588 break; 589 case SymbolFlag::File: 590 Type = ELF::STT_FILE; 591 break; 592 case SymbolFlag::Section: 593 Type = ELF::STT_SECTION; 594 break; 595 case SymbolFlag::Object: 596 Type = ELF::STT_OBJECT; 597 break; 598 case SymbolFlag::Function: 599 Type = ELF::STT_FUNC; 600 break; 601 case SymbolFlag::IndirectFunction: 602 Type = ELF::STT_GNU_IFUNC; 603 break; 604 default: /* Other flag values are ignored for ELF. */ 605 break; 606 }; 607 608 Obj.SymbolTable->addSymbol( 609 SymInfo.SymbolName, Bind, Type, Sec, Value, Visibility, 610 Sec ? (uint16_t)SYMBOL_SIMPLE_INDEX : (uint16_t)SHN_ABS, 0); 611 } 612 613 namespace { 614 struct RemoveNoteDetail { 615 struct DeletedRange { 616 uint64_t OldFrom; 617 uint64_t OldTo; 618 }; 619 620 template <class ELFT> 621 static std::vector<DeletedRange> 622 findNotesToRemove(ArrayRef<uint8_t> Data, size_t Align, 623 ArrayRef<RemoveNoteInfo> NotesToRemove); 624 static std::vector<uint8_t> updateData(ArrayRef<uint8_t> OldData, 625 ArrayRef<DeletedRange> ToRemove); 626 }; 627 } // namespace 628 629 template <class ELFT> 630 std::vector<RemoveNoteDetail::DeletedRange> 631 RemoveNoteDetail::findNotesToRemove(ArrayRef<uint8_t> Data, size_t Align, 632 ArrayRef<RemoveNoteInfo> NotesToRemove) { 633 using Elf_Nhdr = typename ELFT::Nhdr; 634 using Elf_Note = typename ELFT::Note; 635 std::vector<DeletedRange> ToRemove; 636 uint64_t CurPos = 0; 637 while (CurPos + sizeof(Elf_Nhdr) <= Data.size()) { 638 auto Nhdr = reinterpret_cast<const Elf_Nhdr *>(Data.data() + CurPos); 639 size_t FullSize = Nhdr->getSize(Align); 640 if (CurPos + FullSize > Data.size()) 641 break; 642 Elf_Note Note(*Nhdr); 643 bool ShouldRemove = 644 llvm::any_of(NotesToRemove, [&Note](const RemoveNoteInfo &NoteInfo) { 645 return NoteInfo.TypeId == Note.getType() && 646 (NoteInfo.Name.empty() || NoteInfo.Name == Note.getName()); 647 }); 648 if (ShouldRemove) 649 ToRemove.push_back({CurPos, CurPos + FullSize}); 650 CurPos += FullSize; 651 } 652 return ToRemove; 653 } 654 655 std::vector<uint8_t> 656 RemoveNoteDetail::updateData(ArrayRef<uint8_t> OldData, 657 ArrayRef<DeletedRange> ToRemove) { 658 std::vector<uint8_t> NewData; 659 NewData.reserve(OldData.size()); 660 uint64_t CurPos = 0; 661 for (const DeletedRange &RemRange : ToRemove) { 662 if (CurPos < RemRange.OldFrom) { 663 auto Slice = OldData.slice(CurPos, RemRange.OldFrom - CurPos); 664 llvm::append_range(NewData, Slice); 665 } 666 CurPos = RemRange.OldTo; 667 } 668 if (CurPos < OldData.size()) { 669 auto Slice = OldData.slice(CurPos); 670 llvm::append_range(NewData, Slice); 671 } 672 return NewData; 673 } 674 675 static Error removeNotes(Object &Obj, endianness Endianness, 676 ArrayRef<RemoveNoteInfo> NotesToRemove, 677 function_ref<Error(Error)> ErrorCallback) { 678 // TODO: Support note segments. 679 if (ErrorCallback) { 680 for (Segment &Seg : Obj.segments()) { 681 if (Seg.Type == PT_NOTE) { 682 if (Error E = ErrorCallback(createStringError( 683 errc::not_supported, "note segments are not supported"))) 684 return E; 685 break; 686 } 687 } 688 } 689 for (auto &Sec : Obj.sections()) { 690 if (Sec.Type != SHT_NOTE || !Sec.hasContents()) 691 continue; 692 // TODO: Support note sections in segments. 693 if (Sec.ParentSegment) { 694 if (ErrorCallback) 695 if (Error E = ErrorCallback(createStringError( 696 errc::not_supported, 697 "cannot remove note(s) from " + Sec.Name + 698 ": sections in segments are not supported"))) 699 return E; 700 continue; 701 } 702 ArrayRef<uint8_t> OldData = Sec.getContents(); 703 size_t Align = std::max<size_t>(4, Sec.Align); 704 // Note: notes for both 32-bit and 64-bit ELF files use 4-byte words in the 705 // header, so the parsers are the same. 706 auto ToRemove = (Endianness == endianness::little) 707 ? RemoveNoteDetail::findNotesToRemove<ELF64LE>( 708 OldData, Align, NotesToRemove) 709 : RemoveNoteDetail::findNotesToRemove<ELF64BE>( 710 OldData, Align, NotesToRemove); 711 if (!ToRemove.empty()) { 712 if (Error E = Obj.updateSectionData( 713 Sec, RemoveNoteDetail::updateData(OldData, ToRemove))) 714 return E; 715 } 716 } 717 return Error::success(); 718 } 719 720 static Error 721 handleUserSection(const NewSectionInfo &NewSection, 722 function_ref<Error(StringRef, ArrayRef<uint8_t>)> F) { 723 ArrayRef<uint8_t> Data(reinterpret_cast<const uint8_t *>( 724 NewSection.SectionData->getBufferStart()), 725 NewSection.SectionData->getBufferSize()); 726 return F(NewSection.SectionName, Data); 727 } 728 729 static Error verifyNoteSection(StringRef Name, endianness Endianness, 730 ArrayRef<uint8_t> Data) { 731 // An ELF note has the following structure: 732 // Name Size: 4 bytes (integer) 733 // Desc Size: 4 bytes (integer) 734 // Type : 4 bytes 735 // Name : variable size, padded to a 4 byte boundary 736 // Desc : variable size, padded to a 4 byte boundary 737 738 if (Data.empty()) 739 return Error::success(); 740 741 if (Data.size() < 12) { 742 std::string msg; 743 raw_string_ostream(msg) 744 << Name << " data must be either empty or at least 12 bytes long"; 745 return createStringError(errc::invalid_argument, msg); 746 } 747 if (Data.size() % 4 != 0) { 748 std::string msg; 749 raw_string_ostream(msg) 750 << Name << " data size must be a multiple of 4 bytes"; 751 return createStringError(errc::invalid_argument, msg); 752 } 753 ArrayRef<uint8_t> NameSize = Data.slice(0, 4); 754 ArrayRef<uint8_t> DescSize = Data.slice(4, 4); 755 756 uint32_t NameSizeValue = support::endian::read32(NameSize.data(), Endianness); 757 uint32_t DescSizeValue = support::endian::read32(DescSize.data(), Endianness); 758 759 uint64_t ExpectedDataSize = 760 /*NameSize=*/4 + /*DescSize=*/4 + /*Type=*/4 + 761 /*Name=*/alignTo(NameSizeValue, 4) + 762 /*Desc=*/alignTo(DescSizeValue, 4); 763 uint64_t ActualDataSize = Data.size(); 764 if (ActualDataSize != ExpectedDataSize) { 765 std::string msg; 766 raw_string_ostream(msg) 767 << Name 768 << " data size is incompatible with the content of " 769 "the name and description size fields:" 770 << " expecting " << ExpectedDataSize << ", found " << ActualDataSize; 771 return createStringError(errc::invalid_argument, msg); 772 } 773 774 return Error::success(); 775 } 776 777 // This function handles the high level operations of GNU objcopy including 778 // handling command line options. It's important to outline certain properties 779 // we expect to hold of the command line operations. Any operation that "keeps" 780 // should keep regardless of a remove. Additionally any removal should respect 781 // any previous removals. Lastly whether or not something is removed shouldn't 782 // depend a) on the order the options occur in or b) on some opaque priority 783 // system. The only priority is that keeps/copies overrule removes. 784 static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig, 785 ElfType OutputElfType, Object &Obj) { 786 if (Config.OutputArch) { 787 Obj.Machine = Config.OutputArch->EMachine; 788 Obj.OSABI = Config.OutputArch->OSABI; 789 } 790 791 if (!Config.SplitDWO.empty() && Config.ExtractDWO) { 792 return Obj.removeSections( 793 ELFConfig.AllowBrokenLinks, 794 [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); }); 795 } 796 797 // Dump sections before add/remove for compatibility with GNU objcopy. 798 for (StringRef Flag : Config.DumpSection) { 799 StringRef SectionName; 800 StringRef FileName; 801 std::tie(SectionName, FileName) = Flag.split('='); 802 if (Error E = 803 dumpSectionToFile(SectionName, FileName, Config.InputFilename, Obj)) 804 return E; 805 } 806 807 // It is important to remove the sections first. For example, we want to 808 // remove the relocation sections before removing the symbols. That allows 809 // us to avoid reporting the inappropriate errors about removing symbols 810 // named in relocations. 811 if (Error E = replaceAndRemoveSections(Config, ELFConfig, Obj)) 812 return createFileError(Config.InputFilename, std::move(E)); 813 814 if (Error E = updateAndRemoveSymbols(Config, ELFConfig, Obj)) 815 return createFileError(Config.InputFilename, std::move(E)); 816 817 if (!Config.SetSectionAlignment.empty()) { 818 for (SectionBase &Sec : Obj.sections()) { 819 auto I = Config.SetSectionAlignment.find(Sec.Name); 820 if (I != Config.SetSectionAlignment.end()) 821 Sec.Align = I->second; 822 } 823 } 824 825 if (Config.ChangeSectionLMAValAll != 0) { 826 for (Segment &Seg : Obj.segments()) { 827 if (Seg.MemSize > 0) { 828 if (Config.ChangeSectionLMAValAll > 0 && 829 Seg.PAddr > std::numeric_limits<uint64_t>::max() - 830 Config.ChangeSectionLMAValAll) { 831 return createFileError( 832 Config.InputFilename, errc::invalid_argument, 833 "address 0x" + Twine::utohexstr(Seg.PAddr) + 834 " cannot be increased by 0x" + 835 Twine::utohexstr(Config.ChangeSectionLMAValAll) + 836 ". The result would overflow"); 837 } else if (Config.ChangeSectionLMAValAll < 0 && 838 Seg.PAddr < std::numeric_limits<uint64_t>::min() - 839 Config.ChangeSectionLMAValAll) { 840 return createFileError( 841 Config.InputFilename, errc::invalid_argument, 842 "address 0x" + Twine::utohexstr(Seg.PAddr) + 843 " cannot be decreased by 0x" + 844 Twine::utohexstr(std::abs(Config.ChangeSectionLMAValAll)) + 845 ". The result would underflow"); 846 } 847 Seg.PAddr += Config.ChangeSectionLMAValAll; 848 } 849 } 850 } 851 852 if (!Config.ChangeSectionAddress.empty()) { 853 if (Obj.Type != ELF::ET_REL) 854 return createFileError( 855 Config.InputFilename, object_error::invalid_file_type, 856 "cannot change section address in a non-relocatable file"); 857 StringMap<AddressUpdate> SectionsToUpdateAddress; 858 for (const SectionPatternAddressUpdate &PatternUpdate : 859 reverse(Config.ChangeSectionAddress)) { 860 for (SectionBase &Sec : Obj.sections()) { 861 if (PatternUpdate.SectionPattern.matches(Sec.Name) && 862 SectionsToUpdateAddress.try_emplace(Sec.Name, PatternUpdate.Update) 863 .second) { 864 if (PatternUpdate.Update.Kind == AdjustKind::Subtract && 865 Sec.Addr < PatternUpdate.Update.Value) { 866 return createFileError( 867 Config.InputFilename, errc::invalid_argument, 868 "address 0x" + Twine::utohexstr(Sec.Addr) + 869 " cannot be decreased by 0x" + 870 Twine::utohexstr(PatternUpdate.Update.Value) + 871 ". The result would underflow"); 872 } 873 if (PatternUpdate.Update.Kind == AdjustKind::Add && 874 Sec.Addr > std::numeric_limits<uint64_t>::max() - 875 PatternUpdate.Update.Value) { 876 return createFileError( 877 Config.InputFilename, errc::invalid_argument, 878 "address 0x" + Twine::utohexstr(Sec.Addr) + 879 " cannot be increased by 0x" + 880 Twine::utohexstr(PatternUpdate.Update.Value) + 881 ". The result would overflow"); 882 } 883 884 switch (PatternUpdate.Update.Kind) { 885 case (AdjustKind::Set): 886 Sec.Addr = PatternUpdate.Update.Value; 887 break; 888 case (AdjustKind::Subtract): 889 Sec.Addr -= PatternUpdate.Update.Value; 890 break; 891 case (AdjustKind::Add): 892 Sec.Addr += PatternUpdate.Update.Value; 893 break; 894 } 895 } 896 } 897 } 898 } 899 900 if (Config.OnlyKeepDebug) 901 for (auto &Sec : Obj.sections()) 902 if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE) 903 Sec.Type = SHT_NOBITS; 904 905 endianness E = OutputElfType == ELFT_ELF32LE || OutputElfType == ELFT_ELF64LE 906 ? endianness::little 907 : endianness::big; 908 909 if (!ELFConfig.NotesToRemove.empty()) { 910 if (Error Err = 911 removeNotes(Obj, E, ELFConfig.NotesToRemove, Config.ErrorCallback)) 912 return createFileError(Config.InputFilename, std::move(Err)); 913 } 914 915 for (const NewSectionInfo &AddedSection : Config.AddSection) { 916 auto AddSection = [&](StringRef Name, ArrayRef<uint8_t> Data) -> Error { 917 OwnedDataSection &NewSection = 918 Obj.addSection<OwnedDataSection>(Name, Data); 919 if (Name.starts_with(".note") && Name != ".note.GNU-stack") { 920 NewSection.Type = SHT_NOTE; 921 if (ELFConfig.VerifyNoteSections) 922 return verifyNoteSection(Name, E, Data); 923 } 924 return Error::success(); 925 }; 926 if (Error E = handleUserSection(AddedSection, AddSection)) 927 return createFileError(Config.InputFilename, std::move(E)); 928 } 929 930 for (const NewSectionInfo &NewSection : Config.UpdateSection) { 931 auto UpdateSection = [&](StringRef Name, ArrayRef<uint8_t> Data) { 932 return Obj.updateSection(Name, Data); 933 }; 934 if (Error E = handleUserSection(NewSection, UpdateSection)) 935 return createFileError(Config.InputFilename, std::move(E)); 936 } 937 938 if (!Config.AddGnuDebugLink.empty()) 939 Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink, 940 Config.GnuDebugLinkCRC32); 941 942 // If the symbol table was previously removed, we need to create a new one 943 // before adding new symbols. 944 if (!Obj.SymbolTable && !Config.SymbolsToAdd.empty()) 945 if (Error E = Obj.addNewSymbolTable()) 946 return createFileError(Config.InputFilename, std::move(E)); 947 948 for (const NewSymbolInfo &SI : Config.SymbolsToAdd) 949 addSymbol(Obj, SI, ELFConfig.NewSymbolVisibility); 950 951 // --set-section-{flags,type} work with sections added by --add-section. 952 if (!Config.SetSectionFlags.empty() || !Config.SetSectionType.empty()) { 953 for (auto &Sec : Obj.sections()) { 954 const auto Iter = Config.SetSectionFlags.find(Sec.Name); 955 if (Iter != Config.SetSectionFlags.end()) { 956 const SectionFlagsUpdate &SFU = Iter->second; 957 if (Error E = setSectionFlagsAndType(Sec, SFU.NewFlags, Obj.Machine)) 958 return createFileError(Config.InputFilename, std::move(E)); 959 } 960 auto It2 = Config.SetSectionType.find(Sec.Name); 961 if (It2 != Config.SetSectionType.end()) 962 setSectionType(Sec, It2->second); 963 } 964 } 965 966 if (!Config.SectionsToRename.empty()) { 967 std::vector<RelocationSectionBase *> RelocSections; 968 DenseSet<SectionBase *> RenamedSections; 969 for (SectionBase &Sec : Obj.sections()) { 970 auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec); 971 const auto Iter = Config.SectionsToRename.find(Sec.Name); 972 if (Iter != Config.SectionsToRename.end()) { 973 const SectionRename &SR = Iter->second; 974 Sec.Name = std::string(SR.NewName); 975 if (SR.NewFlags) { 976 if (Error E = setSectionFlagsAndType(Sec, *SR.NewFlags, Obj.Machine)) 977 return createFileError(Config.InputFilename, std::move(E)); 978 } 979 RenamedSections.insert(&Sec); 980 } else if (RelocSec && !(Sec.Flags & SHF_ALLOC)) 981 // Postpone processing relocation sections which are not specified in 982 // their explicit '--rename-section' commands until after their target 983 // sections are renamed. 984 // Dynamic relocation sections (i.e. ones with SHF_ALLOC) should be 985 // renamed only explicitly. Otherwise, renaming, for example, '.got.plt' 986 // would affect '.rela.plt', which is not desirable. 987 RelocSections.push_back(RelocSec); 988 } 989 990 // Rename relocation sections according to their target sections. 991 for (RelocationSectionBase *RelocSec : RelocSections) { 992 auto Iter = RenamedSections.find(RelocSec->getSection()); 993 if (Iter != RenamedSections.end()) 994 RelocSec->Name = (RelocSec->getNamePrefix() + (*Iter)->Name).str(); 995 } 996 } 997 998 // Add a prefix to allocated sections and their relocation sections. This 999 // should be done after renaming the section by Config.SectionToRename to 1000 // imitate the GNU objcopy behavior. 1001 if (!Config.AllocSectionsPrefix.empty()) { 1002 DenseSet<SectionBase *> PrefixedSections; 1003 for (SectionBase &Sec : Obj.sections()) { 1004 if (Sec.Flags & SHF_ALLOC) { 1005 Sec.Name = (Config.AllocSectionsPrefix + Sec.Name).str(); 1006 PrefixedSections.insert(&Sec); 1007 } else if (auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec)) { 1008 // Rename relocation sections associated to the allocated sections. 1009 // For example, if we rename .text to .prefix.text, we also rename 1010 // .rel.text to .rel.prefix.text. 1011 // 1012 // Dynamic relocation sections (SHT_REL[A] with SHF_ALLOC) are handled 1013 // above, e.g., .rela.plt is renamed to .prefix.rela.plt, not 1014 // .rela.prefix.plt since GNU objcopy does so. 1015 const SectionBase *TargetSec = RelocSec->getSection(); 1016 if (TargetSec && (TargetSec->Flags & SHF_ALLOC)) { 1017 // If the relocation section comes *after* the target section, we 1018 // don't add Config.AllocSectionsPrefix because we've already added 1019 // the prefix to TargetSec->Name. Otherwise, if the relocation 1020 // section comes *before* the target section, we add the prefix. 1021 if (PrefixedSections.count(TargetSec)) 1022 Sec.Name = (RelocSec->getNamePrefix() + TargetSec->Name).str(); 1023 else 1024 Sec.Name = (RelocSec->getNamePrefix() + Config.AllocSectionsPrefix + 1025 TargetSec->Name) 1026 .str(); 1027 } 1028 } 1029 } 1030 } 1031 1032 if (ELFConfig.EntryExpr) 1033 Obj.Entry = ELFConfig.EntryExpr(Obj.Entry); 1034 return Error::success(); 1035 } 1036 1037 static Error writeOutput(const CommonConfig &Config, Object &Obj, 1038 raw_ostream &Out, ElfType OutputElfType) { 1039 std::unique_ptr<Writer> Writer = 1040 createWriter(Config, Obj, Out, OutputElfType); 1041 if (Error E = Writer->finalize()) 1042 return E; 1043 return Writer->write(); 1044 } 1045 1046 Error objcopy::elf::executeObjcopyOnIHex(const CommonConfig &Config, 1047 const ELFConfig &ELFConfig, 1048 MemoryBuffer &In, raw_ostream &Out) { 1049 IHexReader Reader(&In); 1050 Expected<std::unique_ptr<Object>> Obj = Reader.create(true); 1051 if (!Obj) 1052 return Obj.takeError(); 1053 1054 const ElfType OutputElfType = 1055 getOutputElfType(Config.OutputArch.value_or(MachineInfo())); 1056 if (Error E = handleArgs(Config, ELFConfig, OutputElfType, **Obj)) 1057 return E; 1058 return writeOutput(Config, **Obj, Out, OutputElfType); 1059 } 1060 1061 Error objcopy::elf::executeObjcopyOnRawBinary(const CommonConfig &Config, 1062 const ELFConfig &ELFConfig, 1063 MemoryBuffer &In, 1064 raw_ostream &Out) { 1065 BinaryReader Reader(&In, ELFConfig.NewSymbolVisibility); 1066 Expected<std::unique_ptr<Object>> Obj = Reader.create(true); 1067 if (!Obj) 1068 return Obj.takeError(); 1069 1070 // Prefer OutputArch (-O<format>) if set, otherwise fallback to BinaryArch 1071 // (-B<arch>). 1072 const ElfType OutputElfType = 1073 getOutputElfType(Config.OutputArch.value_or(MachineInfo())); 1074 if (Error E = handleArgs(Config, ELFConfig, OutputElfType, **Obj)) 1075 return E; 1076 return writeOutput(Config, **Obj, Out, OutputElfType); 1077 } 1078 1079 Error objcopy::elf::executeObjcopyOnBinary(const CommonConfig &Config, 1080 const ELFConfig &ELFConfig, 1081 object::ELFObjectFileBase &In, 1082 raw_ostream &Out) { 1083 ELFReader Reader(&In, Config.ExtractPartition); 1084 Expected<std::unique_ptr<Object>> Obj = 1085 Reader.create(!Config.SymbolsToAdd.empty()); 1086 if (!Obj) 1087 return Obj.takeError(); 1088 // Prefer OutputArch (-O<format>) if set, otherwise infer it from the input. 1089 const ElfType OutputElfType = Config.OutputArch 1090 ? getOutputElfType(*Config.OutputArch) 1091 : getOutputElfType(In); 1092 1093 if (Error E = handleArgs(Config, ELFConfig, OutputElfType, **Obj)) 1094 return E; 1095 1096 if (Error E = writeOutput(Config, **Obj, Out, OutputElfType)) 1097 return createFileError(Config.InputFilename, std::move(E)); 1098 1099 return Error::success(); 1100 } 1101