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 Object &Obj) { 190 for (auto &Sec : Obj.sections()) { 191 if (Sec.Name == SecName) { 192 if (Sec.Type == SHT_NOBITS) 193 return createStringError(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 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 E; 205 return Error::success(); 206 } 207 } 208 return createStringError(object_error::parse_failed, "section '%s' not found", 209 SecName.str().c_str()); 210 } 211 212 Error Object::compressOrDecompressSections(const CommonConfig &Config) { 213 // Build a list of sections we are going to replace. 214 // We can't call `addSection` while iterating over sections, 215 // because it would mutate the sections array. 216 SmallVector<std::pair<SectionBase *, std::function<SectionBase *()>>, 0> 217 ToReplace; 218 for (SectionBase &Sec : sections()) { 219 std::optional<DebugCompressionType> CType; 220 for (auto &[Matcher, T] : Config.compressSections) 221 if (Matcher.matches(Sec.Name)) 222 CType = T; 223 // Handle --compress-debug-sections and --decompress-debug-sections, which 224 // apply to non-ALLOC debug sections. 225 if (!(Sec.Flags & SHF_ALLOC) && StringRef(Sec.Name).starts_with(".debug")) { 226 if (Config.CompressionType != DebugCompressionType::None) 227 CType = Config.CompressionType; 228 else if (Config.DecompressDebugSections) 229 CType = DebugCompressionType::None; 230 } 231 if (!CType) 232 continue; 233 234 if (Sec.ParentSegment) 235 return createStringError( 236 errc::invalid_argument, 237 "section '" + Sec.Name + 238 "' within a segment cannot be (de)compressed"); 239 240 if (auto *CS = dyn_cast<CompressedSection>(&Sec)) { 241 if (*CType == DebugCompressionType::None) 242 ToReplace.emplace_back( 243 &Sec, [=] { return &addSection<DecompressedSection>(*CS); }); 244 } else if (*CType != DebugCompressionType::None) { 245 ToReplace.emplace_back(&Sec, [=, S = &Sec] { 246 return &addSection<CompressedSection>( 247 CompressedSection(*S, *CType, Is64Bits)); 248 }); 249 } 250 } 251 252 DenseMap<SectionBase *, SectionBase *> FromTo; 253 for (auto [S, Func] : ToReplace) 254 FromTo[S] = Func(); 255 return replaceSections(FromTo); 256 } 257 258 static bool isAArch64MappingSymbol(const Symbol &Sym) { 259 if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE || 260 Sym.getShndx() == SHN_UNDEF) 261 return false; 262 StringRef Name = Sym.Name; 263 if (!Name.consume_front("$x") && !Name.consume_front("$d")) 264 return false; 265 return Name.empty() || Name.starts_with("."); 266 } 267 268 static bool isArmMappingSymbol(const Symbol &Sym) { 269 if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE || 270 Sym.getShndx() == SHN_UNDEF) 271 return false; 272 StringRef Name = Sym.Name; 273 if (!Name.consume_front("$a") && !Name.consume_front("$d") && 274 !Name.consume_front("$t")) 275 return false; 276 return Name.empty() || Name.starts_with("."); 277 } 278 279 // Check if the symbol should be preserved because it is required by ABI. 280 static bool isRequiredByABISymbol(const Object &Obj, const Symbol &Sym) { 281 switch (Obj.Machine) { 282 case EM_AARCH64: 283 // Mapping symbols should be preserved for a relocatable object file. 284 return Obj.isRelocatable() && isAArch64MappingSymbol(Sym); 285 case EM_ARM: 286 // Mapping symbols should be preserved for a relocatable object file. 287 return Obj.isRelocatable() && isArmMappingSymbol(Sym); 288 default: 289 return false; 290 } 291 } 292 293 static bool isUnneededSymbol(const Symbol &Sym) { 294 return !Sym.Referenced && 295 (Sym.Binding == STB_LOCAL || Sym.getShndx() == SHN_UNDEF) && 296 Sym.Type != STT_SECTION; 297 } 298 299 static Error updateAndRemoveSymbols(const CommonConfig &Config, 300 const ELFConfig &ELFConfig, Object &Obj) { 301 // TODO: update or remove symbols only if there is an option that affects 302 // them. 303 if (!Obj.SymbolTable) 304 return Error::success(); 305 306 Obj.SymbolTable->updateSymbols([&](Symbol &Sym) { 307 if (Config.SymbolsToSkip.matches(Sym.Name)) 308 return; 309 310 // Common and undefined symbols don't make sense as local symbols, and can 311 // even cause crashes if we localize those, so skip them. 312 if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF && 313 ((ELFConfig.LocalizeHidden && 314 (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) || 315 Config.SymbolsToLocalize.matches(Sym.Name))) 316 Sym.Binding = STB_LOCAL; 317 318 for (auto &[Matcher, Visibility] : ELFConfig.SymbolsToSetVisibility) 319 if (Matcher.matches(Sym.Name)) 320 Sym.Visibility = Visibility; 321 322 // Note: these two globalize flags have very similar names but different 323 // meanings: 324 // 325 // --globalize-symbol: promote a symbol to global 326 // --keep-global-symbol: all symbols except for these should be made local 327 // 328 // If --globalize-symbol is specified for a given symbol, it will be 329 // global in the output file even if it is not included via 330 // --keep-global-symbol. Because of that, make sure to check 331 // --globalize-symbol second. 332 if (!Config.SymbolsToKeepGlobal.empty() && 333 !Config.SymbolsToKeepGlobal.matches(Sym.Name) && 334 Sym.getShndx() != SHN_UNDEF) 335 Sym.Binding = STB_LOCAL; 336 337 if (Config.SymbolsToGlobalize.matches(Sym.Name) && 338 Sym.getShndx() != SHN_UNDEF) 339 Sym.Binding = STB_GLOBAL; 340 341 // SymbolsToWeaken applies to both STB_GLOBAL and STB_GNU_UNIQUE. 342 if (Config.SymbolsToWeaken.matches(Sym.Name) && Sym.Binding != STB_LOCAL) 343 Sym.Binding = STB_WEAK; 344 345 if (Config.Weaken && Sym.Binding != STB_LOCAL && 346 Sym.getShndx() != SHN_UNDEF) 347 Sym.Binding = STB_WEAK; 348 349 const auto I = Config.SymbolsToRename.find(Sym.Name); 350 if (I != Config.SymbolsToRename.end()) 351 Sym.Name = std::string(I->getValue()); 352 353 if (!Config.SymbolsPrefixRemove.empty() && Sym.Type != STT_SECTION) 354 if (Sym.Name.compare(0, Config.SymbolsPrefixRemove.size(), 355 Config.SymbolsPrefixRemove) == 0) 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()) { 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.DiscardMode == DiscardType::All || 389 (Config.DiscardMode == DiscardType::Locals && 390 StringRef(Sym.Name).starts_with(".L"))) && 391 Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF && 392 Sym.Type != STT_FILE && Sym.Type != STT_SECTION) 393 return true; 394 395 if ((Config.StripUnneeded || 396 Config.UnneededSymbolsToRemove.matches(Sym.Name)) && 397 (!Obj.isRelocatable() || isUnneededSymbol(Sym))) 398 return true; 399 400 // We want to remove undefined symbols if all references have been stripped. 401 if (!Config.OnlySection.empty() && !Sym.Referenced && 402 Sym.getShndx() == SHN_UNDEF) 403 return true; 404 405 return false; 406 }; 407 408 return Obj.removeSymbols(RemoveSymbolsPred); 409 } 410 411 static Error replaceAndRemoveSections(const CommonConfig &Config, 412 const ELFConfig &ELFConfig, Object &Obj) { 413 SectionPred RemovePred = [](const SectionBase &) { return false; }; 414 415 // Removes: 416 if (!Config.ToRemove.empty()) { 417 RemovePred = [&Config](const SectionBase &Sec) { 418 return Config.ToRemove.matches(Sec.Name); 419 }; 420 } 421 422 if (Config.StripDWO) 423 RemovePred = [RemovePred](const SectionBase &Sec) { 424 return isDWOSection(Sec) || RemovePred(Sec); 425 }; 426 427 if (Config.ExtractDWO) 428 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 429 return onlyKeepDWOPred(Obj, Sec) || RemovePred(Sec); 430 }; 431 432 if (Config.StripAllGNU) 433 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 434 if (RemovePred(Sec)) 435 return true; 436 if ((Sec.Flags & SHF_ALLOC) != 0) 437 return false; 438 if (&Sec == Obj.SectionNames) 439 return false; 440 switch (Sec.Type) { 441 case SHT_SYMTAB: 442 case SHT_REL: 443 case SHT_RELA: 444 case SHT_STRTAB: 445 return true; 446 } 447 return isDebugSection(Sec); 448 }; 449 450 if (Config.StripSections) { 451 RemovePred = [RemovePred](const SectionBase &Sec) { 452 return RemovePred(Sec) || Sec.ParentSegment == nullptr; 453 }; 454 } 455 456 if (Config.StripDebug || Config.StripUnneeded) { 457 RemovePred = [RemovePred](const SectionBase &Sec) { 458 return RemovePred(Sec) || isDebugSection(Sec); 459 }; 460 } 461 462 if (Config.StripNonAlloc) 463 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 464 if (RemovePred(Sec)) 465 return true; 466 if (&Sec == Obj.SectionNames) 467 return false; 468 return (Sec.Flags & SHF_ALLOC) == 0 && Sec.ParentSegment == nullptr; 469 }; 470 471 if (Config.StripAll) 472 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 473 if (RemovePred(Sec)) 474 return true; 475 if (&Sec == Obj.SectionNames) 476 return false; 477 if (StringRef(Sec.Name).starts_with(".gnu.warning")) 478 return false; 479 if (StringRef(Sec.Name).starts_with(".gnu_debuglink")) 480 return false; 481 // We keep the .ARM.attribute section to maintain compatibility 482 // with Debian derived distributions. This is a bug in their 483 // patchset as documented here: 484 // https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=943798 485 if (Sec.Type == SHT_ARM_ATTRIBUTES) 486 return false; 487 if (Sec.ParentSegment != nullptr) 488 return false; 489 return (Sec.Flags & SHF_ALLOC) == 0; 490 }; 491 492 if (Config.ExtractPartition || Config.ExtractMainPartition) { 493 RemovePred = [RemovePred](const SectionBase &Sec) { 494 if (RemovePred(Sec)) 495 return true; 496 if (Sec.Type == SHT_LLVM_PART_EHDR || Sec.Type == SHT_LLVM_PART_PHDR) 497 return true; 498 return (Sec.Flags & SHF_ALLOC) != 0 && !Sec.ParentSegment; 499 }; 500 } 501 502 // Explicit copies: 503 if (!Config.OnlySection.empty()) { 504 RemovePred = [&Config, RemovePred, &Obj](const SectionBase &Sec) { 505 // Explicitly keep these sections regardless of previous removes. 506 if (Config.OnlySection.matches(Sec.Name)) 507 return false; 508 509 // Allow all implicit removes. 510 if (RemovePred(Sec)) 511 return true; 512 513 // Keep special sections. 514 if (Obj.SectionNames == &Sec) 515 return false; 516 if (Obj.SymbolTable == &Sec || 517 (Obj.SymbolTable && Obj.SymbolTable->getStrTab() == &Sec)) 518 return false; 519 520 // Remove everything else. 521 return true; 522 }; 523 } 524 525 if (!Config.KeepSection.empty()) { 526 RemovePred = [&Config, RemovePred](const SectionBase &Sec) { 527 // Explicitly keep these sections regardless of previous removes. 528 if (Config.KeepSection.matches(Sec.Name)) 529 return false; 530 // Otherwise defer to RemovePred. 531 return RemovePred(Sec); 532 }; 533 } 534 535 // This has to be the last predicate assignment. 536 // If the option --keep-symbol has been specified 537 // and at least one of those symbols is present 538 // (equivalently, the updated symbol table is not empty) 539 // the symbol table and the string table should not be removed. 540 if ((!Config.SymbolsToKeep.empty() || ELFConfig.KeepFileSymbols) && 541 Obj.SymbolTable && !Obj.SymbolTable->empty()) { 542 RemovePred = [&Obj, RemovePred](const SectionBase &Sec) { 543 if (&Sec == Obj.SymbolTable || &Sec == Obj.SymbolTable->getStrTab()) 544 return false; 545 return RemovePred(Sec); 546 }; 547 } 548 549 if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred)) 550 return E; 551 552 if (Error E = Obj.compressOrDecompressSections(Config)) 553 return E; 554 555 return Error::success(); 556 } 557 558 // Add symbol to the Object symbol table with the specified properties. 559 static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo, 560 uint8_t DefaultVisibility) { 561 SectionBase *Sec = Obj.findSection(SymInfo.SectionName); 562 uint64_t Value = Sec ? Sec->Addr + SymInfo.Value : SymInfo.Value; 563 564 uint8_t Bind = ELF::STB_GLOBAL; 565 uint8_t Type = ELF::STT_NOTYPE; 566 uint8_t Visibility = DefaultVisibility; 567 568 for (SymbolFlag FlagValue : SymInfo.Flags) 569 switch (FlagValue) { 570 case SymbolFlag::Global: 571 Bind = ELF::STB_GLOBAL; 572 break; 573 case SymbolFlag::Local: 574 Bind = ELF::STB_LOCAL; 575 break; 576 case SymbolFlag::Weak: 577 Bind = ELF::STB_WEAK; 578 break; 579 case SymbolFlag::Default: 580 Visibility = ELF::STV_DEFAULT; 581 break; 582 case SymbolFlag::Hidden: 583 Visibility = ELF::STV_HIDDEN; 584 break; 585 case SymbolFlag::Protected: 586 Visibility = ELF::STV_PROTECTED; 587 break; 588 case SymbolFlag::File: 589 Type = ELF::STT_FILE; 590 break; 591 case SymbolFlag::Section: 592 Type = ELF::STT_SECTION; 593 break; 594 case SymbolFlag::Object: 595 Type = ELF::STT_OBJECT; 596 break; 597 case SymbolFlag::Function: 598 Type = ELF::STT_FUNC; 599 break; 600 case SymbolFlag::IndirectFunction: 601 Type = ELF::STT_GNU_IFUNC; 602 break; 603 default: /* Other flag values are ignored for ELF. */ 604 break; 605 }; 606 607 Obj.SymbolTable->addSymbol( 608 SymInfo.SymbolName, Bind, Type, Sec, Value, Visibility, 609 Sec ? (uint16_t)SYMBOL_SIMPLE_INDEX : (uint16_t)SHN_ABS, 0); 610 } 611 612 namespace { 613 struct RemoveNoteDetail { 614 struct DeletedRange { 615 uint64_t OldFrom; 616 uint64_t OldTo; 617 }; 618 619 template <class ELFT> 620 static std::vector<DeletedRange> 621 findNotesToRemove(ArrayRef<uint8_t> Data, size_t Align, 622 ArrayRef<RemoveNoteInfo> NotesToRemove); 623 static std::vector<uint8_t> updateData(ArrayRef<uint8_t> OldData, 624 ArrayRef<DeletedRange> ToRemove); 625 }; 626 } // namespace 627 628 template <class ELFT> 629 std::vector<RemoveNoteDetail::DeletedRange> 630 RemoveNoteDetail::findNotesToRemove(ArrayRef<uint8_t> Data, size_t Align, 631 ArrayRef<RemoveNoteInfo> NotesToRemove) { 632 using Elf_Nhdr = typename ELFT::Nhdr; 633 using Elf_Note = typename ELFT::Note; 634 std::vector<DeletedRange> ToRemove; 635 uint64_t CurPos = 0; 636 while (CurPos + sizeof(Elf_Nhdr) <= Data.size()) { 637 auto Nhdr = reinterpret_cast<const Elf_Nhdr *>(Data.data() + CurPos); 638 size_t FullSize = Nhdr->getSize(Align); 639 if (CurPos + FullSize > Data.size()) 640 break; 641 Elf_Note Note(*Nhdr); 642 bool ShouldRemove = 643 llvm::any_of(NotesToRemove, [&Note](const RemoveNoteInfo &NoteInfo) { 644 return NoteInfo.TypeId == Note.getType() && 645 (NoteInfo.Name.empty() || NoteInfo.Name == Note.getName()); 646 }); 647 if (ShouldRemove) 648 ToRemove.push_back({CurPos, CurPos + FullSize}); 649 CurPos += FullSize; 650 } 651 return ToRemove; 652 } 653 654 std::vector<uint8_t> 655 RemoveNoteDetail::updateData(ArrayRef<uint8_t> OldData, 656 ArrayRef<DeletedRange> ToRemove) { 657 std::vector<uint8_t> NewData; 658 NewData.reserve(OldData.size()); 659 uint64_t CurPos = 0; 660 for (const DeletedRange &RemRange : ToRemove) { 661 if (CurPos < RemRange.OldFrom) { 662 auto Slice = OldData.slice(CurPos, RemRange.OldFrom - CurPos); 663 NewData.insert(NewData.end(), Slice.begin(), Slice.end()); 664 } 665 CurPos = RemRange.OldTo; 666 } 667 if (CurPos < OldData.size()) { 668 auto Slice = OldData.slice(CurPos); 669 NewData.insert(NewData.end(), Slice.begin(), Slice.end()); 670 } 671 return NewData; 672 } 673 674 static Error removeNotes(Object &Obj, endianness Endianness, 675 ArrayRef<RemoveNoteInfo> NotesToRemove, 676 function_ref<Error(Error)> ErrorCallback) { 677 // TODO: Support note segments. 678 if (ErrorCallback) { 679 for (Segment &Seg : Obj.segments()) { 680 if (Seg.Type == PT_NOTE) { 681 if (Error E = ErrorCallback(createStringError( 682 errc::not_supported, "note segments are not supported"))) 683 return E; 684 break; 685 } 686 } 687 } 688 for (auto &Sec : Obj.sections()) { 689 if (Sec.Type != SHT_NOTE || !Sec.hasContents()) 690 continue; 691 // TODO: Support note sections in segments. 692 if (Sec.ParentSegment) { 693 if (ErrorCallback) 694 if (Error E = ErrorCallback(createStringError( 695 errc::not_supported, 696 "cannot remove note(s) from " + Sec.Name + 697 ": sections in segments are not supported"))) 698 return E; 699 continue; 700 } 701 ArrayRef<uint8_t> OldData = Sec.getContents(); 702 size_t Align = std::max<size_t>(4, Sec.Align); 703 // Note: notes for both 32-bit and 64-bit ELF files use 4-byte words in the 704 // header, so the parsers are the same. 705 auto ToRemove = (Endianness == endianness::little) 706 ? RemoveNoteDetail::findNotesToRemove<ELF64LE>( 707 OldData, Align, NotesToRemove) 708 : RemoveNoteDetail::findNotesToRemove<ELF64BE>( 709 OldData, Align, NotesToRemove); 710 if (!ToRemove.empty()) { 711 if (Error E = Obj.updateSectionData( 712 Sec, RemoveNoteDetail::updateData(OldData, ToRemove))) 713 return E; 714 } 715 } 716 return Error::success(); 717 } 718 719 static Error 720 handleUserSection(const NewSectionInfo &NewSection, 721 function_ref<Error(StringRef, ArrayRef<uint8_t>)> F) { 722 ArrayRef<uint8_t> Data(reinterpret_cast<const uint8_t *>( 723 NewSection.SectionData->getBufferStart()), 724 NewSection.SectionData->getBufferSize()); 725 return F(NewSection.SectionName, Data); 726 } 727 728 static Error verifyNoteSection(StringRef Name, endianness Endianness, 729 ArrayRef<uint8_t> Data) { 730 // An ELF note has the following structure: 731 // Name Size: 4 bytes (integer) 732 // Desc Size: 4 bytes (integer) 733 // Type : 4 bytes 734 // Name : variable size, padded to a 4 byte boundary 735 // Desc : variable size, padded to a 4 byte boundary 736 737 if (Data.empty()) 738 return Error::success(); 739 740 if (Data.size() < 12) { 741 std::string msg; 742 raw_string_ostream(msg) 743 << Name << " data must be either empty or at least 12 bytes long"; 744 return createStringError(errc::invalid_argument, msg); 745 } 746 if (Data.size() % 4 != 0) { 747 std::string msg; 748 raw_string_ostream(msg) 749 << Name << " data size must be a multiple of 4 bytes"; 750 return createStringError(errc::invalid_argument, msg); 751 } 752 ArrayRef<uint8_t> NameSize = Data.slice(0, 4); 753 ArrayRef<uint8_t> DescSize = Data.slice(4, 4); 754 755 uint32_t NameSizeValue = support::endian::read32(NameSize.data(), Endianness); 756 uint32_t DescSizeValue = support::endian::read32(DescSize.data(), Endianness); 757 758 uint64_t ExpectedDataSize = 759 /*NameSize=*/4 + /*DescSize=*/4 + /*Type=*/4 + 760 /*Name=*/alignTo(NameSizeValue, 4) + 761 /*Desc=*/alignTo(DescSizeValue, 4); 762 uint64_t ActualDataSize = Data.size(); 763 if (ActualDataSize != ExpectedDataSize) { 764 std::string msg; 765 raw_string_ostream(msg) 766 << Name 767 << " data size is incompatible with the content of " 768 "the name and description size fields:" 769 << " expecting " << ExpectedDataSize << ", found " << ActualDataSize; 770 return createStringError(errc::invalid_argument, msg); 771 } 772 773 return Error::success(); 774 } 775 776 // This function handles the high level operations of GNU objcopy including 777 // handling command line options. It's important to outline certain properties 778 // we expect to hold of the command line operations. Any operation that "keeps" 779 // should keep regardless of a remove. Additionally any removal should respect 780 // any previous removals. Lastly whether or not something is removed shouldn't 781 // depend a) on the order the options occur in or b) on some opaque priority 782 // system. The only priority is that keeps/copies overrule removes. 783 static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig, 784 ElfType OutputElfType, Object &Obj) { 785 if (Config.OutputArch) { 786 Obj.Machine = Config.OutputArch->EMachine; 787 Obj.OSABI = Config.OutputArch->OSABI; 788 } 789 790 if (!Config.SplitDWO.empty() && Config.ExtractDWO) { 791 return Obj.removeSections( 792 ELFConfig.AllowBrokenLinks, 793 [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); }); 794 } 795 796 // Dump sections before add/remove for compatibility with GNU objcopy. 797 for (StringRef Flag : Config.DumpSection) { 798 StringRef SectionName; 799 StringRef FileName; 800 std::tie(SectionName, FileName) = Flag.split('='); 801 if (Error E = dumpSectionToFile(SectionName, FileName, Obj)) 802 return E; 803 } 804 805 // It is important to remove the sections first. For example, we want to 806 // remove the relocation sections before removing the symbols. That allows 807 // us to avoid reporting the inappropriate errors about removing symbols 808 // named in relocations. 809 if (Error E = replaceAndRemoveSections(Config, ELFConfig, Obj)) 810 return E; 811 812 if (Error E = updateAndRemoveSymbols(Config, ELFConfig, Obj)) 813 return E; 814 815 if (!Config.SetSectionAlignment.empty()) { 816 for (SectionBase &Sec : Obj.sections()) { 817 auto I = Config.SetSectionAlignment.find(Sec.Name); 818 if (I != Config.SetSectionAlignment.end()) 819 Sec.Align = I->second; 820 } 821 } 822 823 if (Config.ChangeSectionLMAValAll != 0) { 824 for (Segment &Seg : Obj.segments()) { 825 if (Seg.FileSize > 0) { 826 if (Config.ChangeSectionLMAValAll > 0 && 827 Seg.PAddr > std::numeric_limits<uint64_t>::max() - 828 Config.ChangeSectionLMAValAll) { 829 return createStringError( 830 errc::invalid_argument, 831 "address 0x" + Twine::utohexstr(Seg.PAddr) + 832 " cannot be increased by 0x" + 833 Twine::utohexstr(Config.ChangeSectionLMAValAll) + 834 ". The result would overflow"); 835 } else if (Config.ChangeSectionLMAValAll < 0 && 836 Seg.PAddr < std::numeric_limits<uint64_t>::min() - 837 Config.ChangeSectionLMAValAll) { 838 return createStringError( 839 errc::invalid_argument, 840 "address 0x" + Twine::utohexstr(Seg.PAddr) + 841 " cannot be decreased by 0x" + 842 Twine::utohexstr(std::abs(Config.ChangeSectionLMAValAll)) + 843 ". The result would underflow"); 844 } 845 Seg.PAddr += Config.ChangeSectionLMAValAll; 846 } 847 } 848 } 849 850 if (!Config.ChangeSectionAddress.empty()) { 851 if (Obj.Type != ELF::ET_REL) 852 return createStringError( 853 object_error::invalid_file_type, 854 "cannot change section address in a non-relocatable file"); 855 856 StringMap<AddressUpdate> SectionsToUpdateAddress; 857 for (const SectionPatternAddressUpdate &PatternUpdate : 858 make_range(Config.ChangeSectionAddress.rbegin(), 859 Config.ChangeSectionAddress.rend())) { 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 createStringError( 867 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 createStringError( 877 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 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 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 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 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 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 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 createFileError(Config.InputFilename, std::move(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