mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-30 23:21:04 +00:00
[WebAssembly] Write DWARF data into wasm object file
- Writes ".debug_XXX" into corresponding custom sections. - Writes relocation records into "reloc.debug_XXX" sections. Patch by Yury Delendik! Differential Revision: https://reviews.llvm.org/D44184 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@330982 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ee52da49b0
commit
db15975983
@ -250,8 +250,9 @@ enum : unsigned {
|
||||
// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
|
||||
enum WasmSymbolType : unsigned {
|
||||
WASM_SYMBOL_TYPE_FUNCTION = 0x0,
|
||||
WASM_SYMBOL_TYPE_DATA = 0x1,
|
||||
WASM_SYMBOL_TYPE_GLOBAL = 0x2,
|
||||
WASM_SYMBOL_TYPE_DATA = 0x1,
|
||||
WASM_SYMBOL_TYPE_GLOBAL = 0x2,
|
||||
WASM_SYMBOL_TYPE_SECTION = 0x3,
|
||||
};
|
||||
|
||||
const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
|
||||
|
@ -11,3 +11,5 @@ WASM_RELOC(R_WEBASSEMBLY_MEMORY_ADDR_SLEB, 4)
|
||||
WASM_RELOC(R_WEBASSEMBLY_MEMORY_ADDR_I32, 5)
|
||||
WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB, 6)
|
||||
WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB, 7)
|
||||
WASM_RELOC(R_WEBASSEMBLY_FUNCTION_OFFSET_I32, 8)
|
||||
WASM_RELOC(R_WEBASSEMBLY_SECTION_OFFSET_I32, 9)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Object/Wasm.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <cstdint>
|
||||
@ -46,6 +47,8 @@ public:
|
||||
return visitCOFF(Rel, R, Value);
|
||||
if (isa<MachOObjectFile>(ObjToVisit))
|
||||
return visitMachO(Rel, R, Value);
|
||||
if (isa<WasmObjectFile>(ObjToVisit))
|
||||
return visitWasm(Rel, R, Value);
|
||||
|
||||
HasError = true;
|
||||
return 0;
|
||||
@ -316,6 +319,27 @@ private:
|
||||
HasError = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t visitWasm(uint32_t Rel, RelocationRef R, uint64_t Value) {
|
||||
if (ObjToVisit.getArch() == Triple::wasm32) {
|
||||
switch (Rel) {
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
|
||||
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
|
||||
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
|
||||
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
|
||||
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
|
||||
// For wasm section, its offset at 0 -- ignoring Value
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
HasError = true;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace object
|
||||
|
@ -53,6 +53,10 @@ public:
|
||||
return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
|
||||
}
|
||||
|
||||
bool isTypeSection() const {
|
||||
return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
|
||||
}
|
||||
|
||||
bool isDefined() const { return !isUndefined(); }
|
||||
|
||||
bool isUndefined() const {
|
||||
@ -206,6 +210,7 @@ private:
|
||||
bool isValidFunctionSymbol(uint32_t Index) const;
|
||||
bool isValidGlobalSymbol(uint32_t Index) const;
|
||||
bool isValidDataSymbol(uint32_t Index) const;
|
||||
bool isValidSectionSymbol(uint32_t Index) const;
|
||||
wasm::WasmFunction &getDefinedFunction(uint32_t Index);
|
||||
wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
|
||||
|
||||
|
@ -48,7 +48,9 @@ static const uint32_t kInitialTableOffset = 1;
|
||||
struct SectionBookkeeping {
|
||||
// Where the size of the section is written.
|
||||
uint64_t SizeOffset;
|
||||
// Where the contents of the section starts (after the header).
|
||||
// Where the section header ends (without custom section name).
|
||||
uint64_t PayloadOffset;
|
||||
// Where the contents of the section starts.
|
||||
uint64_t ContentsOffset;
|
||||
uint32_t Index;
|
||||
};
|
||||
@ -151,6 +153,8 @@ struct WasmRelocationEntry {
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
|
||||
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -169,11 +173,17 @@ struct WasmRelocationEntry {
|
||||
};
|
||||
|
||||
struct WasmCustomSection {
|
||||
StringRef Name;
|
||||
const SmallVectorImpl<char> &Contents;
|
||||
const uint32_t INVALID_INDEX = -1;
|
||||
|
||||
WasmCustomSection(StringRef Name, const SmallVectorImpl<char> &Contents)
|
||||
: Name(Name), Contents(Contents) {}
|
||||
StringRef Name;
|
||||
MCSectionWasm *Section;
|
||||
|
||||
uint32_t OutputContentsOffset;
|
||||
uint32_t OutputIndex;
|
||||
|
||||
WasmCustomSection(StringRef Name, MCSectionWasm *Section)
|
||||
: Name(Name), Section(Section), OutputContentsOffset(0),
|
||||
OutputIndex(INVALID_INDEX) {}
|
||||
};
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
@ -207,13 +217,21 @@ class WasmObjectWriter : public MCObjectWriter {
|
||||
DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices;
|
||||
// Maps data symbols to the Wasm segment and offset/size with the segment.
|
||||
DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations;
|
||||
// Maps section symbols to the section.
|
||||
DenseMap<const MCSymbolWasm *, const MCSectionWasm *> CustomSectionSymbols;
|
||||
|
||||
// Stores output data (index, relocations, content offset) for custom
|
||||
// section.
|
||||
std::vector<WasmCustomSection> CustomSections;
|
||||
// Relocations for fixing up references in the custom sections.
|
||||
DenseMap<const MCSectionWasm *, std::vector<WasmRelocationEntry>>
|
||||
CustomSectionsRelocations;
|
||||
|
||||
DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
|
||||
FunctionTypeIndices;
|
||||
SmallVector<WasmFunctionType, 4> FunctionTypes;
|
||||
SmallVector<WasmGlobal, 4> Globals;
|
||||
SmallVector<WasmDataSegment, 4> DataSegments;
|
||||
std::vector<WasmCustomSection> CustomSections;
|
||||
unsigned NumFunctionImports = 0;
|
||||
unsigned NumGlobalImports = 0;
|
||||
uint32_t SectionCount = 0;
|
||||
@ -245,10 +263,12 @@ private:
|
||||
WasmIndices.clear();
|
||||
TableIndices.clear();
|
||||
DataLocations.clear();
|
||||
CustomSectionsRelocations.clear();
|
||||
FunctionTypeIndices.clear();
|
||||
FunctionTypes.clear();
|
||||
Globals.clear();
|
||||
DataSegments.clear();
|
||||
CustomSectionSymbols.clear();
|
||||
MCObjectWriter::reset();
|
||||
NumFunctionImports = 0;
|
||||
NumGlobalImports = 0;
|
||||
@ -290,7 +310,11 @@ private:
|
||||
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
|
||||
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
|
||||
const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats);
|
||||
void writeUserCustomSections(ArrayRef<WasmCustomSection> CustomSections);
|
||||
void writeCustomSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
|
||||
void writeCustomRelocSections();
|
||||
void
|
||||
updateCustomSectionRelocations(const SmallVector<WasmFunction, 4> &Functions,
|
||||
const MCAsmLayout &Layout);
|
||||
|
||||
uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
|
||||
void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
|
||||
@ -319,6 +343,7 @@ void WasmObjectWriter::startSection(SectionBookkeeping &Section,
|
||||
|
||||
// The position where the section starts, for measuring its size.
|
||||
Section.ContentsOffset = getStream().tell();
|
||||
Section.PayloadOffset = getStream().tell();
|
||||
Section.Index = SectionCount++;
|
||||
}
|
||||
|
||||
@ -326,14 +351,21 @@ void WasmObjectWriter::startCustomSection(SectionBookkeeping &Section,
|
||||
StringRef Name) {
|
||||
DEBUG(dbgs() << "startCustomSection " << Name << "\n");
|
||||
startSection(Section, wasm::WASM_SEC_CUSTOM);
|
||||
|
||||
// The position where the section header ends, for measuring its size.
|
||||
Section.PayloadOffset = getStream().tell();
|
||||
|
||||
// Custom sections in wasm also have a string identifier.
|
||||
writeString(Name);
|
||||
|
||||
// The position where the custom section starts.
|
||||
Section.ContentsOffset = getStream().tell();
|
||||
}
|
||||
|
||||
// Now that the section is complete and we know how big it is, patch up the
|
||||
// section size field at the start of the section.
|
||||
void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
|
||||
uint64_t Size = getStream().tell() - Section.ContentsOffset;
|
||||
uint64_t Size = getStream().tell() - Section.PayloadOffset;
|
||||
if (uint32_t(Size) != Size)
|
||||
report_fatal_error("section size does not fit in a uint32_t");
|
||||
|
||||
@ -374,8 +406,9 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
|
||||
if (FixupSection.getSectionName().startswith(".init_array"))
|
||||
return;
|
||||
|
||||
// TODO(sbc): Add support for debug sections.
|
||||
if (FixupSection.getKind().isMetadata())
|
||||
// TODO: Add support for non-debug metadata sections?
|
||||
if (FixupSection.getKind().isMetadata() &&
|
||||
!FixupSection.getSectionName().startswith(".debug_"))
|
||||
return;
|
||||
|
||||
if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
|
||||
@ -446,21 +479,29 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
|
||||
WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
|
||||
DEBUG(dbgs() << "WasmReloc: " << Rec << "\n");
|
||||
|
||||
// Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB are currently required
|
||||
// to be against a named symbol.
|
||||
// Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB,
|
||||
// R_WEBASSEMBLY_SECTION_OFFSET_I32 or R_WEBASSEMBLY_FUNCTION_OFFSET_I32
|
||||
// are currently required to be against a named symbol.
|
||||
// TODO(sbc): Add support for relocations against unnamed temporaries such
|
||||
// as those generated by llvm's `blockaddress`.
|
||||
// See: test/MC/WebAssembly/blockaddress.ll
|
||||
if (SymA->getName().empty() && Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB)
|
||||
if (SymA->getName().empty() &&
|
||||
!(Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB ||
|
||||
Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32 ||
|
||||
Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32))
|
||||
report_fatal_error("relocations against un-named temporaries are not yet "
|
||||
"supported by wasm");
|
||||
|
||||
if (FixupSection.isWasmData())
|
||||
if (FixupSection.isWasmData()) {
|
||||
DataRelocations.push_back(Rec);
|
||||
else if (FixupSection.getKind().isText())
|
||||
} else if (FixupSection.getKind().isText()) {
|
||||
CodeRelocations.push_back(Rec);
|
||||
else
|
||||
} else if (FixupSection.getKind().isMetadata()) {
|
||||
assert(FixupSection.getSectionName().startswith(".debug_"));
|
||||
CustomSectionsRelocations[&FixupSection].push_back(Rec);
|
||||
} else {
|
||||
llvm_unreachable("unexpected section type");
|
||||
}
|
||||
}
|
||||
|
||||
// Write X as an (unsigned) LEB value at offset Offset in Stream, padded
|
||||
@ -523,6 +564,15 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
|
||||
report_fatal_error("symbol not found in wasm index space: " +
|
||||
RelEntry.Symbol->getName());
|
||||
return WasmIndices[RelEntry.Symbol];
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: {
|
||||
const auto &Section =
|
||||
static_cast<const MCSectionWasm &>(RelEntry.Symbol->getSection());
|
||||
return Section.getSectionOffset() + RelEntry.Addend;
|
||||
}
|
||||
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: {
|
||||
const auto &Section = *CustomSectionSymbols.find(RelEntry.Symbol)->second;
|
||||
return Section.getSectionOffset() + RelEntry.Addend;
|
||||
}
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
|
||||
@ -614,6 +664,8 @@ void WasmObjectWriter::applyRelocations(
|
||||
break;
|
||||
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
|
||||
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
|
||||
WriteI32(Stream, Value, Offset);
|
||||
break;
|
||||
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
|
||||
@ -851,6 +903,13 @@ void WasmObjectWriter::writeRelocSection(
|
||||
endSection(Section);
|
||||
}
|
||||
|
||||
void WasmObjectWriter::writeCustomRelocSections() {
|
||||
for (const auto &Sec : CustomSections) {
|
||||
auto &Relocations = CustomSectionsRelocations[Sec.Section];
|
||||
writeRelocSection(Sec.OutputIndex, Sec.Name, Relocations);
|
||||
}
|
||||
}
|
||||
|
||||
void WasmObjectWriter::writeLinkingMetaDataSection(
|
||||
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
|
||||
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
|
||||
@ -881,6 +940,12 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
|
||||
encodeULEB128(Sym.DataRef.Size, getStream());
|
||||
}
|
||||
break;
|
||||
case wasm::WASM_SYMBOL_TYPE_SECTION: {
|
||||
const uint32_t SectionIndex =
|
||||
CustomSections[Sym.ElementIndex].OutputIndex;
|
||||
encodeULEB128(SectionIndex, getStream());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("unexpected kind");
|
||||
}
|
||||
@ -927,16 +992,66 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
|
||||
endSection(Section);
|
||||
}
|
||||
|
||||
void WasmObjectWriter::writeUserCustomSections(
|
||||
ArrayRef<WasmCustomSection> CustomSections) {
|
||||
for (const auto &CustomSection : CustomSections) {
|
||||
void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
|
||||
const MCAsmLayout &Layout) {
|
||||
for (auto &CustomSection : CustomSections) {
|
||||
SectionBookkeeping Section;
|
||||
auto *Sec = CustomSection.Section;
|
||||
startCustomSection(Section, CustomSection.Name);
|
||||
writeBytes(CustomSection.Contents);
|
||||
|
||||
Sec->setSectionOffset(getStream().tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(Sec, Layout);
|
||||
|
||||
CustomSection.OutputContentsOffset = Section.ContentsOffset;
|
||||
CustomSection.OutputIndex = Section.Index;
|
||||
|
||||
endSection(Section);
|
||||
}
|
||||
}
|
||||
|
||||
void WasmObjectWriter::updateCustomSectionRelocations(
|
||||
const SmallVector<WasmFunction, 4> &Functions, const MCAsmLayout &Layout) {
|
||||
std::map<const MCSection *, const MCSymbolWasm *> SectionSymbols;
|
||||
for (const auto &P : CustomSectionSymbols)
|
||||
SectionSymbols[P.second] = P.first;
|
||||
std::map<const MCSection *, const MCSymbolWasm *> FuncSymbols;
|
||||
for (const auto &FuncInfo : Functions)
|
||||
FuncSymbols[&FuncInfo.Sym->getSection()] = FuncInfo.Sym;
|
||||
|
||||
// Patch relocation records for R_WEBASSEMBLY_FUNCTION_OFFSET_I32 and
|
||||
// R_WEBASSEMBLY_SECTION_OFFSET_I32. The Addend is stuffed the offset from
|
||||
// the beginning of the function or custom section -- all such relocations
|
||||
// target the function or custom section starts.
|
||||
for (auto &Section : CustomSections) {
|
||||
auto &Relocations = CustomSectionsRelocations[Section.Section];
|
||||
for (WasmRelocationEntry &RelEntry : Relocations) {
|
||||
switch (RelEntry.Type) {
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: {
|
||||
assert(RelEntry.hasAddend());
|
||||
auto &Section =
|
||||
static_cast<MCSectionWasm &>(RelEntry.Symbol->getSection());
|
||||
RelEntry.Addend += Layout.getSymbolOffset(*RelEntry.Symbol);
|
||||
RelEntry.Symbol = FuncSymbols[&Section];
|
||||
break;
|
||||
}
|
||||
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: {
|
||||
assert(RelEntry.hasAddend());
|
||||
auto &Section =
|
||||
static_cast<MCSectionWasm &>(RelEntry.Symbol->getSection());
|
||||
RelEntry.Addend += Layout.getSymbolOffset(*RelEntry.Symbol);
|
||||
RelEntry.Symbol = SectionSymbols[&Section];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply fixups.
|
||||
applyRelocations(Relocations, Section.OutputContentsOffset);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm& Symbol) {
|
||||
assert(Symbol.isFunction());
|
||||
assert(TypeIndices.count(&Symbol));
|
||||
@ -1043,8 +1158,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
for (MCSection &Sec : Asm) {
|
||||
auto &Section = static_cast<MCSectionWasm &>(Sec);
|
||||
|
||||
if (cast<MCSectionWasm>(Sec).getSectionName().startswith(
|
||||
".custom_section.")) {
|
||||
if (Section.getSectionName().startswith(".custom_section.")) {
|
||||
if (Section.getFragmentList().empty())
|
||||
continue;
|
||||
if (Section.getFragmentList().size() != 1)
|
||||
@ -1057,8 +1171,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
if (!DataFrag.getFixups().empty())
|
||||
report_fatal_error("fixups not supported in .custom_section section");
|
||||
StringRef UserName = Section.getSectionName().substr(16);
|
||||
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
|
||||
CustomSections.push_back(WasmCustomSection(UserName, Contents));
|
||||
CustomSections.emplace_back(UserName, &Section);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1088,6 +1201,31 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
}
|
||||
}
|
||||
|
||||
// Create symbols for debug/custom sections.
|
||||
for (MCSection &Sec : Asm) {
|
||||
auto &DebugSection = static_cast<MCSectionWasm &>(Sec);
|
||||
StringRef SectionName = DebugSection.getSectionName();
|
||||
|
||||
// TODO: Add support for non-debug metadata sections?
|
||||
if (!Sec.getKind().isMetadata() || !SectionName.startswith(".debug_"))
|
||||
continue;
|
||||
|
||||
uint32_t ElementIndex = CustomSections.size();
|
||||
CustomSections.emplace_back(SectionName, &DebugSection);
|
||||
|
||||
MCSymbolWasm *SectionSym =
|
||||
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SectionName));
|
||||
CustomSectionSymbols[SectionSym] = &DebugSection;
|
||||
|
||||
wasm::WasmSymbolInfo Info;
|
||||
Info.Name = SectionSym->getName();
|
||||
Info.Kind = wasm::WASM_SYMBOL_TYPE_SECTION;
|
||||
Info.Flags = 0;
|
||||
Info.ElementIndex = ElementIndex;
|
||||
SymbolIndices[SectionSym] = SymbolInfos.size();
|
||||
SymbolInfos.emplace_back(Info);
|
||||
}
|
||||
|
||||
// Populate WasmIndices and DataLocations for defined symbols.
|
||||
for (const MCSymbol &S : Asm.symbols()) {
|
||||
// Ignore unnamed temporary symbols, which aren't ever exported, imported,
|
||||
@ -1331,13 +1469,14 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
writeElemSection(TableElems);
|
||||
writeCodeSection(Asm, Layout, Functions);
|
||||
writeDataSection();
|
||||
writeUserCustomSections(CustomSections);
|
||||
writeCustomSections(Asm, Layout);
|
||||
updateCustomSectionRelocations(Functions, Layout);
|
||||
writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
|
||||
writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
|
||||
writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
|
||||
writeCustomRelocSections();
|
||||
|
||||
// TODO: Translate the .comment section to the output.
|
||||
// TODO: Translate debug sections to the output.
|
||||
}
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
|
@ -465,6 +465,14 @@ Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr,
|
||||
}
|
||||
break;
|
||||
|
||||
case wasm::WASM_SYMBOL_TYPE_SECTION: {
|
||||
Info.ElementIndex = readVaruint32(Ptr);
|
||||
// Use somewhat unique section name as symbol name.
|
||||
StringRef SectionName = Sections[Info.ElementIndex].Name;
|
||||
Info.Name = SectionName;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return make_error<GenericBinaryError>("Invalid symbol type",
|
||||
object_error::parse_failed);
|
||||
@ -573,6 +581,18 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr,
|
||||
object_error::parse_failed);
|
||||
Reloc.Addend = readVarint32(Ptr);
|
||||
break;
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
|
||||
if (!isValidFunctionSymbol(Reloc.Index))
|
||||
return make_error<GenericBinaryError>("Bad relocation function index",
|
||||
object_error::parse_failed);
|
||||
Reloc.Addend = readVarint32(Ptr);
|
||||
break;
|
||||
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
|
||||
if (!isValidSectionSymbol(Reloc.Index))
|
||||
return make_error<GenericBinaryError>("Bad relocation section index",
|
||||
object_error::parse_failed);
|
||||
Reloc.Addend = readVarint32(Ptr);
|
||||
break;
|
||||
default:
|
||||
return make_error<GenericBinaryError>("Bad relocation type: " +
|
||||
Twine(Reloc.Type),
|
||||
@ -584,7 +604,9 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr,
|
||||
// to check that.
|
||||
uint64_t Size = 5;
|
||||
if (Reloc.Type == wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 ||
|
||||
Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32)
|
||||
Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32 ||
|
||||
Reloc.Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32 ||
|
||||
Reloc.Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32)
|
||||
Size = 4;
|
||||
if (Reloc.Offset + Size > EndOffset)
|
||||
return make_error<GenericBinaryError>("Bad relocation offset",
|
||||
@ -811,6 +833,10 @@ bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
|
||||
return Index < Symbols.size() && Symbols[Index].isTypeData();
|
||||
}
|
||||
|
||||
bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
|
||||
return Index < Symbols.size() && Symbols[Index].isTypeSection();
|
||||
}
|
||||
|
||||
wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
|
||||
assert(isDefinedFunctionIndex(Index));
|
||||
return Functions[Index - NumImportedFunctions];
|
||||
@ -991,6 +1017,8 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
|
||||
assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST);
|
||||
return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
|
||||
}
|
||||
case wasm::WASM_SYMBOL_TYPE_SECTION:
|
||||
return 0;
|
||||
}
|
||||
llvm_unreachable("invalid symbol type");
|
||||
}
|
||||
@ -1020,6 +1048,8 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
|
||||
return SymbolRef::ST_Other;
|
||||
case wasm::WASM_SYMBOL_TYPE_DATA:
|
||||
return SymbolRef::ST_Data;
|
||||
case wasm::WASM_SYMBOL_TYPE_SECTION:
|
||||
return SymbolRef::ST_Debug;
|
||||
}
|
||||
|
||||
llvm_unreachable("Unknown WasmSymbol::SymbolType");
|
||||
@ -1043,6 +1073,10 @@ WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
|
||||
case wasm::WASM_SYMBOL_TYPE_DATA:
|
||||
Ref.d.a = DataSection;
|
||||
break;
|
||||
case wasm::WASM_SYMBOL_TYPE_SECTION: {
|
||||
Ref.d.a = Sym.Info.ElementIndex;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("Unknown WasmSymbol::SymbolType");
|
||||
}
|
||||
|
@ -405,6 +405,8 @@ void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
|
||||
IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
|
||||
IO.mapRequired("Size", Info.DataRef.Size);
|
||||
}
|
||||
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) {
|
||||
IO.mapRequired("Section", Info.ElementIndex);
|
||||
} else {
|
||||
llvm_unreachable("unsupported symbol kind");
|
||||
}
|
||||
@ -439,6 +441,7 @@ void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration(
|
||||
ECase(FUNCTION);
|
||||
ECase(DATA);
|
||||
ECase(GLOBAL);
|
||||
ECase(SECTION);
|
||||
#undef ECase
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,10 @@
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
#include "llvm/MC/MCFixupKindInfo.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/MC/MCSectionWasm.h"
|
||||
#include "llvm/MC/MCSymbolWasm.h"
|
||||
#include "llvm/MC/MCWasmObjectWriter.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/MC/MCWasmObjectWriter.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
@ -61,6 +62,25 @@ static bool IsFunctionType(const MCValue &Target) {
|
||||
return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX;
|
||||
}
|
||||
|
||||
static const MCSection *GetFixupSection(const MCExpr *Expr) {
|
||||
if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) {
|
||||
if (SyExp->getSymbol().isInSection())
|
||||
return &SyExp->getSymbol().getSection();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) {
|
||||
auto SectionLHS = GetFixupSection(BinOp->getLHS());
|
||||
auto SectionRHS = GetFixupSection(BinOp->getRHS());
|
||||
return SectionLHS == SectionRHS ? nullptr : SectionLHS;
|
||||
}
|
||||
|
||||
if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr))
|
||||
return GetFixupSection(UnOp->getSubExpr());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned
|
||||
WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
|
||||
const MCFixup &Fixup) const {
|
||||
@ -86,6 +106,13 @@ WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
|
||||
case FK_Data_4:
|
||||
if (IsFunction)
|
||||
return wasm::R_WEBASSEMBLY_TABLE_INDEX_I32;
|
||||
if (auto Section = static_cast<const MCSectionWasm *>(
|
||||
GetFixupSection(Fixup.getValue()))) {
|
||||
if (Section->getKind().isText())
|
||||
return wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32;
|
||||
else if (!Section->isWasmData())
|
||||
return wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32;
|
||||
}
|
||||
return wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32;
|
||||
case FK_Data_8:
|
||||
llvm_unreachable("FK_Data_8 not implemented yet");
|
||||
|
@ -1,9 +1,169 @@
|
||||
; RUN: llc -filetype=obj %s -o - | llvm-readobj -r -s -expand-relocs
|
||||
; RUN: llc -filetype=obj %s -o - | llvm-readobj -r -s | FileCheck %s
|
||||
|
||||
; CHECK: Format: WASM
|
||||
; CHECK-NEXT:Arch: wasm32
|
||||
; CHECK-NEXT:AddressSize: 32bit
|
||||
; CHECK-NEXT:Sections [
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: TYPE (0x1)
|
||||
; CHECK-NEXT: Size: 4
|
||||
; CHECK-NEXT: Offset: 8
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: IMPORT (0x2)
|
||||
; CHECK-NEXT: Size: 58
|
||||
; CHECK-NEXT: Offset: 18
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: FUNCTION (0x3)
|
||||
; CHECK-NEXT: Size: 2
|
||||
; CHECK-NEXT: Offset: 82
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: ELEM (0x9)
|
||||
; CHECK-NEXT: Size: 7
|
||||
; CHECK-NEXT: Offset: 90
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CODE (0xA)
|
||||
; CHECK-NEXT: Size: 4
|
||||
; CHECK-NEXT: Offset: 103
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: DATA (0xB)
|
||||
; CHECK-NEXT: Size: 19
|
||||
; CHECK-NEXT: Offset: 113
|
||||
; CHECK-NEXT: Segments [
|
||||
; CHECK-NEXT: Segment {
|
||||
; CHECK-NEXT: Name: .data.foo
|
||||
; CHECK-NEXT: Size: 4
|
||||
; CHECK-NEXT: Offset: 0
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Segment {
|
||||
; CHECK-NEXT: Name: .data.ptr2
|
||||
; CHECK-NEXT: Size: 4
|
||||
; CHECK-NEXT: Offset: 4
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: ]
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 121
|
||||
; CHECK-NEXT: Offset: 138
|
||||
; CHECK-NEXT: Name: .debug_str
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 84
|
||||
; CHECK-NEXT: Offset: 276
|
||||
; CHECK-NEXT: Name: .debug_abbrev
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 106
|
||||
; CHECK-NEXT: Offset: 380
|
||||
; CHECK-NEXT: Name: .debug_info
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 0
|
||||
; CHECK-NEXT: Offset: 504
|
||||
; CHECK-NEXT: Name: .debug_ranges
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 1
|
||||
; CHECK-NEXT: Offset: 524
|
||||
; CHECK-NEXT: Name: .debug_macinfo
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 42
|
||||
; CHECK-NEXT: Offset: 546
|
||||
; CHECK-NEXT: Name: .debug_pubnames
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 26
|
||||
; CHECK-NEXT: Offset: 610
|
||||
; CHECK-NEXT: Name: .debug_pubtypes
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 57
|
||||
; CHECK-NEXT: Offset: 658
|
||||
; CHECK-NEXT: Name: .debug_line
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 100
|
||||
; CHECK-NEXT: Offset: 733
|
||||
; CHECK-NEXT: Name: linking
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 9
|
||||
; CHECK-NEXT: Offset: 847
|
||||
; CHECK-NEXT: Name: reloc.DATA
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 58
|
||||
; CHECK-NEXT: Offset: 873
|
||||
; CHECK-NEXT: Name: reloc..debug_info
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 6
|
||||
; CHECK-NEXT: Offset: 955
|
||||
; CHECK-NEXT: Name: reloc..debug_pubnames
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 6
|
||||
; CHECK-NEXT: Offset: 989
|
||||
; CHECK-NEXT: Name: reloc..debug_pubtypes
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 6
|
||||
; CHECK-NEXT: Offset: 1023
|
||||
; CHECK-NEXT: Name: reloc..debug_line
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT:]
|
||||
; CHECK-NEXT:Relocations [
|
||||
; CHECK-NEXT: Section (6) DATA {
|
||||
; CHECK-NEXT: 0x6 R_WEBASSEMBLY_MEMORY_ADDR_I32[10] 0
|
||||
; CHECK-NEXT: 0xF R_WEBASSEMBLY_TABLE_INDEX_I32[8]
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section (9) .debug_info {
|
||||
; CHECK-NEXT: 0x6 R_WEBASSEMBLY_SECTION_OFFSET_I32[1] 0
|
||||
; CHECK-NEXT: 0xC R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 0
|
||||
; CHECK-NEXT: 0x12 R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 55
|
||||
; CHECK-NEXT: 0x16 R_WEBASSEMBLY_SECTION_OFFSET_I32[7] 0
|
||||
; CHECK-NEXT: 0x1A R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 62
|
||||
; CHECK-NEXT: 0x1E R_WEBASSEMBLY_FUNCTION_OFFSET_I32[8] 0
|
||||
; CHECK-NEXT: 0x27 R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 105
|
||||
; CHECK-NEXT: 0x33 R_WEBASSEMBLY_MEMORY_ADDR_I32[9] 0
|
||||
; CHECK-NEXT: 0x3D R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 109
|
||||
; CHECK-NEXT: 0x44 R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 113
|
||||
; CHECK-NEXT: 0x50 R_WEBASSEMBLY_MEMORY_ADDR_I32[11] 0
|
||||
; CHECK-NEXT: 0x5B R_WEBASSEMBLY_FUNCTION_OFFSET_I32[8] 0
|
||||
; CHECK-NEXT: 0x63 R_WEBASSEMBLY_SECTION_OFFSET_I32[0] 118
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section (12) .debug_pubnames {
|
||||
; CHECK-NEXT: 0x6 R_WEBASSEMBLY_SECTION_OFFSET_I32[2] 0
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section (13) .debug_pubtypes {
|
||||
; CHECK-NEXT: 0x6 R_WEBASSEMBLY_SECTION_OFFSET_I32[2] 0
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section (14) .debug_line {
|
||||
; CHECK-NEXT: 0x2B R_WEBASSEMBLY_FUNCTION_OFFSET_I32[8] 0
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT:]
|
||||
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
; Debug information is currently not supported. This test simply verifies that
|
||||
; a valid object generated.
|
||||
source_filename = "test.c"
|
||||
|
||||
@myextern = external global i32, align 4
|
||||
|
95
test/MC/WebAssembly/dwarfdump.ll
Normal file
95
test/MC/WebAssembly/dwarfdump.ll
Normal file
@ -0,0 +1,95 @@
|
||||
; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
|
||||
|
||||
; CHECK: .debug_info contents:
|
||||
; CHECK-NEXT: 0x00000000: Compile Unit: length = 0x00000066 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x04 (next unit at 0x0000006a)
|
||||
|
||||
; CHECK: 0x0000000b: DW_TAG_compile_unit
|
||||
; CHECK-NEXT: DW_AT_producer ("clang version 6.0.0 (trunk 315924) (llvm/trunk 315960)")
|
||||
; CHECK-NEXT: DW_AT_language (DW_LANG_C99)
|
||||
; CHECK-NEXT: DW_AT_name ("test.c")
|
||||
; CHECK-NEXT: DW_AT_stmt_list (0x00000000)
|
||||
; CHECK-NEXT: DW_AT_comp_dir ("/usr/local/google/home/sbc/dev/wasm/simple")
|
||||
; CHECK-NEXT: DW_AT_GNU_pubnames (true)
|
||||
; CHECK-NEXT: DW_AT_low_pc (0x0000000000000002)
|
||||
; CHECK-NEXT: DW_AT_high_pc (0x0000000000000004)
|
||||
|
||||
; CHECK: 0x00000026: DW_TAG_variable
|
||||
; CHECK-NEXT: DW_AT_name ("foo")
|
||||
; CHECK-NEXT: DW_AT_type (0x00000037 "int*")
|
||||
; CHECK-NEXT: DW_AT_external (true)
|
||||
; CHECK-NEXT: DW_AT_decl_file ("/usr/local/google/home/sbc/dev/wasm/simple/test.c")
|
||||
; CHECK-NEXT: DW_AT_decl_line (4)
|
||||
; CHECK-NEXT: DW_AT_location (DW_OP_addr 0x0)
|
||||
|
||||
; CHECK: 0x00000037: DW_TAG_pointer_type
|
||||
; CHECK-NEXT: DW_AT_type (0x0000003c "int")
|
||||
|
||||
; CHECK: 0x0000003c: DW_TAG_base_type
|
||||
; CHECK-NEXT: DW_AT_name ("int")
|
||||
; CHECK-NEXT: DW_AT_encoding (DW_ATE_signed)
|
||||
; CHECK-NEXT: DW_AT_byte_size (0x04)
|
||||
|
||||
; CHECK: 0x00000043: DW_TAG_variable
|
||||
; CHECK-NEXT: DW_AT_name ("ptr2")
|
||||
; CHECK-NEXT: DW_AT_type (0x00000054 "subroutine *")
|
||||
; CHECK-NEXT: DW_AT_external (true)
|
||||
; CHECK-NEXT: DW_AT_decl_file ("/usr/local/google/home/sbc/dev/wasm/simple/test.c")
|
||||
; CHECK-NEXT: DW_AT_decl_line (5)
|
||||
; CHECK-NEXT: DW_AT_location (DW_OP_addr 0x4)
|
||||
|
||||
; CHECK: 0x00000054: DW_TAG_pointer_type
|
||||
; CHECK-NEXT: DW_AT_type (0x00000059 "subroutine ")
|
||||
|
||||
; CHECK: 0x00000059: DW_TAG_subroutine_type
|
||||
; CHECK-NEXT: DW_AT_prototyped (true)
|
||||
|
||||
; CHECK: 0x0000005a: DW_TAG_subprogram
|
||||
; CHECK-NEXT: DW_AT_low_pc (0x0000000000000002)
|
||||
; CHECK-NEXT: DW_AT_high_pc (0x0000000000000004)
|
||||
; CHECK-NEXT: DW_AT_name ("f2")
|
||||
; CHECK-NEXT: DW_AT_decl_file ("/usr/local/google/home/sbc/dev/wasm/simple/test.c")
|
||||
; CHECK-NEXT: DW_AT_decl_line (2)
|
||||
; CHECK-NEXT: DW_AT_prototyped (true)
|
||||
; CHECK-NEXT: DW_AT_external (true)
|
||||
|
||||
; CHECK: 0x00000069: NULL
|
||||
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
source_filename = "test.c"
|
||||
|
||||
@myextern = external global i32, align 4
|
||||
@foo = hidden global i32* @myextern, align 4, !dbg !0
|
||||
@ptr2 = hidden global void ()* @f2, align 4, !dbg !6
|
||||
|
||||
; Function Attrs: noinline nounwind optnone
|
||||
define hidden void @f2() #0 !dbg !17 {
|
||||
entry:
|
||||
ret void, !dbg !18
|
||||
}
|
||||
|
||||
attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
|
||||
!llvm.dbg.cu = !{!2}
|
||||
!llvm.module.flags = !{!13, !14, !15}
|
||||
!llvm.ident = !{!16}
|
||||
|
||||
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
|
||||
!1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !3, line: 4, type: !11, isLocal: false, isDefinition: true)
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 6.0.0 (trunk 315924) (llvm/trunk 315960)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
|
||||
!3 = !DIFile(filename: "test.c", directory: "/usr/local/google/home/sbc/dev/wasm/simple")
|
||||
!4 = !{}
|
||||
!5 = !{!0, !6}
|
||||
!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
|
||||
!7 = distinct !DIGlobalVariable(name: "ptr2", scope: !2, file: !3, line: 5, type: !8, isLocal: false, isDefinition: true)
|
||||
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 32)
|
||||
!9 = !DISubroutineType(types: !10)
|
||||
!10 = !{null}
|
||||
!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 32)
|
||||
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!13 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!14 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!15 = !{i32 1, !"wchar_size", i32 4}
|
||||
!16 = !{!"clang version 6.0.0 (trunk 315924) (llvm/trunk 315960)"}
|
||||
!17 = distinct !DISubprogram(name: "f2", scope: !3, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !2, variables: !4)
|
||||
!18 = !DILocation(line: 2, column: 16, scope: !17)
|
@ -84,6 +84,8 @@ void WasmDumper::printRelocation(const SectionRef &Section,
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
|
||||
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
|
||||
HasAddend = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -106,6 +106,9 @@ std::unique_ptr<WasmYAML::CustomSection> WasmDumper::dumpCustomSection(const Was
|
||||
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
|
||||
Info.ElementIndex = Symbol.ElementIndex;
|
||||
break;
|
||||
case wasm::WASM_SYMBOL_TYPE_SECTION:
|
||||
Info.ElementIndex = Symbol.ElementIndex;
|
||||
break;
|
||||
}
|
||||
LinkingSec->SymbolTable.emplace_back(Info);
|
||||
}
|
||||
|
@ -165,6 +165,9 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &S
|
||||
encodeULEB128(Info.DataRef.Size, SubSection.GetStream());
|
||||
}
|
||||
break;
|
||||
case wasm::WASM_SYMBOL_TYPE_SECTION:
|
||||
encodeULEB128(Info.ElementIndex, SubSection.GetStream());
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unexpected kind");
|
||||
}
|
||||
@ -424,20 +427,28 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
|
||||
|
||||
int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
|
||||
uint32_t SectionIndex) {
|
||||
StringRef Name;
|
||||
switch (Sec.Type) {
|
||||
case wasm::WASM_SEC_CODE:
|
||||
Name = "reloc.CODE";
|
||||
writeStringRef("reloc.CODE", OS);
|
||||
break;
|
||||
case wasm::WASM_SEC_DATA:
|
||||
Name = "reloc.DATA";
|
||||
writeStringRef("reloc.DATA", OS);
|
||||
break;
|
||||
case wasm::WASM_SEC_CUSTOM: {
|
||||
auto CustomSection = dyn_cast<WasmYAML::CustomSection>(&Sec);
|
||||
if (!CustomSection->Name.startswith(".debug_")) {
|
||||
llvm_unreachable("not yet implemented (only for debug sections)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
writeStringRef(("reloc." + CustomSection->Name).str(), OS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("not yet implemented");
|
||||
return 1;
|
||||
}
|
||||
|
||||
writeStringRef(Name, OS);
|
||||
encodeULEB128(SectionIndex, OS);
|
||||
encodeULEB128(Sec.Relocations.size(), OS);
|
||||
|
||||
@ -449,6 +460,8 @@ int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
|
||||
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
|
||||
encodeULEB128(Reloc.Addend, OS);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user