Start adding support for absolute symbols.

llvm-svn: 246147
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 14566dc..457a78d 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -90,6 +90,9 @@
   StringRef Name = *NameOrErr;
 
   uint32_t SecIndex = Sym->st_shndx;
+  if (SecIndex == SHN_ABS)
+    return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
+
   if (SecIndex == SHN_XINDEX)
     SecIndex = ELFObj->getExtendedSymbolTableIndex(Sym, Symtab, SymtabSHNDX);
 
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 095940c..359632f 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -33,6 +33,7 @@
 
   // Now handle the case where the kinds are the same.
   switch (LK) {
+  case DefinedAbsoluteKind:
   case DefinedRegularKind:
     return 0;
   case DefinedWeakKind:
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 296fd40..309c34f 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -39,11 +39,12 @@
   enum Kind {
     DefinedFirst = 0,
     DefinedRegularKind = 0,
-    DefinedWeakKind = 1,
-    DefinedLast = 1,
-    UndefinedWeakKind = 2,
-    UndefinedKind = 3,
-    UndefinedSyntheticKind = 4
+    DefinedAbsoluteKind = 1,
+    DefinedWeakKind = 2,
+    DefinedLast = 2,
+    UndefinedWeakKind = 3,
+    UndefinedKind = 4,
+    UndefinedSyntheticKind = 5
   };
 
   Kind kind() const { return static_cast<Kind>(SymbolKind); }
@@ -103,14 +104,35 @@
 // etc.
 template <class ELFT> class Defined : public ELFSymbolBody<ELFT> {
   typedef ELFSymbolBody<ELFT> Base;
+
+protected:
+  typedef typename Base::Kind Kind;
+  typedef typename Base::Elf_Sym Elf_Sym;
+
+public:
+  explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym)
+      : ELFSymbolBody<ELFT>(K, N, Sym) {}
+};
+
+template <class ELFT> class DefinedAbsolute : public Defined<ELFT> {
+  typedef ELFSymbolBody<ELFT> Base;
+  typedef typename Base::Elf_Sym Elf_Sym;
+
+public:
+  explicit DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
+      : Defined<ELFT>(Base::DefinedAbsoluteKind, N, Sym) {}
+};
+
+template <class ELFT> class DefinedInSection : public Defined<ELFT> {
+  typedef ELFSymbolBody<ELFT> Base;
   typedef typename Base::Kind Kind;
 
 public:
   typedef typename Base::Elf_Sym Elf_Sym;
 
-  explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym,
-                   SectionChunk<ELFT> &Section)
-      : ELFSymbolBody<ELFT>(K, N, Sym), Section(Section) {}
+  explicit DefinedInSection(Kind K, StringRef N, const Elf_Sym &Sym,
+                            SectionChunk<ELFT> &Section)
+      : Defined<ELFT>(K, N, Sym), Section(Section) {}
 
   static bool classof(const SymbolBody *S) {
     Kind K = S->kind();
@@ -121,28 +143,28 @@
 };
 
 // Regular defined symbols read from object file symbol tables.
-template <class ELFT> class DefinedRegular : public Defined<ELFT> {
+template <class ELFT> class DefinedRegular : public DefinedInSection<ELFT> {
   typedef Defined<ELFT> Base;
   typedef typename Base::Elf_Sym Elf_Sym;
 
 public:
   explicit DefinedRegular(StringRef N, const Elf_Sym &Sym,
                           SectionChunk<ELFT> &Section)
-      : Defined<ELFT>(Base::DefinedRegularKind, N, Sym, Section) {}
+      : DefinedInSection<ELFT>(Base::DefinedRegularKind, N, Sym, Section) {}
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == Base::DefinedRegularKind;
   }
 };
 
-template <class ELFT> class DefinedWeak : public Defined<ELFT> {
+template <class ELFT> class DefinedWeak : public DefinedInSection<ELFT> {
   typedef Defined<ELFT> Base;
   typedef typename Base::Elf_Sym Elf_Sym;
 
 public:
   explicit DefinedWeak(StringRef N, const Elf_Sym &Sym,
                        SectionChunk<ELFT> &Section)
-      : Defined<ELFT>(Base::DefinedWeakKind, N, Sym, Section) {}
+      : DefinedInSection<ELFT>(Base::DefinedWeakKind, N, Sym, Section) {}
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == Base::DefinedWeakKind;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index bde4897..38616f8 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -246,11 +246,12 @@
       llvm_unreachable("Should be defined by now");
     case SymbolBody::DefinedWeakKind:
     case SymbolBody::DefinedRegularKind: {
-      auto *Def = cast<Defined<ELFT>>(Body);
+      auto *Def = cast<DefinedInSection<ELFT>>(Body);
       InputSym = &Def->Sym;
       Section = &Def->Section;
       break;
     }
+    case SymbolBody::DefinedAbsoluteKind:
     case SymbolBody::UndefinedWeakKind:
       InputSym = &cast<ELFSymbolBody<ELFT>>(Body)->Sym;
       break;
@@ -261,6 +262,10 @@
       uint8_t Binding = InputSym->getBinding();
       ESym->setBindingAndType(Binding, Type);
       ESym->st_size = InputSym->st_size;
+      if (InputSym->isAbsolute()) {
+        ESym->st_shndx = SHN_ABS;
+        ESym->st_value = InputSym->st_value;
+      }
     }
 
     if (Section) {
diff --git a/lld/test/elf2/symbols.s b/lld/test/elf2/symbols.s
index be0661d7..44a4787 100644
--- a/lld/test/elf2/symbols.s
+++ b/lld/test/elf2/symbols.s
@@ -28,6 +28,9 @@
 .size zed3, 4
 zed3:
 
+.globl abs
+abs = 0x123
+
 // CHECK:      Name: .text
 // CHECK-NEXT: Type: SHT_PROGBITS
 // CHECK-NEXT: Flags [
@@ -90,6 +93,15 @@
 // CHECK-NEXT:     Section: Undefined (0x0)
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: abs
+// CHECK-NEXT:     Value: 0x123
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Global
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 0
+// CHECK-NEXT:     Section: Absolute
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: foo
 // CHECK-NEXT:     Value: 0x1000
 // CHECK-NEXT:     Size: 0