<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Feb 24, 2014 at 10:52 PM, Shankar Easwaran <span dir="ltr"><<a href="mailto:shankare@codeaurora.org" target="_blank">shankare@codeaurora.org</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi Chandler, Rui,<br>
<br>
For example :-<br>
<br>
OUTPUT_FORMAT(x, "y", "z")<br>
<br>
We need to display an error for the above case, while<br>
<br>
OUTPUT_FORMAT("x", "y", "z") produces no error.<br></blockquote><div><br></div><div>Both gave me error...</div><div><br></div><div>I looked at GNU LD's ldlex.l. it looks like both bare string and quoted string are of type NAME at the lexer level. So probably we shouldn't distinguish them to keep the code simple?</div>

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