Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from llvm:master #66

Merged
merged 2 commits into from
Aug 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions llvm/include/llvm/ObjectYAML/ELFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO)

LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
Expand Down Expand Up @@ -108,11 +106,6 @@ struct Symbol {
llvm::yaml::Hex64 Value;
llvm::yaml::Hex64 Size;
Optional<uint8_t> Other;

// This can be used to set any custom value for the st_other field
// when it is not possible to do so using the "Other" field, which only takes
// specific named constants.
Optional<uint8_t> StOther;
};

struct SectionOrType {
Expand Down Expand Up @@ -401,16 +394,6 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
};

template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
};

template <>
struct ScalarBitSetTraits<ELFYAML::ELF_STO> {
static void bitset(IO &IO, ELFYAML::ELF_STO &Value);
};

template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
Expand Down
8 changes: 4 additions & 4 deletions llvm/include/llvm/Support/YAMLTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ class IO {
IO(void *Ctxt = nullptr);
virtual ~IO();

virtual bool outputting() = 0;
virtual bool outputting() const = 0;

virtual unsigned beginSequence() = 0;
virtual bool preflightElement(unsigned, void *&) = 0;
Expand Down Expand Up @@ -842,7 +842,7 @@ class IO {
Val = Val | ConstVal;
}

void *getContext();
void *getContext() const;
void setContext(void *);

template <typename T> void mapRequired(const char *Key, T &Val) {
Expand Down Expand Up @@ -1402,7 +1402,7 @@ class Input : public IO {
std::error_code error();

private:
bool outputting() override;
bool outputting() const override;
bool mapTag(StringRef, bool) override;
void beginMapping() override;
void endMapping() override;
Expand Down Expand Up @@ -1549,7 +1549,7 @@ class Output : public IO {
/// anyway.
void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }

bool outputting() override;
bool outputting() const override;
bool mapTag(StringRef, bool) override;
void beginMapping() override;
void endMapping() override;
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8715,9 +8715,9 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
if (TLI.isOperationLegalOrCustom(ISD::ABS, VT))
return DAG.getNode(ISD::ABS, DL, VT, LHS);

SDValue Shift = DAG.getNode(
ISD::SRA, DL, VT, LHS,
DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT));
SDValue Shift = DAG.getNode(ISD::SRA, DL, VT, LHS,
DAG.getConstant(VT.getScalarSizeInBits() - 1,
DL, getShiftAmountTy(VT)));
SDValue Add = DAG.getNode(ISD::ADD, DL, VT, LHS, Shift);
AddToWorklist(Shift.getNode());
AddToWorklist(Add.getNode());
Expand Down
7 changes: 1 addition & 6 deletions llvm/lib/ObjectYAML/ELFEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,12 +464,7 @@ toELFSymbols(NameToIdxMap &SN2I, ArrayRef<ELFYAML::Symbol> Symbols,
}
// else Symbol.st_shndex == SHN_UNDEF (== 0), since it was zero'd earlier.
Symbol.st_value = Sym.Value;

if (Sym.Other)
Symbol.st_other = *Sym.Other;
else if (Sym.StOther)
Symbol.st_other = *Sym.StOther;

Symbol.st_other = Sym.Other ? *Sym.Other : 0;
Symbol.st_size = Sym.Size;
}

Expand Down
160 changes: 102 additions & 58 deletions llvm/lib/ObjectYAML/ELFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
//===----------------------------------------------------------------------===//

#include "llvm/ObjectYAML/ELFYAML.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MipsABIFlags.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/WithColor.h"
#include <cassert>
#include <cstdint>

Expand Down Expand Up @@ -592,34 +594,6 @@ void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
IO.enumFallback<Hex8>(Value);
}

void ScalarEnumerationTraits<ELFYAML::ELF_STV>::enumeration(
IO &IO, ELFYAML::ELF_STV &Value) {
#define ECase(X) IO.enumCase(Value, #X, ELF::X)
ECase(STV_DEFAULT);
ECase(STV_INTERNAL);
ECase(STV_HIDDEN);
ECase(STV_PROTECTED);
#undef ECase
}

void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
ELFYAML::ELF_STO &Value) {
const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
assert(Object && "The IO context is not initialized");
#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
switch (Object->Header.Machine) {
case ELF::EM_MIPS:
BCase(STO_MIPS_OPTIONAL);
BCase(STO_MIPS_PLT);
BCase(STO_MIPS_PIC);
BCase(STO_MIPS_MICROMIPS);
break;
default:
break; // Nothing to do
}
#undef BCase
#undef BCaseMask
}

