LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 15393 - error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
Summary: error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDR...
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: Driver (show other bugs)
Version: trunk
Hardware: PC Windows XP
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-02-28 10:02 PST by Michael Kruse
Modified: 2017-04-11 13:30 PDT (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Kruse 2013-02-28 10:02:24 PST
Compiling any program using -g flag fails for target "x86_64-pc-win32"

>type hello.c
#include <stdio.h>

int main(int argc, char *argv[]) {
  printf("Hello World!");
  return 0;
}


>clang hello.c -o hello.exe -g -target "x86_64-pc-win32" -fno-exceptions -fno-cxx-exceptions -fno-use-cxa-atexit -v
clang version 3.3
Target: x86_64-pc-win32
Thread model: posix
clang: warning: argument unused during compilation: '-fno-cxx-exceptions'
 "C:/Users/Meinersbur/src/molly/build64_vc11/bin/Debug/clang.exe" -cc1 -triple x86_64-pc-win32 -emit-obj -mrelax-all -disable-free -main-file-name hello.c -mrelocation-model pic -p
ic-level 2 -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -momit-leaf-frame-pointer -v -g -resource-dir "C:/Users/Meinersbur/
src/molly/build64_vc11/bin/Debug\\..\\lib\\clang\\3.3" -internal-isystem C:/Users/Meinersbur/src/molly/build64_vc11/bin/Debug/../lib/clang/3.3/include -internal-isystem "C:\\Progra
m Files (x86)\\Microsoft Visual Studio 11.0\\VC\\INCLUDE" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\ATLMFC\\INCLUDE" -internal-isystem "C:\\Prog
ram Files (x86)\\Windows Kits\\8.0\\include\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\8.0\\include\\um" -internal-isystem "C:\\Program Files (x86)\\Windows
 Kits\\8.0\\include\\winrt" -ferror-limit 19 -fmessage-length 180 -mstackrealign -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fmsc-version=1300 -fdelayed-template-parsin
g -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o C:/Users/MEINER~1/AppData/Local/Temp/hel
lo-669244.o -x c hello.c
clang -cc1 version 3.3 based upon LLVM 3.3svn default target x86_64-pc-win32
#include "..." search starts here:
#include <...> search starts here:
 C:/Users/Meinersbur/src/molly/build64_vc11/bin/Debug/../lib/clang/3.3/include
 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE
 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\ATLMFC\INCLUDE
 C:\Program Files (x86)\Windows Kits\8.0\include\shared
 C:\Program Files (x86)\Windows Kits\8.0\include\um
 C:\Program Files (x86)\Windows Kits\8.0\include\winrt
End of search list.
 "C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/BIN/amd64/link.exe" -out:hello.exe -defaultlib:libcmt -nologo C:/Users/MEINER~1/AppData/Local/Temp/hello-669244.o
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_line' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.debug_str' invalid without /LARGEADDRESSAWARE:NO
hello-669244.o : error LNK2017: 'ADDR32' relocation to '.text' invalid without /LARGEADDRESSAWARE:NO
LINK : fatal error LNK1165: link failed because of fixup errors
clang: error: linker command failed with exit code 1165 (use -v to see invocation)


This is working:
> clang -c hello.c -o hello.obj -g -target "x86_64-pc-win32" -fno-exceptions -fno-cxx-exceptions -fno-use-cxa-atexit -v
[...]
> "C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/BIN/amd64/link.exe" -out:hello.exe -defaultlib:libcmt -nologo hello.obj /LARGEADDRESSAWARE:NO /MACHINE:X64
[...]
> hello.exe
Hello World!



However, restricting the address space to 31 bits doesn't seem to be the point of compiling to a 64 bit target. Although, this applies only to the debug version.

Using 
clang/llvm r175980
Windows 7
Visual Studio 2012 SP1
Comment 1 Michael Kruse 2013-02-28 10:42:10 PST
Note that the -g flag is useless: Neither Visual Studio nor gdb are able to read the debug symbols.
Comment 2 Werner Wolfrum 2013-06-17 09:57:21 PDT
Hi there,

I got the same problem, while linking libc++ into a win64-dll.
For an example I pick out the "abort_message.cpp" form libcxxabi:

1>Verknüpfen...
.
.
1>LINK : warning LNK4075: /LARGEADDRESSAWARE:NO wird aufgrund der Angabe von /DLL ignoriert.
1>libcxxabi.lib(abort_message.o) : error LNK2017: ADDR32-Umsetzung zu ".debug_str" ist ohne /LARGEADDRESSAWARE:NO ungültig. <- got it 14 times
1>libcxxabi.lib(abort_message.o) : error LNK2017: ADDR32-Umsetzung zu ".debug_line" ist ohne /LARGEADDRESSAWARE:NO ungültig. <- 1 time
1>libcxxabi.lib(abort_message.o) : error LNK2017: ADDR32-Umsetzung zu ".debug_loc" ist ohne /LARGEADDRESSAWARE:NO ungültig. <- 1 time
1>libcxxabi.lib(abort_message.o) : error LNK2017: ADDR32-Umsetzung zu ".text" ist ohne /LARGEADDRESSAWARE:NO ungültig. <- 1 time
.
.
1>libc++34 - 101 Fehler, 1 Warnung(en)
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========


Linking failes, if debug option (-g) is enabled, because in this case the debug medadata sections added to the object. And these sections contain a wrong relocation type (ADDR32) in their relocationtable (here sections #3 and #5):  

(made with: dumpbin /ALL abort_message.o)
SECTION HEADER #3
      /4 name (.debug_info)
       0 physical address
       0 virtual address
      89 size of raw data
     1A3 file pointer to raw data (000001A3 to 0000022B)
     22C file pointer to relocation table
       0 file pointer to line numbers
       D number of relocations
       0 number of line numbers
42100000 flags
         Discardable
         1 byte align
         Read Only

RAW DATA #3
  00000000: 85 00 00 00 02 00 00 00 00 00 08 01 00 00 00 00  ................
  00000010: 04 00 1B 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000020: 00 00 34 00 00 00 02 5D 00 00 00 01 19 00 00 00  ..4....]........
  00000030: 00 00 00 00 00 6B 00 00 00 00 00 00 00 01 56 03  .....k........V.
  00000040: 6B 00 00 00 01 19 68 00 00 00 02 91 78 04 77 00  k.....h.....x.w.
  00000050: 00 00 01 1F 7D 00 00 00 02 91 70 00 05 72 00 00  ....}.....p..r..
  00000060: 00 06 01 06 5C 00 00 00 07 63 00 00 00 07 5C 00  ....\....c....\.
  00000070: 00 00 08 6D 00 00 00 7C 00 00 00 01 1F 08 72 00  ...m...|......r.
  00000080: 00 00 8E 00 00 00 01 1E 00                       .........

