mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 17:46:40 +00:00
Support more Atom attributes. Add more test cases to lld-core
llvm-svn: 147571
This commit is contained in:
parent
e04dadc248
commit
7735a7d1a0
@ -336,7 +336,8 @@ public:
|
||||
, ContentType ct
|
||||
, SectionChoice sc
|
||||
, bool internalName
|
||||
, bool md
|
||||
, bool mergeDupes
|
||||
, bool autoHide
|
||||
, DeadStripKind ds
|
||||
, bool IsThumb
|
||||
, bool IsAlias
|
||||
@ -344,16 +345,18 @@ public:
|
||||
: _address(ord)
|
||||
, _alignmentModulus(a.modulus)
|
||||
, _alignmentPowerOf2(a.powerOf2)
|
||||
, _contentType(ct)
|
||||
, _definition(d)
|
||||
, _scope(s)
|
||||
, _sectionChoice(sc)
|
||||
, _internalName(internalName)
|
||||
, _deadStrip(ds)
|
||||
, _mode(modeOrdinal)
|
||||
, _mergeDuplicates(md)
|
||||
, _mergeDuplicates(mergeDupes)
|
||||
, _thumb(IsThumb)
|
||||
, _autoHide(autoHide)
|
||||
, _alias(IsAlias)
|
||||
, _contentType(ct)
|
||||
, _scope(s)
|
||||
, _sectionChoice(sc) {}
|
||||
{}
|
||||
|
||||
|
||||
protected:
|
||||
|
@ -10,7 +10,8 @@
|
||||
#ifndef LLD_CORE_REFERENCES_H_
|
||||
#define LLD_CORE_REFERENCES_H_
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace lld {
|
||||
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
, Atom::sectionBasedOnContent
|
||||
, false
|
||||
, false
|
||||
, false
|
||||
, deadStripNormal
|
||||
, false
|
||||
, false
|
||||
|
@ -3,6 +3,7 @@ add_lld_library(lldCore
|
||||
File.cpp
|
||||
Resolver.cpp
|
||||
SymbolTable.cpp
|
||||
YamlKeyValues.cpp
|
||||
YamlReader.cpp
|
||||
YamlWriter.cpp
|
||||
)
|
||||
|
@ -84,41 +84,49 @@ void SymbolTable::addByName(const Atom & newAtom) {
|
||||
llvm::StringRef name = newAtom.name();
|
||||
const Atom *existing = this->findByName(name);
|
||||
if (existing == NULL) {
|
||||
// name is not in symbol table yet, add it associate with this atom
|
||||
// Name is not in symbol table yet, add it associate with this atom.
|
||||
_nameTable[name] = &newAtom;
|
||||
} else {
|
||||
// name is already in symbol table and associated with another atom
|
||||
}
|
||||
else {
|
||||
// Name is already in symbol table and associated with another atom.
|
||||
bool useNew = true;
|
||||
switch (collide(existing->definition(), newAtom.definition())) {
|
||||
case NCR_First:
|
||||
// using first, just add new to _replacedAtoms
|
||||
_replacedAtoms[&newAtom] = existing;
|
||||
useNew = false;
|
||||
break;
|
||||
case NCR_Second:
|
||||
// using second, update tables
|
||||
_nameTable[name] = &newAtom;
|
||||
_replacedAtoms[existing] = &newAtom;
|
||||
useNew = true;
|
||||
break;
|
||||
case NCR_Dup:
|
||||
if ( existing->mergeDuplicates() && newAtom.mergeDuplicates() ) {
|
||||
// using existing atom, add new atom to _replacedAtoms
|
||||
_replacedAtoms[&newAtom] = existing;
|
||||
// Both mergeable. Use auto-hide bit as tie breaker
|
||||
if ( existing->autoHide() != newAtom.autoHide() ) {
|
||||
// They have different autoHide values, keep non-autohide one
|
||||
useNew = existing->autoHide();
|
||||
}
|
||||
else {
|
||||
// They have same autoHide, so just keep using existing
|
||||
useNew = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const Atom& use = _platform.handleMultipleDefinitions(*existing, newAtom);
|
||||
if ( &use == existing ) {
|
||||
// using existing atom, add new atom to _replacedAtoms
|
||||
_replacedAtoms[&newAtom] = existing;
|
||||
}
|
||||
else {
|
||||
// using new atom, update tables
|
||||
_nameTable[name] = &newAtom;
|
||||
_replacedAtoms[existing] = &newAtom;
|
||||
}
|
||||
useNew = ( &use != existing );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
llvm::report_fatal_error("SymbolTable::addByName(): unhandled switch clause");
|
||||
}
|
||||
if ( useNew ) {
|
||||
// Update name table to use new atom.
|
||||
_nameTable[name] = &newAtom;
|
||||
// Add existing atom to replacement table.
|
||||
_replacedAtoms[existing] = &newAtom;
|
||||
}
|
||||
else {
|
||||
// New atom is not being used. Add it to replacement table.
|
||||
_replacedAtoms[&newAtom] = existing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
330
lld/lib/Core/YamlKeyValues.cpp
Normal file
330
lld/lib/Core/YamlKeyValues.cpp
Normal file
@ -0,0 +1,330 @@
|
||||
//===- Core/YamlKeyValues.cpp - Reads YAML --------------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "YamlKeyValues.h"
|
||||
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace lld {
|
||||
namespace yaml {
|
||||
|
||||
|
||||
const char* const KeyValues::nameKeyword = "name";
|
||||
const char* const KeyValues::scopeKeyword = "scope";
|
||||
const char* const KeyValues::definitionKeyword = "definition";
|
||||
const char* const KeyValues::contentTypeKeyword = "type";
|
||||
const char* const KeyValues::deadStripKindKeyword = "dead-strip";
|
||||
const char* const KeyValues::sectionChoiceKeyword = "section-choice";
|
||||
const char* const KeyValues::internalNameKeyword = "internal-name";
|
||||
const char* const KeyValues::mergeDuplicatesKeyword = "merge-duplicates";
|
||||
const char* const KeyValues::autoHideKeyword = "auto-hide";
|
||||
const char* const KeyValues::isThumbKeyword = "is-thumb";
|
||||
const char* const KeyValues::isAliasKeyword = "is-alias";
|
||||
const char* const KeyValues::sectionNameKeyword = "section-name";
|
||||
const char* const KeyValues::contentKeyword = "content";
|
||||
const char* const KeyValues::sizeKeyword = "size";
|
||||
|
||||
|
||||
const Atom::Scope KeyValues::scopeDefault = Atom::scopeTranslationUnit;
|
||||
const Atom::Definition KeyValues::definitionDefault = Atom::definitionRegular;
|
||||
const Atom::ContentType KeyValues::contentTypeDefault = Atom::typeData;
|
||||
const Atom::DeadStripKind KeyValues::deadStripKindDefault = Atom::deadStripNormal;
|
||||
const Atom::SectionChoice KeyValues::sectionChoiceDefault = Atom::sectionBasedOnContent;
|
||||
const bool KeyValues::internalNameDefault = false;
|
||||
const bool KeyValues::mergeDuplicatesDefault = false;
|
||||
const bool KeyValues::autoHideDefault = false;
|
||||
const bool KeyValues::isThumbDefault = false;
|
||||
const bool KeyValues::isAliasDefault = false;
|
||||
|
||||
|
||||
struct ScopeMapping {
|
||||
const char* string;
|
||||
Atom::Scope value;
|
||||
};
|
||||
|
||||
static const ScopeMapping scopeMappings[] = {
|
||||
{ "global", Atom::scopeGlobal },
|
||||
{ "hidden", Atom::scopeLinkageUnit },
|
||||
{ "static", Atom::scopeTranslationUnit },
|
||||
{ NULL, Atom::scopeGlobal }
|
||||
};
|
||||
|
||||
Atom::Scope KeyValues::scope(const char* s)
|
||||
{
|
||||
for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
|
||||
if ( strcmp(p->string, s) == 0 )
|
||||
return p->value;
|
||||
}
|
||||
llvm::report_fatal_error("bad scope value");
|
||||
}
|
||||
|
||||
const char* KeyValues::scope(Atom::Scope s) {
|
||||
for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
|
||||
if ( p->value == s )
|
||||
return p->string;
|
||||
}
|
||||
llvm::report_fatal_error("bad scope value");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct DefinitionMapping {
|
||||
const char* string;
|
||||
Atom::Definition value;
|
||||
};
|
||||
|
||||
static const DefinitionMapping defMappings[] = {
|
||||
{ "regular", Atom::definitionRegular },
|
||||
{ "weak", Atom::definitionWeak },
|
||||
{ "tentative", Atom::definitionTentative },
|
||||
{ "absolute", Atom::definitionAbsolute },
|
||||
{ "undefined", Atom::definitionUndefined },
|
||||
{ "shared-library", Atom::definitionSharedLibrary },
|
||||
{ NULL, Atom::definitionRegular }
|
||||
};
|
||||
|
||||
Atom::Definition KeyValues::definition(const char* s)
|
||||
{
|
||||
for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
|
||||
if ( strcmp(p->string, s) == 0 )
|
||||
return p->value;
|
||||
}
|
||||
llvm::report_fatal_error("bad definition value");
|
||||
}
|
||||
|
||||
const char* KeyValues::definition(Atom::Definition s) {
|
||||
for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
|
||||
if ( p->value == s )
|
||||
return p->string;
|
||||
}
|
||||
llvm::report_fatal_error("bad definition value");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct ContentTypeMapping {
|
||||
const char* string;
|
||||
Atom::ContentType value;
|
||||
};
|
||||
|
||||
static const ContentTypeMapping typeMappings[] = {
|
||||
{ "unknown", Atom::typeUnknown },
|
||||
{ "code", Atom::typeCode },
|
||||
{ "resolver", Atom::typeResolver },
|
||||
{ "constant", Atom::typeConstant },
|
||||
{ "c-string", Atom::typeCString },
|
||||
{ "utf16-string", Atom::typeUTF16String },
|
||||
{ "CFI", Atom::typeCFI },
|
||||
{ "LSDA", Atom::typeLSDA },
|
||||
{ "literal-4", Atom::typeLiteral4 },
|
||||
{ "literal-8", Atom::typeLiteral8 },
|
||||
{ "literal-16", Atom::typeLiteral16 },
|
||||
{ "data", Atom::typeData },
|
||||
{ "zero-fill", Atom::typeZeroFill },
|
||||
{ "cf-string", Atom::typeCFString },
|
||||
{ "initializer-ptr",Atom::typeInitializerPtr },
|
||||
{ "terminator-ptr", Atom::typeTerminatorPtr },
|
||||
{ "c-string-ptr", Atom::typeCStringPtr },
|
||||
{ "objc1-class", Atom::typeObjC1Class },
|
||||
{ "objc1-class-ptr",Atom::typeObjCClassPtr },
|
||||
{ "objc2-cat-ptr", Atom::typeObjC2CategoryList },
|
||||
{ "tlv-thunk", Atom::typeThunkTLV },
|
||||
{ "tlv-data", Atom::typeTLVInitialData },
|
||||
{ "tlv-zero-fill", Atom::typeTLVInitialZeroFill },
|
||||
{ "tlv-init-ptr", Atom::typeTLVInitializerPtr },
|
||||
{ NULL, Atom::typeUnknown }
|
||||
};
|
||||
|
||||
Atom::ContentType KeyValues::contentType(const char* s)
|
||||
{
|
||||
for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
|
||||
if ( strcmp(p->string, s) == 0 )
|
||||
return p->value;
|
||||
}
|
||||
llvm::report_fatal_error("bad content type value");
|
||||
}
|
||||
|
||||
const char* KeyValues::contentType(Atom::ContentType s) {
|
||||
for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
|
||||
if ( p->value == s )
|
||||
return p->string;
|
||||
}
|
||||
llvm::report_fatal_error("bad content type value");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct DeadStripMapping {
|
||||
const char* string;
|
||||
Atom::DeadStripKind value;
|
||||
};
|
||||
|
||||
static const DeadStripMapping deadStripMappings[] = {
|
||||
{ "normal", Atom::deadStripNormal },
|
||||
{ "never", Atom::deadStripNever },
|
||||
{ "always", Atom::deadStripAlways },
|
||||
{ NULL, Atom::deadStripNormal }
|
||||
};
|
||||
|
||||
Atom::DeadStripKind KeyValues::deadStripKind(const char* s)
|
||||
{
|
||||
for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
|
||||
if ( strcmp(p->string, s) == 0 )
|
||||
return p->value;
|
||||
}
|
||||
llvm::report_fatal_error("bad dead strip value");
|
||||
}
|
||||
|
||||
const char* KeyValues::deadStripKind(Atom::DeadStripKind dsk) {
|
||||
for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
|
||||
if ( p->value == dsk )
|
||||
return p->string;
|
||||
}
|
||||
llvm::report_fatal_error("bad dead strip value");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct SectionChoiceMapping {
|
||||
const char* string;
|
||||
Atom::SectionChoice value;
|
||||
};
|
||||
|
||||
static const SectionChoiceMapping sectMappings[] = {
|
||||
{ "content", Atom::sectionBasedOnContent },
|
||||
{ "custom", Atom::sectionCustomPreferred },
|
||||
{ "custom-required", Atom::sectionCustomRequired },
|
||||
{ NULL, Atom::sectionBasedOnContent }
|
||||
};
|
||||
|
||||
Atom::SectionChoice KeyValues::sectionChoice(const char* s)
|
||||
{
|
||||
for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
|
||||
if ( strcmp(p->string, s) == 0 )
|
||||
return p->value;
|
||||
}
|
||||
llvm::report_fatal_error("bad dead strip value");
|
||||
}
|
||||
|
||||
const char* KeyValues::sectionChoice(Atom::SectionChoice s) {
|
||||
for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
|
||||
if ( p->value == s )
|
||||
return p->string;
|
||||
}
|
||||
llvm::report_fatal_error("bad dead strip value");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool KeyValues::internalName(const char* s)
|
||||
{
|
||||
if ( strcmp(s, "true") == 0 )
|
||||
return true;
|
||||
else if ( strcmp(s, "false") == 0 )
|
||||
return false;
|
||||
llvm::report_fatal_error("bad internal-name value");
|
||||
}
|
||||
|
||||
const char* KeyValues::internalName(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool KeyValues::mergeDuplicates(const char* s)
|
||||
{
|
||||
if ( strcmp(s, "true") == 0 )
|
||||
return true;
|
||||
else if ( strcmp(s, "false") == 0 )
|
||||
return false;
|
||||
llvm::report_fatal_error("bad merge-duplicates value");
|
||||
}
|
||||
|
||||
const char* KeyValues::mergeDuplicates(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool KeyValues::autoHide(const char* s)
|
||||
{
|
||||
if ( strcmp(s, "true") == 0 )
|
||||
return true;
|
||||
else if ( strcmp(s, "false") == 0 )
|
||||
return false;
|
||||
llvm::report_fatal_error("bad auto-hide value");
|
||||
}
|
||||
|
||||
const char* KeyValues::autoHide(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool KeyValues::isThumb(const char* s)
|
||||
{
|
||||
if ( strcmp(s, "true") == 0 )
|
||||
return true;
|
||||
else if ( strcmp(s, "false") == 0 )
|
||||
return false;
|
||||
llvm::report_fatal_error("bad is-thumb value");
|
||||
}
|
||||
|
||||
const char* KeyValues::isThumb(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool KeyValues::isAlias(const char* s)
|
||||
{
|
||||
if ( strcmp(s, "true") == 0 )
|
||||
return true;
|
||||
else if ( strcmp(s, "false") == 0 )
|
||||
return false;
|
||||
llvm::report_fatal_error("bad is-alias value");
|
||||
}
|
||||
|
||||
const char* KeyValues::isAlias(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace yaml
|
||||
} // namespace lld
|
83
lld/lib/Core/YamlKeyValues.h
Normal file
83
lld/lib/Core/YamlKeyValues.h
Normal file
@ -0,0 +1,83 @@
|
||||
//===- Core/YamlKeyValues.h - Reads YAML ----------------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLD_CORE_YAML_KEY_VALUES_H_
|
||||
#define LLD_CORE_YAML_KEY_VALUES_H_
|
||||
|
||||
#include "lld/Core/Atom.h"
|
||||
|
||||
|
||||
namespace lld {
|
||||
namespace yaml {
|
||||
|
||||
class KeyValues {
|
||||
public:
|
||||
static const char* const nameKeyword;
|
||||
static const char* const sectionNameKeyword;
|
||||
static const char* const contentKeyword;
|
||||
static const char* const sizeKeyword;
|
||||
|
||||
|
||||
static const char* const scopeKeyword;
|
||||
static const Atom::Scope scopeDefault;
|
||||
static Atom::Scope scope(const char*);
|
||||
static const char* scope(Atom::Scope);
|
||||
|
||||
static const char* const definitionKeyword;
|
||||
static const Atom::Definition definitionDefault;
|
||||
static Atom::Definition definition(const char*);
|
||||
static const char* definition(Atom::Definition);
|
||||
|
||||
static const char* const contentTypeKeyword;
|
||||
static const Atom::ContentType contentTypeDefault;
|
||||
static Atom::ContentType contentType(const char*);
|
||||
static const char* contentType(Atom::ContentType);
|
||||
|
||||
static const char* const deadStripKindKeyword;
|
||||
static const Atom::DeadStripKind deadStripKindDefault;
|
||||
static Atom::DeadStripKind deadStripKind(const char*);
|
||||
static const char* deadStripKind(Atom::DeadStripKind);
|
||||
|
||||
static const char* const sectionChoiceKeyword;
|
||||
static const Atom::SectionChoice sectionChoiceDefault;
|
||||
static Atom::SectionChoice sectionChoice(const char*);
|
||||
static const char* sectionChoice(Atom::SectionChoice);
|
||||
|
||||
static const char* const internalNameKeyword;
|
||||
static const bool internalNameDefault;
|
||||
static bool internalName(const char*);
|
||||
static const char* internalName(bool);
|
||||
|
||||
static const char* const mergeDuplicatesKeyword;
|
||||
static const bool mergeDuplicatesDefault;
|
||||
static bool mergeDuplicates(const char*);
|
||||
static const char* mergeDuplicates(bool);
|
||||
|
||||
static const char* const autoHideKeyword;
|
||||
static const bool autoHideDefault;
|
||||
static bool autoHide(const char*);
|
||||
static const char* autoHide(bool);
|
||||
|
||||
static const char* const isThumbKeyword;
|
||||
static const bool isThumbDefault;
|
||||
static bool isThumb(const char*);
|
||||
static const char* isThumb(bool);
|
||||
|
||||
static const char* const isAliasKeyword;
|
||||
static const bool isAliasDefault;
|
||||
static bool isAlias(const char*);
|
||||
static const char* isAlias(bool);
|
||||
|
||||
};
|
||||
|
||||
} // namespace yaml
|
||||
} // namespace lld
|
||||
|
||||
#endif // LLD_CORE_YAML_KEY_VALUES_H_
|
||||
|
@ -7,6 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "YamlKeyValues.h"
|
||||
|
||||
#include "lld/Core/YamlReader.h"
|
||||
#include "lld/Core/Atom.h"
|
||||
#include "lld/Core/File.h"
|
||||
@ -21,10 +23,46 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace { const llvm::error_code success; }
|
||||
|
||||
|
||||
namespace lld {
|
||||
namespace yaml {
|
||||
|
||||
enum yaml_reader_errors {
|
||||
success = 0,
|
||||
unknown_keyword,
|
||||
illegal_value
|
||||
};
|
||||
|
||||
class reader_error_category : public llvm::_do_message {
|
||||
public:
|
||||
virtual const char* name() const {
|
||||
return "lld.yaml.reader";
|
||||
}
|
||||
virtual std::string message(int ev) const;
|
||||
};
|
||||
|
||||
const reader_error_category reader_error_category_singleton;
|
||||
|
||||
std::string reader_error_category::message(int ev) const {
|
||||
switch (ev) {
|
||||
case success:
|
||||
return "Success";
|
||||
case unknown_keyword:
|
||||
return "Unknown keyword found in yaml file";
|
||||
case illegal_value:
|
||||
return "Bad value found in yaml file";
|
||||
default:
|
||||
llvm_unreachable("An enumerator of yaml_reader_errors does not have a "
|
||||
"message defined.");
|
||||
}
|
||||
}
|
||||
|
||||
inline llvm::error_code make_error_code(yaml_reader_errors e) {
|
||||
return llvm::error_code(static_cast<int>(e), reader_error_category_singleton);
|
||||
}
|
||||
|
||||
|
||||
class YAML {
|
||||
public:
|
||||
struct Entry {
|
||||
@ -137,6 +175,7 @@ void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) {
|
||||
state = inTriplePeriod;
|
||||
} else if (c == '\n') {
|
||||
// ignore empty lines
|
||||
depth = 0;
|
||||
} else if (c == '\t') {
|
||||
llvm::report_fatal_error("TAB character found in yaml file");
|
||||
} else {
|
||||
@ -176,6 +215,8 @@ void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) {
|
||||
state = inValueSequence;
|
||||
} else if (c == ' ') {
|
||||
// eat space
|
||||
} else if (c == '\t') {
|
||||
llvm::report_fatal_error("TAB character found in yaml file");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -247,16 +288,20 @@ public:
|
||||
, SectionChoice sc
|
||||
, bool intn
|
||||
, bool md
|
||||
, bool ah
|
||||
, DeadStripKind dsk
|
||||
, bool tb
|
||||
, bool al
|
||||
, Alignment a
|
||||
, YAMLFile& f
|
||||
, const char *n)
|
||||
: Atom(ord, d, s, ct, sc, intn, md, dsk, tb, al, a)
|
||||
, const char *n
|
||||
, const char* sn
|
||||
, uint64_t sz)
|
||||
: Atom(ord, d, s, ct, sc, intn, md, ah, dsk, tb, al, a)
|
||||
, _file(f)
|
||||
, _name(n)
|
||||
, _size(0)
|
||||
, _sectionName(sn)
|
||||
, _size(sz)
|
||||
, _refStartIndex(f._lastRefIndex)
|
||||
, _refEndIndex(f._references.size()) {
|
||||
f._lastRefIndex = _refEndIndex;
|
||||
@ -273,6 +318,10 @@ public:
|
||||
virtual llvm::StringRef name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
virtual llvm::StringRef customSectionName() const {
|
||||
return _sectionName;
|
||||
}
|
||||
|
||||
virtual uint64_t objectAddress() const {
|
||||
return 0;
|
||||
@ -286,11 +335,12 @@ public:
|
||||
virtual Reference::iterator referencesBegin() const;
|
||||
virtual Reference::iterator referencesEnd() const;
|
||||
private:
|
||||
YAMLFile& _file;
|
||||
const char *_name;
|
||||
unsigned long _size;
|
||||
unsigned int _refStartIndex;
|
||||
unsigned int _refEndIndex;
|
||||
YAMLFile& _file;
|
||||
const char * _name;
|
||||
const char * _sectionName;
|
||||
unsigned long _size;
|
||||
unsigned int _refStartIndex;
|
||||
unsigned int _refEndIndex;
|
||||
};
|
||||
|
||||
Reference::iterator YAMLAtom::referencesBegin() const {
|
||||
@ -310,11 +360,7 @@ public:
|
||||
YAMLAtomState();
|
||||
|
||||
void setName(const char *n);
|
||||
void setScope(const char *n);
|
||||
void setType(const char *n);
|
||||
void setAlign2(const char *n);
|
||||
void setDefinition(const char *n);
|
||||
void setMergeDuplicates(const char *n);
|
||||
|
||||
void setFixupKind(const char *n);
|
||||
void setFixupOffset(const char *n);
|
||||
@ -323,8 +369,8 @@ public:
|
||||
|
||||
void makeAtom(YAMLFile&);
|
||||
|
||||
private:
|
||||
uint64_t _ordinal;
|
||||
long long _size;
|
||||
const char *_name;
|
||||
Atom::Alignment _align;
|
||||
Atom::ContentType _type;
|
||||
@ -333,23 +379,29 @@ private:
|
||||
Atom::SectionChoice _sectionChoice;
|
||||
bool _internalName;
|
||||
bool _mergeDuplicates;
|
||||
Atom::DeadStripKind _dontDeadStrip;
|
||||
Atom::DeadStripKind _deadStrip;
|
||||
bool _thumb;
|
||||
bool _alias;
|
||||
bool _autoHide;
|
||||
const char *_sectionName;
|
||||
Reference _ref;
|
||||
};
|
||||
|
||||
YAMLAtomState::YAMLAtomState()
|
||||
: _ordinal(0)
|
||||
, _size(0)
|
||||
, _name(NULL)
|
||||
, _align(0, 0)
|
||||
, _type(Atom::typeData)
|
||||
, _scope(Atom::scopeGlobal)
|
||||
, _internalName(false)
|
||||
, _mergeDuplicates(false)
|
||||
, _dontDeadStrip(Atom::deadStripNormal)
|
||||
, _thumb(false)
|
||||
, _alias(false) {
|
||||
, _type(KeyValues::contentTypeDefault)
|
||||
, _scope(KeyValues::scopeDefault)
|
||||
, _def(KeyValues::definitionDefault)
|
||||
, _internalName(KeyValues::internalNameDefault)
|
||||
, _mergeDuplicates(KeyValues::mergeDuplicatesDefault)
|
||||
, _deadStrip(KeyValues::deadStripKindDefault)
|
||||
, _thumb(KeyValues::isThumbDefault)
|
||||
, _alias(KeyValues::isAliasDefault)
|
||||
, _autoHide(KeyValues::autoHideDefault)
|
||||
, _sectionName(NULL) {
|
||||
_ref.target = NULL;
|
||||
_ref.addend = 0;
|
||||
_ref.offsetInAtom = 0;
|
||||
@ -359,8 +411,9 @@ YAMLAtomState::YAMLAtomState()
|
||||
|
||||
void YAMLAtomState::makeAtom(YAMLFile& f) {
|
||||
Atom *a = new YAMLAtom(_ordinal, _def, _scope, _type, _sectionChoice,
|
||||
_internalName, _mergeDuplicates, _dontDeadStrip,
|
||||
_thumb, _alias, _align, f, _name);
|
||||
_internalName, _mergeDuplicates, _autoHide,
|
||||
_deadStrip, _thumb, _alias, _align, f,
|
||||
_name, _sectionName, _size);
|
||||
|
||||
f._atoms.push_back(a);
|
||||
++_ordinal;
|
||||
@ -369,15 +422,17 @@ void YAMLAtomState::makeAtom(YAMLFile& f) {
|
||||
_name = NULL;
|
||||
_align.powerOf2 = 0;
|
||||
_align.modulus = 0;
|
||||
_type = Atom::typeData;
|
||||
_scope = Atom::scopeGlobal;
|
||||
_def = Atom::definitionRegular;
|
||||
_sectionChoice = Atom::sectionBasedOnContent;
|
||||
_internalName = false;
|
||||
_mergeDuplicates = false;
|
||||
_dontDeadStrip = Atom::deadStripNormal;
|
||||
_thumb = false;
|
||||
_alias = false;
|
||||
_type = KeyValues::contentTypeDefault;
|
||||
_scope = KeyValues::scopeDefault;
|
||||
_def = KeyValues::definitionDefault;
|
||||
_sectionChoice = KeyValues::sectionChoiceDefault;
|
||||
_internalName = KeyValues::internalNameDefault;
|
||||
_mergeDuplicates = KeyValues::mergeDuplicatesDefault;
|
||||
_deadStrip = KeyValues::deadStripKindDefault;
|
||||
_thumb = KeyValues::isThumbDefault;
|
||||
_alias = KeyValues::isAliasDefault;
|
||||
_autoHide = KeyValues::autoHideDefault;
|
||||
_sectionName = NULL;
|
||||
_ref.target = NULL;
|
||||
_ref.addend = 0;
|
||||
_ref.offsetInAtom = 0;
|
||||
@ -389,29 +444,6 @@ void YAMLAtomState::setName(const char *n) {
|
||||
_name = n;
|
||||
}
|
||||
|
||||
void YAMLAtomState::setScope(const char *s) {
|
||||
if (strcmp(s, "global") == 0)
|
||||
_scope = Atom::scopeGlobal;
|
||||
else if (strcmp(s, "hidden") == 0)
|
||||
_scope = Atom::scopeLinkageUnit;
|
||||
else if (strcmp(s, "static") == 0)
|
||||
_scope = Atom::scopeTranslationUnit;
|
||||
else
|
||||
llvm::report_fatal_error("bad scope value");
|
||||
}
|
||||
|
||||
void YAMLAtomState::setType(const char *s) {
|
||||
if (strcmp(s, "code") == 0)
|
||||
_type = Atom::typeCode;
|
||||
else if (strcmp(s, "c-string") == 0)
|
||||
_type = Atom::typeCString;
|
||||
else if (strcmp(s, "zero-fill") == 0)
|
||||
_type = Atom::typeZeroFill;
|
||||
else if (strcmp(s, "data") == 0)
|
||||
_type = Atom::typeData;
|
||||
else
|
||||
llvm::report_fatal_error("bad type value");
|
||||
}
|
||||
|
||||
void YAMLAtomState::setAlign2(const char *s) {
|
||||
llvm::StringRef str(s);
|
||||
@ -420,27 +452,6 @@ void YAMLAtomState::setAlign2(const char *s) {
|
||||
_align.powerOf2 = static_cast<uint16_t>(res);
|
||||
}
|
||||
|
||||
void YAMLAtomState::setDefinition(const char *s) {
|
||||
if (strcmp(s, "regular") == 0)
|
||||
_def = Atom::definitionRegular;
|
||||
else if (strcmp(s, "tentative") == 0)
|
||||
_def = Atom::definitionTentative;
|
||||
else if (strcmp(s, "weak") == 0)
|
||||
_def = Atom::definitionWeak;
|
||||
else if (strcmp(s, "absolute") == 0)
|
||||
_def = Atom::definitionAbsolute;
|
||||
else
|
||||
llvm::report_fatal_error("bad definition value");
|
||||
}
|
||||
|
||||
void YAMLAtomState::setMergeDuplicates(const char *s) {
|
||||
if (strcmp(s, "true") == 0)
|
||||
_mergeDuplicates = true;
|
||||
else if (strcmp(s, "false") == 0)
|
||||
_mergeDuplicates = false;
|
||||
else
|
||||
llvm::report_fatal_error("bad merge-duplicates value");
|
||||
}
|
||||
|
||||
void YAMLAtomState::setFixupKind(const char *s) {
|
||||
if (strcmp(s, "pcrel32") == 0)
|
||||
@ -527,28 +538,76 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
|
||||
haveAtom = false;
|
||||
}
|
||||
}
|
||||
if (strcmp(entry->key, "name") == 0) {
|
||||
if (strcmp(entry->key, KeyValues::nameKeyword) == 0) {
|
||||
atomState.setName(entry->value);
|
||||
haveAtom = true;
|
||||
} else if (strcmp(entry->key, "scope") == 0) {
|
||||
atomState.setScope(entry->value);
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::internalNameKeyword) == 0) {
|
||||
atomState._internalName = KeyValues::internalName(entry->value);
|
||||
haveAtom = true;
|
||||
} else if (strcmp(entry->key, "type") == 0) {
|
||||
atomState.setType(entry->value);
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
|
||||
atomState._def = KeyValues::definition(entry->value);
|
||||
haveAtom = true;
|
||||
} else if (strcmp(entry->key, "align2") == 0) {
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::scopeKeyword) == 0) {
|
||||
atomState._scope = KeyValues::scope(entry->value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::contentTypeKeyword) == 0) {
|
||||
atomState._type = KeyValues::contentType(entry->value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::deadStripKindKeyword) == 0) {
|
||||
atomState._deadStrip = KeyValues::deadStripKind(entry->value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::sectionChoiceKeyword) == 0) {
|
||||
atomState._sectionChoice = KeyValues::sectionChoice(entry->value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::mergeDuplicatesKeyword) == 0) {
|
||||
atomState._mergeDuplicates = KeyValues::mergeDuplicates(entry->value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::autoHideKeyword) == 0) {
|
||||
atomState._autoHide = KeyValues::autoHide(entry->value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::isThumbKeyword) == 0) {
|
||||
atomState._thumb = KeyValues::isThumb(entry->value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::isAliasKeyword) == 0) {
|
||||
atomState._alias = KeyValues::isAlias(entry->value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
|
||||
atomState._sectionName = entry->value;
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::sizeKeyword) == 0) {
|
||||
llvm::StringRef val = entry->value;
|
||||
if ( val.getAsInteger(0, atomState._size) )
|
||||
return make_error_code(illegal_value);
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, KeyValues::contentKeyword) == 0) {
|
||||
// TO DO: switch to content mode
|
||||
haveAtom = true;
|
||||
}
|
||||
else if (strcmp(entry->key, "align2") == 0) {
|
||||
atomState.setAlign2(entry->value);
|
||||
haveAtom = true;
|
||||
} else if (strcmp(entry->key, "definition") == 0) {
|
||||
atomState.setDefinition(entry->value);
|
||||
haveAtom = true;
|
||||
} else if (strcmp(entry->key, "merge-duplicates") == 0) {
|
||||
atomState.setMergeDuplicates(entry->value);
|
||||
haveAtom = true;
|
||||
} else if (strcmp(entry->key, "fixups") == 0) {
|
||||
}
|
||||
else if (strcmp(entry->key, "fixups") == 0) {
|
||||
inFixups = true;
|
||||
}
|
||||
} else if (depthForFixups == entry->depth) {
|
||||
else {
|
||||
return make_error_code(unknown_keyword);
|
||||
}
|
||||
}
|
||||
else if (depthForFixups == entry->depth) {
|
||||
if (entry->beginSequence) {
|
||||
if (haveFixup) {
|
||||
atomState.addFixup(file);
|
||||
@ -574,7 +633,7 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
|
||||
}
|
||||
|
||||
result.push_back(file);
|
||||
return success;
|
||||
return make_error_code(success);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -7,6 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "YamlKeyValues.h"
|
||||
|
||||
#include "lld/Core/YamlWriter.h"
|
||||
#include "lld/Core/Atom.h"
|
||||
#include "lld/Core/File.h"
|
||||
@ -24,26 +26,121 @@ namespace yaml {
|
||||
|
||||
class Handler : public File::AtomHandler {
|
||||
public:
|
||||
Handler(llvm::raw_ostream &out) : _out(out) { }
|
||||
Handler(llvm::raw_ostream &out) : _out(out), _firstAtom(true) { }
|
||||
|
||||
virtual void doFile(const class File &) { }
|
||||
virtual void doFile(const class File &) { _firstAtom = true; }
|
||||
|
||||
virtual void doAtom(const class Atom &atom) {
|
||||
_out << " - name: " << atom.name() << "\n";
|
||||
// add blank line between atoms for readability
|
||||
if ( !_firstAtom )
|
||||
_out << "\n";
|
||||
_firstAtom = false;
|
||||
|
||||
_out << " - "
|
||||
<< KeyValues::nameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::nameKeyword)
|
||||
<< atom.name()
|
||||
<< "\n";
|
||||
|
||||
if ( atom.internalName() )
|
||||
_out << " internal-name: true\n";
|
||||
|
||||
if ( atom.definition() != Atom::definitionRegular )
|
||||
_out << " definition: " << definitionString(atom.definition()) <<"\n";
|
||||
|
||||
if ( atom.scope() != Atom::scopeTranslationUnit )
|
||||
_out << " scope: " << scopeString(atom.scope()) << "\n";
|
||||
|
||||
_out << " type: " << typeString(atom.contentType()) << "\n";
|
||||
if ( atom.internalName() != KeyValues::internalNameDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::internalNameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::internalNameKeyword)
|
||||
<< KeyValues::internalName(atom.internalName())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.mergeDuplicates() )
|
||||
_out << " merge-duplicates: true\n";
|
||||
|
||||
if ( atom.definition() != KeyValues::definitionDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::definitionKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::definitionKeyword)
|
||||
<< KeyValues::definition(atom.definition())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.scope() != KeyValues::scopeDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::scopeKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::scopeKeyword)
|
||||
<< KeyValues::scope(atom.scope())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.contentType() != KeyValues::contentTypeDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::contentTypeKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::contentTypeKeyword)
|
||||
<< KeyValues::contentType(atom.contentType())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::deadStripKindKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::deadStripKindKeyword)
|
||||
<< KeyValues::deadStripKind(atom.deadStrip())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::sectionChoiceKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::sectionChoiceKeyword)
|
||||
<< KeyValues::sectionChoice(atom.sectionChoice())
|
||||
<< "\n";
|
||||
assert( ! atom.customSectionName().empty() );
|
||||
_out << " "
|
||||
<< KeyValues::sectionNameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::sectionNameKeyword)
|
||||
<< atom.customSectionName()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.mergeDuplicates() != KeyValues::mergeDuplicatesDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::mergeDuplicatesKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::mergeDuplicatesKeyword)
|
||||
<< KeyValues::mergeDuplicates(atom.mergeDuplicates())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.autoHide() != KeyValues::autoHideDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::autoHideKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::autoHideKeyword)
|
||||
<< KeyValues::autoHide(atom.autoHide())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.isThumb() != KeyValues::isThumbDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::isThumbKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::isThumbKeyword)
|
||||
<< KeyValues::isThumb(atom.isThumb())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.isAlias() != KeyValues::isAliasDefault ) {
|
||||
_out << " "
|
||||
<< KeyValues::isAliasKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::isAliasKeyword)
|
||||
<< KeyValues::isAlias(atom.isAlias())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
|
||||
if (atom.referencesBegin() != atom.referencesEnd()) {
|
||||
_out << " fixups:\n";
|
||||
for (Reference::iterator it = atom.referencesBegin(),
|
||||
@ -56,49 +153,17 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
const char *scopeString(Atom::Scope scope) {
|
||||
switch (scope) {
|
||||
case Atom::scopeTranslationUnit:
|
||||
return "static";
|
||||
case Atom::scopeLinkageUnit:
|
||||
return "hidden";
|
||||
case Atom::scopeGlobal:
|
||||
return "global";
|
||||
}
|
||||
return "???";
|
||||
// return a string of the correct number of spaces to align value
|
||||
const char* spacePadding(const char* key) {
|
||||
const char* spaces = " ";
|
||||
assert(strlen(spaces) > strlen(key));
|
||||
return &spaces[strlen(key)];
|
||||
}
|
||||
|
||||
const char *typeString(Atom::ContentType type) {
|
||||
switch (type) {
|
||||
case Atom::typeCode:
|
||||
return "code";
|
||||
case Atom::typeCString:
|
||||
return "c-string";
|
||||
case Atom::typeZeroFill:
|
||||
return "zero-fill";
|
||||
case Atom::typeData:
|
||||
return "data";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
const char *definitionString(Atom::Definition def) {
|
||||
switch (def) {
|
||||
case Atom::definitionRegular:
|
||||
return "regular";
|
||||
case Atom::definitionWeak:
|
||||
return "weak";
|
||||
case Atom::definitionTentative:
|
||||
return "tentative";
|
||||
case Atom::definitionAbsolute:
|
||||
return "absolute";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
llvm::raw_ostream &_out;
|
||||
llvm::raw_ostream& _out;
|
||||
bool _firstAtom;
|
||||
};
|
||||
|
||||
void writeObjectText(File &file, llvm::raw_ostream &out) {
|
||||
|
76
lld/test/auto-hide-coalesce.objtxt
Normal file
76
lld/test/auto-hide-coalesce.objtxt
Normal file
@ -0,0 +1,76 @@
|
||||
# RUN: lld-core %s | FileCheck %s
|
||||
|
||||
#
|
||||
# Tests auto-hide bit during coalescing
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: _inlineFunc1
|
||||
scope: global
|
||||
definition: regular
|
||||
type: code
|
||||
merge-duplicates: true
|
||||
auto-hide: true
|
||||
|
||||
- name: _inlineFunc2
|
||||
scope: global
|
||||
definition: regular
|
||||
type: code
|
||||
merge-duplicates: true
|
||||
auto-hide: true
|
||||
|
||||
- name: _inlineFunc3
|
||||
scope: global
|
||||
definition: regular
|
||||
type: code
|
||||
merge-duplicates: true
|
||||
auto-hide: false
|
||||
|
||||
- name: _inlineFunc4
|
||||
scope: global
|
||||
definition: regular
|
||||
type: code
|
||||
merge-duplicates: true
|
||||
auto-hide: false
|
||||
---
|
||||
atoms:
|
||||
- name: _inlineFunc1
|
||||
scope: global
|
||||
definition: regular
|
||||
type: code
|
||||
merge-duplicates: true
|
||||
auto-hide: true
|
||||
|
||||
- name: _inlineFunc2
|
||||
scope: global
|
||||
definition: regular
|
||||
type: code
|
||||
merge-duplicates: true
|
||||
auto-hide: false
|
||||
|
||||
- name: _inlineFunc3
|
||||
scope: global
|
||||
definition: regular
|
||||
type: code
|
||||
merge-duplicates: true
|
||||
auto-hide: true
|
||||
|
||||
- name: _inlineFunc4
|
||||
scope: global
|
||||
definition: regular
|
||||
type: code
|
||||
merge-duplicates: true
|
||||
auto-hide: false
|
||||
...
|
||||
|
||||
|
||||
# CHECK: name: _inlineFunc1
|
||||
# CHECK: auto-hide: true
|
||||
# CHECK: name: _inlineFunc3
|
||||
# CHECK-NOT: auto-hide: true
|
||||
# CHECK: name: _inlineFunc4
|
||||
# CHECK-NOT: auto-hide: true
|
||||
# CHECK: name: _inlineFunc2
|
||||
# CHECK-NOT: auto-hide: true
|
||||
# CHECK: ...
|
34
lld/test/custom-section.objtxt
Normal file
34
lld/test/custom-section.objtxt
Normal file
@ -0,0 +1,34 @@
|
||||
# RUN: lld-core %s | FileCheck %s
|
||||
|
||||
#
|
||||
# Test that custom sections are preserved
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: _foo1
|
||||
scope: global
|
||||
section-choice: content
|
||||
|
||||
- name: _foo2
|
||||
scope: global
|
||||
section-choice: custom
|
||||
section-name: __foozle
|
||||
|
||||
- name: _foo3
|
||||
scope: global
|
||||
section-choice: custom-required
|
||||
section-name: __boozle
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: name: _foo1
|
||||
# CHECK-NOT: section-name:
|
||||
# CHECK: name: _foo2
|
||||
# CHECK: section-choice: custom
|
||||
# CHECK: section-name: __foozle
|
||||
# CHECK: name: _foo3
|
||||
# CHECK: section-choice: custom-required
|
||||
# CHECK: section-name: __boozle
|
||||
# CHECK: ...
|
29
lld/test/dead-strip-attributes.objtxt
Normal file
29
lld/test/dead-strip-attributes.objtxt
Normal file
@ -0,0 +1,29 @@
|
||||
# RUN: lld-core %s | FileCheck %s
|
||||
|
||||
#
|
||||
# Test that dead strip attributes are preserved
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: _foo1
|
||||
dead-strip: normal
|
||||
---
|
||||
atoms:
|
||||
- name: _foo2
|
||||
dead-strip: never
|
||||
---
|
||||
atoms:
|
||||
- name: _foo3
|
||||
dead-strip: always
|
||||
...
|
||||
|
||||
|
||||
# CHECK: name: _foo1
|
||||
# CHECK-NOT: dead-strip: never
|
||||
# CHECK-NOT: dead-strip: always
|
||||
# CHECK: name: _foo2
|
||||
# CHECK: dead-strip: never
|
||||
# CHECK: name: _foo3
|
||||
# CHECK: dead-strip: always
|
||||
# CHECK: ...
|
27
lld/test/internal-name-attributes.objtxt
Normal file
27
lld/test/internal-name-attributes.objtxt
Normal file
@ -0,0 +1,27 @@
|
||||
# RUN: lld-core %s | FileCheck %s
|
||||
|
||||
#
|
||||
# Test that internal-name attributes are preserved
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: foo
|
||||
internal-name: false
|
||||
- name: L0
|
||||
internal-name: true
|
||||
- name: L1
|
||||
internal-name: true
|
||||
- name: bar
|
||||
...
|
||||
|
||||
|
||||
# CHECK: name: foo
|
||||
# CHECK-NOT: internal-name: false
|
||||
# CHECK: name: L0
|
||||
# CHECK: internal-name: true
|
||||
# CHECK: name: L1
|
||||
# CHECK: internal-name: true
|
||||
# CHECK: name: bar
|
||||
# CHECK-NOT: internal-name: false
|
||||
# CHECK: ...
|
@ -8,11 +8,13 @@
|
||||
atoms:
|
||||
- name: _foo
|
||||
definition: regular
|
||||
scope: global
|
||||
type: data
|
||||
---
|
||||
atoms:
|
||||
- name: _foo
|
||||
definition: regular
|
||||
scope: global
|
||||
type: data
|
||||
...
|
||||
|
||||
|
@ -9,12 +9,14 @@
|
||||
atoms:
|
||||
- name: _foo
|
||||
definition: tentative
|
||||
scope: global
|
||||
type: zero-fill
|
||||
size: 4
|
||||
---
|
||||
atoms:
|
||||
- name: _foo
|
||||
definition: regular
|
||||
scope: global
|
||||
type: data
|
||||
content: [ 00, 00, 00, 00 ]
|
||||
...
|
||||
|
@ -8,16 +8,19 @@
|
||||
atoms:
|
||||
- name: _foo
|
||||
definition: weak
|
||||
scope: global
|
||||
type: data
|
||||
---
|
||||
atoms:
|
||||
- name: _foo
|
||||
definition: regular
|
||||
scope: global
|
||||
type: data
|
||||
---
|
||||
atoms:
|
||||
- name: _foo
|
||||
definition: weak
|
||||
scope: global
|
||||
type: data
|
||||
...
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user