void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
IO &IO, ELFYAML::ELF_RSS &Value) {
Expand Down Expand Up @@ -863,31 +837,112 @@ void MappingTraits<ELFYAML::ProgramHeader>::mapping(
IO.mapOptional("Offset", Phdr.Offset);
}

LLVM_YAML_STRONG_TYPEDEF(StringRef, StOtherPiece)

template <> struct ScalarTraits<StOtherPiece> {
static void output(const StOtherPiece &Val, void *, raw_ostream &Out) {
Out << Val;
}
static StringRef input(StringRef Scalar, void *, StOtherPiece &Val) {
Val = Scalar;
return {};
}
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template <> struct SequenceElementTraits<StOtherPiece> {
static const bool flow = true;
};

namespace {

struct NormalizedOther {
NormalizedOther(IO &) {}
NormalizedOther(IO &, Optional<uint8_t> Original) {
if (uint8_t Val = *Original & 0x3)
Visibility = Val;
if (uint8_t Val = *Original & ~0x3)
Other = Val;
NormalizedOther(IO &IO) : YamlIO(IO) {}
NormalizedOther(IO &IO, Optional<uint8_t> Original) : YamlIO(IO) {
assert(Original && "This constructor is only used for outputting YAML and "
"assumes a non-empty Original");
std::vector<StOtherPiece> Ret;
const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
for (std::pair<StringRef, uint8_t> &P :
getFlags(Object->Header.Machine).takeVector()) {
uint8_t FlagValue = P.second;
if ((*Original & FlagValue) != FlagValue)
continue;
*Original &= ~FlagValue;
Ret.push_back({P.first});
}

if (*Original != 0) {
UnknownFlagsHolder = std::to_string(*Original);
Ret.push_back({UnknownFlagsHolder});
}

if (!Ret.empty())
Other = std::move(Ret);
}

uint8_t toValue(StringRef Name) {
const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext());
MapVector<StringRef, uint8_t> Flags = getFlags(Object->Header.Machine);

auto It = Flags.find(Name);
if (It != Flags.end())
return It->second;

uint8_t Val;
if (to_integer(Name, Val))
return Val;

llvm::WithColor::error()
<< "an unknown value is used for symbol's 'Other' field: " << Name
<< ".\n";
exit(1);
}

Optional<uint8_t> denormalize(IO &) {
if (!Visibility && !Other)
if (!Other)
return None;

uint8_t Ret = 0;
if (Visibility)
Ret |= *Visibility;
if (Other)
Ret |= *Other;
for (StOtherPiece &Val : *Other)
Ret |= toValue(Val);
return Ret;
}

Optional<ELFYAML::ELF_STV> Visibility;
Optional<ELFYAML::ELF_STO> Other;
// st_other field is used to encode symbol visibility and platform-dependent
// flags and values. This method returns a name to value map that is used for
// parsing and encoding this field.
MapVector<StringRef, uint8_t> getFlags(unsigned EMachine) {
MapVector<StringRef, uint8_t> Map;
// STV_* values are just enumeration values. We add them in a reversed order
// because when we convert the st_other to named constants when printing
// YAML we want to use a maximum number of bits on each step:
// when we have st_other == 3, we want to print it as STV_PROTECTED (3), but
// not as STV_HIDDEN (2) + STV_INTERNAL (1).
Map["STV_PROTECTED"] = ELF::STV_PROTECTED;
Map["STV_HIDDEN"] = ELF::STV_HIDDEN;
Map["STV_INTERNAL"] = ELF::STV_INTERNAL;
// STV_DEFAULT is used to represent the default visibility and has a value
// 0. We want to be able to read it from YAML documents, but there is no
// reason to print it.
if (!YamlIO.outputting())
Map["STV_DEFAULT"] = ELF::STV_DEFAULT;

// MIPS is not consistent. All of the STO_MIPS_* values are bit flags,
// except STO_MIPS_MIPS16 which overlaps them. It should be checked and
// consumed first when we print the output, because we do not want to print
// any other flags that have the same bits instead.
if (EMachine == ELF::EM_MIPS) {
Map["STO_MIPS_MIPS16"] = ELF::STO_MIPS_MIPS16;
Map["STO_MIPS_MICROMIPS"] = ELF::STO_MIPS_MICROMIPS;
Map["STO_MIPS_PIC"] = ELF::STO_MIPS_PIC;
Map["STO_MIPS_PLT"] = ELF::STO_MIPS_PLT;
Map["STO_MIPS_OPTIONAL"] = ELF::STO_MIPS_OPTIONAL;
}
return Map;
}

const IO &YamlIO;
Optional<std::vector<StOtherPiece>> Other;
std::string UnknownFlagsHolder;
};

} // end anonymous namespace
Expand All @@ -902,22 +957,13 @@ void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
IO.mapOptional("Value", Symbol.Value, Hex64(0));
IO.mapOptional("Size", Symbol.Size, Hex64(0));

// Symbol's Other field is a bit special. It is a bit field that represents
// st_other and usually holds symbol visibility. When we write a YAML document
// we split it into two fields named "Visibility" and "Other". The latter one
// usually holds no value, and so is almost never printed, although some
// targets (e.g. MIPS) may use it to specify the named bits to set (e.g.
// STO_MIPS_OPTIONAL). For producing broken objects we want to allow writing
// any value to st_other. To do this we allow one more field called "StOther".
// If it is present in a YAML document, we set st_other to its integer value
// whatever it is.
// obj2yaml should not print 'StOther', it should print 'Visibility' and
// 'Other' fields instead.
assert(!IO.outputting() || !Symbol.StOther.hasValue());
IO.mapOptional("StOther", Symbol.StOther);
// Symbol's Other field is a bit special. It is usually a field that
// represents st_other and holds the symbol visibility. However, on some
// platforms, it can contain bit fields and regular values, or even sometimes a
// crazy mix of them (see comments for NormalizedOther). Because of this, we
// need special handling.
MappingNormalization<NormalizedOther, Optional<uint8_t>> Keys(IO,
Symbol.Other);
IO.mapOptional("Visibility", Keys->Visibility);
IO.mapOptional("Other", Keys->Other);
}

Expand All @@ -927,8 +973,6 @@ StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
return "Index and Section cannot both be specified for Symbol";
if (Symbol.NameIndex && !Symbol.Name.empty())
return "Name and NameIndex cannot both be specified for Symbol";
if (Symbol.StOther && Symbol.Other)
return "StOther cannot be specified for Symbol with either Visibility or Other";
return StringRef();
}

Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Support/YAMLTraits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ IO::IO(void *Context) : Ctxt(Context) {}

