[ELF2] SECTIONS command basic support

* determine output section by input section name
* discard input sections
* order output sections accordingly

Differential Revision: http://reviews.llvm.org/D14140

llvm-svn: 252868
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 1607247..03c5fc4 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -36,6 +36,7 @@
   static std::vector<StringRef> tokenize(StringRef S);
   static StringRef skipSpace(StringRef S);
   StringRef next();
+  bool skip(StringRef Tok);
   bool atEOF() { return Tokens.size() == Pos; }
   void expect(StringRef Expect);
 
@@ -50,6 +51,9 @@
   void readOutputArch();
   void readOutputFormat();
   void readSearchDir();
+  void readSections();
+
+  void readOutputSectionDescription();
 
   StringSaver Saver;
   std::vector<StringRef> Tokens;
@@ -78,6 +82,8 @@
       readOutputFormat();
     } else if (Tok == "SEARCH_DIR") {
       readSearchDir();
+    } else if (Tok == "SECTIONS") {
+      readSections();
     } else {
       error("unknown directive: " + Tok);
     }
@@ -133,11 +139,20 @@
 }
 
 StringRef LinkerScript::next() {
-  if (Pos == Tokens.size())
+  if (atEOF())
     error("unexpected EOF");
   return Tokens[Pos++];
 }
 
+bool LinkerScript::skip(StringRef Tok) {
+  if (atEOF())
+    error("unexpected EOF");
+  if (Tok != Tokens[Pos])
+    return false;
+  ++Pos;
+  return true;
+}
+
 void LinkerScript::expect(StringRef Expect) {
   StringRef Tok = next();
   if (Tok != Expect)
@@ -255,6 +270,26 @@
   expect(")");
 }
 
+void LinkerScript::readSections() {
+  expect("{");
+  while (!skip("}"))
+    readOutputSectionDescription();
+}
+
+void LinkerScript::readOutputSectionDescription() {
+  StringRef Name = next();
+  std::vector<StringRef> &InputSections = Config->OutputSections[Name];
+
+  expect(":");
+  expect("{");
+  while (!skip("}")) {
+    next(); // Skip input file name.
+    expect("(");
+    while (!skip(")"))
+      InputSections.push_back(next());
+  }
+}
+
 // Entry point. The other functions or classes are private to this file.
 void lld::elf2::readLinkerScript(BumpPtrAllocator *A, MemoryBufferRef MB) {
   LinkerScript(A, MB.getBuffer()).run();