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/STLExtras.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/ADT/Twine.h" 17 #include "llvm/BinaryFormat/ELF.h" 18 #include "llvm/MC/MCTargetOptions.h" 19 #include "llvm/ObjCopy/CommonConfig.h" 20 #include "llvm/ObjCopy/ELF/ELFConfig.h" 21 #include "llvm/Object/Binary.h" 22 #include "llvm/Object/ELFObjectFile.h" 23 #include "llvm/Object/ELFTypes.h" 24 #include "llvm/Object/Error.h" 25 #include "llvm/Option/Option.h" 26 #include "llvm/Support/Casting.h" 27 #include "llvm/Support/Compression.h" 28 #include "llvm/Support/Errc.h" 29 #include "llvm/Support/Error.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/ErrorOr.h" 32 #include "llvm/Support/FileSystem.h" 33 #include "llvm/Support/Memory.h" 34 #include "llvm/Support/Path.h" 35 #include "llvm/Support/raw_ostream.h" 36 #include <algorithm> 37 #include <cassert> 38 #include <cstdlib> 39 #include <functional> 40 #include <iterator> 41 #include <memory> 42 #include <string> 43 #include <system_error> 44 #include <utility> 45 46 using namespace llvm; 47 using namespace llvm::ELF; 48 using namespace llvm::objcopy; 49 using namespace llvm::objcopy::elf; 50 using namespace llvm::object; 51 52 using SectionPred = std::function<bool(const SectionBase &Sec)>; 53 54 static bool isDebugSection(const SectionBase &Sec) { 55 return StringRef(Sec.Name).startswith(".debug") || Sec.Name == ".gdb_index"; 56 } 57 58 static bool isDWOSection(const SectionBase &Sec) { 59 return StringRef(Sec.Name).endswith(".dwo"); 60 } 61 62 static bool onlyKeepDWOPred(const Object &Obj, const SectionBase &Sec) { 63 // We can't remove the section header string table. 64 if (&Sec == Obj.SectionNames) 65 return false; 66 // Short of keeping the string table we want to keep everything that is a DWO 67 // section and remove everything else. 68 return !isDWOSection(Sec); 69 } 70 71 static uint64_t getNewShfFlags(SectionFlag AllFlags) { 72 uint64_t NewFlags = 0; 73 if (AllFlags & SectionFlag::SecAlloc) 74 NewFlags |= ELF::SHF_ALLOC; 75 if (!(AllFlags & SectionFlag::SecReadonly)) 76 NewFlags |= ELF::SHF_WRITE; 77 if (AllFlags & SectionFlag::SecCode) 78 NewFlags |= ELF::SHF_EXECINSTR; 79 if (AllFlags & SectionFlag::SecMerge) 80 NewFlags |= ELF::SHF_MERGE; 81 if (AllFlags & SectionFlag::SecStrings) 82 NewFlags |= ELF::SHF_STRINGS; 83 if (AllFlags & SectionFlag::SecExclude) 84 NewFlags |= ELF::SHF_EXCLUDE; 85 return NewFlags; 86 } 87 88 static uint64_t getSectionFlagsPreserveMask(uint64_t OldFlags, 89 uint64_t NewFlags) { 90 // Preserve some flags which should not be dropped when setting flags. 91 // Also, preserve anything OS/processor dependant. 92 const uint64_t PreserveMask = 93 (ELF::SHF_COMPRESSED | ELF::SHF_GROUP | ELF::SHF_LINK_ORDER | 94 ELF::SHF_MASKOS | ELF::SHF_MASKPROC | ELF::SHF_TLS | 95 ELF::SHF_INFO_LINK) & 96 ~ELF::SHF_EXCLUDE; 97 return (OldFlags & PreserveMask) | (NewFlags & ~PreserveMask); 98 } 99 100 static void setSectionFlagsAndType(SectionBase &Sec, SectionFlag Flags) { 101 Sec.Flags = getSectionFlagsPreserveMask(Sec.Flags, getNewShfFlags(Flags)); 102 103 // In GNU objcopy, certain flags promote SHT_NOBITS to SHT_PROGBITS. This rule 104 // may promote more non-ALLOC sections than GNU objcopy, but it is fine as 105 // non-ALLOC SHT_NOBITS sections do not make much sense. 106 if (Sec.Type == SHT_NOBITS && 107 (!(Sec.Flags & ELF::SHF_ALLOC) || 108 Flags & (SectionFlag::SecContents | SectionFlag::SecLoad))) 109 Sec.Type = SHT_PROGBITS; 110 } 111 112 static ElfType getOutputElfType(const Binary &Bin) { 113 // Infer output ELF type from the input ELF object 114 if (isa<ELFObjectFile<ELF32LE>>(Bin)) 115 return ELFT_ELF32LE; 116 if (isa<ELFObjectFile<ELF64LE>>(Bin)) 117 return ELFT_ELF64LE; 118 if (isa<ELFObjectFile<ELF32BE>>(Bin)) 119 return ELFT_ELF32BE; 120 if (isa<ELFObjectFile<ELF64BE>>(Bin)) 121 return ELFT_ELF64BE; 122 llvm_unreachable("Invalid ELFType"); 123 } 124 125 static ElfType getOutputElfType(const MachineInfo &MI) { 126 // Infer output ELF type from the binary arch specified 127 if (MI.Is64Bit) 128 return MI.IsLittleEndian ? ELFT_ELF64LE : ELFT_ELF64BE; 129 else 130 return MI.IsLittleEndian ? ELFT_ELF32LE : ELFT_ELF32BE; 131 } 132 133 static std::unique_ptr<Writer> createELFWriter(const CommonConfig &Config, 134 Object &Obj, raw_ostream &Out, 135 ElfType OutputElfType) { 136 // Depending on the initial ELFT and OutputFormat we need a different Writer. 137 switch (OutputElfType) { 138 case ELFT_ELF32LE: 139 return std::make_unique<ELFWriter<ELF32LE>>(Obj, Out, !Config.StripSections, 140 Config.OnlyKeepDebug); 141 case ELFT_ELF64LE: 142 return std::make_unique<ELFWriter<ELF64LE>>(Obj, Out, !Config.StripSections, 143 Config.OnlyKeepDebug); 144 case ELFT_ELF32BE: 145 return std::make_unique<ELFWriter<ELF32BE>>(Obj, Out, !Config.StripSections, 146 Config.OnlyKeepDebug); 147 case ELFT_ELF64BE: 148 return std::make_unique<ELFWriter<ELF64BE>>(Obj, Out, !Config.StripSections, 149 Config.OnlyKeepDebug); 150 } 151 llvm_unreachable("Invalid output format"); 152 } 153 154 static std::unique_ptr<Writer> createWriter(const CommonConfig &Config, 155 Object &Obj, raw_ostream &Out, 156 ElfType OutputElfType) { 157 switch (Config.OutputFormat) { 158 case FileFormat::Binary: 159 return std::make_unique<BinaryWriter>(Obj, Out); 160 case FileFormat::IHex: 161 return std::make_unique<IHexWriter>(Obj, Out); 162 default: 163 return createELFWriter(Config, Obj, Out, OutputElfType); 164 } 165 } 166 167 template <class... Ts> 168 static Error makeStringError(std::error_code EC, const Twine &Msg, 169 Ts &&...Args) { 170 std::string FullMsg = (EC.message() + ": " + Msg).str(); 171 return createStringError(EC, FullMsg.c_str(), std::forward<Ts>(Args)...); 172 } 173 174 static Error dumpSectionToFile(StringRef SecName, StringRef Filename, 175 Object &Obj) { 176 for (auto &Sec : Obj.sections()) { 177 if (Sec.Name == SecName) { 178 if (Sec.Type == SHT_NOBITS) 179 return createStringError(object_error::parse_failed, 180 "cannot dump section '%s': it has no contents", 181 SecName.str().c_str()); 182 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 183 FileOutputBuffer::create(Filename, Sec.OriginalData.size()); 184 if (!BufferOrErr) 185 return BufferOrErr.takeError(); 186 std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr); 187 std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), 188 Buf->getBufferStart()); 189 if (Error E = Buf->commit()) 190 return E; 191 return Error::success(); 192 } 193 } 194 return createStringError(object_error::parse_failed, "section '%s' not found", 195 SecName.str().c_str()); 196 } 197 198 static bool isCompressable(const SectionBase &Sec) { 199 return !(Sec.Flags & ELF::SHF_COMPRESSED) && 200 StringRef(Sec.Name).startswith(".debug"); 201 } 202 203 static Error replaceDebugSections( 204 Object &Obj, function_ref<bool(const SectionBase &)> ShouldReplace, 205 function_ref<Expected<SectionBase *>(const SectionBase *)> AddSection) { 206 // Build a list of the debug sections we are going to replace. 207 // We can't call `AddSection` while iterating over sections, 208 // because it would mutate the sections array. 209 SmallVector<SectionBase *, 13> ToReplace; 210 for (auto &Sec : Obj.sections()) 211 if (ShouldReplace(Sec)) 212 ToReplace.push_back(&Sec); 213 214 // Build a mapping from original section to a new one. 215 DenseMap<SectionBase *, SectionBase *> FromTo; 216 for (SectionBase *S : ToReplace) { 217 Expected<SectionBase *> NewSection = AddSection(S); 218 if (!NewSection) 219 return NewSection.takeError(); 220 221 FromTo[S] = *NewSection; 222 } 223 224 return Obj.replaceSections(FromTo); 225 } 226 227 static bool isAArch64MappingSymbol(const Symbol &Sym) { 228 if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE || 229 Sym.getShndx() == SHN_UNDEF) 230 return false; 231 StringRef Name = Sym.Name; 232 if (!Name.consume_front("$x") && !Name.consume_front("$d")) 233 return false; 234 return Name.empty() || Name.startswith("."); 235 } 236 237 static bool isArmMappingSymbol(const Symbol &Sym) { 238 if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE || 239 Sym.getShndx() == SHN_UNDEF) 240 return false; 241 StringRef Name = Sym.Name; 242 if (!Name.consume_front("$a") && !Name.consume_front("$d") && 243 !Name.consume_front("$t")) 244 return false; 245 return Name.empty() || Name.startswith("."); 246 } 247 248 // Check if the symbol should be preserved because it is required by ABI. 249 static bool isRequiredByABISymbol(const Object &Obj, const Symbol &Sym) { 250 switch (Obj.Machine) { 251 case EM_AARCH64: 252 // Mapping symbols should be preserved for a relocatable object file. 253 return Obj.isRelocatable() && isAArch64MappingSymbol(Sym); 254 case EM_ARM: 255 // Mapping symbols should be preserved for a relocatable object file. 256 return Obj.isRelocatable() && isArmMappingSymbol(Sym); 257 default: 258 return false; 259 } 260 } 261 262 static bool isUnneededSymbol(const Symbol &Sym) { 263 return !Sym.Referenced && 264 (Sym.Binding == STB_LOCAL || Sym.getShndx() == SHN_UNDEF) && 265 Sym.Type != STT_SECTION; 266 } 267 268 static Error updateAndRemoveSymbols(const CommonConfig &Config, 269 const ELFConfig &ELFConfig, Object &Obj) { 270 // TODO: update or remove symbols only if there is an option that affects 271 // them. 272 if (!Obj.SymbolTable) 273 return Error::success(); 274 275 Obj.SymbolTable->updateSymbols([&](Symbol &Sym) { 276 // Common and undefined symbols don't make sense as local symbols, and can 277 // even cause crashes if we localize those, so skip them. 278 if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF && 279 ((ELFConfig.LocalizeHidden && 280 (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) || 281 Config.SymbolsToLocalize.matches(Sym.Name))) 282 Sym.Binding = STB_LOCAL; 283 284 // Note: these two globalize flags have very similar names but different 285 // meanings: 286 // 287 // --globalize-symbol: promote a symbol to global 288 // --keep-global-symbol: all symbols except for these should be made local 289 // 290 // If --globalize-symbol is specified for a given symbol, it will be 291 // global in the output file even if it is not included via 292 // --keep-global-symbol. Because of that, make sure to check 293 // --globalize-symbol second. 294 if (!Config.SymbolsToKeepGlobal.empty() && 295 !Config.SymbolsToKeepGlobal.matches(Sym.Name) && 296 Sym.getShndx() != SHN_UNDEF) 297 Sym.Binding = STB_LOCAL; 298 299 if (Config.SymbolsToGlobalize.matches(Sym.Name) && 300 Sym.getShndx() != SHN_UNDEF) 301 Sym.Binding = STB_GLOBAL; 302 303 // SymbolsToWeaken applies to both STB_GLOBAL and STB_GNU_UNIQUE. 304 if (Config.SymbolsToWeaken.matches(Sym.Name) && Sym.Binding != STB_LOCAL) 305 Sym.Binding = STB_WEAK; 306 307 if (Config.Weaken && Sym.Binding != STB_LOCAL && 308 Sym.getShndx() != SHN_UNDEF) 309 Sym.Binding = STB_WEAK; 310 311 const auto I = Config.SymbolsToRename.find(Sym.Name); 312 if (I != Config.SymbolsToRename.end()) 313 Sym.Name = std::string(I->getValue()); 314 315 if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION) 316 Sym.Name = (Config.SymbolsPrefix + Sym.Name).str(); 317 }); 318 319 // The purpose of this loop is to mark symbols referenced by sections 320 // (like GroupSection or RelocationSection). This way, we know which 321 // symbols are still 'needed' and which are not. 322 if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty() || 323 !Config.OnlySection.empty()) { 324 for (SectionBase &Sec : Obj.sections()) 325 Sec.markSymbols(); 326 } 327 328 auto RemoveSymbolsPred = [&](const Symbol &Sym) { 329 if (Config.SymbolsToKeep.matches(Sym.Name) || 330 (ELFConfig.KeepFileSymbols && Sym.Type == STT_FILE)) 331 return false; 332 333 if (Config.SymbolsToRemove.matches(Sym.Name)) 334 return true; 335 336 if (Config.StripAll || Config.StripAllGNU) 337 return true; 338 339 if (isRequiredByABISymbol(Obj, Sym)) 340 return false; 341 342 if (Config.StripDebug && Sym.Type == STT_FILE) 343 return true; 344 345 if ((Config.DiscardMode == DiscardType::All || 346 (Config.DiscardMode == DiscardType::Locals && 347 StringRef(Sym.Name).startswith(".L"))) && 348 Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF && 349 Sym.Type != STT_FILE && Sym.Type != STT_SECTION) 350 return true; 351 352 if ((Config.StripUnneeded || 353 Config.UnneededSymbolsToRemove.matches(Sym.Name)) && 354 (!Obj.isRelocatable() || isUnneededSymbol(Sym))) 355 return true; 356 357 // We want to remove undefined symbols if all references have been stripped. 358 if (!Config.OnlySection.empty() && !Sym.Referenced && 359 Sym.getShndx() == SHN_UNDEF) 360 return true; 361 362 return false; 363 }; 364 365 return Obj.removeSymbols(RemoveSymbolsPred); 366 } 367 368 static Error replaceAndRemoveSections(const CommonConfig &Config, 369 const ELFConfig &ELFConfig, Object &Obj) { 370 SectionPred RemovePred = [](const SectionBase &) { return false; }; 371 372 // Removes: 373 if (!Config.ToRemove.empty()) { 374 RemovePred = [&Config](const SectionBase &Sec) { 375 return Config.ToRemove.matches(Sec.Name); 376 }; 377 } 378 379 if (Config.StripDWO) 380 RemovePred = [RemovePred](const SectionBase &Sec) { 381 return isDWOSection(Sec) || RemovePred(Sec); 382 }; 383 384 if (Config.ExtractDWO) 385 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 386 return onlyKeepDWOPred(Obj, Sec) || RemovePred(Sec); 387 }; 388 389 if (Config.StripAllGNU) 390 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 391 if (RemovePred(Sec)) 392 return true; 393 if ((Sec.Flags & SHF_ALLOC) != 0) 394 return false; 395 if (&Sec == Obj.SectionNames) 396 return false; 397 switch (Sec.Type) { 398 case SHT_SYMTAB: 399 case SHT_REL: 400 case SHT_RELA: 401 case SHT_STRTAB: 402 return true; 403 } 404 return isDebugSection(Sec); 405 }; 406 407 if (Config.StripSections) { 408 RemovePred = [RemovePred](const SectionBase &Sec) { 409 return RemovePred(Sec) || Sec.ParentSegment == nullptr; 410 }; 411 } 412 413 if (Config.StripDebug || Config.StripUnneeded) { 414 RemovePred = [RemovePred](const SectionBase &Sec) { 415 return RemovePred(Sec) || isDebugSection(Sec); 416 }; 417 } 418 419 if (Config.StripNonAlloc) 420 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 421 if (RemovePred(Sec)) 422 return true; 423 if (&Sec == Obj.SectionNames) 424 return false; 425 return (Sec.Flags & SHF_ALLOC) == 0 && Sec.ParentSegment == nullptr; 426 }; 427 428 if (Config.StripAll) 429 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 430 if (RemovePred(Sec)) 431 return true; 432 if (&Sec == Obj.SectionNames) 433 return false; 434 if (StringRef(Sec.Name).startswith(".gnu.warning")) 435 return false; 436 // We keep the .ARM.attribute section to maintain compatibility 437 // with Debian derived distributions. This is a bug in their 438 // patchset as documented here: 439 // https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=943798 440 if (Sec.Type == SHT_ARM_ATTRIBUTES) 441 return false; 442 if (Sec.ParentSegment != nullptr) 443 return false; 444 return (Sec.Flags & SHF_ALLOC) == 0; 445 }; 446 447 if (Config.ExtractPartition || Config.ExtractMainPartition) { 448 RemovePred = [RemovePred](const SectionBase &Sec) { 449 if (RemovePred(Sec)) 450 return true; 451 if (Sec.Type == SHT_LLVM_PART_EHDR || Sec.Type == SHT_LLVM_PART_PHDR) 452 return true; 453 return (Sec.Flags & SHF_ALLOC) != 0 && !Sec.ParentSegment; 454 }; 455 } 456 457 // Explicit copies: 458 if (!Config.OnlySection.empty()) { 459 RemovePred = [&Config, RemovePred, &Obj](const SectionBase &Sec) { 460 // Explicitly keep these sections regardless of previous removes. 461 if (Config.OnlySection.matches(Sec.Name)) 462 return false; 463 464 // Allow all implicit removes. 465 if (RemovePred(Sec)) 466 return true; 467 468 // Keep special sections. 469 if (Obj.SectionNames == &Sec) 470 return false; 471 if (Obj.SymbolTable == &Sec || 472 (Obj.SymbolTable && Obj.SymbolTable->getStrTab() == &Sec)) 473 return false; 474 475 // Remove everything else. 476 return true; 477 }; 478 } 479 480 if (!Config.KeepSection.empty()) { 481 RemovePred = [&Config, RemovePred](const SectionBase &Sec) { 482 // Explicitly keep these sections regardless of previous removes. 483 if (Config.KeepSection.matches(Sec.Name)) 484 return false; 485 // Otherwise defer to RemovePred. 486 return RemovePred(Sec); 487 }; 488 } 489 490 // This has to be the last predicate assignment. 491 // If the option --keep-symbol has been specified 492 // and at least one of those symbols is present 493 // (equivalently, the updated symbol table is not empty) 494 // the symbol table and the string table should not be removed. 495 if ((!Config.SymbolsToKeep.empty() || ELFConfig.KeepFileSymbols) && 496 Obj.SymbolTable && !Obj.SymbolTable->empty()) { 497 RemovePred = [&Obj, RemovePred](const SectionBase &Sec) { 498 if (&Sec == Obj.SymbolTable || &Sec == Obj.SymbolTable->getStrTab()) 499 return false; 500 return RemovePred(Sec); 501 }; 502 } 503 504 if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred)) 505 return E; 506 507 if (Config.CompressionType != DebugCompressionType::None) { 508 if (Error Err = replaceDebugSections( 509 Obj, isCompressable, 510 [&Config, &Obj](const SectionBase *S) -> Expected<SectionBase *> { 511 return &Obj.addSection<CompressedSection>( 512 CompressedSection(*S, Config.CompressionType, Obj.Is64Bits)); 513 })) 514 return Err; 515 } else if (Config.DecompressDebugSections) { 516 if (Error Err = replaceDebugSections( 517 Obj, 518 [](const SectionBase &S) { return isa<CompressedSection>(&S); }, 519 [&Obj](const SectionBase *S) { 520 const CompressedSection *CS = cast<CompressedSection>(S); 521 return &Obj.addSection<DecompressedSection>(*CS); 522 })) 523 return Err; 524 } 525 526 return Error::success(); 527 } 528 529 // Add symbol to the Object symbol table with the specified properties. 530 static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo, 531 uint8_t DefaultVisibility) { 532 SectionBase *Sec = Obj.findSection(SymInfo.SectionName); 533 uint64_t Value = Sec ? Sec->Addr + SymInfo.Value : SymInfo.Value; 534 535 uint8_t Bind = ELF::STB_GLOBAL; 536 uint8_t Type = ELF::STT_NOTYPE; 537 uint8_t Visibility = DefaultVisibility; 538 539 for (SymbolFlag FlagValue : SymInfo.Flags) 540 switch (FlagValue) { 541 case SymbolFlag::Global: 542 Bind = ELF::STB_GLOBAL; 543 break; 544 case SymbolFlag::Local: 545 Bind = ELF::STB_LOCAL; 546 break; 547 case SymbolFlag::Weak: 548 Bind = ELF::STB_WEAK; 549 break; 550 case SymbolFlag::Default: 551 Visibility = ELF::STV_DEFAULT; 552 break; 553 case SymbolFlag::Hidden: 554 Visibility = ELF::STV_HIDDEN; 555 break; 556 case SymbolFlag::Protected: 557 Visibility = ELF::STV_PROTECTED; 558 break; 559 case SymbolFlag::File: 560 Type = ELF::STT_FILE; 561 break; 562 case SymbolFlag::Section: 563 Type = ELF::STT_SECTION; 564 break; 565 case SymbolFlag::Object: 566 Type = ELF::STT_OBJECT; 567 break; 568 case SymbolFlag::Function: 569 Type = ELF::STT_FUNC; 570 break; 571 case SymbolFlag::IndirectFunction: 572 Type = ELF::STT_GNU_IFUNC; 573 break; 574 default: /* Other flag values are ignored for ELF. */ 575 break; 576 }; 577 578 Obj.SymbolTable->addSymbol( 579 SymInfo.SymbolName, Bind, Type, Sec, Value, Visibility, 580 Sec ? (uint16_t)SYMBOL_SIMPLE_INDEX : (uint16_t)SHN_ABS, 0); 581 } 582 583 static Error 584 handleUserSection(const NewSectionInfo &NewSection, 585 function_ref<Error(StringRef, ArrayRef<uint8_t>)> F) { 586 ArrayRef<uint8_t> Data(reinterpret_cast<const uint8_t *>( 587 NewSection.SectionData->getBufferStart()), 588 NewSection.SectionData->getBufferSize()); 589 return F(NewSection.SectionName, Data); 590 } 591 592 // This function handles the high level operations of GNU objcopy including 593 // handling command line options. It's important to outline certain properties 594 // we expect to hold of the command line operations. Any operation that "keeps" 595 // should keep regardless of a remove. Additionally any removal should respect 596 // any previous removals. Lastly whether or not something is removed shouldn't 597 // depend a) on the order the options occur in or b) on some opaque priority 598 // system. The only priority is that keeps/copies overrule removes. 599 static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig, 600 Object &Obj) { 601 if (Config.OutputArch) { 602 Obj.Machine = Config.OutputArch->EMachine; 603 Obj.OSABI = Config.OutputArch->OSABI; 604 } 605 606 if (!Config.SplitDWO.empty() && Config.ExtractDWO) { 607 return Obj.removeSections( 608 ELFConfig.AllowBrokenLinks, 609 [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); }); 610 } 611 612 // Dump sections before add/remove for compatibility with GNU objcopy. 613 for (StringRef Flag : Config.DumpSection) { 614 StringRef SectionName; 615 StringRef FileName; 616 std::tie(SectionName, FileName) = Flag.split('='); 617 if (Error E = dumpSectionToFile(SectionName, FileName, Obj)) 618 return E; 619 } 620 621 // It is important to remove the sections first. For example, we want to 622 // remove the relocation sections before removing the symbols. That allows 623 // us to avoid reporting the inappropriate errors about removing symbols 624 // named in relocations. 625 if (Error E = replaceAndRemoveSections(Config, ELFConfig, Obj)) 626 return E; 627 628 if (Error E = updateAndRemoveSymbols(Config, ELFConfig, Obj)) 629 return E; 630 631 if (!Config.SetSectionAlignment.empty()) { 632 for (SectionBase &Sec : Obj.sections()) { 633 auto I = Config.SetSectionAlignment.find(Sec.Name); 634 if (I != Config.SetSectionAlignment.end()) 635 Sec.Align = I->second; 636 } 637 } 638 639 if (Config.OnlyKeepDebug) 640 for (auto &Sec : Obj.sections()) 641 if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE) 642 Sec.Type = SHT_NOBITS; 643 644 for (const NewSectionInfo &AddedSection : Config.AddSection) { 645 auto AddSection = [&](StringRef Name, ArrayRef<uint8_t> Data) { 646 OwnedDataSection &NewSection = 647 Obj.addSection<OwnedDataSection>(Name, Data); 648 if (Name.startswith(".note") && Name != ".note.GNU-stack") 649 NewSection.Type = SHT_NOTE; 650 return Error::success(); 651 }; 652 if (Error E = handleUserSection(AddedSection, AddSection)) 653 return E; 654 } 655 656 for (const NewSectionInfo &NewSection : Config.UpdateSection) { 657 auto UpdateSection = [&](StringRef Name, ArrayRef<uint8_t> Data) { 658 return Obj.updateSection(Name, Data); 659 }; 660 if (Error E = handleUserSection(NewSection, UpdateSection)) 661 return E; 662 } 663 664 if (!Config.AddGnuDebugLink.empty()) 665 Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink, 666 Config.GnuDebugLinkCRC32); 667 668 // If the symbol table was previously removed, we need to create a new one 669 // before adding new symbols. 670 if (!Obj.SymbolTable && !Config.SymbolsToAdd.empty()) 671 if (Error E = Obj.addNewSymbolTable()) 672 return E; 673 674 for (const NewSymbolInfo &SI : Config.SymbolsToAdd) 675 addSymbol(Obj, SI, ELFConfig.NewSymbolVisibility); 676 677 // --set-section-{flags,type} work with sections added by --add-section. 678 if (!Config.SetSectionFlags.empty() || !Config.SetSectionType.empty()) { 679 for (auto &Sec : Obj.sections()) { 680 const auto Iter = Config.SetSectionFlags.find(Sec.Name); 681 if (Iter != Config.SetSectionFlags.end()) { 682 const SectionFlagsUpdate &SFU = Iter->second; 683 setSectionFlagsAndType(Sec, SFU.NewFlags); 684 } 685 auto It2 = Config.SetSectionType.find(Sec.Name); 686 if (It2 != Config.SetSectionType.end()) 687 Sec.Type = It2->second; 688 } 689 } 690 691 if (!Config.SectionsToRename.empty()) { 692 std::vector<RelocationSectionBase *> RelocSections; 693 DenseSet<SectionBase *> RenamedSections; 694 for (SectionBase &Sec : Obj.sections()) { 695 auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec); 696 const auto Iter = Config.SectionsToRename.find(Sec.Name); 697 if (Iter != Config.SectionsToRename.end()) { 698 const SectionRename &SR = Iter->second; 699 Sec.Name = std::string(SR.NewName); 700 if (SR.NewFlags) 701 setSectionFlagsAndType(Sec, *SR.NewFlags); 702 RenamedSections.insert(&Sec); 703 } else if (RelocSec && !(Sec.Flags & SHF_ALLOC)) 704 // Postpone processing relocation sections which are not specified in 705 // their explicit '--rename-section' commands until after their target 706 // sections are renamed. 707 // Dynamic relocation sections (i.e. ones with SHF_ALLOC) should be 708 // renamed only explicitly. Otherwise, renaming, for example, '.got.plt' 709 // would affect '.rela.plt', which is not desirable. 710 RelocSections.push_back(RelocSec); 711 } 712 713 // Rename relocation sections according to their target sections. 714 for (RelocationSectionBase *RelocSec : RelocSections) { 715 auto Iter = RenamedSections.find(RelocSec->getSection()); 716 if (Iter != RenamedSections.end()) 717 RelocSec->Name = (RelocSec->getNamePrefix() + (*Iter)->Name).str(); 718 } 719 } 720 721 // Add a prefix to allocated sections and their relocation sections. This 722 // should be done after renaming the section by Config.SectionToRename to 723 // imitate the GNU objcopy behavior. 724 if (!Config.AllocSectionsPrefix.empty()) { 725 DenseSet<SectionBase *> PrefixedSections; 726 for (SectionBase &Sec : Obj.sections()) { 727 if (Sec.Flags & SHF_ALLOC) { 728 Sec.Name = (Config.AllocSectionsPrefix + Sec.Name).str(); 729 PrefixedSections.insert(&Sec); 730 } else if (auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec)) { 731 // Rename relocation sections associated to the allocated sections. 732 // For example, if we rename .text to .prefix.text, we also rename 733 // .rel.text to .rel.prefix.text. 734 // 735 // Dynamic relocation sections (SHT_REL[A] with SHF_ALLOC) are handled 736 // above, e.g., .rela.plt is renamed to .prefix.rela.plt, not 737 // .rela.prefix.plt since GNU objcopy does so. 738 const SectionBase *TargetSec = RelocSec->getSection(); 739 if (TargetSec && (TargetSec->Flags & SHF_ALLOC)) { 740 // If the relocation section comes *after* the target section, we 741 // don't add Config.AllocSectionsPrefix because we've already added 742 // the prefix to TargetSec->Name. Otherwise, if the relocation 743 // section comes *before* the target section, we add the prefix. 744 if (PrefixedSections.count(TargetSec)) 745 Sec.Name = (RelocSec->getNamePrefix() + TargetSec->Name).str(); 746 else 747 Sec.Name = (RelocSec->getNamePrefix() + Config.AllocSectionsPrefix + 748 TargetSec->Name) 749 .str(); 750 } 751 } 752 } 753 } 754 755 if (ELFConfig.EntryExpr) 756 Obj.Entry = ELFConfig.EntryExpr(Obj.Entry); 757 return Error::success(); 758 } 759 760 static Error writeOutput(const CommonConfig &Config, Object &Obj, 761 raw_ostream &Out, ElfType OutputElfType) { 762 std::unique_ptr<Writer> Writer = 763 createWriter(Config, Obj, Out, OutputElfType); 764 if (Error E = Writer->finalize()) 765 return E; 766 return Writer->write(); 767 } 768 769 Error objcopy::elf::executeObjcopyOnIHex(const CommonConfig &Config, 770 const ELFConfig &ELFConfig, 771 MemoryBuffer &In, raw_ostream &Out) { 772 IHexReader Reader(&In); 773 Expected<std::unique_ptr<Object>> Obj = Reader.create(true); 774 if (!Obj) 775 return Obj.takeError(); 776 777 const ElfType OutputElfType = 778 getOutputElfType(Config.OutputArch.value_or(MachineInfo())); 779 if (Error E = handleArgs(Config, ELFConfig, **Obj)) 780 return E; 781 return writeOutput(Config, **Obj, Out, OutputElfType); 782 } 783 784 Error objcopy::elf::executeObjcopyOnRawBinary(const CommonConfig &Config, 785 const ELFConfig &ELFConfig, 786 MemoryBuffer &In, 787 raw_ostream &Out) { 788 BinaryReader Reader(&In, ELFConfig.NewSymbolVisibility); 789 Expected<std::unique_ptr<Object>> Obj = Reader.create(true); 790 if (!Obj) 791 return Obj.takeError(); 792 793 // Prefer OutputArch (-O<format>) if set, otherwise fallback to BinaryArch 794 // (-B<arch>). 795 const ElfType OutputElfType = 796 getOutputElfType(Config.OutputArch.value_or(MachineInfo())); 797 if (Error E = handleArgs(Config, ELFConfig, **Obj)) 798 return E; 799 return writeOutput(Config, **Obj, Out, OutputElfType); 800 } 801 802 Error objcopy::elf::executeObjcopyOnBinary(const CommonConfig &Config, 803 const ELFConfig &ELFConfig, 804 object::ELFObjectFileBase &In, 805 raw_ostream &Out) { 806 ELFReader Reader(&In, Config.ExtractPartition); 807 Expected<std::unique_ptr<Object>> Obj = 808 Reader.create(!Config.SymbolsToAdd.empty()); 809 if (!Obj) 810 return Obj.takeError(); 811 // Prefer OutputArch (-O<format>) if set, otherwise infer it from the input. 812 const ElfType OutputElfType = Config.OutputArch 813 ? getOutputElfType(*Config.OutputArch) 814 : getOutputElfType(In); 815 816 if (Error E = handleArgs(Config, ELFConfig, **Obj)) 817 return createFileError(Config.InputFilename, std::move(E)); 818 819 if (Error E = writeOutput(Config, **Obj, Out, OutputElfType)) 820 return createFileError(Config.InputFilename, std::move(E)); 821 822 return Error::success(); 823 } 824