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