|
14 | 14 | #include "llvm/Support/Path.h"
|
15 | 15 | #include "llvm/Support/WithColor.h"
|
16 | 16 | #include "llvm/Support/raw_ostream.h"
|
| 17 | +#include <vector> |
17 | 18 |
|
18 | 19 | namespace {
|
19 | 20 | using namespace llvm;
|
@@ -51,6 +52,8 @@ class MachODebugMapParser {
|
51 | 52 | StringRef MainBinaryStrings;
|
52 | 53 | /// The constructed DebugMap.
|
53 | 54 | std::unique_ptr<DebugMap> Result;
|
| 55 | + /// List of common symbols that need to be added to the debug map. |
| 56 | + std::vector<std::string> CommonSymbols; |
54 | 57 |
|
55 | 58 | /// Map of the currently processed object file symbol addresses.
|
56 | 59 | StringMap<Optional<uint64_t>> CurrentObjectAddresses;
|
@@ -81,6 +84,8 @@ class MachODebugMapParser {
|
81 | 84 | STE.n_value);
|
82 | 85 | }
|
83 | 86 |
|
| 87 | + void addCommonSymbols(); |
| 88 | + |
84 | 89 | /// Dump the symbol table output header.
|
85 | 90 | void dumpSymTabHeader(raw_ostream &OS, StringRef Arch);
|
86 | 91 |
|
@@ -122,11 +127,32 @@ void MachODebugMapParser::resetParserState() {
|
122 | 127 | CurrentDebugMapObject = nullptr;
|
123 | 128 | }
|
124 | 129 |
|
| 130 | +/// Commons symbols won't show up in the symbol map but might need to be |
| 131 | +/// relocated. We can add them to the symbol table ourselves by combining the |
| 132 | +/// information in the object file (the symbol name) and the main binary (the |
| 133 | +/// address). |
| 134 | +void MachODebugMapParser::addCommonSymbols() { |
| 135 | + for (auto &CommonSymbol : CommonSymbols) { |
| 136 | + uint64_t CommonAddr = getMainBinarySymbolAddress(CommonSymbol); |
| 137 | + if (CommonAddr == 0) { |
| 138 | + // The main binary doesn't have an address for the given symbol. |
| 139 | + continue; |
| 140 | + } |
| 141 | + if (!CurrentDebugMapObject->addSymbol(CommonSymbol, None /*ObjectAddress*/, |
| 142 | + CommonAddr, 0 /*size*/)) { |
| 143 | + // The symbol is already present. |
| 144 | + continue; |
| 145 | + } |
| 146 | + } |
| 147 | + CommonSymbols.clear(); |
| 148 | +} |
| 149 | + |
125 | 150 | /// Create a new DebugMapObject. This function resets the state of the
|
126 | 151 | /// parser that was referring to the last object file and sets
|
127 | 152 | /// everything up to add symbols to the new one.
|
128 | 153 | void MachODebugMapParser::switchToNewDebugMapObject(
|
129 | 154 | StringRef Filename, sys::TimePoint<std::chrono::seconds> Timestamp) {
|
| 155 | + addCommonSymbols(); |
130 | 156 | resetParserState();
|
131 | 157 |
|
132 | 158 | SmallString<80> Path(PathPrefix);
|
@@ -466,10 +492,15 @@ void MachODebugMapParser::loadCurrentObjectFileSymbols(
|
466 | 492 | // relocations will use the symbol itself, and won't need an
|
467 | 493 | // object file address. The object file address field is optional
|
468 | 494 | // in the DebugMap, leave it unassigned for these symbols.
|
469 |
| - if (Sym.getFlags() & (SymbolRef::SF_Absolute | SymbolRef::SF_Common)) |
| 495 | + uint32_t Flags = Sym.getFlags(); |
| 496 | + if (Flags & SymbolRef::SF_Absolute) { |
470 | 497 | CurrentObjectAddresses[*Name] = None;
|
471 |
| - else |
| 498 | + } else if (Flags & SymbolRef::SF_Common) { |
| 499 | + CurrentObjectAddresses[*Name] = None; |
| 500 | + CommonSymbols.push_back(*Name); |
| 501 | + } else { |
472 | 502 | CurrentObjectAddresses[*Name] = Addr;
|
| 503 | + } |
473 | 504 | }
|
474 | 505 | }
|
475 | 506 |
|
|
0 commit comments