IO::~IO() = default;

void *IO::getContext() {
void *IO::getContext() const {
return Ctxt;
}

Expand Down Expand Up @@ -79,7 +79,7 @@ void Input::ScalarHNode::anchor() {}
void Input::MapHNode::anchor() {}
void Input::SequenceHNode::anchor() {}

bool Input::outputting() {
bool Input::outputting() const {
return false;
}

Expand Down Expand Up @@ -440,7 +440,7 @@ Output::Output(raw_ostream &yout, void *context, int WrapColumn)

Output::~Output() = default;

bool Output::outputting() {
bool Output::outputting() const {
return true;
}

Expand Down
12 changes: 6 additions & 6 deletions llvm/test/tools/llvm-objcopy/ELF/localize-hidden.test
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Symbols:
Section: .text
Value: 0x1008
Size: 8
Visibility: STV_HIDDEN
Other: [ STV_HIDDEN ]
- Name: defaultGlobal
Type: STT_FUNC
Size: 8
Expand All @@ -46,14 +46,14 @@ Symbols:
Section: .data
Value: 0x2006
Size: 2
Visibility: STV_HIDDEN
Other: [ STV_HIDDEN ]
Binding: STB_GLOBAL
- Name: hiddenGlobalCommon
Type: STT_OBJECT
Index: SHN_COMMON
Value: 0x2006
Size: 2
Visibility: STV_HIDDEN
Other: [ STV_HIDDEN ]
Binding: STB_GLOBAL
- Name: undefGlobal
Type: STT_FUNC
Expand All @@ -64,21 +64,21 @@ Symbols:
Section: .data
Value: 0x2002
Size: 2
Visibility: STV_INTERNAL
Other: [ STV_INTERNAL ]
Binding: STB_GLOBAL
- Name: protectedGlobal
Type: STT_OBJECT
Section: .data
Value: 0x2000
Size: 4
Visibility: STV_PROTECTED
Other: [ STV_PROTECTED ]
Binding: STB_GLOBAL
- Name: hiddenWeak
Type: STT_FUNC
Section: .text
Value: 0x1010
Size: 8
Visibility: STV_HIDDEN
Other: [ STV_HIDDEN ]
Binding: STB_WEAK

#CHECK: Relocations [
Expand Down
Loading