void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
IO.mapOptional("Name", Symbol.Name, StringRef());
+ IO.mapOptional("NameIndex", Symbol.NameIndex);
IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
IO.mapOptional("Section", Symbol.Section, StringRef());
IO.mapOptional("Index", Symbol.Index);
StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
ELFYAML::Symbol &Symbol) {
- if (Symbol.Index && Symbol.Section.data()) {
+ if (Symbol.Index && Symbol.Section.data())
return "Index and Section cannot both be specified for Symbol";
- }
- if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX)) {
+ if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX))
return "Large indexes are not supported";
- }
+ if (Symbol.NameIndex && !Symbol.Name.empty())
+ return "Name and NameIndex cannot both be specified for Symbol";
return StringRef();
}
} // end anonymous namespace
// Used to keep track of section and symbol names, so that in the YAML file
-// sections and symbols can be referenced by name instead of by index.\r
-namespace {\r
-class NameToIdxMap {\r
+// sections and symbols can be referenced by name instead of by index.
+namespace {
+class NameToIdxMap {
StringMap<unsigned> Map;\r
\r
-public:\r
+public:
/// \Returns false if name is already present in the map.\r
bool addName(StringRef Name, unsigned Ndx) {\r
return Map.insert({Name, Ndx}).second;\r
- }\r
+ }
/// \Returns false if name is not present in the map.\r
- bool lookup(StringRef Name, unsigned &Idx) const {\r
+ bool lookup(StringRef Name, unsigned &Idx) const {
auto I = Map.find(Name);\r
- if (I == Map.end())\r
+ if (I == Map.end())
return false;\r
- Idx = I->getValue();\r
+ Idx = I->getValue();
return true;\r
- }\r
+ }
/// Asserts if name is not present in the map.\r
- unsigned get(StringRef Name) const {\r
+ unsigned get(StringRef Name) const {
unsigned Idx;\r
if (lookup(Name, Idx))\r
return Idx;\r
assert(false && "Expected section not found in index");\r
return 0;\r
- }\r
- unsigned size() const { return Map.size(); }\r
-};\r
+ }
+ unsigned size() const { return Map.size(); }
+};
} // end anonymous namespace
template <class T>
PHeaders.push_back(Phdr);
}
}
-\r
-static bool convertSectionIndex(NameToIdxMap &SN2I, StringRef SecName,\r
- StringRef IndexSrc, unsigned &IndexDest) {\r
+
+static bool convertSectionIndex(NameToIdxMap &SN2I, StringRef SecName,
+ StringRef IndexSrc, unsigned &IndexDest) {
if (!SN2I.lookup(IndexSrc, IndexDest) && !to_integer(IndexSrc, IndexDest)) {\r
- WithColor::error() << "Unknown section referenced: '" << IndexSrc\r
- << "' at YAML section '" << SecName << "'.\n";\r
- return false;\r
+ WithColor::error() << "Unknown section referenced: '" << IndexSrc
+ << "' at YAML section '" << SecName << "'.\n";
+ return false;
}
return true;
}
for (const auto &Sym : Symbols) {
Elf_Sym Symbol;
zero(Symbol);
- if (!Sym.Name.empty())
+
+ // If NameIndex, which contains the name offset, is explicitly specified, we
+ // use it. This is useful for preparing broken objects. Otherwise, we add
+ // the specified Name to the string table builder to get its offset.
+ if (Sym.NameIndex)
+ Symbol.st_name = *Sym.NameIndex;
+ else if (!Sym.Name.empty())
Symbol.st_name = Strtab.getOffset(Sym.Name);
- Symbol.setBindingAndType(Sym.Binding, Sym.Type);\r
- if (!Sym.Section.empty()) {\r
- unsigned Index;\r
+
+ Symbol.setBindingAndType(Sym.Binding, Sym.Type);
+ if (!Sym.Section.empty()) {
+ unsigned Index;
if (!SN2I.lookup(Sym.Section, Index)) {\r
- WithColor::error() << "Unknown section referenced: '" << Sym.Section\r
- << "' by YAML symbol " << Sym.Name << ".\n";\r
- exit(1);\r
+ WithColor::error() << "Unknown section referenced: '" << Sym.Section
+ << "' by YAML symbol " << Sym.Name << ".\n";
+ exit(1);
}
Symbol.st_shndx = Index;
} else if (Sym.Index) {
auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
for (const auto &Rel : Section.Relocations) {
- unsigned SymIdx = 0;\r
- // If a relocation references a symbol, try to look one up in the symbol\r
- // table. If it is not there, treat the value as a symbol index.\r
+ unsigned SymIdx = 0;
+ // If a relocation references a symbol, try to look one up in the symbol
+ // table. If it is not there, treat the value as a symbol index.
if (Rel.Symbol && !SymN2I.lookup(*Rel.Symbol, SymIdx) &&\r
- !to_integer(*Rel.Symbol, SymIdx)) {\r
- WithColor::error() << "Unknown symbol referenced: '" << *Rel.Symbol\r
- << "' at YAML section '" << Section.Name << "'.\n";\r
+ !to_integer(*Rel.Symbol, SymIdx)) {
+ WithColor::error() << "Unknown symbol referenced: '" << *Rel.Symbol
+ << "' at YAML section '" << Section.Name << "'.\n";
return false;
}
"Section type is not SHT_GROUP");
SHeader.sh_entsize = 4;
- SHeader.sh_size = SHeader.sh_entsize * Section.Members.size();\r
-\r
+ SHeader.sh_size = SHeader.sh_entsize * Section.Members.size();
+
unsigned SymIdx;\r
if (!SymN2I.lookup(Section.Signature, SymIdx) &&\r
!to_integer(Section.Signature, SymIdx)) {\r
template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
- StringRef Name = Doc.Sections[i]->Name;\r
- DotShStrtab.add(Name);\r
- // "+ 1" to take into account the SHT_NULL entry.\r
+ StringRef Name = Doc.Sections[i]->Name;
+ DotShStrtab.add(Name);
+ // "+ 1" to take into account the SHT_NULL entry.
if (!SN2I.addName(Name, i + 1)) {\r
- WithColor::error() << "Repeated section name: '" << Name\r
- << "' at YAML section number " << i << ".\n";\r
- return false;\r
+ WithColor::error() << "Repeated section name: '" << Name
+ << "' at YAML section number " << i << ".\n";
+ return false;
}
}
"' after global in Symbols list.\n";
return false;
}
- if (Sym.Binding.value != ELF::STB_LOCAL)\r
- GlobalSymbolSeen = true;\r
-\r
+ if (Sym.Binding.value != ELF::STB_LOCAL)
+ GlobalSymbolSeen = true;
+
if (!Name.empty() && !SymN2I.addName(Name, I)) {\r
- WithColor::error() << "Repeated symbol name: '" << Name << "'.\n";\r
- return false;\r
- }\r
+ WithColor::error() << "Repeated symbol name: '" << Name << "'.\n";
+ return false;
+ }
}
return true;
}