Index: llvm/docs/CommandGuide/llvm-objcopy.rst =================================================================== --- llvm/docs/CommandGuide/llvm-objcopy.rst +++ llvm/docs/CommandGuide/llvm-objcopy.rst @@ -193,6 +193,18 @@ - `sparcel` - `x86-64` +.. option:: --binary-symbol-visibility + + Specify the visibility of the symbols automatically created when using binary + input. Valid options are: + + - `default` + - `hidden` + - `internal` + - `protected` + + The default is `default`. + .. option:: --build-id-link-dir Set the directory used by :option:`--build-id-link-input` and Index: llvm/test/tools/llvm-objcopy/ELF/binary-symbol-visibility.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objcopy/ELF/binary-symbol-visibility.test @@ -0,0 +1,22 @@ +## Ensure that the visibility of the start, end and size symbols created when +## using binary input can be specified. + +# RUN: llvm-objcopy -I binary -B i386:x86-64 %s %t.unspecified +# RUN: llvm-readelf -s %t.unspecified | FileCheck %s -DVISIBILITY=DEFAULT +# RUN: llvm-objcopy --binary-symbol-visibility default -I binary -B i386:x86-64 %s %t.default +# RUN: llvm-readelf -s %t.default | FileCheck %s -DVISIBILITY=DEFAULT +# RUN: llvm-objcopy --binary-symbol-visibility hidden -I binary -B i386:x86-64 %s %t.hidden +# RUN: llvm-readelf -s %t.hidden | FileCheck %s -DVISIBILITY=HIDDEN +# RUN: llvm-objcopy --binary-symbol-visibility protected -I binary -B i386:x86-64 %s %t.protected +# RUN: llvm-readelf -s %t.protected | FileCheck %s -DVISIBILITY=PROTECTED +# RUN: llvm-objcopy --binary-symbol-visibility internal -I binary -B i386:x86-64 %s %t.internal +# RUN: llvm-readelf -s %t.internal | FileCheck %s -DVISIBILITY=INTERNAL + +# CHECK: [[VISIBILITY]] {{.*}} _binary{{.*}}_start +# CHECK-NEXT: [[VISIBILITY]] {{.*}} _binary{{.*}}_end +# CHECK-NEXT: [[VISIBILITY]] {{.*}} _binary{{.*}}_size + +# RUN: not llvm-objcopy --binary-symbol-visibility fluff -I binary -B i386:x86-64 %s %t.error 2>&1 \ +# RUN: | FileCheck %s --check-prefix=ERR + +# ERR: error: 'fluff' is not a valid binary symbol visibility Index: llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -201,18 +201,18 @@ if (!Config.AddGnuDebugLink.empty()) addGnuDebugLink(Obj, Config.AddGnuDebugLink); - if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() || - Config.BuildIdLinkInput || Config.BuildIdLinkOutput || - !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() || - !Config.AllocSectionsPrefix.empty() || !Config.DumpSection.empty() || - !Config.KeepSection.empty() || !Config.SymbolsToGlobalize.empty() || - !Config.SymbolsToKeep.empty() || !Config.SymbolsToLocalize.empty() || - !Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() || - !Config.SectionsToRename.empty() || !Config.SetSectionFlags.empty() || - !Config.SymbolsToRename.empty() || Config.ExtractDWO || - Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates || - Config.StripDWO || Config.StripNonAlloc || Config.StripSections || - Config.Weaken || Config.DecompressDebugSections || + if (Config.AllowBrokenLinks || Config.BinarySymbolVisibility || + !Config.BuildIdLinkDir.empty() || Config.BuildIdLinkInput || + Config.BuildIdLinkOutput || !Config.SplitDWO.empty() || + !Config.SymbolsPrefix.empty() || !Config.AllocSectionsPrefix.empty() || + !Config.DumpSection.empty() || !Config.KeepSection.empty() || + !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() || + !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() || + !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() || + !Config.SetSectionFlags.empty() || !Config.SymbolsToRename.empty() || + Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden || + Config.PreserveDates || Config.StripDWO || Config.StripNonAlloc || + Config.StripSections || Config.Weaken || Config.DecompressDebugSections || Config.DiscardMode == DiscardType::Locals || !Config.SymbolsToAdd.empty() || Config.EntryExpr) { return createStringError(llvm::errc::invalid_argument, Index: llvm/tools/llvm-objcopy/CopyConfig.h =================================================================== --- llvm/tools/llvm-objcopy/CopyConfig.h +++ llvm/tools/llvm-objcopy/CopyConfig.h @@ -120,6 +120,9 @@ // Only applicable when --output-format!=binary (e.g. elf64-x86-64). Optional OutputArch; + // Applicable if new data sections are generated. + Optional BinarySymbolVisibility; + // Advanced options StringRef AddGnuDebugLink; // Cached gnu_debuglink's target CRC Index: llvm/tools/llvm-objcopy/CopyConfig.cpp =================================================================== --- llvm/tools/llvm-objcopy/CopyConfig.cpp +++ llvm/tools/llvm-objcopy/CopyConfig.cpp @@ -486,6 +486,24 @@ if (!MI) return MI.takeError(); Config.BinaryArch = *MI; + + if (InputArgs.hasArg(OBJCOPY_binary_symbol_visibility)) { + const uint8_t Invalid = 0xff; + Config.BinarySymbolVisibility = + StringSwitch( + InputArgs.getLastArgValue(OBJCOPY_binary_symbol_visibility)) + .Case("default", ELF::STV_DEFAULT) + .Case("hidden", ELF::STV_HIDDEN) + .Case("internal", ELF::STV_INTERNAL) + .Case("protected", ELF::STV_PROTECTED) + .Default(Invalid); + + if (Config.BinarySymbolVisibility == Invalid) + return createStringError( + errc::invalid_argument, + "'" + InputArgs.getLastArgValue(OBJCOPY_binary_symbol_visibility) + + "' is not a valid binary symbol visibility"); + } } Config.OutputFormat = StringSwitch(OutputFormat) Index: llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -756,7 +756,10 @@ Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In, Buffer &Out) { - BinaryReader Reader(Config.BinaryArch, &In); + uint8_t Visibility = (Config.BinarySymbolVisibility) + ? *Config.BinarySymbolVisibility + : STV_DEFAULT; + BinaryReader Reader(Config.BinaryArch, Visibility, &In); std::unique_ptr Obj = Reader.create(); // Prefer OutputArch (-O) if set, otherwise fallback to BinaryArch Index: llvm/tools/llvm-objcopy/ELF/Object.h =================================================================== --- llvm/tools/llvm-objcopy/ELF/Object.h +++ llvm/tools/llvm-objcopy/ELF/Object.h @@ -889,11 +889,12 @@ class BinaryELFBuilder : public BasicELFBuilder { MemoryBuffer *MemBuf; + uint8_t SymbolVisibility; void addData(SymbolTableSection *SymTab); public: - BinaryELFBuilder(uint16_t EM, MemoryBuffer *MB) - : BasicELFBuilder(EM), MemBuf(MB) {} + BinaryELFBuilder(uint16_t EM, uint8_t Visibility, MemoryBuffer *MB) + : BasicELFBuilder(EM), SymbolVisibility(Visibility), MemBuf(MB) {} std::unique_ptr build(); }; @@ -941,11 +942,12 @@ class BinaryReader : public Reader { const MachineInfo &MInfo; + const uint8_t SymbolVisibility; MemoryBuffer *MemBuf; public: - BinaryReader(const MachineInfo &MI, MemoryBuffer *MB) - : MInfo(MI), MemBuf(MB) {} + BinaryReader(const MachineInfo &MI, const uint8_t Visibility, MemoryBuffer *MB) + : MInfo(MI), SymbolVisibility(Visibility), MemBuf(MB) {} std::unique_ptr create() const override; }; Index: llvm/tools/llvm-objcopy/ELF/Object.cpp =================================================================== --- llvm/tools/llvm-objcopy/ELF/Object.cpp +++ llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -1161,11 +1161,12 @@ Twine Prefix = Twine("_binary_") + SanitizedFilename; SymTab->addSymbol(Prefix + "_start", STB_GLOBAL, STT_NOTYPE, &DataSection, - /*Value=*/0, STV_DEFAULT, 0, 0); + /*Value=*/0, SymbolVisibility, 0, 0); SymTab->addSymbol(Prefix + "_end", STB_GLOBAL, STT_NOTYPE, &DataSection, - /*Value=*/DataSection.Size, STV_DEFAULT, 0, 0); + /*Value=*/DataSection.Size, SymbolVisibility, 0, 0); SymTab->addSymbol(Prefix + "_size", STB_GLOBAL, STT_NOTYPE, nullptr, - /*Value=*/DataSection.Size, STV_DEFAULT, SHN_ABS, 0); + /*Value=*/DataSection.Size, SymbolVisibility, SHN_ABS, + 0); } std::unique_ptr BinaryELFBuilder::build() { @@ -1610,7 +1611,7 @@ Reader::~Reader() {} std::unique_ptr BinaryReader::create() const { - return BinaryELFBuilder(MInfo.EMachine, MemBuf).build(); + return BinaryELFBuilder(MInfo.EMachine, SymbolVisibility, MemBuf).build(); } Expected> IHexReader::parse() const { Index: llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -20,15 +20,16 @@ using namespace object; static Error handleArgs(const CopyConfig &Config, Object &Obj) { - if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() || - Config.BuildIdLinkInput || Config.BuildIdLinkOutput || - !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() || - !Config.AllocSectionsPrefix.empty() || !Config.AddSection.empty() || - !Config.DumpSection.empty() || !Config.KeepSection.empty() || - !Config.OnlySection.empty() || !Config.SymbolsToGlobalize.empty() || - !Config.SymbolsToKeep.empty() || !Config.SymbolsToLocalize.empty() || - !Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() || - !Config.SectionsToRename.empty() || !Config.SymbolsToRename.empty() || + if (Config.AllowBrokenLinks || Config.BinarySymbolVisibility || + !Config.BuildIdLinkDir.empty() || Config.BuildIdLinkInput || + Config.BuildIdLinkOutput || !Config.SplitDWO.empty() || + !Config.SymbolsPrefix.empty() || !Config.AllocSectionsPrefix.empty() || + !Config.AddSection.empty() || !Config.DumpSection.empty() || + !Config.KeepSection.empty() || !Config.OnlySection.empty() || + !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() || + !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() || + !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() || + !Config.SymbolsToRename.empty() || !Config.UnneededSymbolsToRemove.empty() || !Config.SetSectionFlags.empty() || !Config.ToRemove.empty() || Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden || Index: llvm/tools/llvm-objcopy/ObjcopyOpts.td =================================================================== --- llvm/tools/llvm-objcopy/ObjcopyOpts.td +++ llvm/tools/llvm-objcopy/ObjcopyOpts.td @@ -33,6 +33,9 @@ Values<"binary">; def O : JoinedOrSeparate<["-"], "O">, Alias; +defm binary_symbol_visibility : Eq <"binary-symbol-visibility", "Visibility of symbols " + "generated for binary input">; + def compress_debug_sections : Flag<["--"], "compress-debug-sections">; def compress_debug_sections_eq : Joined<["--"], "compress-debug-sections=">,