summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ObjectYAML
diff options
context:
space:
mode:
authorgeorgerim <georgerim@gmail.com>2019-10-25 13:03:19 +0300
committergeorgerim <georgerim@gmail.com>2019-10-25 13:25:56 +0300
commitde3cef1d5d33212059164d6095aca5c5b0284001 (patch)
treeba617e1ffe517fbf1622d98b21ef6e5a25a3d659 /llvm/lib/ObjectYAML
parent8aa84ad37db7ddbff5c1a2e4ef8ff2a616f1da57 (diff)
downloadbcm5719-llvm-de3cef1d5d33212059164d6095aca5c5b0284001.tar.gz
bcm5719-llvm-de3cef1d5d33212059164d6095aca5c5b0284001.zip
[yaml2obj, obj2yaml] - Add support for SHT_NOTE sections.
SHT_NOTE is the section that consists of namesz, descsz, type, name + padding, desc + padding data. This patch teaches yaml2obj, obj2yaml to dump and parse them. This patch implements the section how it is described here: https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html Which says: "For 64–bit objects and 32–bit objects, each entry is an array of 4-byte words in the format of the target processor" The official specification is different http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section And says: "n 64-bit objects (files with e_ident[EI_CLASS] equal to ELFCLASS64), each entry is an array of 8-byte words in the format of the target processor. In 32-bit objects (files with e_ident[EI_CLASS] equal to ELFCLASS32), each entry is an array of 4-byte words in the format of the target processor" Since LLVM uses the first, 32-bit way, this patch follows it. Differential revision: https://reviews.llvm.org/D68983
Diffstat (limited to 'llvm/lib/ObjectYAML')
-rw-r--r--llvm/lib/ObjectYAML/ELFEmitter.cpp72
-rw-r--r--llvm/lib/ObjectYAML/ELFYAML.cpp38
2 files changed, 102 insertions, 8 deletions
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 8ba1608254b..dae3f395993 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -36,6 +36,16 @@ class ContiguousBlobAccumulator {
SmallVector<char, 128> Buf;
raw_svector_ostream OS;
+public:
+ ContiguousBlobAccumulator(uint64_t InitialOffset_)
+ : InitialOffset(InitialOffset_), Buf(), OS(Buf) {}
+
+ template <class Integer>
+ raw_ostream &getOSAndAlignedOffset(Integer &Offset, unsigned Align) {
+ Offset = padToAlignment(Align);
+ return OS;
+ }
+
/// \returns The new offset.
uint64_t padToAlignment(unsigned Align) {
if (Align == 0)
@@ -46,14 +56,6 @@ class ContiguousBlobAccumulator {
return AlignedOffset; // == CurrentOffset;
}
-public:
- ContiguousBlobAccumulator(uint64_t InitialOffset_)
- : InitialOffset(InitialOffset_), Buf(), OS(Buf) {}
- template <class Integer>
- raw_ostream &getOSAndAlignedOffset(Integer &Offset, unsigned Align) {
- Offset = padToAlignment(Align);
- return OS;
- }
void writeBlobToStream(raw_ostream &Out) { Out << OS.str(); }
};
@@ -177,6 +179,9 @@ template <class ELFT> class ELFState {
void writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::AddrsigSection &Section,
ContiguousBlobAccumulator &CBA);
+ void writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::NoteSection &Section,
+ ContiguousBlobAccumulator &CBA);
ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH);
@@ -440,6 +445,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
writeSectionContent(SHeader, *S, CBA);
} else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) {
writeSectionContent(SHeader, *S, CBA);
+ } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) {
+ writeSectionContent(SHeader, *S, CBA);
} else {
llvm_unreachable("Unknown section type");
}
@@ -1035,6 +1042,55 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
}
}
+template <class ELFT>
+void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::NoteSection &Section,
+ ContiguousBlobAccumulator &CBA) {
+ raw_ostream &OS =
+ CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+ uint64_t Offset = OS.tell();
+
+ if (Section.Content || Section.Size) {
+ SHeader.sh_size = writeContent(OS, Section.Content, Section.Size);
+ return;
+ }
+
+ for (const ELFYAML::NoteEntry &NE : *Section.Notes) {
+ // Write name size.
+ if (NE.Name.empty())
+ support::endian::write<uint32_t>(OS, 0, ELFT::TargetEndianness);
+ else
+ support::endian::write<uint32_t>(OS, NE.Name.size() + 1,
+ ELFT::TargetEndianness);
+
+ // Write description size.
+ if (NE.Desc.binary_size() == 0)
+ support::endian::write<uint32_t>(OS, 0, ELFT::TargetEndianness);
+ else
+ support::endian::write<uint32_t>(OS, NE.Desc.binary_size(),
+ ELFT::TargetEndianness);
+
+ // Write type.
+ support::endian::write<uint32_t>(OS, NE.Type, ELFT::TargetEndianness);
+
+ // Write name, null terminator and padding.
+ if (!NE.Name.empty()) {
+ support::endian::write<uint8_t>(OS, arrayRefFromStringRef(NE.Name),
+ ELFT::TargetEndianness);
+ support::endian::write<uint8_t>(OS, 0, ELFT::TargetEndianness);
+ CBA.padToAlignment(4);
+ }
+
+ // Write description and padding.
+ if (NE.Desc.binary_size() != 0) {
+ NE.Desc.writeAsBinary(OS);
+ CBA.padToAlignment(4);
+ }
+ }
+
+ SHeader.sh_size = OS.tell() - Offset;
+}
+
template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
for (unsigned I = 0, E = Doc.Sections.size(); I != E; ++I) {
StringRef Name = Doc.Sections[I]->Name;
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 29585abe6e8..ad316be85e8 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1032,6 +1032,13 @@ static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
IO.mapOptional("Size", Section.Size);
}
+static void sectionMapping(IO &IO, ELFYAML::NoteSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Content", Section.Content);
+ IO.mapOptional("Size", Section.Size);
+ IO.mapOptional("Notes", Section.Notes);
+}
+
static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
commonSectionMapping(IO, Section);
IO.mapOptional("Size", Section.Size, Hex64(0));
@@ -1143,6 +1150,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
Section.reset(new ELFYAML::HashSection());
sectionMapping(IO, *cast<ELFYAML::HashSection>(Section.get()));
break;
+ case ELF::SHT_NOTE:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::NoteSection());
+ sectionMapping(IO, *cast<ELFYAML::NoteSection>(Section.get()));
+ break;
case ELF::SHT_MIPS_ABIFLAGS:
if (!IO.outputting())
Section.reset(new ELFYAML::MipsABIFlags());
@@ -1270,6 +1282,24 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
return {};
}
+ if (const auto *NS = dyn_cast<ELFYAML::NoteSection>(Section.get())) {
+ if (!NS->Content && !NS->Size && !NS->Notes)
+ return "one of \"Content\", \"Size\" or \"Notes\" must be "
+ "specified";
+
+ if (!NS->Content && !NS->Size)
+ return {};
+
+ if (NS->Size && NS->Content &&
+ (uint64_t)*NS->Size < NS->Content->binary_size())
+ return "\"Size\" must be greater than or equal to the content "
+ "size";
+
+ if (NS->Notes)
+ return "\"Notes\" cannot be used with \"Content\" or \"Size\"";
+ return {};
+ }
+
return {};
}
@@ -1313,6 +1343,14 @@ void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
IO.mapRequired("Value", Rel.Val);
}
+void MappingTraits<ELFYAML::NoteEntry>::mapping(IO &IO, ELFYAML::NoteEntry &N) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapOptional("Name", N.Name);
+ IO.mapOptional("Desc", N.Desc);
+ IO.mapRequired("Type", N.Type);
+}
+
void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
ELFYAML::VerdefEntry &E) {
assert(IO.getContext() && "The IO context is not initialized");
OpenPOWER on IntegriCloud