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, Config.OutputFilename); 186 case FileFormat::SREC: 187 return std::make_unique<SRECWriter>(Obj, Out, Config.OutputFilename); 188 default: 189 return createELFWriter(Config, Obj, Out, OutputElfType); 190 } 191 } 192 193 static Error dumpSectionToFile(StringRef SecName, StringRef Filename, 194 Object &Obj) { 195 for (auto &Sec : Obj.sections()) { 196 if (Sec.Name == SecName) { 197 if (Sec.Type == SHT_NOBITS) 198 return createStringError(object_error::parse_failed, 199 "cannot dump section '%s': it has no contents", 200 SecName.str().c_str()); 201 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 202 FileOutputBuffer::create(Filename, Sec.OriginalData.size()); 203 if (!BufferOrErr) 204 return BufferOrErr.takeError(); 205 std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr); 206 std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), 207 Buf->getBufferStart()); 208 if (Error E = Buf->commit()) 209 return E; 210 return Error::success(); 211 } 212 } 213 return createStringError(object_error::parse_failed, "section '%s' not found", 214 SecName.str().c_str()); 215 } 216 217 Error Object::compressOrDecompressSections(const CommonConfig &Config) { 218 // Build a list of sections we are going to replace. 219 // We can't call `addSection` while iterating over sections, 220 // because it would mutate the sections array. 221 SmallVector<std::pair<SectionBase *, std::function<SectionBase *()>>, 0> 222 ToReplace; 223 for (SectionBase &Sec : sections()) { 224 std::optional<DebugCompressionType> CType; 225 for (auto &[Matcher, T] : Config.compressSections) 226 if (Matcher.matches(Sec.Name)) 227 CType = T; 228 // Handle --compress-debug-sections and --decompress-debug-sections, which 229 // apply to non-ALLOC debug sections. 230 if (!(Sec.Flags & SHF_ALLOC) && StringRef(Sec.Name).starts_with(".debug")) { 231 if (Config.CompressionType != DebugCompressionType::None) 232 CType = Config.CompressionType; 233 else if (Config.DecompressDebugSections) 234 CType = DebugCompressionType::None; 235 } 236 if (!CType) 237 continue; 238 239 if (Sec.ParentSegment) 240 return createStringError( 241 errc::invalid_argument, 242 "section '" + Sec.Name + 243 "' within a segment cannot be (de)compressed"); 244 245 if (auto *CS = dyn_cast<CompressedSection>(&Sec)) { 246 if (*CType == DebugCompressionType::None) 247 ToReplace.emplace_back( 248 &Sec, [=] { return &addSection<DecompressedSection>(*CS); }); 249 } else if (*CType != DebugCompressionType::None) { 250 ToReplace.emplace_back(&Sec, [=, S = &Sec] { 251 return &addSection<CompressedSection>( 252 CompressedSection(*S, *CType, Is64Bits)); 253 }); 254 } 255 } 256 257 DenseMap<SectionBase *, SectionBase *> FromTo; 258 for (auto [S, Func] : ToReplace) 259 FromTo[S] = Func(); 260 return replaceSections(FromTo); 261 } 262 263 static bool isAArch64MappingSymbol(const Symbol &Sym) { 264 if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE || 265 Sym.getShndx() == SHN_UNDEF) 266 return false; 267 StringRef Name = Sym.Name; 268 if (!Name.consume_front("$x") && !Name.consume_front("$d")) 269 return false; 270 return Name.empty() || Name.starts_with("."); 271 } 272 273 static bool isArmMappingSymbol(const Symbol &Sym) { 274 if (Sym.Binding != STB_LOCAL || Sym.Type != STT_NOTYPE || 275 Sym.getShndx() == SHN_UNDEF) 276 return false; 277 StringRef Name = Sym.Name; 278 if (!Name.consume_front("$a") && !Name.consume_front("$d") && 279 !Name.consume_front("$t")) 280 return false; 281 return Name.empty() || Name.starts_with("."); 282 } 283 284 // Check if the symbol should be preserved because it is required by ABI. 285 static bool isRequiredByABISymbol(const Object &Obj, const Symbol &Sym) { 286 switch (Obj.Machine) { 287 case EM_AARCH64: 288 // Mapping symbols should be preserved for a relocatable object file. 289 return Obj.isRelocatable() && isAArch64MappingSymbol(Sym); 290 case EM_ARM: 291 // Mapping symbols should be preserved for a relocatable object file. 292 return Obj.isRelocatable() && isArmMappingSymbol(Sym); 293 default: 294 return false; 295 } 296 } 297 298 static bool isUnneededSymbol(const Symbol &Sym) { 299 return !Sym.Referenced && 300 (Sym.Binding == STB_LOCAL || Sym.getShndx() == SHN_UNDEF) && 301 Sym.Type != STT_SECTION; 302 } 303 304 static Error updateAndRemoveSymbols(const CommonConfig &Config, 305 const ELFConfig &ELFConfig, Object &Obj) { 306 // TODO: update or remove symbols only if there is an option that affects 307 // them. 308 if (!Obj.SymbolTable) 309 return Error::success(); 310 311 Obj.SymbolTable->updateSymbols([&](Symbol &Sym) { 312 if (Config.SymbolsToSkip.matches(Sym.Name)) 313 return; 314 315 // Common and undefined symbols don't make sense as local symbols, and can 316 // even cause crashes if we localize those, so skip them. 317 if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF && 318 ((ELFConfig.LocalizeHidden && 319 (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) || 320 Config.SymbolsToLocalize.matches(Sym.Name))) 321 Sym.Binding = STB_LOCAL; 322 323 for (auto &[Matcher, Visibility] : ELFConfig.SymbolsToSetVisibility) 324 if (Matcher.matches(Sym.Name)) 325 Sym.Visibility = Visibility; 326 327 // Note: these two globalize flags have very similar names but different 328 // meanings: 329 // 330 // --globalize-symbol: promote a symbol to global 331 // --keep-global-symbol: all symbols except for these should be made local 332 // 333 // If --globalize-symbol is specified for a given symbol, it will be 334 // global in the output file even if it is not included via 335 // --keep-global-symbol. Because of that, make sure to check 336 // --globalize-symbol second. 337 if (!Config.SymbolsToKeepGlobal.empty() && 338 !Config.SymbolsToKeepGlobal.matches(Sym.Name) && 339 Sym.getShndx() != SHN_UNDEF) 340 Sym.Binding = STB_LOCAL; 341 342 if (Config.SymbolsToGlobalize.matches(Sym.Name) && 343 Sym.getShndx() != SHN_UNDEF) 344 Sym.Binding = STB_GLOBAL; 345 346 // SymbolsToWeaken applies to both STB_GLOBAL and STB_GNU_UNIQUE. 347 if (Config.SymbolsToWeaken.matches(Sym.Name) && Sym.Binding != STB_LOCAL) 348 Sym.Binding = STB_WEAK; 349 350 if (Config.Weaken && Sym.Binding != STB_LOCAL && 351 Sym.getShndx() != SHN_UNDEF) 352 Sym.Binding = STB_WEAK; 353 354 const auto I = Config.SymbolsToRename.find(Sym.Name); 355 if (I != Config.SymbolsToRename.end()) 356 Sym.Name = std::string(I->getValue()); 357 358 if (!Config.SymbolsPrefixRemove.empty() && Sym.Type != STT_SECTION) 359 if (Sym.Name.compare(0, Config.SymbolsPrefixRemove.size(), 360 Config.SymbolsPrefixRemove) == 0) 361 Sym.Name = Sym.Name.substr(Config.SymbolsPrefixRemove.size()); 362 363 if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION) 364 Sym.Name = (Config.SymbolsPrefix + Sym.Name).str(); 365 }); 366 367 // The purpose of this loop is to mark symbols referenced by sections 368 // (like GroupSection or RelocationSection). This way, we know which 369 // symbols are still 'needed' and which are not. 370 if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty() || 371 !Config.OnlySection.empty() || Config.DiscardMode != DiscardType::None) { 372 for (SectionBase &Sec : Obj.sections()) 373 Sec.markSymbols(); 374 } 375 376 auto RemoveSymbolsPred = [&](const Symbol &Sym) { 377 if (Config.SymbolsToKeep.matches(Sym.Name) || 378 (ELFConfig.KeepFileSymbols && Sym.Type == STT_FILE)) 379 return false; 380 381 if (Config.SymbolsToRemove.matches(Sym.Name)) 382 return true; 383 384 if (Config.StripAll || Config.StripAllGNU) 385 return true; 386 387 if (isRequiredByABISymbol(Obj, Sym)) 388 return false; 389 390 if (Config.StripDebug && Sym.Type == STT_FILE) 391 return true; 392 393 if ((Config.StripUnneeded || 394 Config.UnneededSymbolsToRemove.matches(Sym.Name)) && 395 (!Obj.isRelocatable() || isUnneededSymbol(Sym))) 396 return true; 397 398 if (!Sym.Referenced) { 399 if ((Config.DiscardMode == DiscardType::All || 400 (Config.DiscardMode == DiscardType::Locals && 401 StringRef(Sym.Name).starts_with(".L"))) && 402 Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF && 403 Sym.Type != STT_FILE && Sym.Type != STT_SECTION) 404 return true; 405 // We want to remove undefined symbols if all references have been 406 // stripped. 407 if (!Config.OnlySection.empty() && Sym.getShndx() == SHN_UNDEF) 408 return true; 409 } 410 411 return false; 412 }; 413 414 return Obj.removeSymbols(RemoveSymbolsPred); 415 } 416 417 static Error replaceAndRemoveSections(const CommonConfig &Config, 418 const ELFConfig &ELFConfig, Object &Obj) { 419 SectionPred RemovePred = [](const SectionBase &) { return false; }; 420 421 // Removes: 422 if (!Config.ToRemove.empty()) { 423 RemovePred = [&Config](const SectionBase &Sec) { 424 return Config.ToRemove.matches(Sec.Name); 425 }; 426 } 427 428 if (Config.StripDWO) 429 RemovePred = [RemovePred](const SectionBase &Sec) { 430 return isDWOSection(Sec) || RemovePred(Sec); 431 }; 432 433 if (Config.ExtractDWO) 434 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 435 return onlyKeepDWOPred(Obj, Sec) || RemovePred(Sec); 436 }; 437 438 if (Config.StripAllGNU) 439 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 440 if (RemovePred(Sec)) 441 return true; 442 if ((Sec.Flags & SHF_ALLOC) != 0) 443 return false; 444 if (&Sec == Obj.SectionNames) 445 return false; 446 switch (Sec.Type) { 447 case SHT_SYMTAB: 448 case SHT_REL: 449 case SHT_RELA: 450 case SHT_STRTAB: 451 return true; 452 } 453 return isDebugSection(Sec); 454 }; 455 456 if (Config.StripSections) { 457 RemovePred = [RemovePred](const SectionBase &Sec) { 458 return RemovePred(Sec) || Sec.ParentSegment == nullptr; 459 }; 460 } 461 462 if (Config.StripDebug || Config.StripUnneeded) { 463 RemovePred = [RemovePred](const SectionBase &Sec) { 464 return RemovePred(Sec) || isDebugSection(Sec); 465 }; 466 } 467 468 if (Config.StripNonAlloc) 469 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 470 if (RemovePred(Sec)) 471 return true; 472 if (&Sec == Obj.SectionNames) 473 return false; 474 return (Sec.Flags & SHF_ALLOC) == 0 && Sec.ParentSegment == nullptr; 475 }; 476 477 if (Config.StripAll) 478 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) { 479 if (RemovePred(Sec)) 480 return true; 481 if (&Sec == Obj.SectionNames) 482 return false; 483 if (StringRef(Sec.Name).starts_with(".gnu.warning")) 484 return false; 485 if (StringRef(Sec.Name).starts_with(".gnu_debuglink")) 486 return false; 487 // We keep the .ARM.attribute section to maintain compatibility 488 // with Debian derived distributions. This is a bug in their 489 // patchset as documented here: 490 // https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=943798 491 if (Sec.Type == SHT_ARM_ATTRIBUTES) 492 return false; 493 if (Sec.ParentSegment != nullptr) 494 return false; 495 return (Sec.Flags & SHF_ALLOC) == 0; 496 }; 497 498 if (Config.ExtractPartition || Config.ExtractMainPartition) { 499 RemovePred = [RemovePred](const SectionBase &Sec) { 500 if (RemovePred(Sec)) 501 return true; 502 if (Sec.Type == SHT_LLVM_PART_EHDR || Sec.Type == SHT_LLVM_PART_PHDR) 503 return true; 504 return (Sec.Flags & SHF_ALLOC) != 0 && !Sec.ParentSegment; 505 }; 506 } 507 508 // Explicit copies: 509 if (!Config.OnlySection.empty()) { 510 RemovePred = [&Config, RemovePred, &Obj](const SectionBase &Sec) { 511 // Explicitly keep these sections regardless of previous removes. 512 if (Config.OnlySection.matches(Sec.Name)) 513 return false; 514 515 // Allow all implicit removes. 516 if (RemovePred(Sec)) 517 return true; 518 519 // Keep special sections. 520 if (Obj.SectionNames == &Sec) 521 return false; 522 if (Obj.SymbolTable == &Sec || 523 (Obj.SymbolTable && Obj.SymbolTable->getStrTab() == &Sec)) 524 return false; 525 526 // Remove everything else. 527 return true; 528 }; 529 } 530 531 if (!Config.KeepSection.empty()) { 532 RemovePred = [&Config, RemovePred](const SectionBase &Sec) { 533 // Explicitly keep these sections regardless of previous removes. 534 if (Config.KeepSection.matches(Sec.Name)) 535 return false; 536 // Otherwise defer to RemovePred. 537 return RemovePred(Sec); 538 }; 539 } 540 541 // This has to be the last predicate assignment. 542 // If the option --keep-symbol has been specified 543 // and at least one of those symbols is present 544 // (equivalently, the updated symbol table is not empty) 545 // the symbol table and the string table should not be removed. 546 if ((!Config.SymbolsToKeep.empty() || ELFConfig.KeepFileSymbols) && 547 Obj.SymbolTable && !Obj.SymbolTable->empty()) { 548 RemovePred = [&Obj, RemovePred](const SectionBase &Sec) { 549 if (&Sec == Obj.SymbolTable || &Sec == Obj.SymbolTable->getStrTab()) 550 return false; 551 return RemovePred(Sec); 552 }; 553 } 554 555 if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred)) 556 return E; 557 558 if (Error E = Obj.compressOrDecompressSections(Config)) 559 return E; 560 561 return Error::success(); 562 } 563 564 // Add symbol to the Object symbol table with the specified properties. 565 static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo, 566 uint8_t DefaultVisibility) { 567 SectionBase *Sec = Obj.findSection(SymInfo.SectionName); 568 uint64_t Value = Sec ? Sec->Addr + SymInfo.Value : SymInfo.Value; 569 570 uint8_t Bind = ELF::STB_GLOBAL; 571 uint8_t Type = ELF::STT_NOTYPE; 572 uint8_t Visibility = DefaultVisibility; 573 574 for (SymbolFlag FlagValue : SymInfo.Flags) 575 switch (FlagValue) { 576 case SymbolFlag::Global: 577 Bind = ELF::STB_GLOBAL; 578 break; 579 case SymbolFlag::Local: 580 Bind = ELF::STB_LOCAL; 581 break; 582 case SymbolFlag::Weak: 583 Bind = ELF::STB_WEAK; 584 break; 585 case SymbolFlag::Default: 586 Visibility = ELF::STV_DEFAULT; 587 break; 588 case SymbolFlag::Hidden: 589 Visibility = ELF::STV_HIDDEN; 590 break; 591 case SymbolFlag::Protected: 592 Visibility = ELF::STV_PROTECTED; 593 break; 594 case SymbolFlag::File: 595 Type = ELF::STT_FILE; 596 break; 597 case SymbolFlag::Section: 598 Type = ELF::STT_SECTION; 599 break; 600 case SymbolFlag::Object: 601 Type = ELF::STT_OBJECT; 602 break; 603 case SymbolFlag::Function: 604 Type = ELF::STT_FUNC; 605 break; 606 case SymbolFlag::IndirectFunction: 607 Type = ELF::STT_GNU_IFUNC; 608 break; 609 default: /* Other flag values are ignored for ELF. */ 610 break; 611 }; 612 613 Obj.SymbolTable->addSymbol( 614 SymInfo.SymbolName, Bind, Type, Sec, Value, Visibility, 615 Sec ? (uint16_t)SYMBOL_SIMPLE_INDEX : (uint16_t)SHN_ABS, 0); 616 } 617 618 static Error 619 handleUserSection(const NewSectionInfo &NewSection, 620 function_ref<Error(StringRef, ArrayRef<uint8_t>)> F) { 621 ArrayRef<uint8_t> Data(reinterpret_cast<const uint8_t *>( 622 NewSection.SectionData->getBufferStart()), 623 NewSection.SectionData->getBufferSize()); 624 return F(NewSection.SectionName, Data); 625 } 626 627 static Error verifyNoteSection(StringRef Name, endianness Endianness, 628 ArrayRef<uint8_t> Data) { 629 // An ELF note has the following structure: 630 // Name Size: 4 bytes (integer) 631 // Desc Size: 4 bytes (integer) 632 // Type : 4 bytes 633 // Name : variable size, padded to a 4 byte boundary 634 // Desc : variable size, padded to a 4 byte boundary 635 636 if (Data.empty()) 637 return Error::success(); 638 639 if (Data.size() < 12) { 640 std::string msg; 641 raw_string_ostream(msg) 642 << Name << " data must be either empty or at least 12 bytes long"; 643 return createStringError(errc::invalid_argument, msg); 644 } 645 if (Data.size() % 4 != 0) { 646 std::string msg; 647 raw_string_ostream(msg) 648 << Name << " data size must be a multiple of 4 bytes"; 649 return createStringError(errc::invalid_argument, msg); 650 } 651 ArrayRef<uint8_t> NameSize = Data.slice(0, 4); 652 ArrayRef<uint8_t> DescSize = Data.slice(4, 4); 653 654 uint32_t NameSizeValue = support::endian::read32(NameSize.data(), Endianness); 655 uint32_t DescSizeValue = support::endian::read32(DescSize.data(), Endianness); 656 657 uint64_t ExpectedDataSize = 658 /*NameSize=*/4 + /*DescSize=*/4 + /*Type=*/4 + 659 /*Name=*/alignTo(NameSizeValue, 4) + 660 /*Desc=*/alignTo(DescSizeValue, 4); 661 uint64_t ActualDataSize = Data.size(); 662 if (ActualDataSize != ExpectedDataSize) { 663 std::string msg; 664 raw_string_ostream(msg) 665 << Name 666 << " data size is incompatible with the content of " 667 "the name and description size fields:" 668 << " expecting " << ExpectedDataSize << ", found " << ActualDataSize; 669 return createStringError(errc::invalid_argument, msg); 670 } 671 672 return Error::success(); 673 } 674 675 // This function handles the high level operations of GNU objcopy including 676 // handling command line options. It's important to outline certain properties 677 // we expect to hold of the command line operations. Any operation that "keeps" 678 // should keep regardless of a remove. Additionally any removal should respect 679 // any previous removals. Lastly whether or not something is removed shouldn't 680 // depend a) on the order the options occur in or b) on some opaque priority 681 // system. The only priority is that keeps/copies overrule removes. 682 static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig, 683 ElfType OutputElfType, Object &Obj) { 684 if (Config.OutputArch) { 685 Obj.Machine = Config.OutputArch->EMachine; 686 Obj.OSABI = Config.OutputArch->OSABI; 687 } 688 689 if (!Config.SplitDWO.empty() && Config.ExtractDWO) { 690 return Obj.removeSections( 691 ELFConfig.AllowBrokenLinks, 692 [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); }); 693 } 694 695 // Dump sections before add/remove for compatibility with GNU objcopy. 696 for (StringRef Flag : Config.DumpSection) { 697 StringRef SectionName; 698 StringRef FileName; 699 std::tie(SectionName, FileName) = Flag.split('='); 700 if (Error E = dumpSectionToFile(SectionName, FileName, Obj)) 701 return E; 702 } 703 704 // It is important to remove the sections first. For example, we want to 705 // remove the relocation sections before removing the symbols. That allows 706 // us to avoid reporting the inappropriate errors about removing symbols 707 // named in relocations. 708 if (Error E = replaceAndRemoveSections(Config, ELFConfig, Obj)) 709 return E; 710 711 if (Error E = updateAndRemoveSymbols(Config, ELFConfig, Obj)) 712 return E; 713 714 if (!Config.SetSectionAlignment.empty()) { 715 for (SectionBase &Sec : Obj.sections()) { 716 auto I = Config.SetSectionAlignment.find(Sec.Name); 717 if (I != Config.SetSectionAlignment.end()) 718 Sec.Align = I->second; 719 } 720 } 721 722 if (Config.ChangeSectionLMAValAll != 0) { 723 for (Segment &Seg : Obj.segments()) { 724 if (Seg.FileSize > 0) { 725 if (Config.ChangeSectionLMAValAll > 0 && 726 Seg.PAddr > std::numeric_limits<uint64_t>::max() - 727 Config.ChangeSectionLMAValAll) { 728 return createStringError( 729 errc::invalid_argument, 730 "address 0x" + Twine::utohexstr(Seg.PAddr) + 731 " cannot be increased by 0x" + 732 Twine::utohexstr(Config.ChangeSectionLMAValAll) + 733 ". The result would overflow"); 734 } else if (Config.ChangeSectionLMAValAll < 0 && 735 Seg.PAddr < std::numeric_limits<uint64_t>::min() - 736 Config.ChangeSectionLMAValAll) { 737 return createStringError( 738 errc::invalid_argument, 739 "address 0x" + Twine::utohexstr(Seg.PAddr) + 740 " cannot be decreased by 0x" + 741 Twine::utohexstr(std::abs(Config.ChangeSectionLMAValAll)) + 742 ". The result would underflow"); 743 } 744 Seg.PAddr += Config.ChangeSectionLMAValAll; 745 } 746 } 747 } 748 749 if (Config.OnlyKeepDebug) 750 for (auto &Sec : Obj.sections()) 751 if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE) 752 Sec.Type = SHT_NOBITS; 753 754 endianness E = OutputElfType == ELFT_ELF32LE || OutputElfType == ELFT_ELF64LE 755 ? endianness::little 756 : endianness::big; 757 758 for (const NewSectionInfo &AddedSection : Config.AddSection) { 759 auto AddSection = [&](StringRef Name, ArrayRef<uint8_t> Data) -> Error { 760 OwnedDataSection &NewSection = 761 Obj.addSection<OwnedDataSection>(Name, Data); 762 if (Name.starts_with(".note") && Name != ".note.GNU-stack") { 763 NewSection.Type = SHT_NOTE; 764 if (ELFConfig.VerifyNoteSections) 765 return verifyNoteSection(Name, E, Data); 766 } 767 return Error::success(); 768 }; 769 if (Error E = handleUserSection(AddedSection, AddSection)) 770 return E; 771 } 772 773 for (const NewSectionInfo &NewSection : Config.UpdateSection) { 774 auto UpdateSection = [&](StringRef Name, ArrayRef<uint8_t> Data) { 775 return Obj.updateSection(Name, Data); 776 }; 777 if (Error E = handleUserSection(NewSection, UpdateSection)) 778 return E; 779 } 780 781 if (!Config.AddGnuDebugLink.empty()) 782 Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink, 783 Config.GnuDebugLinkCRC32); 784 785 // If the symbol table was previously removed, we need to create a new one 786 // before adding new symbols. 787 if (!Obj.SymbolTable && !Config.SymbolsToAdd.empty()) 788 if (Error E = Obj.addNewSymbolTable()) 789 return E; 790 791 for (const NewSymbolInfo &SI : Config.SymbolsToAdd) 792 addSymbol(Obj, SI, ELFConfig.NewSymbolVisibility); 793 794 // --set-section-{flags,type} work with sections added by --add-section. 795 if (!Config.SetSectionFlags.empty() || !Config.SetSectionType.empty()) { 796 for (auto &Sec : Obj.sections()) { 797 const auto Iter = Config.SetSectionFlags.find(Sec.Name); 798 if (Iter != Config.SetSectionFlags.end()) { 799 const SectionFlagsUpdate &SFU = Iter->second; 800 if (Error E = setSectionFlagsAndType(Sec, SFU.NewFlags, Obj.Machine)) 801 return E; 802 } 803 auto It2 = Config.SetSectionType.find(Sec.Name); 804 if (It2 != Config.SetSectionType.end()) 805 setSectionType(Sec, It2->second); 806 } 807 } 808 809 if (!Config.SectionsToRename.empty()) { 810 std::vector<RelocationSectionBase *> RelocSections; 811 DenseSet<SectionBase *> RenamedSections; 812 for (SectionBase &Sec : Obj.sections()) { 813 auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec); 814 const auto Iter = Config.SectionsToRename.find(Sec.Name); 815 if (Iter != Config.SectionsToRename.end()) { 816 const SectionRename &SR = Iter->second; 817 Sec.Name = std::string(SR.NewName); 818 if (SR.NewFlags) { 819 if (Error E = setSectionFlagsAndType(Sec, *SR.NewFlags, Obj.Machine)) 820 return E; 821 } 822 RenamedSections.insert(&Sec); 823 } else if (RelocSec && !(Sec.Flags & SHF_ALLOC)) 824 // Postpone processing relocation sections which are not specified in 825 // their explicit '--rename-section' commands until after their target 826 // sections are renamed. 827 // Dynamic relocation sections (i.e. ones with SHF_ALLOC) should be 828 // renamed only explicitly. Otherwise, renaming, for example, '.got.plt' 829 // would affect '.rela.plt', which is not desirable. 830 RelocSections.push_back(RelocSec); 831 } 832 833 // Rename relocation sections according to their target sections. 834 for (RelocationSectionBase *RelocSec : RelocSections) { 835 auto Iter = RenamedSections.find(RelocSec->getSection()); 836 if (Iter != RenamedSections.end()) 837 RelocSec->Name = (RelocSec->getNamePrefix() + (*Iter)->Name).str(); 838 } 839 } 840 841 // Add a prefix to allocated sections and their relocation sections. This 842 // should be done after renaming the section by Config.SectionToRename to 843 // imitate the GNU objcopy behavior. 844 if (!Config.AllocSectionsPrefix.empty()) { 845 DenseSet<SectionBase *> PrefixedSections; 846 for (SectionBase &Sec : Obj.sections()) { 847 if (Sec.Flags & SHF_ALLOC) { 848 Sec.Name = (Config.AllocSectionsPrefix + Sec.Name).str(); 849 PrefixedSections.insert(&Sec); 850 } else if (auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec)) { 851 // Rename relocation sections associated to the allocated sections. 852 // For example, if we rename .text to .prefix.text, we also rename 853 // .rel.text to .rel.prefix.text. 854 // 855 // Dynamic relocation sections (SHT_REL[A] with SHF_ALLOC) are handled 856 // above, e.g., .rela.plt is renamed to .prefix.rela.plt, not 857 // .rela.prefix.plt since GNU objcopy does so. 858 const SectionBase *TargetSec = RelocSec->getSection(); 859 if (TargetSec && (TargetSec->Flags & SHF_ALLOC)) { 860 // If the relocation section comes *after* the target section, we 861 // don't add Config.AllocSectionsPrefix because we've already added 862 // the prefix to TargetSec->Name. Otherwise, if the relocation 863 // section comes *before* the target section, we add the prefix. 864 if (PrefixedSections.count(TargetSec)) 865 Sec.Name = (RelocSec->getNamePrefix() + TargetSec->Name).str(); 866 else 867 Sec.Name = (RelocSec->getNamePrefix() + Config.AllocSectionsPrefix + 868 TargetSec->Name) 869 .str(); 870 } 871 } 872 } 873 } 874 875 if (ELFConfig.EntryExpr) 876 Obj.Entry = ELFConfig.EntryExpr(Obj.Entry); 877 return Error::success(); 878 } 879 880 static Error writeOutput(const CommonConfig &Config, Object &Obj, 881 raw_ostream &Out, ElfType OutputElfType) { 882 std::unique_ptr<Writer> Writer = 883 createWriter(Config, Obj, Out, OutputElfType); 884 if (Error E = Writer->finalize()) 885 return E; 886 return Writer->write(); 887 } 888 889 Error objcopy::elf::executeObjcopyOnIHex(const CommonConfig &Config, 890 const ELFConfig &ELFConfig, 891 MemoryBuffer &In, raw_ostream &Out) { 892 IHexReader Reader(&In); 893 Expected<std::unique_ptr<Object>> Obj = Reader.create(true); 894 if (!Obj) 895 return Obj.takeError(); 896 897 const ElfType OutputElfType = 898 getOutputElfType(Config.OutputArch.value_or(MachineInfo())); 899 if (Error E = handleArgs(Config, ELFConfig, OutputElfType, **Obj)) 900 return E; 901 return writeOutput(Config, **Obj, Out, OutputElfType); 902 } 903 904 Error objcopy::elf::executeObjcopyOnRawBinary(const CommonConfig &Config, 905 const ELFConfig &ELFConfig, 906 MemoryBuffer &In, 907 raw_ostream &Out) { 908 BinaryReader Reader(&In, ELFConfig.NewSymbolVisibility); 909 Expected<std::unique_ptr<Object>> Obj = Reader.create(true); 910 if (!Obj) 911 return Obj.takeError(); 912 913 // Prefer OutputArch (-O<format>) if set, otherwise fallback to BinaryArch 914 // (-B<arch>). 915 const ElfType OutputElfType = 916 getOutputElfType(Config.OutputArch.value_or(MachineInfo())); 917 if (Error E = handleArgs(Config, ELFConfig, OutputElfType, **Obj)) 918 return E; 919 return writeOutput(Config, **Obj, Out, OutputElfType); 920 } 921 922 Error objcopy::elf::executeObjcopyOnBinary(const CommonConfig &Config, 923 const ELFConfig &ELFConfig, 924 object::ELFObjectFileBase &In, 925 raw_ostream &Out) { 926 ELFReader Reader(&In, Config.ExtractPartition); 927 Expected<std::unique_ptr<Object>> Obj = 928 Reader.create(!Config.SymbolsToAdd.empty()); 929 if (!Obj) 930 return Obj.takeError(); 931 // Prefer OutputArch (-O<format>) if set, otherwise infer it from the input. 932 const ElfType OutputElfType = Config.OutputArch 933 ? getOutputElfType(*Config.OutputArch) 934 : getOutputElfType(In); 935 936 if (Error E = handleArgs(Config, ELFConfig, OutputElfType, **Obj)) 937 return createFileError(Config.InputFilename, std::move(E)); 938 939 if (Error E = writeOutput(Config, **Obj, Out, OutputElfType)) 940 return createFileError(Config.InputFilename, std::move(E)); 941 942 return Error::success(); 943 } 944