[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / tools / llvm-objcopy / ELF / ELFConfig.cpp
blob40993760add79f7842b3fce01ad7ee5abfa1a7e0
1 //===- ELFConfig.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 //===----------------------------------------------------------------------===//
9 #include "CopyConfig.h"
10 #include "llvm/ADT/Optional.h"
11 #include "llvm/ADT/StringSwitch.h"
12 #include "llvm/Support/Errc.h"
13 #include "llvm/Support/Error.h"
15 namespace llvm {
16 namespace objcopy {
17 namespace elf {
19 static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue,
20 uint8_t DefaultVisibility) {
21 // Parse value given with --add-symbol option and create the
22 // new symbol if possible. The value format for --add-symbol is:
24 // <name>=[<section>:]<value>[,<flags>]
26 // where:
27 // <name> - symbol name, can be empty string
28 // <section> - optional section name. If not given ABS symbol is created
29 // <value> - symbol value, can be decimal or hexadecimal number prefixed
30 // with 0x.
31 // <flags> - optional flags affecting symbol type, binding or visibility:
32 // The following are currently supported:
34 // global, local, weak, default, hidden, file, section, object,
35 // indirect-function.
37 // The following flags are ignored and provided for GNU
38 // compatibility only:
40 // warning, debug, constructor, indirect, synthetic,
41 // unique-object, before=<symbol>.
42 NewSymbolInfo SI;
43 StringRef Value;
44 std::tie(SI.SymbolName, Value) = FlagValue.split('=');
45 if (Value.empty())
46 return createStringError(
47 errc::invalid_argument,
48 "bad format for --add-symbol, missing '=' after '%s'",
49 SI.SymbolName.str().c_str());
51 if (Value.contains(':')) {
52 std::tie(SI.SectionName, Value) = Value.split(':');
53 if (SI.SectionName.empty() || Value.empty())
54 return createStringError(
55 errc::invalid_argument,
56 "bad format for --add-symbol, missing section name or symbol value");
59 SmallVector<StringRef, 6> Flags;
60 Value.split(Flags, ',');
61 if (Flags[0].getAsInteger(0, SI.Value))
62 return createStringError(errc::invalid_argument, "bad symbol value: '%s'",
63 Flags[0].str().c_str());
65 SI.Visibility = DefaultVisibility;
67 using Functor = std::function<void(void)>;
68 SmallVector<StringRef, 6> UnsupportedFlags;
69 for (size_t I = 1, NumFlags = Flags.size(); I < NumFlags; ++I)
70 static_cast<Functor>(
71 StringSwitch<Functor>(Flags[I])
72 .CaseLower("global", [&SI] { SI.Bind = ELF::STB_GLOBAL; })
73 .CaseLower("local", [&SI] { SI.Bind = ELF::STB_LOCAL; })
74 .CaseLower("weak", [&SI] { SI.Bind = ELF::STB_WEAK; })
75 .CaseLower("default", [&SI] { SI.Visibility = ELF::STV_DEFAULT; })
76 .CaseLower("hidden", [&SI] { SI.Visibility = ELF::STV_HIDDEN; })
77 .CaseLower("protected",
78 [&SI] { SI.Visibility = ELF::STV_PROTECTED; })
79 .CaseLower("file", [&SI] { SI.Type = ELF::STT_FILE; })
80 .CaseLower("section", [&SI] { SI.Type = ELF::STT_SECTION; })
81 .CaseLower("object", [&SI] { SI.Type = ELF::STT_OBJECT; })
82 .CaseLower("function", [&SI] { SI.Type = ELF::STT_FUNC; })
83 .CaseLower("indirect-function",
84 [&SI] { SI.Type = ELF::STT_GNU_IFUNC; })
85 .CaseLower("debug", [] {})
86 .CaseLower("constructor", [] {})
87 .CaseLower("warning", [] {})
88 .CaseLower("indirect", [] {})
89 .CaseLower("synthetic", [] {})
90 .CaseLower("unique-object", [] {})
91 .StartsWithLower("before", [] {})
92 .Default([&] { UnsupportedFlags.push_back(Flags[I]); }))();
93 if (!UnsupportedFlags.empty())
94 return createStringError(errc::invalid_argument,
95 "unsupported flag%s for --add-symbol: '%s'",
96 UnsupportedFlags.size() > 1 ? "s" : "",
97 join(UnsupportedFlags, "', '").c_str());
98 return SI;
101 Expected<ELFCopyConfig> parseConfig(const CopyConfig &Config) {
102 ELFCopyConfig ELFConfig;
103 if (Config.NewSymbolVisibility) {
104 const uint8_t Invalid = 0xff;
105 ELFConfig.NewSymbolVisibility =
106 StringSwitch<uint8_t>(*Config.NewSymbolVisibility)
107 .Case("default", ELF::STV_DEFAULT)
108 .Case("hidden", ELF::STV_HIDDEN)
109 .Case("internal", ELF::STV_INTERNAL)
110 .Case("protected", ELF::STV_PROTECTED)
111 .Default(Invalid);
113 if (ELFConfig.NewSymbolVisibility == Invalid)
114 return createStringError(errc::invalid_argument,
115 "'%s' is not a valid symbol visibility",
116 Config.NewSymbolVisibility->str().c_str());
119 for (StringRef Arg : Config.SymbolsToAdd) {
120 Expected<elf::NewSymbolInfo> NSI = parseNewSymbolInfo(
121 Arg,
122 ELFConfig.NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT));
123 if (!NSI)
124 return NSI.takeError();
125 ELFConfig.SymbolsToAdd.push_back(*NSI);
128 return ELFConfig;
131 } // end namespace elf
132 } // end namespace objcopy
133 } // end namespace llvm