[lld] r202111 - [LinkerScript] OUTPUT_FORMAT: Parse Quoted Strings

Shankar Easwaran shankare at codeaurora.org
Mon Feb 24 22:52:20 PST 2014


Hi Chandler, Rui,

For example :-

OUTPUT_FORMAT(x, "y", "z")

We need to display an error for the above case, while

OUTPUT_FORMAT("x", "y", "z") produces no error.

Its so easy to check, that the string that appeared before was a 
quotedstring versus just an identifier.

Thanks

Shankar Easwaran


On 2/25/2014 12:44 AM, Rui Ueyama wrote:
> On Mon, Feb 24, 2014 at 10:33 PM, Shankar Easwaran
> <shankare at codeaurora.org>wrote:
>
>> Hi Rui,
>>
>> It makes checking for errors very easy, when you dont have a valid
>> identifier, whether it appeared in a quoted string or not.
>>
> Can you give me an example? It seems to me that better error checking and
> token type in Linker Script is orthogonal.
>
>
>> I think identifiers and strings need to be separately considered for other
>> cases which I am not sure of.
>>
> We don't generally want to write code to prepare for a thing that we are
> not sure, I think, as we can easily change the code once we figure it out.
> On the other hand, this change added a bit of burden. We now have to check
> if token is of identifier or quotedString everywhere we used to just check
> for an identifier. That's error prone.
>
> Adding Bigcheese here.
>> Thanks
>>
>> Shankar Easwaran
>>
>>
>> On 2/25/2014 12:21 AM, Rui Ueyama wrote:
>>
>>> On Mon, Feb 24, 2014 at 10:10 PM, Shankar Easwaran
>>> <shankare at codeaurora.org>wrote:
>>>
>>>   Hi Rui,
>>>> No error in this case :-
>>>>
>>>> $cat x
>>>> SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64");
>>>> $ld -T x
>>>> ld: no input files
>>>>
>>>   Error in the below case, when the input is not a string :
>>>>   That's not a counter example because "=" is an operator in Linker
>>> Script.
>>> The rule seems like this: identifier can appear without quotes if it does
>>> not contain any character that has special meaning, such as "=" or "(". If
>>> it contains such character, it must be quoted. Both are still identifier
>>> whether quoted or non-quoted.
>>>
>>>
>>>   $cat x
>>>> SEARCH_DIR(=/usr/x86_64-linux-gnu/lib64);
>>>> $ld -T x
>>>> ld:x:1: syntax error
>>>>
>>>> We need identifiers need to be separately treated from quoted strings,
>>>> for
>>>> few other cases too.
>>>>
>>>> Thanks
>>>>
>>>> Shankar Easwaran
>>>>
>>>>
>>>> On 2/25/2014 12:04 AM, Rui Ueyama wrote:
>>>>
>>>>   On Mon, Feb 24, 2014 at 9:46 PM, Shankar Easwaran
>>>>> <shankare at codeaurora.org>wrote:
>>>>>
>>>>>    Hi Rui,
>>>>>
>>>>>> We want to distinguish between when a quotedString would appear and
>>>>>> when
>>>>>> an identifier would appear.
>>>>>>
>>>>>> For example: The SEARCH_DIR command doesnot allow identifiers, it only
>>>>>> allows quoted strings.
>>>>>>
>>>>>>    Is it true? I added "SEARCH_DIR ( /foo/bar )" to libc.so as a test
>>>>>> and
>>>>>>
>>>>> GNU
>>>>> ld does not print any error.
>>>>>
>>>>>
>>>>>    There is also a error case that needs to be handled in the following
>>>>>
>>>>>> patches, if a list is specified, only quoted strings are allowed.
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>> Shankar Easwaran
>>>>>>
>>>>>>
>>>>>> On 2/24/2014 11:42 PM, Rui Ueyama wrote:
>>>>>>
>>>>>>    In this patch, "foo" will be parsed as a token of type quotedString
>>>>>> and
>>>>>>
>>>>>>> foo
>>>>>>> (bare string) is of type identifier, but I think we don't need to
>>>>>>> distinguish one from other. Whether a token was quoted or not is not
>>>>>>> important for the core linker script interpreter. Can you remove
>>>>>>> quotedString and just use type identifier?
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Feb 24, 2014 at 9:17 PM, Shankar Easwaran
>>>>>>> <shankare at codeaurora.org>wrote:
>>>>>>>
>>>>>>>     Author: shankare
>>>>>>>
>>>>>>>   Date: Mon Feb 24 23:17:24 2014
>>>>>>>> New Revision: 202111
>>>>>>>>
>>>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=202111&view=rev
>>>>>>>> Log:
>>>>>>>> [LinkerScript] OUTPUT_FORMAT: Parse Quoted Strings
>>>>>>>>
>>>>>>>> Added:
>>>>>>>>         lld/trunk/test/LinkerScript/
>>>>>>>>         lld/trunk/test/LinkerScript/linker-script-outputformat.test
>>>>>>>>         lld/trunk/test/LinkerScript/linker-script.test
>>>>>>>>           - copied, changed from r202101,
>>>>>>>> lld/trunk/test/linker-script.
>>>>>>>> test
>>>>>>>> Removed:
>>>>>>>>         lld/trunk/test/linker-script.test
>>>>>>>> Modified:
>>>>>>>>         lld/trunk/include/lld/ReaderWriter/LinkerScript.h
>>>>>>>>         lld/trunk/lib/ReaderWriter/LinkerScript.cpp
>>>>>>>>
>>>>>>>> Modified: lld/trunk/include/lld/ReaderWriter/LinkerScript.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/
>>>>>>>> ReaderWriter/LinkerScript.h?rev=202111&r1=202110&r2=202111&view=diff
>>>>>>>>
>>>>>>>> ============================================================
>>>>>>>> ==================
>>>>>>>> --- lld/trunk/include/lld/ReaderWriter/LinkerScript.h (original)
>>>>>>>> +++ lld/trunk/include/lld/ReaderWriter/LinkerScript.h Mon Feb 24
>>>>>>>> 23:17:24
>>>>>>>> 2014
>>>>>>>> @@ -16,6 +16,7 @@
>>>>>>>>      #define LLD_READER_WRITER_LINKER_SCRIPT_H
>>>>>>>>
>>>>>>>>      #include "lld/Core/LLVM.h"
>>>>>>>> +#include "lld/Core/range.h"
>>>>>>>>
>>>>>>>>      #include "llvm/ADT/OwningPtr.h"
>>>>>>>>      #include "llvm/ADT/StringSwitch.h"
>>>>>>>> @@ -25,6 +26,8 @@
>>>>>>>>      #include "llvm/Support/SourceMgr.h"
>>>>>>>>      #include "llvm/Support/system_error.h"
>>>>>>>>
>>>>>>>> +#include <vector>
>>>>>>>> +
>>>>>>>>      namespace lld {
>>>>>>>>      namespace script {
>>>>>>>>      class Token {
>>>>>>>> @@ -33,6 +36,8 @@ public:
>>>>>>>>          unknown,
>>>>>>>>          eof,
>>>>>>>>          identifier,
>>>>>>>> +    comma,
>>>>>>>> +    quotedString,
>>>>>>>>          l_paren,
>>>>>>>>          r_paren,
>>>>>>>>          kw_entry,
>>>>>>>> @@ -93,21 +98,30 @@ private:
>>>>>>>>
>>>>>>>>      class OutputFormat : public Command {
>>>>>>>>      public:
>>>>>>>> -  explicit OutputFormat(StringRef format)
>>>>>>>> -      : Command(Kind::OutputFormat), _format(format) {}
>>>>>>>> +  explicit OutputFormat(StringRef format) :
>>>>>>>> Command(Kind::OutputFormat)
>>>>>>>> {
>>>>>>>> +    _formats.push_back(format);
>>>>>>>> +  }
>>>>>>>>
>>>>>>>>        static bool classof(const Command *c) {
>>>>>>>>          return c->getKind() == Kind::OutputFormat;
>>>>>>>>        }
>>>>>>>>
>>>>>>>>        virtual void dump(raw_ostream &os) const {
>>>>>>>> -    os << "OUTPUT_FORMAT(" << getFormat() << ")\n";
>>>>>>>> +    os << "OUTPUT_FORMAT(";
>>>>>>>> +    for (auto fb = _formats.begin(), fe = _formats.end(); fb != fe;
>>>>>>>> ++fb)
>>>>>>>> {
>>>>>>>> +      if (fb != _formats.begin())
>>>>>>>> +        os << ",";
>>>>>>>> +      os << *fb;
>>>>>>>> +    }
>>>>>>>> +    os << ")\n";
>>>>>>>>        }
>>>>>>>>
>>>>>>>> -  StringRef getFormat() const { return _format; }
>>>>>>>> +  virtual void addOutputFormat(StringRef format) {
>>>>>>>> _formats.push_back(format); }
>>>>>>>> +
>>>>>>>> +  range<StringRef *> getFormats() { return _formats; }
>>>>>>>>
>>>>>>>>      private:
>>>>>>>> -  StringRef _format;
>>>>>>>> +  std::vector<StringRef> _formats;
>>>>>>>>      };
>>>>>>>>
>>>>>>>>      class OutputArch : public Command {
>>>>>>>> @@ -227,6 +241,8 @@ private:
>>>>>>>>          return true;
>>>>>>>>        }
>>>>>>>>
>>>>>>>> +  bool isNextToken(Token::Kind kind) { return (_tok._kind == kind);
>>>>>>>> }
>>>>>>>> +
>>>>>>>>        OutputFormat *parseOutputFormat();
>>>>>>>>        OutputArch *parseOutputArch();
>>>>>>>>        Group *parseGroup();
>>>>>>>>
>>>>>>>> Modified: lld/trunk/lib/ReaderWriter/LinkerScript.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/
>>>>>>>> ReaderWriter/LinkerScript.cpp?rev=202111&r1=202110&r2=
>>>>>>>> 202111&view=diff
>>>>>>>>
>>>>>>>> ============================================================
>>>>>>>> ==================
>>>>>>>> --- lld/trunk/lib/ReaderWriter/LinkerScript.cpp (original)
>>>>>>>> +++ lld/trunk/lib/ReaderWriter/LinkerScript.cpp Mon Feb 24 23:17:24
>>>>>>>> 2014
>>>>>>>> @@ -29,6 +29,8 @@ void Token::dump(raw_ostream &os) const
>>>>>>>>        CASE(kw_group)
>>>>>>>>        CASE(kw_output_format)
>>>>>>>>        CASE(kw_output_arch)
>>>>>>>> +  CASE(quotedString)
>>>>>>>> +  CASE(comma)
>>>>>>>>        CASE(l_paren)
>>>>>>>>        CASE(r_paren)
>>>>>>>>        CASE(unknown)
>>>>>>>> @@ -67,7 +69,12 @@ bool Lexer::canContinueName(char c) cons
>>>>>>>>        case '0': case '1': case '2': case '3': case '4': case '5':
>>>>>>>> case
>>>>>>>> '6':
>>>>>>>>        case '7': case '8': case '9':
>>>>>>>>        case '_': case '.': case '$': case '/': case '\\': case '~':
>>>>>>>> case
>>>>>>>> '=':
>>>>>>>> -  case '+': case ',': case '[': case ']': case '*': case '?': case
>>>>>>>> '-':
>>>>>>>> +  case '+':
>>>>>>>> +  case '[':
>>>>>>>> +  case ']':
>>>>>>>> +  case '*':
>>>>>>>> +  case '?':
>>>>>>>> +  case '-':
>>>>>>>>        case ':':
>>>>>>>>          return true;
>>>>>>>>        default:
>>>>>>>> @@ -94,7 +101,23 @@ void Lexer::lex(Token &tok) {
>>>>>>>>          tok = Token(_buffer.substr(0, 1), Token::r_paren);
>>>>>>>>          _buffer = _buffer.drop_front();
>>>>>>>>          return;
>>>>>>>> +  case ',':
>>>>>>>> +    tok = Token(_buffer.substr(0, 1), Token::comma);
>>>>>>>> +    _buffer = _buffer.drop_front();
>>>>>>>> +    return;
>>>>>>>>        default:
>>>>>>>> +    // Quoted strings ?
>>>>>>>> +    if ((_buffer[0] == '\"') || (_buffer[0] == '\'')) {
>>>>>>>> +      char c = _buffer[0];
>>>>>>>> +      _buffer = _buffer.drop_front();
>>>>>>>> +      auto quotedStringEnd = _buffer.find(c);
>>>>>>>> +      if (quotedStringEnd == StringRef::npos || quotedStringEnd ==
>>>>>>>> 0)
>>>>>>>> +        break;
>>>>>>>> +      StringRef word = _buffer.substr(0, quotedStringEnd);
>>>>>>>> +      tok = Token(word, Token::quotedString);
>>>>>>>> +      _buffer = _buffer.drop_front(quotedStringEnd + 1);
>>>>>>>> +      return;
>>>>>>>> +    }
>>>>>>>>          /// keyword or identifer.
>>>>>>>>          if (!canStartName(_buffer[0]))
>>>>>>>>            break;
>>>>>>>> @@ -215,14 +238,27 @@ OutputFormat *Parser::parseOutputFormat(
>>>>>>>>        if (!expectAndConsume(Token::l_paren, "expected ("))
>>>>>>>>          return nullptr;
>>>>>>>>
>>>>>>>> -  if (_tok._kind != Token::identifier) {
>>>>>>>> -    error(_tok, "Expected identifier in OUTPUT_FORMAT.");
>>>>>>>> +  if (_tok._kind != Token::quotedString && _tok._kind !=
>>>>>>>> Token::identifier) {
>>>>>>>> +    error(_tok, "Expected identifier/string in OUTPUT_FORMAT.");
>>>>>>>>          return nullptr;
>>>>>>>>        }
>>>>>>>>
>>>>>>>>        auto ret = new (_alloc) OutputFormat(_tok._range);
>>>>>>>>        consumeToken();
>>>>>>>>
>>>>>>>> +  do {
>>>>>>>> +    if (isNextToken(Token::comma))
>>>>>>>> +      consumeToken();
>>>>>>>> +    else
>>>>>>>> +      break;
>>>>>>>> +    if (_tok._kind != Token::quotedString && _tok._kind !=
>>>>>>>> Token::identifier) {
>>>>>>>> +      error(_tok, "Expected identifier/string in OUTPUT_FORMAT.");
>>>>>>>> +      return nullptr;
>>>>>>>> +    }
>>>>>>>> +    ret->addOutputFormat(_tok._range);
>>>>>>>> +    consumeToken();
>>>>>>>> +  } while (isNextToken(Token::comma));
>>>>>>>> +
>>>>>>>>        if (!expectAndConsume(Token::r_paren, "expected )"))
>>>>>>>>          return nullptr;
>>>>>>>>
>>>>>>>>
>>>>>>>> Added: lld/trunk/test/LinkerScript/linker-script-outputformat.test
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/
>>>>>>>> LinkerScript/linker-script-outputformat.test?rev=202111&view=auto
>>>>>>>>
>>>>>>>> ============================================================
>>>>>>>> ==================
>>>>>>>> --- lld/trunk/test/LinkerScript/linker-script-outputformat.test
>>>>>>>> (added)
>>>>>>>> +++ lld/trunk/test/LinkerScript/linker-script-outputformat.test Mon
>>>>>>>> Feb
>>>>>>>> 24
>>>>>>>> 23:17:24 2014
>>>>>>>> @@ -0,0 +1,12 @@
>>>>>>>> +/* RUN: linker-script-test %s | FileCheck %s
>>>>>>>> +*/
>>>>>>>> +
>>>>>>>> +OUTPUT_FORMAT(elf64-x86-64)
>>>>>>>> +
>>>>>>>> +/*
>>>>>>>> +CHECK: kw_output_format: OUTPUT_FORMAT
>>>>>>>> +CHECK: l_paren: (
>>>>>>>> +CHECK: identifier: elf64-x86-64
>>>>>>>> +CHECK: r_paren: )
>>>>>>>> +CHECK: OUTPUT_FORMAT(elf64-x86-64)
>>>>>>>> +*/
>>>>>>>>
>>>>>>>> Copied: lld/trunk/test/LinkerScript/linker-script.test (from
>>>>>>>> r202101,
>>>>>>>> lld/trunk/test/linker-script.test)
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/
>>>>>>>> LinkerScript/linker-script.test?p2=lld/trunk/test/
>>>>>>>> LinkerScript/linker-script.test&p1=lld/trunk/test/linker-
>>>>>>>> script.test&r1=202101&r2=202111&rev=202111&view=diff
>>>>>>>>
>>>>>>>> ============================================================
>>>>>>>> ==================
>>>>>>>> --- lld/trunk/test/linker-script.test (original)
>>>>>>>> +++ lld/trunk/test/LinkerScript/linker-script.test Mon Feb 24
>>>>>>>> 23:17:24
>>>>>>>> 2014
>>>>>>>> @@ -2,7 +2,7 @@
>>>>>>>>      */
>>>>>>>>
>>>>>>>>      OUTPUT_ARCH(i386:x86_64)
>>>>>>>> -OUTPUT_FORMAT(elf64-x86-64)
>>>>>>>> +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
>>>>>>>>      GROUP ( /lib/x86_64-linux-gnu/libc.so.6
>>>>>>>> /usr/lib/x86_64-linux-gnu/libc_nonshared.a  AS_NEEDED (
>>>>>>>> /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 ) )
>>>>>>>>      ENTRY(init)
>>>>>>>>
>>>>>>>> @@ -13,7 +13,11 @@ CHECK: identifier: i386:x86_64
>>>>>>>>      CHECK: r_paren: )
>>>>>>>>      CHECK: kw_output_format: OUTPUT_FORMAT
>>>>>>>>      CHECK: l_paren: (
>>>>>>>> -CHECK: identifier: elf64-x86-64
>>>>>>>> +CHECK: quotedString: elf64-x86-64
>>>>>>>> +CHECK: comma: ,
>>>>>>>> +CHECK: quotedString: elf64-x86-64
>>>>>>>> +CHECK: comma: ,
>>>>>>>> +CHECK: quotedString: elf64-x86-64
>>>>>>>>      CHECK: r_paren: )
>>>>>>>>      CHECK: kw_group: GROUP
>>>>>>>>      CHECK: l_paren: (
>>>>>>>> @@ -29,7 +33,7 @@ CHECK: l_paren: (
>>>>>>>>      CHECK: identifier: init
>>>>>>>>      CHECK: r_paren: )
>>>>>>>>      CHECK: eof:
>>>>>>>> -CHECK: OUTPUT_FORMAT(elf64-x86-64)
>>>>>>>> +CHECK: OUTPUT_FORMAT(elf64-x86-64,elf64-x86-64,elf64-x86-64)
>>>>>>>>      CHECK: GROUP(/lib/x86_64-linux-gnu/libc.so.6
>>>>>>>> /usr/lib/x86_64-linux-gnu/libc_nonshared.a
>>>>>>>> AS_NEEDED(/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2))
>>>>>>>>      CHECK: ENTRY(init)
>>>>>>>>      */
>>>>>>>>
>>>>>>>> Removed: lld/trunk/test/linker-script.test
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/linker-
>>>>>>>> script.test?rev=202110&view=auto
>>>>>>>>
>>>>>>>> ============================================================
>>>>>>>> ==================
>>>>>>>> --- lld/trunk/test/linker-script.test (original)
>>>>>>>> +++ lld/trunk/test/linker-script.test (removed)
>>>>>>>> @@ -1,35 +0,0 @@
>>>>>>>> -/* RUN: linker-script-test %s | FileCheck %s
>>>>>>>> -*/
>>>>>>>> -
>>>>>>>> -OUTPUT_ARCH(i386:x86_64)
>>>>>>>> -OUTPUT_FORMAT(elf64-x86-64)
>>>>>>>> -GROUP ( /lib/x86_64-linux-gnu/libc.so.6
>>>>>>>> /usr/lib/x86_64-linux-gnu/libc_nonshared.a  AS_NEEDED (
>>>>>>>> /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 ) )
>>>>>>>> -ENTRY(init)
>>>>>>>> -
>>>>>>>> -/*
>>>>>>>> -CHECK: kw_output_arch: OUTPUT_ARCH
>>>>>>>> -CHECK: l_paren: (
>>>>>>>> -CHECK: identifier: i386:x86_64
>>>>>>>> -CHECK: r_paren: )
>>>>>>>> -CHECK: kw_output_format: OUTPUT_FORMAT
>>>>>>>> -CHECK: l_paren: (
>>>>>>>> -CHECK: identifier: elf64-x86-64
>>>>>>>> -CHECK: r_paren: )
>>>>>>>> -CHECK: kw_group: GROUP
>>>>>>>> -CHECK: l_paren: (
>>>>>>>> -CHECK: identifier: /lib/x86_64-linux-gnu/libc.so.6
>>>>>>>> -CHECK: identifier: /usr/lib/x86_64-linux-gnu/libc_nonshared.a
>>>>>>>> -CHECK: kw_as_needed: AS_NEEDED
>>>>>>>> -CHECK: l_paren: (
>>>>>>>> -CHECK: identifier: /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
>>>>>>>> -CHECK: r_paren: )
>>>>>>>> -CHECK: r_paren: )
>>>>>>>> -CHECK: kw_entry: ENTRY
>>>>>>>> -CHECK: l_paren: (
>>>>>>>> -CHECK: identifier: init
>>>>>>>> -CHECK: r_paren: )
>>>>>>>> -CHECK: eof:
>>>>>>>> -CHECK: OUTPUT_FORMAT(elf64-x86-64)
>>>>>>>> -CHECK: GROUP(/lib/x86_64-linux-gnu/libc.so.6
>>>>>>>> /usr/lib/x86_64-linux-gnu/libc_nonshared.a
>>>>>>>> AS_NEEDED(/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2))
>>>>>>>> -CHECK: ENTRY(init)
>>>>>>>> -*/
>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> llvm-commits mailing list
>>>>>>>> llvm-commits at cs.uiuc.edu
>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>>>>>>
>>>>>>>>
>>>>>>>>    --
>>>>>>>>
>>>>>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>>>>>> hosted
>>>>>> by the Linux Foundation
>>>>>>
>>>>>>
>>>>>>
>>>>>>   --
>>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted
>>>> by the Linux Foundation
>>>>
>>>>
>>>>
>> --
>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted
>> by the Linux Foundation
>>
>>


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation




More information about the llvm-commits mailing list