mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[yaml2obj][obj2yaml] - Use a single "Other" field instead of "Other", "Visibility" and "StOther".
Currenly we can encode the 'st_other' field of symbol using 3 fields. 'Visibility' is used to encode STV_* values. 'Other' is used to encode everything except the visibility, but it can't handle arbitrary values. 'StOther' is used to encode arbitrary values when 'Visibility'/'Other' are not helpfull enough. 'st_other' field is used to encode symbol visibility and platform-dependent flags and values. Problem to encode it is that it consists of Visibility part (STV_* values) which are enumeration values and the Other part, which is different and inconsistent. For MIPS the Other part contains flags for all STO_MIPS_* values except STO_MIPS_MIPS16. (Like comment in ELFDumper says: "Someones in their infinite wisdom decided to make STO_MIPS_MIPS16 flag overlapped with other ST_MIPS_xxx flags."...) And for PPC64 the Other part might actually encode any value. This patch implements custom logic for handling the st_other and removes 'Visibility' and 'StOther' fields. Here is an example of a new YAML style this patch allows: - Name: foo Other: [ 0x4 ] - Name: bar Other: [ STV_PROTECTED, 4 ] - Name: zed Other: [ STV_PROTECTED, STO_MIPS_OPTIONAL, 0xf8 ] Differential revision: https://reviews.llvm.org/D66886 llvm-svn: 370472
This commit is contained in:
parent
fc6d78bba9
commit
fa73d7c8a9
@ -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)
|
||||
@ -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 {
|
||||
@ -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);
|
||||
|
@ -748,7 +748,7 @@ public:
|
||||
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;
|
||||
@ -842,7 +842,7 @@ public:
|
||||
Val = Val | ConstVal;
|
||||
}
|
||||
|
||||
void *getContext();
|
||||
void *getContext() const;
|
||||
void setContext(void *);
|
||||
|
||||
template <typename T> void mapRequired(const char *Key, T &Val) {
|
||||
@ -1402,7 +1402,7 @@ public:
|
||||
std::error_code error();
|
||||
|
||||
private:
|
||||
bool outputting() override;
|
||||
bool outputting() const override;
|
||||
bool mapTag(StringRef, bool) override;
|
||||
void beginMapping() override;
|
||||
void endMapping() override;
|
||||
@ -1549,7 +1549,7 @@ public:
|
||||
/// 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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
||||
@ -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) {
|
||||
@ -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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ IO::IO(void *Context) : Ctxt(Context) {}
|
||||
|
||||
IO::~IO() = default;
|
||||
|
||||
void *IO::getContext() {
|
||||
void *IO::getContext() const {
|
||||
return Ctxt;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ Symbols:
|
||||
Section: .text
|
||||
Value: 0x1008
|
||||
Size: 8
|
||||
Visibility: STV_HIDDEN
|
||||
Other: [ STV_HIDDEN ]
|
||||
- Name: defaultGlobal
|
||||
Type: STT_FUNC
|
||||
Size: 8
|
||||
@ -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
|
||||
@ -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 [
|
||||
|
@ -33,7 +33,7 @@ Symbols:
|
||||
Section: .text
|
||||
Value: 0x1001
|
||||
Size: 4
|
||||
Visibility: STV_HIDDEN
|
||||
Other: [ STV_HIDDEN ]
|
||||
Binding: STB_GLOBAL
|
||||
- Name: foo
|
||||
Type: STT_FUNC
|
||||
@ -45,7 +45,7 @@ Symbols:
|
||||
Section: .data
|
||||
Value: 0x2002
|
||||
Size: 2
|
||||
Visibility: STV_INTERNAL
|
||||
Other: [ STV_INTERNAL ]
|
||||
Binding: STB_GLOBAL
|
||||
- Name: bar
|
||||
Type: STT_OBJECT
|
||||
|
@ -23,13 +23,13 @@ Symbols:
|
||||
- Name: default
|
||||
Section: .text
|
||||
- Name: internal
|
||||
Visibility: STV_INTERNAL
|
||||
Other: [ STV_INTERNAL ]
|
||||
Section: .text
|
||||
- Name: hidden
|
||||
Visibility: STV_HIDDEN
|
||||
Other: [ STV_HIDDEN ]
|
||||
Section: .text
|
||||
- Name: protected
|
||||
Visibility: STV_PROTECTED
|
||||
Other: [ STV_PROTECTED ]
|
||||
Section: .text
|
||||
- Name: mips_pic
|
||||
Other: [ STO_MIPS_PIC ]
|
||||
|
@ -39,17 +39,17 @@ FileHeader:
|
||||
Machine: EM_386
|
||||
Symbols:
|
||||
- Name: default
|
||||
Visibility: STV_DEFAULT
|
||||
Other: [ STV_DEFAULT ]
|
||||
Binding: STB_GLOBAL
|
||||
- Name: internal
|
||||
Visibility: STV_INTERNAL
|
||||
Other: [ STV_INTERNAL ]
|
||||
Binding: STB_GLOBAL
|
||||
- Name: hidden
|
||||
Visibility: STV_HIDDEN
|
||||
Other: [ STV_HIDDEN ]
|
||||
Binding: STB_GLOBAL
|
||||
- Name: protected
|
||||
Visibility: STV_PROTECTED
|
||||
Other: [ STV_PROTECTED ]
|
||||
Binding: STB_GLOBAL
|
||||
- Name: other
|
||||
Binding: STB_GLOBAL
|
||||
StOther: 4
|
||||
Other: [ 4 ]
|
||||
|
@ -10,12 +10,12 @@
|
||||
# CHECK-NEXT: Machine: EM_X86_64
|
||||
# CHECK-NEXT: Symbols:
|
||||
# CHECK-NEXT: - Name: default
|
||||
# CHECK-NEXT: - Name: internal
|
||||
# CHECK-NEXT: Visibility: STV_INTERNAL
|
||||
# CHECK-NEXT: - Name: hidden
|
||||
# CHECK-NEXT: Visibility: STV_HIDDEN
|
||||
# CHECK-NEXT: - Name: protected
|
||||
# CHECK-NEXT: Visibility: STV_PROTECTED
|
||||
# CHECK-NEXT: - Name: internal
|
||||
# CHECK-NEXT: Other: [ STV_INTERNAL ]
|
||||
# CHECK-NEXT: - Name: hidden
|
||||
# CHECK-NEXT: Other: [ STV_HIDDEN ]
|
||||
# CHECK-NEXT: - Name: protected
|
||||
# CHECK-NEXT: Other: [ STV_PROTECTED ]
|
||||
# CHECK-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
@ -25,11 +25,11 @@ FileHeader:
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Symbols:
|
||||
- Name: default
|
||||
Visibility: STV_DEFAULT
|
||||
- Name: internal
|
||||
Visibility: STV_INTERNAL
|
||||
- Name: hidden
|
||||
Visibility: STV_HIDDEN
|
||||
- Name: protected
|
||||
Visibility: STV_PROTECTED
|
||||
- Name: default
|
||||
Other: [ STV_DEFAULT ]
|
||||
- Name: internal
|
||||
Other: [ STV_INTERNAL ]
|
||||
- Name: hidden
|
||||
Other: [ STV_HIDDEN ]
|
||||
- Name: protected
|
||||
Other: [ STV_PROTECTED ]
|
||||
|
@ -4,8 +4,7 @@
|
||||
## to a different machine type to what is specified by the YAML.
|
||||
|
||||
# RUN: not yaml2obj --docnum=1 2>&1 %s | FileCheck %s --check-prefix=ERR
|
||||
# ERR: error: unknown bit value
|
||||
# ERR-NEXT: Other: [ STO_MIPS_OPTIONAL ]
|
||||
# ERR: error: an unknown value is used for symbol's 'Other' field: STO_MIPS_OPTIONAL.
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
@ -38,21 +37,23 @@ Symbols:
|
||||
- Name: foo
|
||||
Other: [ STO_MIPS_OPTIONAL ]
|
||||
|
||||
## Test that instead of using the "Other" field we can use the "StOther" field
|
||||
## to set st_other to any arbitrary value.
|
||||
## Test that we can mix named and unnamed constants and set
|
||||
## st_other to any arbitrary value.
|
||||
|
||||
# RUN: yaml2obj --docnum=3 %s > %t3
|
||||
# RUN: llvm-readobj --symbols %t3 | FileCheck %s --check-prefix=USE-STOTHER
|
||||
# RUN: yaml2obj --docnum=4 %s > %t4
|
||||
# RUN: llvm-readobj --symbols %t4 | FileCheck %s --check-prefix=USE-STOTHER
|
||||
# RUN: llvm-readobj --symbols %t3 | FileCheck %s --check-prefix=VALUE
|
||||
|
||||
# USE-STOTHER: Name: foo
|
||||
# USE-STOTHER: Other [
|
||||
# USE-STOTHER-SAME: (0x4)
|
||||
# VALUE: Name: foo
|
||||
# VALUE: Other [
|
||||
# VALUE-SAME: (0x4)
|
||||
|
||||
# USE-STOTHER: Name: bar
|
||||
# USE-STOTHER: Other [
|
||||
# USE-STOTHER-SAME: (0xFF)
|
||||
# VALUE: Name: bar
|
||||
# VALUE: Other [
|
||||
# VALUE-SAME: (0x7)
|
||||
|
||||
# VALUE: Name: zed
|
||||
# VALUE: Other [
|
||||
# VALUE-SAME: (0xFF)
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
@ -61,48 +62,9 @@ FileHeader:
|
||||
Type: ET_REL
|
||||
Machine: EM_MIPS
|
||||
Symbols:
|
||||
- Name: foo
|
||||
StOther: 4
|
||||
- Name: bar
|
||||
StOther: 0xff
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_386
|
||||
Symbols:
|
||||
- Name: foo
|
||||
StOther: 4
|
||||
- Name: bar
|
||||
StOther: 0xff
|
||||
|
||||
## Check we can't set StOther for a symbol if Visibility or Other is also specified.
|
||||
|
||||
# RUN: not yaml2obj --docnum=5 2>&1 %s | FileCheck %s --check-prefix=ERR2
|
||||
# RUN: not yaml2obj --docnum=6 2>&1 %s | FileCheck %s --check-prefix=ERR2
|
||||
|
||||
# ERR2: error: StOther cannot be specified for Symbol with either Visibility or Other
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_MIPS
|
||||
Symbols:
|
||||
- Name: foo
|
||||
StOther: 0
|
||||
Other: [ STO_MIPS_OPTIONAL ]
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_MIPS
|
||||
Symbols:
|
||||
- Name: foo
|
||||
StOther: 0
|
||||
Visibility: STV_DEFAULT
|
||||
- Name: foo
|
||||
Other: [ 0x4 ]
|
||||
- Name: bar
|
||||
Other: [ STV_PROTECTED, 4 ]
|
||||
- Name: zed
|
||||
Other: [ STV_PROTECTED, STO_MIPS_OPTIONAL, 0xf8 ]
|
||||
|
@ -3,7 +3,7 @@
|
||||
# RUN: yaml2obj %s | llvm-readobj --symbols - | FileCheck --check-prefix OBJ %s
|
||||
|
||||
# OBJ: Symbol {
|
||||
# OBJ: Name: default (1)
|
||||
# OBJ: Name: default1
|
||||
# OBJ-NEXT: Value: 0x0
|
||||
# OBJ-NEXT: Size: 0
|
||||
# OBJ-NEXT: Binding: Local (0x0)
|
||||
@ -12,7 +12,16 @@
|
||||
# OBJ-NEXT: Section: Undefined (0x0)
|
||||
# OBJ-NEXT: }
|
||||
# OBJ-NEXT: Symbol {
|
||||
# OBJ-NEXT: Name: internal (16)
|
||||
# OBJ-NEXT: Name: default2
|
||||
# OBJ-NEXT: Value: 0x0
|
||||
# OBJ-NEXT: Size: 0
|
||||
# OBJ-NEXT: Binding: Local (0x0)
|
||||
# OBJ-NEXT: Type: None (0x0)
|
||||
# OBJ-NEXT: Other: 0
|
||||
# OBJ-NEXT: Section: Undefined (0x0)
|
||||
# OBJ-NEXT: }
|
||||
# OBJ-NEXT: Symbol {
|
||||
# OBJ-NEXT: Name: internal
|
||||
# OBJ-NEXT: Value: 0x0
|
||||
# OBJ-NEXT: Size: 0
|
||||
# OBJ-NEXT: Binding: Local (0x0)
|
||||
@ -23,7 +32,7 @@
|
||||
# OBJ-NEXT: Section: Undefined (0x0)
|
||||
# OBJ-NEXT: }
|
||||
# OBJ-NEXT: Symbol {
|
||||
# OBJ-NEXT: Name: hidden (9)
|
||||
# OBJ-NEXT: Name: hidden
|
||||
# OBJ-NEXT: Value: 0x0
|
||||
# OBJ-NEXT: Size: 0
|
||||
# OBJ-NEXT: Binding: Local (0x0)
|
||||
@ -34,7 +43,7 @@
|
||||
# OBJ-NEXT: Section: Undefined (0x0)
|
||||
# OBJ-NEXT: }
|
||||
# OBJ-NEXT: Symbol {
|
||||
# OBJ-NEXT: Name: protected (25)
|
||||
# OBJ-NEXT: Name: protected
|
||||
# OBJ-NEXT: Value: 0x0
|
||||
# OBJ-NEXT: Size: 0
|
||||
# OBJ-NEXT: Binding: Local (0x0)
|
||||
@ -52,11 +61,12 @@ FileHeader:
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Symbols:
|
||||
- Name: default
|
||||
Visibility: STV_DEFAULT
|
||||
- Name: internal
|
||||
Visibility: STV_INTERNAL
|
||||
- Name: hidden
|
||||
Visibility: STV_HIDDEN
|
||||
- Name: protected
|
||||
Visibility: STV_PROTECTED
|
||||
- Name: default1
|
||||
- Name: default2
|
||||
Other: [ STV_DEFAULT ]
|
||||
- Name: internal
|
||||
Other: [ STV_INTERNAL ]
|
||||
- Name: hidden
|
||||
Other: [ STV_HIDDEN ]
|
||||
- Name: protected
|
||||
Other: [ STV_PROTECTED ]
|
||||
|
Loading…
Reference in New Issue
Block a user