llvm.org GIT mirror llvm / 821b06f
Change how symbol sizes are handled in lib/Object. COFF and MachO only define symbol sizes for common symbols. Reflect that in the class hierarchy by having a method for common symbols only in the base and a general one in ELF. This avoids the need of using a magic value for the size, which had a few problems * Most callers didn't check for it. * The ones that did could not tell the magic value from a file actually having that value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240529 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 5 years ago
19 changed file(s) with 90 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
635635 StringRef &Res) const override;
636636 std::error_code getSymbolAddress(DataRefImpl Symb,
637637 uint64_t &Res) const override;
638 uint64_t getSymbolSize(DataRefImpl Symb) const override;
638 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
639639 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
640640 std::error_code getSymbolType(DataRefImpl Symb,
641641 SymbolRef::Type &Res) const override;
5151 virtual uint64_t getSectionFlags(SectionRef Sec) const = 0;
5252 virtual uint32_t getSectionType(SectionRef Sec) const = 0;
5353
54 virtual uint64_t getSymbolSize(SymbolRef Symb) const = 0;
55
5456 static inline bool classof(const Binary *v) { return v->isELF(); }
5557 };
5658
7173 typedef typename ELFFile::Elf_Shdr_Iter Elf_Shdr_Iter;
7274 typedef typename ELFFile::Elf_Dyn_Iter Elf_Dyn_Iter;
7375
76 uint64_t getSymbolSize(SymbolRef Symb) const override;
77
7478 protected:
7579 ELFFile EF;
7680
8084 std::error_code getSymbolAddress(DataRefImpl Symb,
8185 uint64_t &Res) const override;
8286 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
83 uint64_t getSymbolSize(DataRefImpl Symb) const override;
87 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
8488 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
8589 std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override;
8690 std::error_code getSymbolType(DataRefImpl Symb,
276280 switch (EF.getSymbolTableIndex(ESym)) {
277281 case ELF::SHN_COMMON:
278282 case ELF::SHN_UNDEF:
279 Result = UnknownAddressOrSize;
283 Result = UnknownAddress;
280284 return std::error_code();
281285 case ELF::SHN_ABS:
282286 Result = ESym->st_value;
311315 }
312316
313317 template
314 uint64_t ELFObjectFile::getSymbolSize(DataRefImpl Symb) const {
318 uint64_t ELFObjectFile::getSymbolSize(SymbolRef Symb) const {
319 return toELFSymIter(Symb.getRawDataRefImpl())->st_size;
320 }
321
322 template
323 uint64_t ELFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
315324 return toELFSymIter(Symb)->st_size;
316325 }
317326
206206 std::error_code getSymbolAddress(DataRefImpl Symb,
207207 uint64_t &Res) const override;
208208 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
209 uint64_t getSymbolSize(DataRefImpl Symb) const override;
209 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
210210 std::error_code getSymbolType(DataRefImpl Symb,
211211 SymbolRef::Type &Res) const override;
212212 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
140140 std::error_code getAddress(uint64_t &Result) const;
141141 /// @brief Get the alignment of this symbol as the actual value (not log 2).
142142 uint32_t getAlignment() const;
143 uint64_t getSize() const;
143 uint64_t getCommonSize() const;
144144 std::error_code getType(SymbolRef::Type &Result) const;
145145 std::error_code getOther(uint8_t &Result) const;
146146
200200 virtual std::error_code getSymbolAddress(DataRefImpl Symb,
201201 uint64_t &Res) const = 0;
202202 virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
203 virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
203 virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
204204 virtual std::error_code getSymbolType(DataRefImpl Symb,
205205 SymbolRef::Type &Res) const = 0;
206206 virtual std::error_code getSymbolSection(DataRefImpl Symb,
251251 }
252252
253253 public:
254 uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
255 assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
256 return getCommonSymbolSizeImpl(Symb);
257 }
258
254259 typedef iterator_range symbol_iterator_range;
255260 symbol_iterator_range symbols() const {
256261 return symbol_iterator_range(symbol_begin(), symbol_end());
325330 return getObject()->getSymbolAlignment(getRawDataRefImpl());
326331 }
327332
328 inline uint64_t SymbolRef::getSize() const {
329 return getObject()->getSymbolSize(getRawDataRefImpl());
333 inline uint64_t SymbolRef::getCommonSize() const {
334 return getObject()->getCommonSymbolSize(getRawDataRefImpl());
330335 }
331336
332337 inline std::error_code SymbolRef::getSection(section_iterator &Result) const {
114114
115115 typedef content_iterator basic_symbol_iterator;
116116
117 const uint64_t UnknownAddressOrSize = ~0ULL;
117 const uint64_t UnknownAddress = ~0ULL;
118118
119119 class SymbolicFile : public Binary {
120120 public:
117117 if (std::error_code EC = Sym.getAddress(Address))
118118 return EC;
119119
120 if (Address == UnknownAddressOrSize) {
121 Result = UnknownAddressOrSize;
120 if (Address == UnknownAddress) {
121 Result = UnknownAddress;
122122 return std::error_code();
123123 }
124124
128128 return EC;
129129
130130 if (SecI == Obj->section_end()) {
131 Result = UnknownAddressOrSize;
131 Result = UnknownAddress;
132132 return std::error_code();
133133 }
134134
386386 uint32_t Flags = I->getFlags();
387387 if (Flags & SymbolRef::SF_Common) {
388388 // Add the common symbols to a list. We'll allocate them all below.
389 uint64_t Size = I->getSize();
389 uint64_t Size = I->getCommonSize();
390390 CommonSize += Size;
391391 }
392392 }
493493 }
494494
495495 uint32_t Align = Sym.getAlignment();
496 uint64_t Size = Sym.getSize();
496 uint64_t Size = Sym.getCommonSize();
497497
498498 CommonSize += Align + Size;
499499 SymbolsToAllocate.push_back(Sym);
516516 for (auto &Sym : SymbolsToAllocate) {
517517 uint32_t Align = Sym.getAlignment();
518518 StringRef Name;
519 uint64_t Size = Sym.getSize();
519 uint64_t Size = Sym.getCommonSize();
520520 Check(Sym.getName(Name));
521521 if (Align) {
522522 // This symbol has an alignment requirement.
6363 uint64_t RuntimeDyldCOFF::getSymbolOffset(const SymbolRef &Sym) {
6464 uint64_t Address;
6565 if (Sym.getAddress(Address))
66 return UnknownAddressOrSize;
66 return UnknownAddress;
6767
68 if (Address == UnknownAddressOrSize)
69 return UnknownAddressOrSize;
68 if (Address == UnknownAddress)
69 return UnknownAddress;
7070
7171 const ObjectFile *Obj = Sym.getObject();
7272 section_iterator SecI(Obj->section_end());
7373 if (Sym.getSection(SecI))
74 return UnknownAddressOrSize;
74 return UnknownAddress;
7575
7676 if (SecI == Obj->section_end())
77 return UnknownAddressOrSize;
77 return UnknownAddress;
7878
7979 uint64_t SectionAddress = SecI->getAddress();
8080 return Address - SectionAddress;
154154 COFFSymbolRef Symb = getCOFFSymbol(Ref);
155155
156156 if (Symb.isAnyUndefined()) {
157 Result = UnknownAddressOrSize;
157 Result = UnknownAddress;
158158 return std::error_code();
159159 }
160160 if (Symb.isCommon()) {
161 Result = UnknownAddressOrSize;
161 Result = UnknownAddress;
162162 return std::error_code();
163163 }
164164 int32_t SectionNumber = Symb.getSectionNumber();
235235 return Result;
236236 }
237237
238 uint64_t COFFObjectFile::getSymbolSize(DataRefImpl Ref) const {
238 uint64_t COFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Ref) const {
239239 COFFSymbolRef Symb = getCOFFSymbol(Ref);
240
241 if (Symb.isCommon())
242 return Symb.getValue();
243 return UnknownAddressOrSize;
240 return Symb.getValue();
244241 }
245242
246243 std::error_code
374374 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
375375 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
376376 Entry.n_value == 0)
377 Res = UnknownAddressOrSize;
377 Res = UnknownAddress;
378378 else
379379 Res = Entry.n_value;
380380 } else {
381381 MachO::nlist Entry = getSymbolTableEntry(Symb);
382382 if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
383383 Entry.n_value == 0)
384 Res = UnknownAddressOrSize;
384 Res = UnknownAddress;
385385 else
386386 Res = Entry.n_value;
387387 }
397397 return 0;
398398 }
399399
400 uint64_t MachOObjectFile::getSymbolSize(DataRefImpl DRI) const {
400 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
401401 uint64_t Value;
402402 getSymbolAddress(DRI, Value);
403 uint32_t flags = getSymbolFlags(DRI);
404 if (flags & SymbolRef::SF_Common)
405 return Value;
406 return UnknownAddressOrSize;
403 return Value;
407404 }
408405
409406 std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
452449 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
453450 uint64_t Value;
454451 getSymbolAddress(DRI, Value);
455 if (Value && Value != UnknownAddressOrSize)
452 if (Value && Value != UnknownAddress)
456453 Result |= SymbolRef::SF_Common;
457454 }
458455
186186 }
187187
188188 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
189 return (*unwrap(SI))->getSize();
189 return (*unwrap(SI))->getCommonSize();
190190 }
191191
192192 // RelocationRef accessors
4040 llvm::object::computeSymbolSizes(const ObjectFile &O) {
4141 std::vector> Ret;
4242
43 if (isa(&O)) {
44 for (SymbolRef Sym : O.symbols()) {
45 Ret.push_back({Sym, Sym.getSize()});
46 }
43 if (const auto *E = dyn_cast(&O)) {
44 for (SymbolRef Sym : E->symbols())
45 Ret.push_back({Sym, E->getSymbolSize(Sym)});
4746 return Ret;
4847 }
4948
3030
3131 StringRef SymName; SymI->getName(SymName);
3232 uint64_t SymAddr; SymI->getAddress(SymAddr);
33 uint64_t SymSize = SymI->getSize();
3433 auto *Obj = cast(Rel.getObjectFile());
34 uint64_t SymSize = Obj->getSymbolSize(*SymI);
3535 int64_t Addend = *Obj->getRelocationAddend(Rel.getRawDataRefImpl());
3636
3737 MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);
0 // RUN: llvm-mc %s -o %t -filetype=obj -triple=x86_64-pc-linux
1 // RUN: llvm-nm --print-size %t | FileCheck %s
2
3 // CHECK: 0000000000000000 ffffffffffffffff t a
4
5 a:
6 .size a, 0xffffffffffffffff
None config.suffixes = ['.test', '.ll', '.yaml']
0 config.suffixes = ['.test', '.ll', '.s', '.yaml']
159159 // symbol table to find its address as it might not be in the
160160 // debug map (for common symbols).
161161 Value = getMainBinarySymbolAddress(Name);
162 if (Value == UnknownAddressOrSize)
162 if (Value == UnknownAddress)
163163 return;
164164 break;
165165 case MachO::N_FUN:
198198 for (auto Sym : CurrentObjectHolder.Get().symbols()) {
199199 StringRef Name;
200200 uint64_t Addr;
201 if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize ||
202 Sym.getName(Name))
201 if (Sym.getAddress(Addr) || Addr == UnknownAddress || Sym.getName(Name))
203202 continue;
204203 CurrentObjectAddresses[Name] = Addr;
205204 }
211210 uint64_t MachODebugMapParser::getMainBinarySymbolAddress(StringRef Name) {
212211 auto Sym = MainBinarySymbolAddresses.find(Name);
213212 if (Sym == MainBinarySymbolAddresses.end())
214 return UnknownAddressOrSize;
213 return UnknownAddress;
215214 return Sym->second;
216215 }
217216
232231 // are the only ones that need to be queried because the address
233232 // of common data won't be described in the debug map. All other
234233 // addresses should be fetched for the debug map.
235 if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize ||
234 if (Sym.getAddress(Addr) || Addr == UnknownAddress ||
236235 !(Sym.getFlags() & SymbolRef::SF_Global) || Sym.getSection(Section) ||
237236 Section->isText() || Sym.getName(Name) || Name.size() == 0 ||
238237 Name[0] == '\0')
568568 continue;
569569 if ((I->TypeChar == 'U') && DefinedOnly)
570570 continue;
571 if (SizeSort && !PrintAddress && I->Size == UnknownAddressOrSize)
571 if (SizeSort && !PrintAddress)
572572 continue;
573573 if (PrintFileName) {
574574 if (!ArchitectureName.empty())
585585 char SymbolAddrStr[18] = "";
586586 char SymbolSizeStr[18] = "";
587587
588 if (OutputFormat == sysv || I->Address == UnknownAddressOrSize)
588 if (OutputFormat == sysv || I->Address == UnknownAddress)
589589 strcpy(SymbolAddrStr, printBlanks);
590590 if (OutputFormat == sysv)
591591 strcpy(SymbolSizeStr, printBlanks);
592592
593 if (I->Address != UnknownAddressOrSize)
593 if (I->Address != UnknownAddress)
594594 format(printFormat, I->Address)
595595 .print(SymbolAddrStr, sizeof(SymbolAddrStr));
596 if (I->Size != UnknownAddressOrSize)
597 format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
596 format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
598597
599598 // If OutputFormat is darwin or we are printing Mach-O symbols in hex and
600599 // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's
612611 outs() << SymbolAddrStr << ' ';
613612 if (PrintSize) {
614613 outs() << SymbolSizeStr;
615 if (I->Size != UnknownAddressOrSize)
616 outs() << ' ';
614 outs() << ' ';
617615 }
618616 outs() << I->TypeChar;
619617 if (I->TypeChar == '-' && MachO)
929927 if (Nsect && Nsect != getNsectInMachO(*MachO, I))
930928 continue;
931929 NMSymbol S;
932 S.Size = UnknownAddressOrSize;
933 S.Address = UnknownAddressOrSize;
934 if (PrintSize && isa(Obj)) {
935 symbol_iterator SymI = I;
936 S.Size = SymI->getSize();
930 S.Size = 0;
931 S.Address = UnknownAddress;
932 if (PrintSize) {
933 if (auto *E = dyn_cast(&Obj)) {
934 symbol_iterator SymI = I;
935 S.Size = E->getSymbolSize(*SymI);
936 }
937937 }
938938 if (PrintAddress && isa(Obj))
939939 if (error(symbol_iterator(I)->getAddress(S.Address)))
24162416 // for the specified section offset in the specified section reference.
24172417 // If no relocation information is found and a non-zero ReferenceValue for the
24182418 // symbol is passed, look up that address in the info's AddrMap.
2419 static const char *
2420 get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info,
2421 uint64_t &n_value,
2422 uint64_t ReferenceValue = UnknownAddressOrSize) {
2419 static const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
2420 DisassembleInfo *info, uint64_t &n_value,
2421 uint64_t ReferenceValue = UnknownAddress) {
24232422 n_value = 0;
24242423 if (!info->verbose)
24252424 return nullptr;
24532452 const char *SymbolName = nullptr;
24542453 if (reloc_found && isExtern) {
24552454 Symbol.getAddress(n_value);
2456 if (n_value == UnknownAddressOrSize)
2455 if (n_value == UnknownAddress)
24572456 n_value = 0;
24582457 StringRef name;
24592458 Symbol.getName(name);
24742473
24752474 // We did not find an external relocation entry so look up the ReferenceValue
24762475 // as an address of a symbol and if found return that symbol's name.
2477 if (ReferenceValue != UnknownAddressOrSize)
2476 if (ReferenceValue != UnknownAddress)
24782477 SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
24792478
24802479 return SymbolName;
783783 uint64_t Address;
784784 if (error(Symbol.getAddress(Address)))
785785 break;
786 if (Address == UnknownAddressOrSize)
786 if (Address == UnknownAddress)
787787 continue;
788788 Address -= SectionAddr;
789789 if (Address >= SectSize)
11001100 bool Hidden = Flags & SymbolRef::SF_Hidden;
11011101
11021102 if (Common)
1103 Address = Symbol.getSize();
1104
1105 if (Address == UnknownAddressOrSize)
1103 Address = Symbol.getCommonSize();
1104
1105 if (Address == UnknownAddress)
11061106 Address = 0;
11071107 char GlobLoc = ' ';
11081108 if (Type != SymbolRef::ST_Unknown)
11481148
11491149 outs() << '\t';
11501150 if (Common || isa(o)) {
1151 uint64_t Val = Common ? Symbol.getAlignment() : Symbol.getSize();
1151 uint64_t Val = Common ? Symbol.getAlignment()
1152 : cast(o)->getSymbolSize(Symbol);
11521153 outs() << format("\t %08" PRIx64 " ", Val);
11531154 }
11541155
9393 return;
9494 uint64_t SymbolAddress;
9595 if (error(Symbol.getAddress(SymbolAddress)) ||
96 SymbolAddress == UnknownAddressOrSize)
96 SymbolAddress == UnknownAddress)
9797 return;
9898 if (OpdExtractor) {
9999 // For big-endian PowerPC64 ELF, symbols in the .opd section refer to
108108 SymbolAddress = OpdExtractor->getAddress(&OpdOffset32);
109109 }
110110 uint64_t SymbolSize;
111 // Getting symbol size is linear for Mach-O files, so assume that symbol
112 // occupies the memory range up to the following symbol.
113 if (isa(Module))
111 // Onyl ELF has a size for every symbol so assume that symbol occupies the
112 // memory range up to the following symbol.
113 if (auto *E = dyn_cast(Module))
114 SymbolSize = E->getSymbolSize(Symbol);
115 else
114116 SymbolSize = 0;
115 else {
116 SymbolSize = Symbol.getSize();
117 if (SymbolSize == UnknownAddressOrSize)
118 return;
119 }
120117 StringRef SymbolName;
121118 if (error(Symbol.getName(SymbolName)))
122119 return;