diff options
author | Chris Jackson <snortotter@gmail.com> | 2019-08-30 10:17:16 +0000 |
---|---|---|
committer | Chris Jackson <snortotter@gmail.com> | 2019-08-30 10:17:16 +0000 |
commit | fa1fe937893c1581c71b225602f44a32102b86ff (patch) | |
tree | 2872328c078795646501b6edc37ef19509117d96 | |
parent | b4fd7d4258589c52539043c0806fd2a143a2c15d (diff) | |
download | bcm5719-llvm-fa1fe937893c1581c71b225602f44a32102b86ff.tar.gz bcm5719-llvm-fa1fe937893c1581c71b225602f44a32102b86ff.zip |
[llvm-objcopy] Allow the visibility of symbols created by --binary and
--add-symbol to be specified with --new-symbol-visibility
llvm-svn: 370458
-rw-r--r-- | llvm/docs/CommandGuide/llvm-objcopy.rst | 12 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objcopy/ELF/add-symbol-new-symbol-visibility.test | 20 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objcopy/ELF/new-symbol-visibility.test | 22 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 16 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/CopyConfig.cpp | 24 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/CopyConfig.h | 1 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ELF/Object.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ELF/Object.h | 12 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOpts.td | 5 |
11 files changed, 111 insertions, 23 deletions
diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst index 044293c7e8a..065811c782b 100644 --- a/llvm/docs/CommandGuide/llvm-objcopy.rst +++ b/llvm/docs/CommandGuide/llvm-objcopy.rst @@ -318,6 +318,18 @@ them. represents a single symbol, with leading and trailing whitespace ignored, as is anything following a '#'. Can be specified multiple times to read names from multiple files. + +.. option:: --new-symbol-visibility <visibility> + + Specify the visibility of the symbols automatically created when using binary + input or :option:`--add-symbol`. Valid options are: + + - `default` + - `hidden` + - `internal` + - `protected` + + The default is `default`. .. option:: --output-target <format>, -O diff --git a/llvm/test/tools/llvm-objcopy/ELF/add-symbol-new-symbol-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/add-symbol-new-symbol-visibility.test new file mode 100644 index 00000000000..9ef5849f991 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/add-symbol-new-symbol-visibility.test @@ -0,0 +1,20 @@ +## Ensure that the visibility of symbols added with --add-symbol can be +## specified with the --new-symbol-visibility switch. + +# RUN: yaml2obj %s -o %t.obj +# RUN: llvm-objcopy --new-symbol-visibility protected --add-symbol symbol_protected=.text:42 \ +# RUN: --add-symbol symbol_hidden=.text:42,hidden %t.obj %t +# RUN: llvm-readelf -s %t | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + +# CHECK: PROTECTED {{.*}} symbol_protected +# CHECK: HIDDEN {{.*}} symbol_hidden diff --git a/llvm/test/tools/llvm-objcopy/ELF/new-symbol-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/new-symbol-visibility.test new file mode 100644 index 00000000000..143a18c0a7e --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/new-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 with the --new-symbol-visibility switch. + +# RUN: llvm-objcopy -I binary -B i386:x86-64 %s %t.unspecified +# RUN: llvm-readelf -s %t.unspecified | FileCheck %s --check-prefix=BINARY -DVISIBILITY=DEFAULT +# RUN: llvm-objcopy --new-symbol-visibility default -I binary -B i386:x86-64 %s %t.default +# RUN: llvm-readelf -s %t.default | FileCheck %s --check-prefix=BINARY -DVISIBILITY=DEFAULT +# RUN: llvm-objcopy --new-symbol-visibility hidden -I binary -B i386:x86-64 %s %t.hidden +# RUN: llvm-readelf -s %t.hidden | FileCheck %s --check-prefix=BINARY -DVISIBILITY=HIDDEN +# RUN: llvm-objcopy --new-symbol-visibility protected -I binary -B i386:x86-64 %s %t.protected +# RUN: llvm-readelf -s %t.protected | FileCheck %s --check-prefix=BINARY -DVISIBILITY=PROTECTED +# RUN: llvm-objcopy --new-symbol-visibility internal -I binary -B i386:x86-64 %s %t.internal +# RUN: llvm-readelf -s %t.internal | FileCheck %s --check-prefix=BINARY -DVISIBILITY=INTERNAL + +# BINARY: [[VISIBILITY]] {{.*}} _binary{{.*}}_start +# BINARY-NEXT: [[VISIBILITY]] {{.*}} _binary{{.*}}_end +# BINARY-NEXT: [[VISIBILITY]] {{.*}} _binary{{.*}}_size + +# RUN: not llvm-objcopy --new-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 symbol visibility diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp index 55bf69ce85b..28de0eb6efd 100644 --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -204,14 +204,14 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { 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.KeepSection.empty() || Config.NewSymbolVisibility || + !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, diff --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp index 2c1dab98c53..9591e5aeb77 100644 --- a/llvm/tools/llvm-objcopy/CopyConfig.cpp +++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp @@ -177,7 +177,8 @@ parseSetSectionFlagValue(StringRef FlagValue) { return SFU; } -static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue) { +static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue, + uint8_t DefaultVisibility) { // Parse value given with --add-symbol option and create the // new symbol if possible. The value format for --add-symbol is: // @@ -222,6 +223,8 @@ static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue) { return createStringError(errc::invalid_argument, "bad symbol value: '%s'", Flags[0].str().c_str()); + SI.Visibility = DefaultVisibility; + using Functor = std::function<void(void)>; SmallVector<StringRef, 6> UnsupportedFlags; for (size_t I = 1, NumFlags = Flags.size(); I < NumFlags; ++I) @@ -488,6 +491,21 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) { Config.BinaryArch = *MI; } + if (opt::Arg *A = InputArgs.getLastArg(OBJCOPY_new_symbol_visibility)) { + const uint8_t Invalid = 0xff; + Config.NewSymbolVisibility = StringSwitch<uint8_t>(A->getValue()) + .Case("default", ELF::STV_DEFAULT) + .Case("hidden", ELF::STV_HIDDEN) + .Case("internal", ELF::STV_INTERNAL) + .Case("protected", ELF::STV_PROTECTED) + .Default(Invalid); + + if (Config.NewSymbolVisibility == Invalid) + return createStringError( + errc::invalid_argument, "'%s' is not a valid symbol visibility", + InputArgs.getLastArgValue(OBJCOPY_new_symbol_visibility).str().c_str()); + } + Config.OutputFormat = StringSwitch<FileFormat>(OutputFormat) .Case("binary", FileFormat::Binary) .Case("ihex", FileFormat::IHex) @@ -696,7 +714,9 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) { Arg->getValue(), UseRegex)) return std::move(E); for (auto Arg : InputArgs.filtered(OBJCOPY_add_symbol)) { - Expected<NewSymbolInfo> NSI = parseNewSymbolInfo(Arg->getValue()); + Expected<NewSymbolInfo> NSI = parseNewSymbolInfo( + Arg->getValue(), + Config.NewSymbolVisibility.getValueOr(ELF::STV_DEFAULT)); if (!NSI) return NSI.takeError(); Config.SymbolsToAdd.push_back(*NSI); diff --git a/llvm/tools/llvm-objcopy/CopyConfig.h b/llvm/tools/llvm-objcopy/CopyConfig.h index f7bb587d8e0..e7f293d7fc2 100644 --- a/llvm/tools/llvm-objcopy/CopyConfig.h +++ b/llvm/tools/llvm-objcopy/CopyConfig.h @@ -145,6 +145,7 @@ struct CopyConfig { StringRef SymbolsPrefix; StringRef AllocSectionsPrefix; DiscardType DiscardMode = DiscardType::None; + Optional<uint8_t> NewSymbolVisibility; // Repeated options std::vector<StringRef> AddSection; diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp index bfc2ecaa2c8..07197769996 100644 --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -755,7 +755,9 @@ Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In, Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In, Buffer &Out) { - BinaryReader Reader(Config.BinaryArch, &In); + uint8_t NewSymbolVisibility = + Config.NewSymbolVisibility.getValueOr(ELF::STV_DEFAULT); + BinaryReader Reader(Config.BinaryArch, &In, NewSymbolVisibility); std::unique_ptr<Object> Obj = Reader.create(); // Prefer OutputArch (-O<format>) if set, otherwise fallback to BinaryArch diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp index 79245aef026..54cddcdd2cd 100644 --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -1161,11 +1161,12 @@ void BinaryELFBuilder::addData(SymbolTableSection *SymTab) { Twine Prefix = Twine("_binary_") + SanitizedFilename; SymTab->addSymbol(Prefix + "_start", STB_GLOBAL, STT_NOTYPE, &DataSection, - /*Value=*/0, STV_DEFAULT, 0, 0); + /*Value=*/0, NewSymbolVisibility, 0, 0); SymTab->addSymbol(Prefix + "_end", STB_GLOBAL, STT_NOTYPE, &DataSection, - /*Value=*/DataSection.Size, STV_DEFAULT, 0, 0); + /*Value=*/DataSection.Size, NewSymbolVisibility, 0, 0); SymTab->addSymbol(Prefix + "_size", STB_GLOBAL, STT_NOTYPE, nullptr, - /*Value=*/DataSection.Size, STV_DEFAULT, SHN_ABS, 0); + /*Value=*/DataSection.Size, NewSymbolVisibility, SHN_ABS, + 0); } std::unique_ptr<Object> BinaryELFBuilder::build() { @@ -1610,7 +1611,7 @@ Writer::~Writer() {} Reader::~Reader() {} std::unique_ptr<Object> BinaryReader::create() const { - return BinaryELFBuilder(MInfo.EMachine, MemBuf).build(); + return BinaryELFBuilder(MInfo.EMachine, MemBuf, NewSymbolVisibility).build(); } Expected<std::vector<IHexRecord>> IHexReader::parse() const { diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h index 42d254c1b2b..42844dae3b4 100644 --- a/llvm/tools/llvm-objcopy/ELF/Object.h +++ b/llvm/tools/llvm-objcopy/ELF/Object.h @@ -889,11 +889,13 @@ public: class BinaryELFBuilder : public BasicELFBuilder { MemoryBuffer *MemBuf; + uint8_t NewSymbolVisibility; void addData(SymbolTableSection *SymTab); public: - BinaryELFBuilder(uint16_t EM, MemoryBuffer *MB) - : BasicELFBuilder(EM), MemBuf(MB) {} + BinaryELFBuilder(uint16_t EM, MemoryBuffer *MB, uint8_t NewSymbolVisibility) + : BasicELFBuilder(EM), MemBuf(MB), + NewSymbolVisibility(NewSymbolVisibility) {} std::unique_ptr<Object> build(); }; @@ -942,10 +944,12 @@ public: class BinaryReader : public Reader { const MachineInfo &MInfo; MemoryBuffer *MemBuf; + uint8_t NewSymbolVisibility; public: - BinaryReader(const MachineInfo &MI, MemoryBuffer *MB) - : MInfo(MI), MemBuf(MB) {} + BinaryReader(const MachineInfo &MI, MemoryBuffer *MB, + const uint8_t NewSymbolVisibility) + : MInfo(MI), MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {} std::unique_ptr<Object> create() const override; }; diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp index c59fa2bd795..a52931e469f 100644 --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -25,10 +25,11 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { !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.NewSymbolVisibility || !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 || diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td index 94a4dc8bfb1..55e26fc881e 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td +++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td @@ -25,6 +25,11 @@ def O : JoinedOrSeparate<["-"], "O">, Alias<output_target>, HelpText<"Alias for --output-target">; +defm new_symbol_visibility : Eq<"new-symbol-visibility", "Visibility of " + "symbols generated for binary input or added" + " with --add-symbol unless otherwise" + " specified. The default value is 'default'.">; + def compress_debug_sections : Flag<["--"], "compress-debug-sections">; def compress_debug_sections_eq : Joined<["--"], "compress-debug-sections=">, |