[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