RELOCATIONS #3
                                                Symbol    Symbol
 Offset    Type              Applied To         Index     Name
 --------  ----------------  -----------------  --------  ------
 00000006  SECREL                     00000000         6  .debug_abbrev
 0000000C  ADDR32                     00000000         A  .debug_str
 00000012  ADDR32                     0000001B         A  .debug_str
 0000001E  ADDR32                     00000000         8  .debug_line
 00000022  ADDR32                     00000034         A  .debug_str
 00000027  ADDR32                     0000005D         A  .debug_str
 0000002D  ADDR64            00000000 00000000         0  .text
 00000035  ADDR64            00000000 0000006B         0  .text
 00000040  ADDR32                     0000006B         A  .debug_str
 0000004E  ADDR32                     00000077         A  .debug_str
 0000005D  ADDR32                     00000072         A  .debug_str
 00000077  ADDR32                     0000007C         A  .debug_str
 00000082  ADDR32                     0000008E         A  .debug_str

SECTION HEADER #5
     /30 name (.debug_line)
       0 physical address
       0 virtual address
      53 size of raw data
     317 file pointer to raw data (00000317 to 00000369)
     36A file pointer to relocation table
       0 file pointer to line numbers
       1 number of relocations
       0 number of line numbers
42100000 flags
         Discardable
         1 byte align
         Read Only

RAW DATA #5
  00000000: 4F 00 00 00 02 00 2F 00 00 00 01 01 FB 0E 0D 00  O...../.....û...
  00000010: 01 01 01 01 00 00 00 01 00 00 01 2E 2E 2F 73 72  ............./sr
  00000020: 63 00 00 61 62 6F 72 74 5F 6D 65 73 73 61 67 65  c..abort_message
  00000030: 2E 63 70 70 00 01 00 00 00 00 05 02 00 00 00 00  .cpp............
  00000040: 03 19 01 0A 08 B2 4B 08 F4 03 0C 08 AC 83 02 06  .....²K.ô...¬...
  00000050: 00 01 01                                         ...

RELOCATIONS #5
                                                Symbol    Symbol
 Offset    Type              Applied To         Index     Name
 --------  ----------------  -----------------  --------  ------
 0000003C  ADDR32                     00000000         0  .text


The type "ADDR32" - which mean an absolut 32 bit address  - makes fairly no sense within a 64 bit image. For a quick test, I've manually changed all "ADDR32" to "ADDR32NB" in the object and tried linking again. And even if it makes sense – MS link.exe was happy ;-)

