[llvm] r209894 - MachO: support N_INDR aliases in assembly files.
Rafael EspĂndola
rafael.espindola at gmail.com
Fri Aug 8 16:55:37 PDT 2014
btw, does that mean that simple aliases (a = b, but not a = b + 1) now
work on MachO? Is a new linker required?
On 30 May 2014 09:23, Tim Northover <tnorthover at apple.com> wrote:
> Author: tnorthover
> Date: Fri May 30 08:22:59 2014
> New Revision: 209894
>
> URL: http://llvm.org/viewvc/llvm-project?rev=209894&view=rev
> Log:
> MachO: support N_INDR aliases in assembly files.
>
> This makes LLVM create N_INDR aliases (to be resolved by the linker) when
> appropriate.
>
> rdar://problem/15125513
>
> Added:
> llvm/trunk/test/MC/MachO/aliased-symbols.s
> Modified:
> llvm/trunk/include/llvm/MC/MCMachObjectWriter.h
> llvm/trunk/include/llvm/Object/SymbolicFile.h
> llvm/trunk/lib/MC/MachObjectWriter.cpp
> llvm/trunk/lib/Object/MachOObjectFile.cpp
> llvm/trunk/test/MC/MachO/variable-exprs.s
> llvm/trunk/tools/llvm-nm/llvm-nm.cpp
>
> Modified: llvm/trunk/include/llvm/MC/MCMachObjectWriter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCMachObjectWriter.h?rev=209894&r1=209893&r2=209894&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCMachObjectWriter.h (original)
> +++ llvm/trunk/include/llvm/MC/MCMachObjectWriter.h Fri May 30 08:22:59 2014
> @@ -111,6 +111,8 @@ class MachObjectWriter : public MCObject
>
> /// @}
>
> + MachSymbolData *findSymbolData(const MCSymbol &Sym);
> +
> public:
> MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
> bool _IsLittleEndian)
>
> Modified: llvm/trunk/include/llvm/Object/SymbolicFile.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/SymbolicFile.h?rev=209894&r1=209893&r2=209894&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/SymbolicFile.h (original)
> +++ llvm/trunk/include/llvm/Object/SymbolicFile.h Fri May 30 08:22:59 2014
> @@ -86,6 +86,7 @@ public:
> SF_Weak = 1U << 2, // Weak symbol
> SF_Absolute = 1U << 3, // Absolute symbol
> SF_Common = 1U << 4, // Symbol has common linkage
> + SF_Indirect = 1U << 5,
> SF_FormatSpecific = 1U << 5 // Specific to the object file format
> // (e.g. section symbols)
> };
>
> Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=209894&r1=209893&r2=209894&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Fri May 30 08:22:59 2014
> @@ -303,20 +303,50 @@ void MachObjectWriter::WriteDysymtabLoad
> assert(OS.tell() - Start == sizeof(MachO::dysymtab_command));
> }
>
> +MachObjectWriter::MachSymbolData *
> +MachObjectWriter::findSymbolData(const MCSymbol &Sym) {
> + for (auto &Entry : LocalSymbolData)
> + if (&Entry.SymbolData->getSymbol() == &Sym)
> + return &Entry;
> +
> + for (auto &Entry : ExternalSymbolData)
> + if (&Entry.SymbolData->getSymbol() == &Sym)
> + return &Entry;
> +
> + for (auto &Entry : UndefinedSymbolData)
> + if (&Entry.SymbolData->getSymbol() == &Sym)
> + return &Entry;
> +
> + return nullptr;
> +}
> +
> void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
> const MCAsmLayout &Layout) {
> MCSymbolData &Data = *MSD.SymbolData;
> - const MCSymbol &Symbol = Data.getSymbol();
> + const MCSymbol *Symbol = &Data.getSymbol();
> + const MCSymbol *AliasedSymbol = &Symbol->AliasedSymbol();
> + uint8_t SectionIndex = MSD.SectionIndex;
> uint8_t Type = 0;
> uint16_t Flags = Data.getFlags();
> uint64_t Address = 0;
> + bool IsAlias = Symbol != AliasedSymbol;
> +
> + MachSymbolData *AliaseeInfo;
> + if (IsAlias) {
> + AliaseeInfo = findSymbolData(*AliasedSymbol);
> + if (AliaseeInfo)
> + SectionIndex = AliaseeInfo->SectionIndex;
> + Symbol = AliasedSymbol;
> + }
>
> // Set the N_TYPE bits. See <mach-o/nlist.h>.
> //
> // FIXME: Are the prebound or indirect fields possible here?
> - if (Symbol.isUndefined())
> + if (IsAlias && Symbol->isUndefined())
> + Type = MachO::N_INDR;
> + else if (Symbol->isUndefined())
> Type = MachO::N_UNDF;
> - else if (Symbol.isAbsolute())
> + else if (Symbol->isAbsolute())
> Type = MachO::N_ABS;
> else
> Type = MachO::N_SECT;
> @@ -327,13 +357,15 @@ void MachObjectWriter::WriteNlist(MachSy
> Type |= MachO::N_PEXT;
>
> // Set external bit.
> - if (Data.isExternal() || Symbol.isUndefined())
> + if (Data.isExternal() || (!IsAlias && Symbol->isUndefined()))
> Type |= MachO::N_EXT;
>
> // Compute the symbol address.
> - if (Symbol.isDefined()) {
> + if (IsAlias && Symbol->isUndefined())
> + Address = AliaseeInfo->StringIndex;
> + else if (Symbol->isDefined())
> Address = getSymbolAddress(&Data, Layout);
> - } else if (Data.isCommon()) {
> + else if (Data.isCommon()) {
> // Common symbols are encoded with the size in the address
> // field, and their alignment in the flags.
> Address = Data.getCommonSize();
> @@ -344,21 +376,21 @@ void MachObjectWriter::WriteNlist(MachSy
> assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
> if (Log2Size > 15)
> report_fatal_error("invalid 'common' alignment '" +
> - Twine(Align) + "' for '" + Symbol.getName() + "'",
> + Twine(Align) + "' for '" + Symbol->getName() + "'",
> false);
> // FIXME: Keep this mask with the SymbolFlags enumeration.
> Flags = (Flags & 0xF0FF) | (Log2Size << 8);
> }
> }
>
> - if (Layout.getAssembler().isThumbFunc(&Symbol))
> + if (Layout.getAssembler().isThumbFunc(Symbol))
> Flags |= SF_ThumbFunc;
>
> // struct nlist (12 bytes)
>
> Write32(MSD.StringIndex);
> Write8(Type);
> - Write8(MSD.SectionIndex);
> + Write8(SectionIndex);
>
> // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
> // value.
>
> Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=209894&r1=209893&r2=209894&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
> +++ llvm/trunk/lib/Object/MachOObjectFile.cpp Fri May 30 08:22:59 2014
> @@ -584,6 +584,9 @@ uint32_t MachOObjectFile::getSymbolFlags
> if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
> Result |= SymbolRef::SF_Undefined;
>
> + if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
> + Result |= SymbolRef::SF_Indirect;
> +
> if (MachOType & MachO::N_STAB)
> Result |= SymbolRef::SF_FormatSpecific;
>
>
> Added: llvm/trunk/test/MC/MachO/aliased-symbols.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/aliased-symbols.s?rev=209894&view=auto
> ==============================================================================
> --- llvm/trunk/test/MC/MachO/aliased-symbols.s (added)
> +++ llvm/trunk/test/MC/MachO/aliased-symbols.s Fri May 30 08:22:59 2014
> @@ -0,0 +1,115 @@
> +// RUN: llvm-mc -triple thumbv7m-apple-darwin-eabi %s -filetype=obj -o %t
> +// RUN: llvm-readobj -symbols %t | FileCheck %s
> +
> + .data
> + var1 = var2
> + .long var1
> + .long var2
> + .long var2 + 4
> +defined_early:
> + .long 0
> +
> + alias_to_early = defined_early
> + alias_to_late = defined_late
> +
> +defined_late:
> + .long 0
> +
> + .global extern_test
> + extern_test = var2
> +
> + alias_to_local = Ltmp0
> +Ltmp0:
> +
> +// CHECK: Symbols [
> +
> + // defined_early was defined. Actually has value 0xc.
> +// CHECK: Symbol {
> +// CHECK-NEXT: Name: defined_early
> +// CHECK-NEXT: Type: Section (0xE)
> +// CHECK-NEXT: Section: __data (0x2)
> +// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
> +// CHECK-NEXT: Flags [ (0x0)
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Value: 0x[[DEFINED_EARLY:[0-9A-F]+]]
> +// CHECK-NEXT: }
> +
> + // alias_to_early was an alias to defined_early. But we can resolve it.
> +// CHECK: Symbol {
> +// CHECK-NEXT: Name: alias_to_early
> +// CHECK-NEXT: Type: Section (0xE)
> +// CHECK-NEXT: Section: __data (0x2)
> +// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
> +// CHECK-NEXT: Flags [ (0x0)
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Value: 0x[[DEFINED_EARLY]]
> +// CHECK-NEXT: }
> +
> + // defined_late was defined. Just after defined_early.
> +// CHECK: Symbol {
> +// CHECK-NEXT: Name: defined_late
> +// CHECK-NEXT: Type: Section (0xE)
> +// CHECK-NEXT: Section: __data (0x2)
> +// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
> +// CHECK-NEXT: Flags [ (0x0)
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Value: 0x[[DEFINED_LATE:[0-9A-F]+]]
> +// CHECK-NEXT: }
> +
> + // alias_to_late was an alias to defined_late. But we can resolve it.
> +// CHECK: Symbol {
> +// CHECK-NEXT: Name: alias_to_late
> +// CHECK-NEXT: Type: Section (0xE)
> +// CHECK-NEXT: Section: __data (0x2)
> +// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
> +// CHECK-NEXT: Flags [ (0x0)
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Value: 0x[[DEFINED_LATE]]
> +// CHECK-NEXT: }
> +
> + // alias_to_local is an alias, but what it points to has no
> + // MachO representation. We must resolve it.
> +// CHECK: Symbol {
> +// CHECK-NEXT: Name: alias_to_local (37)
> +// CHECK-NEXT: Type: Section (0xE)
> +// CHECK-NEXT: Section: (0x0)
> +// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
> +// CHECK-NEXT: Flags [ (0x0)
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Value: 0x14
> +// CHECK-NEXT: }
> +
> + // extern_test was a pure alias to the unknown "var2".
> + // N_INDR and Extern.
> +// CHECK: Name: extern_test
> +// CHECK-NEXT: Extern
> +// CHECK-NEXT: Type: Indirect (0xA)
> +// CHECK-NEXT: Section: (0x0)
> +// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
> +// CHECK-NEXT: Flags [ (0x0)
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Value: 0x[[VAR2_STRINGINDEX:[0-9a-f]+]]
> +// CHECK-NEXT: }
> +
> + // var1 was another alias to an unknown variable. Not extern this time.
> +// CHECK: Symbol {
> +// CHECK-NEXT: Name: var1 (1)
> +// CHECK-NEXT: Type: Indirect (0xA)
> +// CHECK-NEXT: Section: (0x0)
> +// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
> +// CHECK-NEXT: Flags [ (0x0)
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Value: 0x[[VAR2_STRINGINDEX]]
> +// CHECK-NEXT: }
> +
> + // var2 was a normal undefined (extern) symbol.
> +// CHECK: Symbol {
> +// CHECK-NEXT: Name: var2
> +// CHECK-NEXT: Extern
> +// CHECK-NEXT: Type: Undef (0x0)
> +// CHECK-NEXT: Section: (0x0)
> +// CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
> +// CHECK-NEXT: Flags [ (0x0)
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Value: 0x0
> +// CHECK-NEXT: }
>
> Modified: llvm/trunk/test/MC/MachO/variable-exprs.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/variable-exprs.s?rev=209894&r1=209893&r2=209894&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/MachO/variable-exprs.s (original)
> +++ llvm/trunk/test/MC/MachO/variable-exprs.s Fri May 30 08:22:59 2014
> @@ -202,10 +202,10 @@ Lt0_x = Lt0_a - Lt0_b
> // CHECK-I386: ),
> // CHECK-I386: # Symbol 8
> // CHECK-I386: (('n_strx', 1)
> -// CHECK-I386: ('n_type', 0x1)
> +// CHECK-I386: ('n_type', 0xb)
> // CHECK-I386: ('n_sect', 0)
> // CHECK-I386: ('n_desc', 0)
> -// CHECK-I386: ('n_value', 0)
> +// CHECK-I386: ('n_value', 4)
> // CHECK-I386: ('_string', 'd2')
> // CHECK-I386: ),
> // CHECK-I386: # Symbol 9
> @@ -403,10 +403,10 @@ Lt0_x = Lt0_a - Lt0_b
> // CHECK-X86_64: ),
> // CHECK-X86_64: # Symbol 8
> // CHECK-X86_64: (('n_strx', 1)
> -// CHECK-X86_64: ('n_type', 0x1)
> +// CHECK-X86_64: ('n_type', 0xb)
> // CHECK-X86_64: ('n_sect', 0)
> // CHECK-X86_64: ('n_desc', 0)
> -// CHECK-X86_64: ('n_value', 0)
> +// CHECK-X86_64: ('n_value', 4)
> // CHECK-X86_64: ('_string', 'd2')
> // CHECK-X86_64: ),
> // CHECK-X86_64: # Symbol 9
>
> Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=209894&r1=209893&r2=209894&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original)
> +++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Fri May 30 08:22:59 2014
> @@ -395,6 +395,8 @@ static char getSymbolNMTypeChar(MachOObj
> switch (NType & MachO::N_TYPE) {
> case MachO::N_ABS:
> return 's';
> + case MachO::N_INDR:
> + return 'i';
> case MachO::N_SECT: {
> section_iterator Sec = Obj.section_end();
> Obj.getSymbolSection(Symb, Sec);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list