Re-land "[dsymutil] Fix handling of common symbols in multiple object files."
The original patch got reverted because it hit a long-standing legacy issue on Windows that prevents files from being named `com`. Thanks Kristina & Jeremy for pointing this out. llvm-svn: 374178
This commit is contained in:
		
							parent
							
								
									7faa14a98b
								
							
						
					
					
						commit
						e7affcdbd2
					
				
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -f -o - | llvm-dwarfdump -debug-info - | FileCheck %s
 | 
				
			||||||
 | 
					RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/common/common.x86_64 -dump-debug-map | FileCheck %s --check-prefix DEBUGMAP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The test was compiled from two source files:
 | 
				
			||||||
 | 
					$ cd /private/tmp/common
 | 
				
			||||||
 | 
					$ cat common1.c
 | 
				
			||||||
 | 
					int i[1000];
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					  return i[1];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					$ cat common2.c
 | 
				
			||||||
 | 
					extern int i[1000];
 | 
				
			||||||
 | 
					int bar() {
 | 
				
			||||||
 | 
					  return i[0];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					$ clang -fcommon -g -c common1.c -o common1.o
 | 
				
			||||||
 | 
					$ clang -fcommon -g -c common2.c -o common2.o
 | 
				
			||||||
 | 
					$ clang -fcommon -g common1.o common2.o -o common.x86_64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CHECK: DW_TAG_compile_unit
 | 
				
			||||||
 | 
					CHECK:   DW_TAG_variable
 | 
				
			||||||
 | 
					CHECK-NOT: {{NULL|DW_TAG}}
 | 
				
			||||||
 | 
					CHECK:     DW_AT_name{{.*}}"i"
 | 
				
			||||||
 | 
					CHECK-NOT: {{NULL|DW_TAG}}
 | 
				
			||||||
 | 
					CHECK:     DW_AT_location{{.*}}DW_OP_addr 0x100001000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CHECK: DW_TAG_compile_unit
 | 
				
			||||||
 | 
					CHECK:   DW_TAG_variable
 | 
				
			||||||
 | 
					CHECK-NOT: {{NULL|DW_TAG}}
 | 
				
			||||||
 | 
					CHECK:     DW_AT_name{{.*}}"i"
 | 
				
			||||||
 | 
					CHECK-NOT: {{NULL|DW_TAG}}
 | 
				
			||||||
 | 
					CHECK:     DW_AT_location{{.*}}DW_OP_addr 0x100001000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEBUGMAP: filename:{{.*}}common1.o
 | 
				
			||||||
 | 
					DEBUGMAP: symbols:
 | 
				
			||||||
 | 
					DEBUGMAP: sym: _i, binAddr: 0x0000000100001000, size: 0x00000000
 | 
				
			||||||
 | 
					DEBUGMAP: filename:{{.*}}common2.o
 | 
				
			||||||
 | 
					DEBUGMAP: symbols:
 | 
				
			||||||
 | 
					DEBUGMAP: sym: _i, binAddr: 0x0000000100001000, size: 0x00000000
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
#include "llvm/Support/Path.h"
 | 
					#include "llvm/Support/Path.h"
 | 
				
			||||||
#include "llvm/Support/WithColor.h"
 | 
					#include "llvm/Support/WithColor.h"
 | 
				
			||||||
#include "llvm/Support/raw_ostream.h"
 | 
					#include "llvm/Support/raw_ostream.h"
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
using namespace llvm;
 | 
					using namespace llvm;
 | 
				
			||||||
| 
						 | 
					@ -51,6 +52,8 @@ private:
 | 
				
			||||||
  StringRef MainBinaryStrings;
 | 
					  StringRef MainBinaryStrings;
 | 
				
			||||||
  /// The constructed DebugMap.
 | 
					  /// The constructed DebugMap.
 | 
				
			||||||
  std::unique_ptr<DebugMap> Result;
 | 
					  std::unique_ptr<DebugMap> Result;
 | 
				
			||||||
 | 
					  /// List of common symbols that need to be added to the debug map.
 | 
				
			||||||
 | 
					  std::vector<std::string> CommonSymbols;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Map of the currently processed object file symbol addresses.
 | 
					  /// Map of the currently processed object file symbol addresses.
 | 
				
			||||||
  StringMap<Optional<uint64_t>> CurrentObjectAddresses;
 | 
					  StringMap<Optional<uint64_t>> CurrentObjectAddresses;
 | 
				
			||||||
| 
						 | 
					@ -81,6 +84,8 @@ private:
 | 
				
			||||||
                               STE.n_value);
 | 
					                               STE.n_value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void addCommonSymbols();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Dump the symbol table output header.
 | 
					  /// Dump the symbol table output header.
 | 
				
			||||||
  void dumpSymTabHeader(raw_ostream &OS, StringRef Arch);
 | 
					  void dumpSymTabHeader(raw_ostream &OS, StringRef Arch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,11 +127,32 @@ void MachODebugMapParser::resetParserState() {
 | 
				
			||||||
  CurrentDebugMapObject = nullptr;
 | 
					  CurrentDebugMapObject = nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Commons symbols won't show up in the symbol map but might need to be
 | 
				
			||||||
 | 
					/// relocated. We can add them to the symbol table ourselves by combining the
 | 
				
			||||||
 | 
					/// information in the object file (the symbol name) and the main binary (the
 | 
				
			||||||
 | 
					/// address).
 | 
				
			||||||
 | 
					void MachODebugMapParser::addCommonSymbols() {
 | 
				
			||||||
 | 
					  for (auto &CommonSymbol : CommonSymbols) {
 | 
				
			||||||
 | 
					    uint64_t CommonAddr = getMainBinarySymbolAddress(CommonSymbol);
 | 
				
			||||||
 | 
					    if (CommonAddr == 0) {
 | 
				
			||||||
 | 
					      // The main binary doesn't have an address for the given symbol.
 | 
				
			||||||
 | 
					      continue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!CurrentDebugMapObject->addSymbol(CommonSymbol, None /*ObjectAddress*/,
 | 
				
			||||||
 | 
					                                          CommonAddr, 0 /*size*/)) {
 | 
				
			||||||
 | 
					      // The symbol is already present.
 | 
				
			||||||
 | 
					      continue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  CommonSymbols.clear();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Create a new DebugMapObject. This function resets the state of the
 | 
					/// Create a new DebugMapObject. This function resets the state of the
 | 
				
			||||||
/// parser that was referring to the last object file and sets
 | 
					/// parser that was referring to the last object file and sets
 | 
				
			||||||
/// everything up to add symbols to the new one.
 | 
					/// everything up to add symbols to the new one.
 | 
				
			||||||
void MachODebugMapParser::switchToNewDebugMapObject(
 | 
					void MachODebugMapParser::switchToNewDebugMapObject(
 | 
				
			||||||
    StringRef Filename, sys::TimePoint<std::chrono::seconds> Timestamp) {
 | 
					    StringRef Filename, sys::TimePoint<std::chrono::seconds> Timestamp) {
 | 
				
			||||||
 | 
					  addCommonSymbols();
 | 
				
			||||||
  resetParserState();
 | 
					  resetParserState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SmallString<80> Path(PathPrefix);
 | 
					  SmallString<80> Path(PathPrefix);
 | 
				
			||||||
| 
						 | 
					@ -466,10 +492,15 @@ void MachODebugMapParser::loadCurrentObjectFileSymbols(
 | 
				
			||||||
    // relocations will use the symbol itself, and won't need an
 | 
					    // relocations will use the symbol itself, and won't need an
 | 
				
			||||||
    // object file address. The object file address field is optional
 | 
					    // object file address. The object file address field is optional
 | 
				
			||||||
    // in the DebugMap, leave it unassigned for these symbols.
 | 
					    // in the DebugMap, leave it unassigned for these symbols.
 | 
				
			||||||
    if (Sym.getFlags() & (SymbolRef::SF_Absolute | SymbolRef::SF_Common))
 | 
					    uint32_t Flags = Sym.getFlags();
 | 
				
			||||||
 | 
					    if (Flags & SymbolRef::SF_Absolute) {
 | 
				
			||||||
      CurrentObjectAddresses[*Name] = None;
 | 
					      CurrentObjectAddresses[*Name] = None;
 | 
				
			||||||
    else
 | 
					    } else if (Flags & SymbolRef::SF_Common) {
 | 
				
			||||||
 | 
					      CurrentObjectAddresses[*Name] = None;
 | 
				
			||||||
 | 
					      CommonSymbols.push_back(*Name);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
      CurrentObjectAddresses[*Name] = Addr;
 | 
					      CurrentObjectAddresses[*Name] = Addr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue