llvm.org GIT mirror llvm / bc884fd
move getSymbolNMTypeChar to the one program that needs it: nm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193933 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
7 changed file(s) with 226 addition(s) and 192 deletion(s). Raw diff Collapse all Expand all
245245 virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
246246 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
247247 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
248 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
249248 virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
250249 virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
251250 virtual error_code getSymbolSection(DataRefImpl Symb,
6060 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
6161 virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
6262 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
63 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
6463 virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
6564 virtual error_code getSymbolType(DataRefImpl Symb,
6665 SymbolRef::Type &Res) const;
103102 getRelocationValueString(DataRefImpl Rel,
104103 SmallVectorImpl &Result) const;
105104
106 protected: // ELF specific protected members.
107 const Elf_Sym *getSymbol(DataRefImpl Symb) const;
108105 uint64_t getROffset(DataRefImpl Rel) const;
109106 StringRef getRelocationTypeName(uint32_t Type) const;
110107
168165
169166 public:
170167 ELFObjectFile(MemoryBuffer *Object, error_code &ec);
168
169 const Elf_Sym *getSymbol(DataRefImpl Symb) const;
171170
172171 virtual symbol_iterator begin_symbols() const;
173172 virtual symbol_iterator end_symbols() const;
334333 error_code ELFObjectFile::getSymbolSize(DataRefImpl Symb,
335334 uint64_t &Result) const {
336335 Result = toELFSymIter(Symb)->st_size;
337 return object_error::success;
338 }
339
340 template
341 error_code ELFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,
342 char &Result) const {
343 const Elf_Sym *ESym = getSymbol(Symb);
344 const Elf_Shdr *ESec = EF.getSection(ESym);
345
346 char ret = '?';
347
348 if (ESec) {
349 switch (ESec->sh_type) {
350 case ELF::SHT_PROGBITS:
351 case ELF::SHT_DYNAMIC:
352 switch (ESec->sh_flags) {
353 case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
354 ret = 't';
355 break;
356 case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
357 ret = 'd';
358 break;
359 case ELF::SHF_ALLOC:
360 case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
361 case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
362 ret = 'r';
363 break;
364 }
365 break;
366 case ELF::SHT_NOBITS:
367 ret = 'b';
368 }
369 }
370
371 switch (EF.getSymbolTableIndex(ESym)) {
372 case ELF::SHN_UNDEF:
373 if (ret == '?')
374 ret = 'U';
375 break;
376 case ELF::SHN_ABS:
377 ret = 'a';
378 break;
379 case ELF::SHN_COMMON:
380 ret = 'c';
381 break;
382 }
383
384 switch (ESym->getBinding()) {
385 case ELF::STB_GLOBAL:
386 ret = ::toupper(ret);
387 break;
388 case ELF::STB_WEAK:
389 if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF)
390 ret = 'w';
391 else if (ESym->getType() == ELF::STT_OBJECT)
392 ret = 'V';
393 else
394 ret = 'W';
395 }
396
397 if (ret == '?' && ESym->getType() == ELF::STT_SECTION) {
398 ErrorOr Name = EF.getSymbolName(toELFSymIter(Symb));
399 if (!Name)
400 return Name;
401 Result = StringSwitch(*Name)
402 .StartsWith(".debug", 'N')
403 .StartsWith(".note", 'n')
404 .Default('?');
405 return object_error::success;
406 }
407
408 Result = ret;
409336 return object_error::success;
410337 }
411338
6666 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
6767 virtual error_code getSymbolType(DataRefImpl Symb,
6868 SymbolRef::Type &Res) const;
69 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
7069 virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
7170 virtual error_code getSymbolSection(DataRefImpl Symb,
7271 section_iterator &Res) const;
219219 error_code getAlignment(uint32_t &Result) const;
220220 error_code getSize(uint64_t &Result) const;
221221 error_code getType(SymbolRef::Type &Result) const;
222
223 /// Returns the ascii char that should be displayed in a symbol table dump via
224 /// nm for this symbol.
225 error_code getNMTypeChar(char &Result) const;
226222
227223 /// Get symbol flags (bitwise OR of SymbolRef::Flags)
228224 error_code getFlags(uint32_t &Result) const;
295291 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
296292 virtual error_code getSymbolType(DataRefImpl Symb,
297293 SymbolRef::Type &Res) const = 0;
298 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
299294 virtual error_code getSymbolFlags(DataRefImpl Symb,
300295 uint32_t &Res) const = 0;
301296 virtual error_code getSymbolSection(DataRefImpl Symb,
430425 return OwningObject->getSymbolSize(SymbolPimpl, Result);
431426 }
432427
433 inline error_code SymbolRef::getNMTypeChar(char &Result) const {
434 return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
435 }
436
437428 inline error_code SymbolRef::getFlags(uint32_t &Result) const {
438429 return OwningObject->getSymbolFlags(SymbolPimpl, Result);
439430 }
203203 Result = Section->SizeOfRawData - symb->Value;
204204 else
205205 Result = 0;
206 return object_error::success;
207 }
208
209 error_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,
210 char &Result) const {
211 const coff_symbol *symb = toSymb(Symb);
212 StringRef name;
213 if (error_code ec = getSymbolName(Symb, name))
214 return ec;
215 char ret = StringSwitch(name)
216 .StartsWith(".debug", 'N')
217 .StartsWith(".sxdata", 'N')
218 .Default('?');
219
220 if (ret != '?') {
221 Result = ret;
222 return object_error::success;
223 }
224
225 uint32_t Characteristics = 0;
226 if (symb->SectionNumber > 0) {
227 const coff_section *Section = NULL;
228 if (error_code ec = getSection(symb->SectionNumber, Section))
229 return ec;
230 Characteristics = Section->Characteristics;
231 }
232
233 switch (symb->SectionNumber) {
234 case COFF::IMAGE_SYM_UNDEFINED:
235 // Check storage classes.
236 if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) {
237 Result = 'w';
238 return object_error::success; // Don't do ::toupper.
239 } else if (symb->Value != 0) // Check for common symbols.
240 ret = 'c';
241 else
242 ret = 'u';
243 break;
244 case COFF::IMAGE_SYM_ABSOLUTE:
245 ret = 'a';
246 break;
247 case COFF::IMAGE_SYM_DEBUG:
248 ret = 'n';
249 break;
250 default:
251 // Check section type.
252 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
253 ret = 't';
254 else if ( Characteristics & COFF::IMAGE_SCN_MEM_READ
255 && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
256 ret = 'r';
257 else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
258 ret = 'd';
259 else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
260 ret = 'b';
261 else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
262 ret = 'i';
263
264 // Check for section symbol.
265 else if ( symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
266 && symb->Value == 0)
267 ret = 's';
268 }
269
270 if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
271 ret = ::toupper(static_cast(ret));
272
273 Result = ret;
274206 return object_error::success;
275207 }
276208
587587 Res = SymbolRef::ST_Function;
588588 break;
589589 }
590 return object_error::success;
591 }
592
593 error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,
594 char &Res) const {
595 nlist_base Entry = getSymbolTableEntryBase(this, Symb);
596 uint8_t NType = Entry.n_type;
597
598 char Char;
599 switch (NType & MachO::N_TYPE) {
600 case MachO::N_UNDF:
601 Char = 'u';
602 break;
603 case MachO::N_ABS:
604 Char = 's';
605 break;
606 case MachO::N_SECT: {
607 section_iterator Sec = end_sections();
608 getSymbolSection(Symb, Sec);
609 DataRefImpl Ref = Sec->getRawDataRefImpl();
610 StringRef SectionName;
611 getSectionName(Ref, SectionName);
612 StringRef SegmentName = getSectionFinalSegmentName(Ref);
613 if (SegmentName == "__TEXT" && SectionName == "__text")
614 Char = 't';
615 else
616 Char = 's';
617 }
618 break;
619 default:
620 Char = '?';
621 break;
622 }
623
624 if (NType & (MachO::N_EXT | MachO::N_PEXT))
625 Char = toupper(static_cast(Char));
626 Res = Char;
627590 return object_error::success;
628591 }
629592
1919 #include "llvm/Bitcode/ReaderWriter.h"
2020 #include "llvm/IR/Module.h"
2121 #include "llvm/Object/Archive.h"
22 #include "llvm/Object/COFF.h"
23 #include "llvm/Object/ELFObjectFile.h"
24 #include "llvm/Object/MachO.h"
2225 #include "llvm/Object/MachOUniversal.h"
2326 #include "llvm/Object/ObjectFile.h"
2427 #include "llvm/Support/CommandLine.h"
302305 SortAndPrintSymbolList();
303306 }
304307
308 template
309 error_code getSymbolNMTypeChar(ELFObjectFile &Obj, symbol_iterator I,
310 char &Result) {
311 typedef typename ELFObjectFile::Elf_Sym Elf_Sym;
312 typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr;
313
314 DataRefImpl Symb = I->getRawDataRefImpl();
315 const Elf_Sym *ESym = Obj.getSymbol(Symb);
316 const ELFFile &EF = *Obj.getELFFile();
317 const Elf_Shdr *ESec = EF.getSection(ESym);
318
319 char ret = '?';
320
321 if (ESec) {
322 switch (ESec->sh_type) {
323 case ELF::SHT_PROGBITS:
324 case ELF::SHT_DYNAMIC:
325 switch (ESec->sh_flags) {
326 case(ELF::SHF_ALLOC | ELF::SHF_EXECINSTR) :
327 ret = 't';
328 break;
329 case(ELF::SHF_ALLOC | ELF::SHF_WRITE) :
330 ret = 'd';
331 break;
332 case ELF::SHF_ALLOC:
333 case(ELF::SHF_ALLOC | ELF::SHF_MERGE) :
334 case(ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS) :
335 ret = 'r';
336 break;
337 }
338 break;
339 case ELF::SHT_NOBITS:
340 ret = 'b';
341 }
342 }
343
344 switch (EF.getSymbolTableIndex(ESym)) {
345 case ELF::SHN_UNDEF:
346 if (ret == '?')
347 ret = 'U';
348 break;
349 case ELF::SHN_ABS:
350 ret = 'a';
351 break;
352 case ELF::SHN_COMMON:
353 ret = 'c';
354 break;
355 }
356
357 switch (ESym->getBinding()) {
358 case ELF::STB_GLOBAL:
359 ret = ::toupper(ret);
360 break;
361 case ELF::STB_WEAK:
362 if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF)
363 ret = 'w';
364 else if (ESym->getType() == ELF::STT_OBJECT)
365 ret = 'V';
366 else
367 ret = 'W';
368 }
369
370 if (ret == '?' && ESym->getType() == ELF::STT_SECTION) {
371 StringRef Name;
372 error_code EC = I->getName(Name);
373 if (EC)
374 return EC;
375 Result = StringSwitch(Name)
376 .StartsWith(".debug", 'N')
377 .StartsWith(".note", 'n')
378 .Default('?');
379 return object_error::success;
380 }
381
382 Result = ret;
383 return object_error::success;
384 }
385
386 static error_code getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I,
387 char &Result) {
388 const coff_symbol *symb = Obj.getCOFFSymbol(I);
389 StringRef name;
390 if (error_code ec = I->getName(name))
391 return ec;
392 char ret = StringSwitch(name)
393 .StartsWith(".debug", 'N')
394 .StartsWith(".sxdata", 'N')
395 .Default('?');
396
397 if (ret != '?') {
398 Result = ret;
399 return object_error::success;
400 }
401
402 uint32_t Characteristics = 0;
403 if (symb->SectionNumber > 0) {
404 section_iterator SecI = Obj.end_sections();
405 if (error_code ec = I->getSection(SecI))
406 return ec;
407 const coff_section *Section = Obj.getCOFFSection(SecI);
408 Characteristics = Section->Characteristics;
409 }
410
411 switch (symb->SectionNumber) {
412 case COFF::IMAGE_SYM_UNDEFINED:
413 // Check storage classes.
414 if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) {
415 Result = 'w';
416 return object_error::success; // Don't do ::toupper.
417 } else if (symb->Value != 0) // Check for common symbols.
418 ret = 'c';
419 else
420 ret = 'u';
421 break;
422 case COFF::IMAGE_SYM_ABSOLUTE:
423 ret = 'a';
424 break;
425 case COFF::IMAGE_SYM_DEBUG:
426 ret = 'n';
427 break;
428 default:
429 // Check section type.
430 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
431 ret = 't';
432 else if (Characteristics & COFF::IMAGE_SCN_MEM_READ &&
433 ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
434 ret = 'r';
435 else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
436 ret = 'd';
437 else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
438 ret = 'b';
439 else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
440 ret = 'i';
441
442 // Check for section symbol.
443 else if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC &&
444 symb->Value == 0)
445 ret = 's';
446 }
447
448 if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
449 ret = ::toupper(static_cast(ret));
450
451 Result = ret;
452 return object_error::success;
453 }
454
455 static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) {
456 if (Obj.is64Bit()) {
457 MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
458 return STE.n_type;
459 }
460 MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
461 return STE.n_type;
462 }
463
464 static error_code getSymbolNMTypeChar(MachOObjectFile &Obj, symbol_iterator I,
465 char &Res) {
466 DataRefImpl Symb = I->getRawDataRefImpl();
467 uint8_t NType = getNType(Obj, Symb);
468
469 char Char;
470 switch (NType & MachO::N_TYPE) {
471 case MachO::N_UNDF:
472 Char = 'u';
473 break;
474 case MachO::N_ABS:
475 Char = 's';
476 break;
477 case MachO::N_SECT: {
478 section_iterator Sec = Obj.end_sections();
479 Obj.getSymbolSection(Symb, Sec);
480 DataRefImpl Ref = Sec->getRawDataRefImpl();
481 StringRef SectionName;
482 Obj.getSectionName(Ref, SectionName);
483 StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref);
484 if (SegmentName == "__TEXT" && SectionName == "__text")
485 Char = 't';
486 else
487 Char = 's';
488 } break;
489 default:
490 Char = '?';
491 break;
492 }
493
494 if (NType & (MachO::N_EXT | MachO::N_PEXT))
495 Char = toupper(static_cast(Char));
496 Res = Char;
497 return object_error::success;
498 }
499
500 static char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) {
501 char Res = '?';
502 if (COFFObjectFile *COFF = dyn_cast(Obj)) {
503 error(getSymbolNMTypeChar(*COFF, I, Res));
504 return Res;
505 }
506 if (MachOObjectFile *MachO = dyn_cast(Obj)) {
507 error(getSymbolNMTypeChar(*MachO, I, Res));
508 return Res;
509 }
510
511 if (ELF32LEObjectFile *ELF = dyn_cast(Obj)) {
512 error(getSymbolNMTypeChar(*ELF, I, Res));
513 return Res;
514 }
515 if (ELF64LEObjectFile *ELF = dyn_cast(Obj)) {
516 error(getSymbolNMTypeChar(*ELF, I, Res));
517 return Res;
518 }
519 if (ELF32BEObjectFile *ELF = dyn_cast(Obj)) {
520 error(getSymbolNMTypeChar(*ELF, I, Res));
521 return Res;
522 }
523 ELF64BEObjectFile *ELF = cast(Obj);
524 error(getSymbolNMTypeChar(*ELF, I, Res));
525 return Res;
526 }
527
305528 static void DumpSymbolNamesFromObject(ObjectFile *obj) {
306529 error_code ec;
307530 symbol_iterator ibegin = obj->begin_symbols();
324547 }
325548 if (PrintAddress)
326549 if (error(i->getAddress(s.Address))) break;
327 if (error(i->getNMTypeChar(s.TypeChar))) break;
550 s.TypeChar = getNMTypeChar(obj, i);
328551 if (error(i->getName(s.Name))) break;
329552 SymbolList.push_back(s);
330553 }