[llvm] r220952 - Object, COFF: Cleanup symbol type code, improve binutils compatibility
David Majnemer
david.majnemer at gmail.com
Thu Oct 30 22:07:01 PDT 2014
Author: majnemer
Date: Fri Oct 31 00:07:00 2014
New Revision: 220952
URL: http://llvm.org/viewvc/llvm-project?rev=220952&view=rev
Log:
Object, COFF: Cleanup symbol type code, improve binutils compatibility
Do a better job classifying symbols. This increases the consistency
between the COFF handling code and the ELF side of things.
Modified:
llvm/trunk/include/llvm/Object/COFF.h
llvm/trunk/lib/Object/COFFObjectFile.cpp
llvm/trunk/test/Object/coff-archive-short.test
llvm/trunk/test/Object/coff-archive.test
llvm/trunk/test/Object/nm-archive.test
llvm/trunk/test/Object/nm-trivial-object.test
llvm/trunk/tools/llvm-nm/llvm-nm.cpp
llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
llvm/trunk/tools/obj2yaml/coff2yaml.cpp
Modified: llvm/trunk/include/llvm/Object/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/COFF.h?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/COFF.h (original)
+++ llvm/trunk/include/llvm/Object/COFF.h Fri Oct 31 00:07:00 2014
@@ -301,9 +301,26 @@ public:
uint8_t getComplexType() const { return (getType() & 0xF0) >> 4; }
+ bool isExternal() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
+ }
+
+ bool isCommon() const {
+ return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
+ getValue() != 0;
+ }
+
+ bool isUndefined() const {
+ return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
+ getValue() == 0;
+ }
+
+ bool isWeakExternal() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
+ }
+
bool isFunctionDefinition() const {
- return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
+ return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
!COFF::isReservedSectionNumber(getSectionNumber());
}
@@ -312,10 +329,8 @@ public:
return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION;
}
- bool isWeakExternal() const {
- return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
- (getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED && getValue() == 0);
+ bool isAnyUndefined() const {
+ return isUndefined() || isWeakExternal();
}
bool isFileRecord() const {
@@ -329,6 +344,8 @@ public:
getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE;
bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC;
+ if (!getNumberOfAuxSymbols())
+ return false;
return isAppdomainGlobal || isOrdinarySection;
}
Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cpp?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/lib/Object/COFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/COFFObjectFile.cpp Fri Oct 31 00:07:00 2014
@@ -147,39 +147,54 @@ std::error_code COFFObjectFile::getSymbo
std::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref,
uint64_t &Result) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
- const coff_section *Section = nullptr;
- if (std::error_code EC = getSection(Symb.getSectionNumber(), Section))
- return EC;
- if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED)
+ if (Symb.isAnyUndefined()) {
Result = UnknownAddressOrSize;
- else if (Section)
+ return object_error::success;
+ }
+ if (Symb.isCommon()) {
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
+ int32_t SectionNumber = Symb.getSectionNumber();
+ if (!COFF::isReservedSectionNumber(SectionNumber)) {
+ const coff_section *Section = nullptr;
+ if (std::error_code EC = getSection(SectionNumber, Section))
+ return EC;
+
Result = Section->VirtualAddress + Symb.getValue();
- else
- Result = Symb.getValue();
+ return object_error::success;
+ }
+
+ Result = Symb.getValue();
return object_error::success;
}
std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
SymbolRef::Type &Result) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
+ int32_t SectionNumber = Symb.getSectionNumber();
Result = SymbolRef::ST_Other;
- if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) {
+ if (Symb.isAnyUndefined()) {
Result = SymbolRef::ST_Unknown;
} else if (Symb.isFunctionDefinition()) {
Result = SymbolRef::ST_Function;
- } else {
- uint32_t Characteristics = 0;
- if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) {
- const coff_section *Section = nullptr;
- if (std::error_code EC = getSection(Symb.getSectionNumber(), Section))
- return EC;
- Characteristics = Section->Characteristics;
- }
- if (Characteristics & COFF::IMAGE_SCN_MEM_READ &&
- ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
+ } else if (Symb.isCommon()) {
+ Result = SymbolRef::ST_Data;
+ } else if (Symb.isFileRecord()) {
+ Result = SymbolRef::ST_File;
+ } else if (SectionNumber == COFF::IMAGE_SYM_DEBUG) {
+ Result = SymbolRef::ST_Debug;
+ } else if (!COFF::isReservedSectionNumber(SectionNumber)) {
+ const coff_section *Section = nullptr;
+ if (std::error_code EC = getSection(SectionNumber, Section))
+ return EC;
+ uint32_t Characteristics = Section->Characteristics;
+ if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
+ Result = SymbolRef::ST_Function;
+ else if (Characteristics & (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA))
Result = SymbolRef::ST_Data;
}
return object_error::success;
@@ -189,50 +204,66 @@ uint32_t COFFObjectFile::getSymbolFlags(
COFFSymbolRef Symb = getCOFFSymbol(Ref);
uint32_t Result = SymbolRef::SF_None;
- // TODO: Correctly set SF_FormatSpecific, SF_Common
-
- if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) {
- if (Symb.getValue() == 0)
- Result |= SymbolRef::SF_Undefined;
- else
- Result |= SymbolRef::SF_Common;
- }
-
-
- // TODO: This are certainly too restrictive.
- if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL)
+ if (Symb.isExternal() || Symb.isWeakExternal())
Result |= SymbolRef::SF_Global;
- if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
+ if (Symb.isWeakExternal())
Result |= SymbolRef::SF_Weak;
if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE)
Result |= SymbolRef::SF_Absolute;
+ if (Symb.isFileRecord())
+ Result |= SymbolRef::SF_FormatSpecific;
+
+ if (Symb.isSectionDefinition())
+ Result |= SymbolRef::SF_FormatSpecific;
+
+ if (Symb.isCommon())
+ Result |= SymbolRef::SF_Common;
+
+ if (Symb.isAnyUndefined())
+ Result |= SymbolRef::SF_Undefined;
+
return Result;
}
std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
uint64_t &Result) const {
+ COFFSymbolRef Symb = getCOFFSymbol(Ref);
+
+ if (Symb.isAnyUndefined()) {
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
+ if (Symb.isCommon()) {
+ Result = Symb.getValue();
+ return object_error::success;
+ }
+ if (Symb.isFunctionDefinition()) {
+ ArrayRef<uint8_t> AuxData = getSymbolAuxData(Symb);
+ if (!AuxData.empty()) {
+ const auto *CAFD =
+ reinterpret_cast<const coff_aux_function_definition *>(
+ AuxData.data());
+ Result = CAFD->TotalSize;
+ return object_error::success;
+ }
+ }
// FIXME: Return the correct size. This requires looking at all the symbols
// in the same section as this symbol, and looking for either the next
// symbol, or the end of the section.
- COFFSymbolRef Symb = getCOFFSymbol(Ref);
- const coff_section *Section = nullptr;
- if (std::error_code EC = getSection(Symb.getSectionNumber(), Section))
- return EC;
-
- if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) {
- if (Symb.getValue() == 0)
- Result = UnknownAddressOrSize;
- else
- Result = Symb.getValue();
- } else if (Section) {
+ int32_t SectionNumber = Symb.getSectionNumber();
+ if (!COFF::isReservedSectionNumber(SectionNumber)) {
+ const coff_section *Section = nullptr;
+ if (std::error_code EC = getSection(SectionNumber, Section))
+ return EC;
+
Result = Section->SizeOfRawData - Symb.getValue();
- } else {
- Result = 0;
+ return object_error::success;
}
+ Result = 0;
return object_error::success;
}
Modified: llvm/trunk/test/Object/coff-archive-short.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/coff-archive-short.test?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/test/Object/coff-archive-short.test (original)
+++ llvm/trunk/test/Object/coff-archive-short.test Fri Oct 31 00:07:00 2014
@@ -5,7 +5,7 @@
# than 15 characters, thus, unlike coff_archive.lib, it has no string
# table as the third member.
#
-RUN: llvm-nm --numeric-sort -M %p/Inputs/coff_archive_short.lib | FileCheck -check-prefix=CHECKIDX %s
+RUN: llvm-nm -a --numeric-sort -M %p/Inputs/coff_archive_short.lib | FileCheck -check-prefix=CHECKIDX %s
CHECKIDX: Archive map
CHECKIDX: _shortfn1 in short1.obj
Modified: llvm/trunk/test/Object/coff-archive.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/coff-archive.test?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/test/Object/coff-archive.test (original)
+++ llvm/trunk/test/Object/coff-archive.test Fri Oct 31 00:07:00 2014
@@ -1,7 +1,7 @@
#
# Check if the index is appearing properly in the output file
#
-RUN: llvm-nm --numeric-sort -M %p/Inputs/coff_archive.lib | FileCheck -check-prefix=CHECKIDX %s
+RUN: llvm-nm -a --numeric-sort -M %p/Inputs/coff_archive.lib | FileCheck -check-prefix=CHECKIDX %s
CHECKIDX: Archive map
CHECKIDX: ??0invalid_argument at std@@QAE at PBD@Z in Debug\mymath.obj
Modified: llvm/trunk/test/Object/nm-archive.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/nm-archive.test?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/test/Object/nm-archive.test (original)
+++ llvm/trunk/test/Object/nm-archive.test Fri Oct 31 00:07:00 2014
@@ -1,4 +1,4 @@
-RUN: llvm-nm %p/Inputs/archive-test.a-coff-i386 \
+RUN: llvm-nm -a %p/Inputs/archive-test.a-coff-i386 \
RUN: | FileCheck %s -check-prefix COFF
COFF: trivial-object-test.coff-i386:
@@ -9,7 +9,7 @@ COFF-NEXT: U _SomeOtherFunction
COFF-NEXT: 00000000 T _main
COFF-NEXT: U _puts
-RUN: llvm-nm -o %p/Inputs/archive-test.a-coff-i386 \
+RUN: llvm-nm -a -o %p/Inputs/archive-test.a-coff-i386 \
RUN: | FileCheck %s -check-prefix COFF-o
COFF-o: {{.*}}/archive-test.a-coff-i386:trivial-object-test.coff-i386: 00000000 d .data
Modified: llvm/trunk/test/Object/nm-trivial-object.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/nm-trivial-object.test?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/test/Object/nm-trivial-object.test (original)
+++ llvm/trunk/test/Object/nm-trivial-object.test Fri Oct 31 00:07:00 2014
@@ -1,6 +1,6 @@
-RUN: yaml2obj %p/Inputs/COFF/i386.yaml | llvm-nm - \
+RUN: yaml2obj %p/Inputs/COFF/i386.yaml | llvm-nm -a - \
RUN: | FileCheck %s -check-prefix COFF
-RUN: yaml2obj %p/Inputs/COFF/x86-64.yaml | llvm-nm - \
+RUN: yaml2obj %p/Inputs/COFF/x86-64.yaml | llvm-nm -a - \
RUN: | FileCheck %s -check-prefix COFF
RUN: llvm-nm %p/Inputs/trivial-object-test.elf-i386 \
RUN: | FileCheck %s -check-prefix ELF
@@ -36,7 +36,7 @@ RUN: llvm-nm -p -a %p/Inputs/macho-hello
RUN: | FileCheck %s -check-prefix macho-pa
RUN: llvm-nm -u %p/Inputs/macho-hello-g.macho-x86_64 \
RUN: | FileCheck %s -check-prefix macho-u
-RUN: llvm-nm -S %p/Inputs/common.coff-i386 \
+RUN: llvm-nm -S -a %p/Inputs/common.coff-i386 \
RUN: | FileCheck %s -check-prefix COFF-COMMON
RUN: llvm-nm %p/Inputs/relocatable-with-section-address.elf-x86-64 \
RUN: | FileCheck %s -check-prefix ELF-SEC-ADDR64
Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original)
+++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Fri Oct 31 00:07:00 2014
@@ -721,18 +721,14 @@ static char getSymbolNMTypeChar(COFFObje
// Check section type.
if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
return 't';
- else if (Characteristics & COFF::IMAGE_SCN_MEM_READ &&
- ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
- return 'r';
- else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
- return 'd';
- else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
+ return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r';
+ if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
return 'b';
- else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
+ if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
return 'i';
-
// Check for section symbol.
- else if (Symb.isSectionDefinition())
+ if (Symb.isSectionDefinition())
return 's';
}
Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Fri Oct 31 00:07:00 2014
@@ -857,7 +857,7 @@ void COFFDumper::printSymbol(const Symbo
W.printHex("PointerToLineNumber", Aux->PointerToLinenumber);
W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
- } else if (Symbol.isWeakExternal()) {
+ } else if (Symbol.isAnyUndefined()) {
const coff_aux_weak_external *Aux;
if (error(getSymbolAuxData(Obj, Symbol, I, Aux)))
break;
Modified: llvm/trunk/tools/obj2yaml/coff2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/coff2yaml.cpp?rev=220952&r1=220951&r2=220952&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/coff2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/coff2yaml.cpp Fri Oct 31 00:07:00 2014
@@ -161,7 +161,7 @@ void COFFDumper::dumpSymbols(unsigned Nu
reinterpret_cast<const object::coff_aux_bf_and_ef_symbol *>(
AuxData.data());
dumpbfAndEfLineInfo(&Sym, ObjBES);
- } else if (Symbol.isWeakExternal()) {
+ } else if (Symbol.isAnyUndefined()) {
// This symbol represents a weak external definition.
assert(Symbol.getNumberOfAuxSymbols() == 1 &&
"Expected a single aux symbol to describe this weak symbol!");
More information about the llvm-commits
mailing list