[lld] r340804 - [LLD][ELD] - Do not reject INFO output section type when used with a start address.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 28 01:39:21 PDT 2018


Author: grimar
Date: Tue Aug 28 01:39:21 2018
New Revision: 340804

URL: http://llvm.org/viewvc/llvm-project?rev=340804&view=rev
Log:
[LLD][ELD] - Do not reject INFO output section type when used with a start address.

This is https://bugs.llvm.org/show_bug.cgi?id=38625

LLD accept this: 

".stack (INFO) : {", 

but not this:

".stack address_expression (INFO) :"

The patch fixes it.

Differential revision: https://reviews.llvm.org/D51027

Modified:
    lld/trunk/ELF/ScriptLexer.cpp
    lld/trunk/ELF/ScriptLexer.h
    lld/trunk/ELF/ScriptParser.cpp
    lld/trunk/test/ELF/linkerscript/info-section-type.s

Modified: lld/trunk/ELF/ScriptLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptLexer.cpp?rev=340804&r1=340803&r2=340804&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptLexer.cpp (original)
+++ lld/trunk/ELF/ScriptLexer.cpp Tue Aug 28 01:39:21 2018
@@ -244,6 +244,15 @@ StringRef ScriptLexer::peek() {
   return Tok;
 }
 
+StringRef ScriptLexer::peek2() {
+  skip();
+  StringRef Tok = next();
+  if (errorCount())
+    return "";
+  Pos = Pos - 2;
+  return Tok;
+}
+
 bool ScriptLexer::consume(StringRef Tok) {
   if (peek() == Tok) {
     skip();

Modified: lld/trunk/ELF/ScriptLexer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptLexer.h?rev=340804&r1=340803&r2=340804&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptLexer.h (original)
+++ lld/trunk/ELF/ScriptLexer.h Tue Aug 28 01:39:21 2018
@@ -29,6 +29,7 @@ public:
   bool atEOF();
   StringRef next();
   StringRef peek();
+  StringRef peek2();
   void skip();
   bool consume(StringRef Tok);
   void expect(StringRef Expect);

Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=340804&r1=340803&r2=340804&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Tue Aug 28 01:39:21 2018
@@ -80,6 +80,7 @@ private:
   ByteCommand *readByteCommand(StringRef Tok);
   uint32_t readFill();
   uint32_t parseFill(StringRef Tok);
+  bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2);
   void readSectionAddressType(OutputSection *Cmd);
   OutputSection *readOverlaySectionDescription();
   OutputSection *readOutputSectionDescription(StringRef OutSec);
@@ -699,6 +700,26 @@ uint32_t ScriptParser::readFill() {
   return V;
 }
 
+// Tries to read the special directive for an output section definition which
+// can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)".
+// Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below.
+bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) {
+  if (Tok1 != "(")
+    return false;
+  if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY")
+    return false;
+
+  expect("(");
+  if (consume("NOLOAD")) {
+    Cmd->Noload = true;
+  } else {
+    skip(); // This is "COPY", "INFO" or "OVERLAY".
+    Cmd->NonAlloc = true;
+  }
+  expect(")");
+  return true;
+}
+
 // Reads an expression and/or the special directive for an output
 // section definition. Directive is one of following: "(NOLOAD)",
 // "(COPY)", "(INFO)" or "(OVERLAY)".
@@ -711,28 +732,12 @@ uint32_t ScriptParser::readFill() {
 // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
 // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
 void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
-  if (consume("(")) {
-    if (consume("NOLOAD")) {
-      expect(")");
-      Cmd->Noload = true;
-      return;
-    }
-    if (consume("COPY") || consume("INFO") || consume("OVERLAY")) {
-      expect(")");
-      Cmd->NonAlloc = true;
-      return;
-    }
-    Cmd->AddrExpr = readExpr();
-    expect(")");
-  } else {
-    Cmd->AddrExpr = readExpr();
-  }
+  if (readSectionDirective(Cmd, peek(), peek2()))
+    return;
 
-  if (consume("(")) {
-    expect("NOLOAD");
-    expect(")");
-    Cmd->Noload = true;
-  }
+  Cmd->AddrExpr = readExpr();
+  if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2()))
+    setError("unknown section directive: " + peek2());
 }
 
 static Expr checkAlignment(Expr E, std::string &Loc) {

Modified: lld/trunk/test/ELF/linkerscript/info-section-type.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/info-section-type.s?rev=340804&r1=340803&r2=340804&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/info-section-type.s (original)
+++ lld/trunk/test/ELF/linkerscript/info-section-type.s Tue Aug 28 01:39:21 2018
@@ -29,5 +29,14 @@
 # RUN: ld.lld -o %t --script %t.script %t.o
 # RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
 
+# RUN: echo "SECTIONS { .bar 0x20000 (INFO) : { *(.foo) } };" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
+
+# RUN: echo "SECTIONS { .bar 0x20000 (BAR) : { *(.foo) } };" > %t.script
+# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 |\
+# RUN:   FileCheck %s --check-prefix=UNKNOWN
+# UNKNOWN: unknown section directive: BAR
+
 .section .foo,"a", at progbits
 .zero 1




More information about the llvm-commits mailing list