|
@@ -16,6 +16,11 @@ type
|
|
endofdata : int64;
|
|
endofdata : int64;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ TSymbolObject = class(TObject)
|
|
|
|
+ syminfo : TSymInfo;
|
|
|
|
+ next : TSymbolObject;
|
|
|
|
+ end;
|
|
|
|
+
|
|
{ TBinWriter }
|
|
{ TBinWriter }
|
|
|
|
|
|
TBinWriter = class
|
|
TBinWriter = class
|
|
@@ -24,10 +29,17 @@ type
|
|
org : TStream;
|
|
org : TStream;
|
|
strm : TList;
|
|
strm : TList;
|
|
|
|
|
|
|
|
+ module : TWasmModule;
|
|
|
|
+
|
|
// the list of relocations per module
|
|
// the list of relocations per module
|
|
writeSec : Byte;
|
|
writeSec : Byte;
|
|
reloc : array of TRelocationEntry;
|
|
reloc : array of TRelocationEntry;
|
|
relocCount : integer;
|
|
relocCount : integer;
|
|
|
|
+
|
|
|
|
+ symHead : TSymbolObject;
|
|
|
|
+ symTail : TSymbolObject;
|
|
|
|
+ symCount : Integer;
|
|
|
|
+ function AddSymbolObject: TSymbolObject;
|
|
procedure AddReloc(relocType: byte; ofs: int64; index: UInt32);
|
|
procedure AddReloc(relocType: byte; ofs: int64; index: UInt32);
|
|
|
|
|
|
procedure WriteRelocU32(u: longword);
|
|
procedure WriteRelocU32(u: longword);
|
|
@@ -37,13 +49,13 @@ type
|
|
|
|
|
|
procedure WriteInstList(list: TWasmInstrList; ofsAddition: LongWord);
|
|
procedure WriteInstList(list: TWasmInstrList; ofsAddition: LongWord);
|
|
|
|
|
|
- procedure WriteFuncTypeSect(m: TWasmModule);
|
|
|
|
- procedure WriteFuncSect(m: TWasmModule);
|
|
|
|
- procedure WriteExportSect(m: TWasmModule);
|
|
|
|
- procedure WriteCodeSect(m: TWasmModule);
|
|
|
|
|
|
+ procedure WriteFuncTypeSect;
|
|
|
|
+ procedure WriteFuncSect;
|
|
|
|
+ procedure WriteExportSect;
|
|
|
|
+ procedure WriteCodeSect;
|
|
|
|
|
|
- procedure WriteLinkingSect(m: TWasmModule);
|
|
|
|
- procedure WriteRelocSect(m: TWasmModule);
|
|
|
|
|
|
+ procedure WriteLinkingSect;
|
|
|
|
+ procedure WriteRelocSect;
|
|
|
|
|
|
procedure pushStream(st: TStream);
|
|
procedure pushStream(st: TStream);
|
|
function popStream: TStream;
|
|
function popStream: TStream;
|
|
@@ -124,17 +136,53 @@ end;
|
|
|
|
|
|
{ TBinWriter }
|
|
{ TBinWriter }
|
|
|
|
|
|
|
|
+function TBinWriter.AddSymbolObject: TSymbolObject;
|
|
|
|
+var
|
|
|
|
+ so : TSymbolObject;
|
|
|
|
+begin
|
|
|
|
+ so := TSymbolObject.Create;
|
|
|
|
+ if not Assigned(symHead) then symHead:=so;
|
|
|
|
+ if Assigned(symTail) then symTail.Next:=so;
|
|
|
|
+ symTail:=so;
|
|
|
|
+ inc(symCount);
|
|
|
|
+ Result:=so;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TBinWriter.AddReloc(relocType: byte; ofs: int64; index: UInt32);
|
|
procedure TBinWriter.AddReloc(relocType: byte; ofs: int64; index: UInt32);
|
|
|
|
+var
|
|
|
|
+ i : integer;
|
|
|
|
+ f : TWasmFunc;
|
|
|
|
+ so : TSymbolObject;
|
|
begin
|
|
begin
|
|
if relocCount=length(reloc) then begin
|
|
if relocCount=length(reloc) then begin
|
|
if relocCount=0 then SetLength(reloc, 16)
|
|
if relocCount=0 then SetLength(reloc, 16)
|
|
else SetLength(reloc, relocCount*2);
|
|
else SetLength(reloc, relocCount*2);
|
|
end;
|
|
end;
|
|
- reloc[relocCount].sec:=writeSec;
|
|
|
|
- reloc[relocCount].reltype:=relocType;
|
|
|
|
- reloc[relocCount].offset:=ofs;
|
|
|
|
- reloc[relocCount].index:=index;
|
|
|
|
|
|
+ i:=relocCount;
|
|
|
|
+ reloc[i].sec:=writeSec;
|
|
|
|
+ reloc[i].reltype:=relocType;
|
|
|
|
+ reloc[i].offset:=ofs;
|
|
|
|
+ reloc[i].index:=index;
|
|
inc(relocCount);
|
|
inc(relocCount);
|
|
|
|
+
|
|
|
|
+ case relocType of
|
|
|
|
+ R_WASM_FUNCTION_INDEX_LEB:
|
|
|
|
+ begin
|
|
|
|
+ // ok, so this is function.
|
|
|
|
+ // the function MUST HAVE a symbol information available
|
|
|
|
+ // if it doesn't have a symbol then "wasm-objdump" would fail to read it
|
|
|
|
+ f:=module.GetFunc(index);
|
|
|
|
+ if not f.hasSym then begin
|
|
|
|
+ so:=AddSymbolObject;
|
|
|
|
+ so.syminfo.kind:=SYMTAB_FUNCTION;
|
|
|
|
+ so.syminfo.flags:=0; // WASM_SYM_EXPLICIT_NAME or WASM_SYM_BINDING_LOCAL;
|
|
|
|
+ so.syminfo.symname:=f.id;
|
|
|
|
+ so.syminfo.symindex:=index;
|
|
|
|
+ so.syminfo.hasSymIndex:=true;
|
|
|
|
+ f.hasSym:=true;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TBinWriter.WriteRelocU32(u: longword);
|
|
procedure TBinWriter.WriteRelocU32(u: longword);
|
|
@@ -159,6 +207,7 @@ begin
|
|
end;
|
|
end;
|
|
keepLeb128:=keepLeb128 or writeReloc; // use 128, if relocation has been requested
|
|
keepLeb128:=keepLeb128 or writeReloc; // use 128, if relocation has been requested
|
|
|
|
|
|
|
|
+ module:=m;
|
|
dst:=adst;
|
|
dst:=adst;
|
|
org:=adst;
|
|
org:=adst;
|
|
|
|
|
|
@@ -169,31 +218,31 @@ begin
|
|
writeSec:=0;
|
|
writeSec:=0;
|
|
// 01 function type section
|
|
// 01 function type section
|
|
if m.TypesCount>0 then begin
|
|
if m.TypesCount>0 then begin
|
|
- WriteFuncTypeSect(m);
|
|
|
|
|
|
+ WriteFuncTypeSect;
|
|
inc(writeSec);
|
|
inc(writeSec);
|
|
end;
|
|
end;
|
|
|
|
|
|
// 03 function section
|
|
// 03 function section
|
|
if m.FuncCount>0 then begin
|
|
if m.FuncCount>0 then begin
|
|
- WriteFuncSect(m);
|
|
|
|
|
|
+ WriteFuncSect;
|
|
inc(writeSec);
|
|
inc(writeSec);
|
|
end;
|
|
end;
|
|
|
|
|
|
// 07 export section
|
|
// 07 export section
|
|
if m.ExportCount>0 then begin
|
|
if m.ExportCount>0 then begin
|
|
- WriteExportSect(m);
|
|
|
|
|
|
+ WriteExportSect;
|
|
inc(writeSec);
|
|
inc(writeSec);
|
|
end;
|
|
end;
|
|
|
|
|
|
// 10 code section
|
|
// 10 code section
|
|
if m.FuncCount>0 then begin
|
|
if m.FuncCount>0 then begin
|
|
- WriteCodeSect(m);
|
|
|
|
|
|
+ WriteCodeSect;
|
|
inc(writeSec);
|
|
inc(writeSec);
|
|
end;
|
|
end;
|
|
|
|
|
|
if writeReloc then begin
|
|
if writeReloc then begin
|
|
- WriteLinkingSect(m);
|
|
|
|
- WriteRelocSect(m)
|
|
|
|
|
|
+ WriteLinkingSect;
|
|
|
|
+ WriteRelocSect;
|
|
end;
|
|
end;
|
|
|
|
|
|
Result:=true;
|
|
Result:=true;
|
|
@@ -221,7 +270,7 @@ begin
|
|
Result := true;
|
|
Result := true;
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TBinWriter.WriteFuncTypeSect(m: TWasmModule);
|
|
|
|
|
|
+procedure TBinWriter.WriteFuncTypeSect;
|
|
var
|
|
var
|
|
sc : TSectionRec;
|
|
sc : TSectionRec;
|
|
i : integer;
|
|
i : integer;
|
|
@@ -230,9 +279,9 @@ var
|
|
begin
|
|
begin
|
|
SectionBegin(SECT_TYPE, sc);
|
|
SectionBegin(SECT_TYPE, sc);
|
|
|
|
|
|
- WriteU32(dst, m.TypesCount);
|
|
|
|
- for i:=0 to m.TypesCount-1 do begin
|
|
|
|
- tp:=m.GetType(i);
|
|
|
|
|
|
+ WriteU32(dst, module.TypesCount);
|
|
|
|
+ for i:=0 to module.TypesCount-1 do begin
|
|
|
|
+ tp:=module.GetType(i);
|
|
dst.WriteByte(func_type);
|
|
dst.WriteByte(func_type);
|
|
|
|
|
|
WriteU32(dst, tp.ParamCount);
|
|
WriteU32(dst, tp.ParamCount);
|
|
@@ -246,23 +295,23 @@ begin
|
|
SectionEnd(sc);
|
|
SectionEnd(sc);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TBinWriter.WriteFuncSect(m: TWasmModule);
|
|
|
|
|
|
+procedure TBinWriter.WriteFuncSect;
|
|
var
|
|
var
|
|
sc : TSectionRec;
|
|
sc : TSectionRec;
|
|
i : integer;
|
|
i : integer;
|
|
begin
|
|
begin
|
|
SectionBegin(SECT_FUNCTION, sc);
|
|
SectionBegin(SECT_FUNCTION, sc);
|
|
|
|
|
|
- WriteU32(dst, m.FuncCount);
|
|
|
|
- for i:=0 to m.FuncCount-1 do
|
|
|
|
|
|
+ WriteU32(dst, module.FuncCount);
|
|
|
|
+ for i:=0 to module.FuncCount-1 do
|
|
// wat2test doesn't write the function section as relocatable
|
|
// wat2test doesn't write the function section as relocatable
|
|
// WriteRelocU32(m.GetFunc(i).functype.typeNum);
|
|
// WriteRelocU32(m.GetFunc(i).functype.typeNum);
|
|
- WriteU32(dst, m.GetFunc(i).functype.typeNum);
|
|
|
|
|
|
+ WriteU32(dst, module.GetFunc(i).functype.typeNum);
|
|
|
|
|
|
SectionEnd(sc);
|
|
SectionEnd(sc);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TBinWriter.WriteExportSect(m: TWasmModule);
|
|
|
|
|
|
+procedure TBinWriter.WriteExportSect;
|
|
var
|
|
var
|
|
sc : TSectionRec;
|
|
sc : TSectionRec;
|
|
i : integer;
|
|
i : integer;
|
|
@@ -270,9 +319,9 @@ var
|
|
begin
|
|
begin
|
|
SectionBegin(SECT_EXPORT, sc);
|
|
SectionBegin(SECT_EXPORT, sc);
|
|
|
|
|
|
- WriteU32(dst, m.ExportCount);
|
|
|
|
- for i:=0 to m.ExportCount-1 do begin
|
|
|
|
- x:=m.GetExport(i);
|
|
|
|
|
|
+ WriteU32(dst, module.ExportCount);
|
|
|
|
+ for i:=0 to module.ExportCount-1 do begin
|
|
|
|
+ x:=module.GetExport(i);
|
|
WriteU32(dst, length(x.name));
|
|
WriteU32(dst, length(x.name));
|
|
if length(x.name)>0 then
|
|
if length(x.name)>0 then
|
|
dst.Write(x.name[1], length(x.name));
|
|
dst.Write(x.name[1], length(x.name));
|
|
@@ -287,7 +336,7 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
-procedure TBinWriter.WriteCodeSect(m: TWasmModule);
|
|
|
|
|
|
+procedure TBinWriter.WriteCodeSect;
|
|
var
|
|
var
|
|
sc : TSectionRec;
|
|
sc : TSectionRec;
|
|
i, j : integer;
|
|
i, j : integer;
|
|
@@ -296,19 +345,20 @@ var
|
|
la : TLocalInfoArray;
|
|
la : TLocalInfoArray;
|
|
f : TWasmFunc;
|
|
f : TWasmFunc;
|
|
dofs : Int64;
|
|
dofs : Int64;
|
|
|
|
+ p : Int64;
|
|
begin
|
|
begin
|
|
SectionBegin(SECT_CODE, sc);
|
|
SectionBegin(SECT_CODE, sc);
|
|
|
|
|
|
mem:=TMemoryStream.Create;
|
|
mem:=TMemoryStream.Create;
|
|
try
|
|
try
|
|
- WriteU32(dst, m.FuncCount);
|
|
|
|
- for i :=0 to m.FuncCount-1 do begin
|
|
|
|
- f:=m.GetFunc(i);
|
|
|
|
|
|
+ WriteU32(dst, module.FuncCount);
|
|
|
|
+ for i :=0 to module.FuncCount-1 do begin
|
|
|
|
+ f:=module.GetFunc(i);
|
|
|
|
|
|
GetLocalInfo(f, la);
|
|
GetLocalInfo(f, la);
|
|
|
|
|
|
mem.Position:=0;
|
|
mem.Position:=0;
|
|
- dofs:=dst.Position;
|
|
|
|
|
|
+ dofs:=dst.Position+5; // "la" will be written after, 5 is for the writeSize. +5 is for WriteRelocU32(sz)
|
|
pushStream(mem);
|
|
pushStream(mem);
|
|
|
|
|
|
WriteU32(dst, length(la));
|
|
WriteU32(dst, length(la));
|
|
@@ -331,20 +381,49 @@ begin
|
|
SectionEnd(sc);
|
|
SectionEnd(sc);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TBinWriter.WriteLinkingSect(m: TWasmModule);
|
|
|
|
|
|
+procedure TBinWriter.WriteLinkingSect;
|
|
var
|
|
var
|
|
sc : TSectionRec;
|
|
sc : TSectionRec;
|
|
|
|
+ mem : TMemoryStream;
|
|
|
|
+ so : TSymbolObject;
|
|
begin
|
|
begin
|
|
SectionBegin(SECT_CUSTOM, sc);
|
|
SectionBegin(SECT_CUSTOM, sc);
|
|
WriteString(SectionName_Linking);
|
|
WriteString(SectionName_Linking);
|
|
|
|
|
|
WriteU32(dst, LINKING_VERSION);
|
|
WriteU32(dst, LINKING_VERSION);
|
|
|
|
+ if symCount>0 then begin
|
|
|
|
+ dst.WriteByte(WASM_SYMBOL_TABLE);
|
|
|
|
+ mem := TMemoryStream.Create;
|
|
|
|
+ try
|
|
|
|
+ pushStream(mem);
|
|
|
|
+ //WriteU32(dst, symCount);
|
|
|
|
+ WriteRelocU32(symCount);
|
|
|
|
+ so:=symHead;
|
|
|
|
+ while Assigned(so) do begin
|
|
|
|
+ dst.WriteByte(so.syminfo.kind);
|
|
|
|
+ WriteU32(dst, so.syminfo.flags);
|
|
|
|
+ WriteU32(dst, so.syminfo.symindex);
|
|
|
|
+ //if ((so.syminfo.flags and WASM_SYM_EXPLICIT_NAME)>0) then begin
|
|
|
|
+ WriteU32(dst, length(so.syminfo.symname));
|
|
|
|
+ dst.Write(so.syminfo.symname[1], length(so.syminfo.symname));
|
|
|
|
+ //end;
|
|
|
|
+ so:=so.next;
|
|
|
|
+ end;
|
|
|
|
+ popStream;
|
|
|
|
+
|
|
|
|
+ mem.Position:=0;
|
|
|
|
+ WriteU32(dst, mem.Size);
|
|
|
|
+ dst.CopyFrom(mem, mem.size);
|
|
|
|
+ finally
|
|
|
|
+ mem.Free;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
// todo: fill out subsections
|
|
// todo: fill out subsections
|
|
|
|
|
|
SectionEnd(sc);
|
|
SectionEnd(sc);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TBinWriter.WriteRelocSect(m: TWasmModule);
|
|
|
|
|
|
+procedure TBinWriter.WriteRelocSect;
|
|
var
|
|
var
|
|
i : integer;
|
|
i : integer;
|
|
j : integer;
|
|
j : integer;
|