1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[ObjectYAML] [COFF] Support multiple symbols with the same name

Differential Revision: https://reviews.llvm.org/D56294

llvm-svn: 350566
This commit is contained in:
Martin Storsjo 2019-01-07 20:55:33 +00:00
parent 132e187f9d
commit da0464bee6
5 changed files with 109 additions and 3 deletions

View File

@ -58,7 +58,13 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType)
struct Relocation {
uint32_t VirtualAddress;
uint16_t Type;
// Normally a Relocation can refer to the symbol via its name.
// It can also use a direct symbol table index instead (with no name
// specified), allowing disambiguating between multiple symbols with the
// same name or crafting intentionally broken files for testing.
StringRef SymbolName;
Optional<uint32_t> SymbolTableIndex;
};
struct Section {

View File

@ -407,7 +407,8 @@ struct NDLLCharacteristics {
void MappingTraits<COFFYAML::Relocation>::mapping(IO &IO,
COFFYAML::Relocation &Rel) {
IO.mapRequired("VirtualAddress", Rel.VirtualAddress);
IO.mapRequired("SymbolName", Rel.SymbolName);
IO.mapOptional("SymbolName", Rel.SymbolName, StringRef());
IO.mapOptional("SymbolTableIndex", Rel.SymbolTableIndex);
COFF::header &H = *static_cast<COFF::header *>(IO.getContext());
if (H.Machine == COFF::IMAGE_FILE_MACHINE_I386) {

View File

@ -0,0 +1,74 @@
# RUN: yaml2obj %s -o %t
# RUN: llvm-readobj -relocations %t | FileCheck %s --check-prefix=RELOCS
# RUN: obj2yaml %t | FileCheck %s --check-prefix=YAML
# RELOCS: Relocations [
# RELOCS-NEXT: Section (1) .text {
# RELOCS-NEXT: 0x3 IMAGE_REL_AMD64_REL32 .rdata (0)
# RELOCS-NEXT: 0xA IMAGE_REL_AMD64_REL32 .rdata (1)
# RELOCS-NEXT: 0x11 IMAGE_REL_AMD64_REL32 foo (2)
# RELOCS-NEXT: }
# RELOCS-NEXT: ]
# Check that we usually output relocations with SymbolName.
# For relocations with a non-unique symbol name, output
# SymbolTableIndex instead.
# YAML: Relocations:
# YAML-NEXT: - VirtualAddress: 3
# YAML-NEXT: SymbolTableIndex: 0
# YAML-NEXT: Type: IMAGE_REL_AMD64_REL32
# YAML-NEXT: - VirtualAddress: 10
# YAML-NEXT: SymbolTableIndex: 1
# YAML-NEXT: Type: IMAGE_REL_AMD64_REL32
# YAML-NEXT: - VirtualAddress: 17
# YAML-NEXT: SymbolName: foo
# YAML-NEXT: Type: IMAGE_REL_AMD64_REL32
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_AMD64
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ ]
Alignment: 4
SectionData: 488B0500000000488B0500000000488B0500000000
Relocations:
- VirtualAddress: 3
SymbolTableIndex: 0
Type: IMAGE_REL_AMD64_REL32
- VirtualAddress: 10
SymbolTableIndex: 1
Type: IMAGE_REL_AMD64_REL32
- VirtualAddress: 17
SymbolName: foo
Type: IMAGE_REL_AMD64_REL32
- Name: .rdata
Characteristics: [ ]
Alignment: 1
SectionData: '00'
- Name: .rdata
Characteristics: [ ]
Alignment: 1
SectionData: '01'
symbols:
- Name: .rdata
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: .rdata
Value: 0
SectionNumber: 3
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: foo
Value: 0
SectionNumber: 3
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "obj2yaml.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
@ -142,6 +143,18 @@ void COFFDumper::dumpSections(unsigned NumSections) {
codeview::StringsAndChecksumsRef SC;
initializeFileAndStringTable(Obj, SC);
StringMap<bool> SymbolUnique;
for (const auto &S : Obj.symbols()) {
object::COFFSymbolRef Symbol = Obj.getCOFFSymbol(S);
StringRef Name;
Obj.getSymbolName(Symbol, Name);
StringMap<bool>::iterator It;
bool Inserted;
std::tie(It, Inserted) = SymbolUnique.insert(std::make_pair(Name, true));
if (!Inserted)
It->second = false;
}
for (const auto &ObjSection : Obj.sections()) {
const object::coff_section *COFFSection = Obj.getCOFFSection(ObjSection);
COFFYAML::Section NewYAMLSection;
@ -192,7 +205,10 @@ void COFFDumper::dumpSections(unsigned NumSections) {
OS.flush();
report_fatal_error(Buf);
}
Rel.SymbolName = *SymbolNameOrErr;
if (SymbolUnique.lookup(*SymbolNameOrErr))
Rel.SymbolName = *SymbolNameOrErr;
else
Rel.SymbolTableIndex = reloc->SymbolTableIndex;
Rel.VirtualAddress = reloc->VirtualAddress;
Rel.Type = reloc->Type;
Relocations.push_back(Rel);

View File

@ -24,6 +24,7 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <vector>
@ -520,7 +521,15 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
assert(S.Header.SizeOfRawData >= S.SectionData.binary_size());
OS << num_zeros(S.Header.SizeOfRawData - S.SectionData.binary_size());
for (const COFFYAML::Relocation &R : S.Relocations) {
uint32_t SymbolTableIndex = SymbolTableIndexMap[R.SymbolName];
uint32_t SymbolTableIndex;
if (R.SymbolTableIndex) {
if (!R.SymbolName.empty())
WithColor::error()
<< "Both SymbolName and SymbolTableIndex specified\n";
SymbolTableIndex = *R.SymbolTableIndex;
} else {
SymbolTableIndex = SymbolTableIndexMap[R.SymbolName];
}
OS << binary_le(R.VirtualAddress)
<< binary_le(SymbolTableIndex)
<< binary_le(R.Type);