Index: include/lld/Core/Atom.h =================================================================== --- include/lld/Core/Atom.h +++ include/lld/Core/Atom.h @@ -36,11 +36,14 @@ /// The scope in which this atom is acessible to other atoms. enum Scope { scopeTranslationUnit, ///< Accessible only to atoms in the same translation - /// unit (e.g. a C static). + /// unit (e.g. visibility=internal). scopeLinkageUnit, ///< Accessible to atoms being linked but not visible /// to runtime loader (e.g. visibility=hidden). - scopeGlobal ///< Accessible to all atoms and visible to runtime + scopeGlobal, ///< Accessible to all atoms and visible to runtime /// loader (e.g. visibility=default). + scopeProtected ///< Accessible to all atoms and visible to runtime + /// loader, but can't be overriden + /// (e.g. visibility=protected). }; Index: lib/ReaderWriter/ELF/SectionChunks.h =================================================================== --- lib/ReaderWriter/ELF/SectionChunks.h +++ lib/ReaderWriter/ELF/SectionChunks.h @@ -729,7 +729,7 @@ template void SymbolTable::addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da, int64_t addr) { - unsigned char binding = 0, type = 0; + unsigned char binding = 0, type = 0, visibility = 0; sym.st_size = da->size(); DefinedAtom::ContentType ct; switch (ct = da->contentType()) { @@ -773,6 +773,21 @@ else binding = llvm::ELF::STB_GLOBAL; + switch (DefinedAtom::Scope vt = da->scope()) { + case DefinedAtom::scopeLinkageUnit: + visibility = llvm::ELF::STV_HIDDEN; + break; + case DefinedAtom::scopeTranslationUnit: + visibility = llvm::ELF::STV_INTERNAL; + break; + case DefinedAtom::scopeGlobal: + visibility = llvm::ELF::STV_DEFAULT; + break; + case DefinedAtom::scopeProtected: + visibility = llvm::ELF::STV_PROTECTED; + break; + } + sym.setVisibility(visibility); sym.setBindingAndType(binding, type); } @@ -784,6 +799,8 @@ sym.st_shndx = llvm::ELF::SHN_ABS; switch (aa->scope()) { case AbsoluteAtom::scopeLinkageUnit: + // XXX this is unsafe because it might override + // the other bits of st_other. sym.st_other = llvm::ELF::STV_HIDDEN; binding = llvm::ELF::STB_LOCAL; break; @@ -793,6 +810,8 @@ case AbsoluteAtom::scopeGlobal: binding = llvm::ELF::STB_GLOBAL; break; + case AbsoluteAtom::scopeProtected: + break; } sym.st_value = addr; sym.setBindingAndType(binding, type); Index: lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp =================================================================== --- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -766,8 +766,8 @@ return std::error_code(); } break; - } llvm_unreachable("atom->scope() unknown enum value"); + } } std::error_code Util::addSymbols(const lld::File &atomFile, Index: test/elf/Mips/mips-options-gp0.test =================================================================== --- test/elf/Mips/mips-options-gp0.test +++ test/elf/Mips/mips-options-gp0.test @@ -10,7 +10,7 @@ # SYM-NEXT: Size: 4 # SYM-NEXT: Binding: Local (0x0) # SYM-NEXT: Type: Function (0x2) -# SYM-NEXT: Other: 0 +# SYM-NEXT: Other: 1 # SYM-NEXT: Section: .text (0x4) # SYM: Name: _gp (34) Index: test/elf/Mips/rel-gprel16.test =================================================================== --- test/elf/Mips/rel-gprel16.test +++ test/elf/Mips/rel-gprel16.test @@ -10,7 +10,7 @@ # SYM-NEXT: Size: 4 # SYM-NEXT: Binding: Local (0x0) # SYM-NEXT: Type: Function (0x2) -# SYM-NEXT: Other: 0 +# SYM-NEXT: Other: 1 # SYM-NEXT: Section: .text (0x4) # SYM: Name: G1 (4) Index: test/elf/Mips/rel-gprel32.test =================================================================== --- test/elf/Mips/rel-gprel32.test +++ test/elf/Mips/rel-gprel32.test @@ -10,7 +10,7 @@ # SYM-NEXT: Size: 4 # SYM-NEXT: Binding: Local (0x0) # SYM-NEXT: Type: Function (0x2) -# SYM-NEXT: Other: 0 +# SYM-NEXT: Other: 1 # SYM-NEXT: Section: .text (0x5) # # SYM: Name: _gp (212)