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