X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FObject%2FCOFFObjectFile.cpp;h=6d9e959f3f3fef317ab352847c7696a68b08fccb;hb=3ca2ad11567f83883ae2719c5fac5afc30c7b3d1;hp=18aad9a9517ce3c628af82070227a15a54c09525;hpb=25b15777df42d5d608810f6881b6c98107481d69;p=oota-llvm.git diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 18aad9a9517..6d9e959f3f3 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -114,10 +114,10 @@ error_code COFFObjectFile::getSymbolNext(DataRefImpl Symb, return object_error::success; } -error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, +error_code COFFObjectFile::getSymbolOffset(DataRefImpl Symb, uint64_t &Result) const { const coff_symbol *symb = toSymb(Symb); - const coff_section *Section; + const coff_section *Section = NULL; if (error_code ec = getSection(symb->SectionNumber, Section)) return ec; char Type; @@ -132,13 +132,62 @@ error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, return object_error::success; } +error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, + uint64_t &Result) const { + const coff_symbol *symb = toSymb(Symb); + const coff_section *Section = NULL; + if (error_code ec = getSection(symb->SectionNumber, Section)) + return ec; + char Type; + if (error_code ec = getSymbolNMTypeChar(Symb, Type)) + return ec; + if (Type == 'U' || Type == 'w') + Result = UnknownAddressOrSize; + else if (Section) + Result = reinterpret_cast(base() + + Section->PointerToRawData + + symb->Value); + else + Result = reinterpret_cast(base() + symb->Value); + return object_error::success; +} + +error_code COFFObjectFile::getSymbolType(DataRefImpl Symb, + SymbolRef::SymbolType &Result) const { + const coff_symbol *symb = toSymb(Symb); + Result = SymbolRef::ST_Other; + if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && + symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { + Result = SymbolRef::ST_External; + } else { + if (symb->Type.ComplexType == COFF::IMAGE_SYM_DTYPE_FUNCTION) { + Result = SymbolRef::ST_Function; + } else { + char Type; + if (error_code ec = getSymbolNMTypeChar(Symb, Type)) + return ec; + if (Type == 'r' || Type == 'R') { + Result = SymbolRef::ST_Data; + } + } + } + return object_error::success; +} + +error_code COFFObjectFile::isSymbolGlobal(DataRefImpl Symb, + bool &Result) const { + const coff_symbol *symb = toSymb(Symb); + Result = (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL); + return object_error::success; +} + error_code COFFObjectFile::getSymbolSize(DataRefImpl Symb, uint64_t &Result) const { // 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. const coff_symbol *symb = toSymb(Symb); - const coff_section *Section; + const coff_section *Section = NULL; if (error_code ec = getSection(symb->SectionNumber, Section)) return ec; char Type; @@ -171,7 +220,7 @@ error_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, uint32_t Characteristics = 0; if (symb->SectionNumber > 0) { - const coff_section *Section; + const coff_section *Section = NULL; if (error_code ec = getSection(symb->SectionNumber, Section)) return ec; Characteristics = Section->Characteristics; @@ -293,6 +342,14 @@ error_code COFFObjectFile::isSectionText(DataRefImpl Sec, return object_error::success; } +error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { + // FIXME: Unimplemented. + Result = false; + return object_error::success; +} + COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) : ObjectFile(Binary::isCOFF, Object, ec) { // Check that we at least have enough room for a header. @@ -309,8 +366,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) if (!checkSize(Data, ec, 0x3c + 8)) return; HeaderStart += *reinterpret_cast(base() + 0x3c); // Check the PE header. ("PE\0\0") - if (StringRef(reinterpret_cast(base() + HeaderStart), 4) - != "PE\0\0") { + if (std::memcmp(base() + HeaderStart, "PE\0\0", 4) != 0) { ec = object_error::parse_failed; return; } @@ -320,7 +376,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) Header = reinterpret_cast(base() + HeaderStart); if (!checkAddr(Data, ec, uintptr_t(Header), sizeof(coff_file_header))) return; - + SectionTable = reinterpret_cast( base() + HeaderStart @@ -353,7 +409,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) ec = object_error::parse_failed; return; } - + ec = object_error::success; } @@ -438,6 +494,77 @@ error_code COFFObjectFile::getString(uint32_t offset, return object_error::success; } +const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { + assert(Rel.d.b < Header->NumberOfSections && "Section index out of range!"); + const coff_section *Sect = NULL; + getSection(Rel.d.b, Sect); + assert(Rel.d.a < Sect->NumberOfRelocations && "Relocation index out of range!"); + return + reinterpret_cast(base() + + Sect->PointerToRelocations) + + Rel.d.a; +} +error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const { + const coff_section *Sect = NULL; + if (error_code ec = getSection(Rel.d.b, Sect)) + return ec; + if (++Rel.d.a >= Sect->NumberOfRelocations) { + Rel.d.a = 0; + while (++Rel.d.b < Header->NumberOfSections) { + const coff_section *Sect = NULL; + getSection(Rel.d.b, Sect); + if (Sect->NumberOfRelocations > 0) + break; + } + } + Res = RelocationRef(Rel, this); + return object_error::success; +} +error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const { + const coff_section *Sect = NULL; + if (error_code ec = getSection(Rel.d.b, Sect)) + return ec; + const coff_relocation* R = toRel(Rel); + Res = reinterpret_cast(base() + + Sect->PointerToRawData + + R->VirtualAddress); + return object_error::success; +} +error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const { + const coff_relocation* R = toRel(Rel); + DataRefImpl Symb; + Symb.p = reinterpret_cast(SymbolTable + R->SymbolTableIndex); + Res = SymbolRef(Symb, this); + return object_error::success; +} +error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, + uint32_t &Res) const { + const coff_relocation* R = toRel(Rel); + Res = R->Type; + return object_error::success; +} +error_code COFFObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const { + Res = 0; + return object_error::success; +} +ObjectFile::relocation_iterator COFFObjectFile::begin_relocations() const { + DataRefImpl ret; + ret.d.a = 0; + ret.d.b = 1; + return relocation_iterator(RelocationRef(ret, this)); +} +ObjectFile::relocation_iterator COFFObjectFile::end_relocations() const { + DataRefImpl ret; + ret.d.a = 0; + ret.d.b = Header->NumberOfSections; + return relocation_iterator(RelocationRef(ret, this)); +} + + namespace llvm { ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {