summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Silva <silvas@purdue.edu>2013-06-15 00:25:26 +0000
committerSean Silva <silvas@purdue.edu>2013-06-15 00:25:26 +0000
commita6423eb8beee1d87aeb47d0db820b210ed2b1c79 (patch)
tree193f741d2b2cdcfe5b69156d1f1e95c24264b735
parent371573448c5fb5d102c5783c6f0ab15a40aa0929 (diff)
downloadbcm5719-llvm-a6423eb8beee1d87aeb47d0db820b210ed2b1c79.tar.gz
bcm5719-llvm-a6423eb8beee1d87aeb47d0db820b210ed2b1c79.zip
[yaml2obj] Add support for sh_link via `Link` key.
llvm-svn: 184022
-rw-r--r--llvm/include/llvm/Object/ELFYAML.h1
-rw-r--r--llvm/lib/Object/ELFYAML.cpp1
-rw-r--r--llvm/test/Object/yaml2obj-elf-section-basic.yaml3
-rw-r--r--llvm/tools/yaml2obj/yaml2elf.cpp45
4 files changed, 49 insertions, 1 deletions
diff --git a/llvm/include/llvm/Object/ELFYAML.h b/llvm/include/llvm/Object/ELFYAML.h
index 124af7a936f..04ba0a66225 100644
--- a/llvm/include/llvm/Object/ELFYAML.h
+++ b/llvm/include/llvm/Object/ELFYAML.h
@@ -55,6 +55,7 @@ struct Section {
ELF_SHF Flags;
llvm::yaml::Hex64 Address;
object::yaml::BinaryRef Content;
+ StringRef Link;
llvm::yaml::Hex64 AddressAlign;
};
struct Object {
diff --git a/llvm/lib/Object/ELFYAML.cpp b/llvm/lib/Object/ELFYAML.cpp
index 6e99767f87f..e0e95bee934 100644
--- a/llvm/lib/Object/ELFYAML.cpp
+++ b/llvm/lib/Object/ELFYAML.cpp
@@ -267,6 +267,7 @@ void MappingTraits<ELFYAML::Section>::mapping(IO &IO,
IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0));
IO.mapOptional("Address", Section.Address, Hex64(0));
IO.mapOptional("Content", Section.Content);
+ IO.mapOptional("Link", Section.Link);
IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
}
diff --git a/llvm/test/Object/yaml2obj-elf-section-basic.yaml b/llvm/test/Object/yaml2obj-elf-section-basic.yaml
index e3749868053..34be11d3658 100644
--- a/llvm/test/Object/yaml2obj-elf-section-basic.yaml
+++ b/llvm/test/Object/yaml2obj-elf-section-basic.yaml
@@ -10,6 +10,7 @@ Sections:
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0xCAFEBABE
+ Link: .text # Doesn't make sense for SHT_PROGBITS, but good enough for test.
Content: EBFE
AddressAlign: 2
@@ -26,6 +27,8 @@ Sections:
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0xCAFEBABE
# CHECK: Size: 2
+# Check that Link != 0.
+# CHECK: Link: {{[1-9][0-9]*}}
# CHECK: AddressAlignment: 2
# CHECK: SectionData (
# CHECK-NEXT: 0000: EBFE
diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp
index e5988be3293..e6a157cfd88 100644
--- a/llvm/tools/yaml2obj/yaml2elf.cpp
+++ b/llvm/tools/yaml2obj/yaml2elf.cpp
@@ -76,6 +76,29 @@ public:
void writeBlobToStream(raw_ostream &Out) { Out << OS.str(); }
};
+// Used to keep track of section names, so that in the YAML file sections
+// can be referenced by name instead of by index.
+class SectionNameToIdxMap {
+ StringMap<int> Map;
+public:
+ /// \returns true if name is already present in the map.
+ bool addName(StringRef SecName, unsigned i) {
+ StringMapEntry<int> &Entry = Map.GetOrCreateValue(SecName, -1);
+ if (Entry.getValue() != -1)
+ return true;
+ Entry.setValue((int)i);
+ return false;
+ }
+ /// \returns true if name is not present in the map
+ bool lookupSection(StringRef SecName, unsigned &Idx) const {
+ StringMap<int>::const_iterator I = Map.find(SecName);
+ if (I == Map.end())
+ return true;
+ Idx = I->getValue();
+ return false;
+ }
+};
+
template <class T>
static size_t vectorDataSize(const std::vector<T> &Vec) {
return Vec.size() * sizeof(T);
@@ -138,6 +161,18 @@ static void writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
// Place section header string table last.
Header.e_shstrndx = Sections.size();
+ SectionNameToIdxMap SN2I;
+ for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
+ StringRef Name = Sections[i].Name;
+ if (Name.empty())
+ continue;
+ if (SN2I.addName(Name, i)) {
+ errs() << "error: Repeated section name: '" << Name
+ << "' at YAML section number " << i << ".\n";
+ return;
+ }
+ }
+
StringTableBuilder StrTab;
SmallVector<char, 128> Buf;
// XXX: This offset is tightly coupled with the order that we write
@@ -159,7 +194,15 @@ static void writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
SHeader.sh_size = Sec.Content.binary_size();
Sec.Content.writeAsBinary(CBA.getOS());
- SHeader.sh_link = 0;
+ if (!Sec.Link.empty()) {
+ unsigned Index;
+ if (SN2I.lookupSection(Sec.Link, Index)) {
+ errs() << "error: Unknown section referenced: '" << Sec.Link
+ << "' at YAML section number " << i << ".\n";
+ return;
+ }
+ SHeader.sh_link = Index;
+ }
SHeader.sh_info = 0;
SHeader.sh_addralign = Sec.AddressAlign;
SHeader.sh_entsize = 0;
OpenPOWER on IntegriCloud