For one of the entries I continued the experiments: Only “ADDR32” fail with LNK2017 and “TOKEN” cause link.exe to crash. All other rel types do not strike the linker.

After searching in the code - here the failure came into effect (even if it’s not clear, if the bug resides here):

unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
                                              const MCFixup &Fixup,
                                              bool IsCrossSection) const {
  unsigned FixupKind = IsCrossSection ? FK_PCRel_4 : Fixup.getKind();

  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();

  switch (FixupKind) {
  case FK_PCRel_4:
  case X86::reloc_riprel_4byte:
  case X86::reloc_riprel_4byte_movq_load:
    return Is64Bit ? COFF::IMAGE_REL_AMD64_REL32 : COFF::IMAGE_REL_I386_REL32;
  case FK_Data_4:
  case X86::reloc_signed_4byte:
    if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
      return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32NB :
                       COFF::IMAGE_REL_I386_DIR32NB;
    return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32 : COFF::IMAGE_REL_I386_DIR32;
  case FK_Data_8:
    if (Is64Bit)
      return COFF::IMAGE_REL_AMD64_ADDR64;
    llvm_unreachable("unsupported relocation type");
  case FK_SecRel_4:
    return Is64Bit ? COFF::IMAGE_REL_AMD64_SECREL : COFF::IMAGE_REL_I386_SECREL;
  default:
    llvm_unreachable("unsupported relocation type");
  }
}

As an example for the ".debug_info" section the variable "FixupKind" get the value "FK_Data_4" => 32 bit.

In

  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();

"Modifier" get "VK_None" in any case, because "SymA" holds also "VK_None".

In

  case X86::reloc_signed_4byte:
    if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
      return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32NB :
                       COFF::IMAGE_REL_I386_DIR32NB;
    return Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32 : COFF::IMAGE_REL_I386_DIR32;

this leads to the wrong "IMAGE_REL_AMD64_ADDR32" is returned.

I'm still not familiar with Dwarf or deply insight this part of llvm, but:
 - if Dwarf can handle image relative 32 bit offsets, then the MCValue "SymA"
   should come in with "VK_COFF_IMGREL32" set.
 - if Dwarf needs an absolut address, then "Kind" in "Fixup" should contain
   "FK_Data_8" (for a 64 bit address).

Now the question is, where is the place to make the segment absolute (to get "ADDR64") or how to make the MCValues relative inside the image (to get out "ADDR32NB")?

Any ideas?

-Werner
Comment 3 Eric Youngdale 2014-12-18 11:11:57 PST
It isn't quite true that using -g on Windows is useless.  Starting with llvm 3.5, the compiler can emit codeview line tables which enables one to have source file/line numbers while debugging.  But the problem is that if you specify "-g", you also get the dwarf symbols, and the dwarf symbols create these linking problems.

For what it is worth, I am seeing similar issues except that there are relocations in the ".debug_frame" section that have ADDR32 relocations.  Same issue - different dwarf section.
Comment 4 vtjnash 2016-04-13 22:34:25 PDT
I've found the following patch makes the dwarf-4 relocations correct:

```
diff -rpu llvm-3.7.1.src/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp llvm-3.7.1/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
--- llvm-3.7.1.src/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp  2015-06-23 05:49:53.000000000 -0400
+++ llvm-3.7.1/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp   2016-02-10 05:06:57.700825100 -0500
@@ -55,6 +55,9 @@ unsigned X86WinCOFFObjectWriter::getRelo
     case X86::reloc_riprel_4byte_movq_load:
       return COFF::IMAGE_REL_AMD64_REL32;
     case FK_Data_4:
+      if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
+        return COFF::IMAGE_REL_AMD64_ADDR32NB;
+      return COFF::IMAGE_REL_AMD64_SECREL;
     case X86::reloc_signed_4byte:
       if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32)
         return COFF::IMAGE_REL_AMD64_ADDR32NB;
```

From looking at the code, I think this may be closer to how the MachO and ELF targets handle this relocation type as well. From looking at the dwarf standard, it seems that this should have been FK_SecRel_4, but I haven't been able to follow this part of the code (or find any documentation on it) to understand where the `.debug_info` section is created by LLVM. I also don't know why IMAGE_REL_AMD64_ADDR32 would ever be required as a relocation type?

(dwarf-2 still seems to be broken, so I can only assume that some of these relocations were supposed to be PCREL32, but I can't find a way to tell which ones. somewhat fortunately, dwarf-4 wants all of the relocations to be SECREL, so it's a bit easier to support.)