Browse Source

[PATCH 067/188] adding support for symbols in functions

From 46531029f3fd74bd36acdae6875dad89fe22999d Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Wed, 4 Mar 2020 09:46:41 -0500

git-svn-id: branches/wasm@46063 -
nickysn 5 years ago
parent
commit
26ca05c0a8
2 changed files with 64 additions and 14 deletions
  1. 53 5
      utils/wasmbin/wasmbinwriter.pas
  2. 11 9
      utils/wasmbin/watparser.pas

+ 53 - 5
utils/wasmbin/wasmbinwriter.pas

@@ -59,6 +59,8 @@ type
 
     procedure pushStream(st: TStream);
     function popStream: TStream;
+
+    procedure PrepareLinkSym(m: TWasmModule);
   public
     keepLeb128 : Boolean; // keep leb128 at 4 offset relocatable
     writeReloc : Boolean; // writting relocation (linking) information
@@ -67,7 +69,9 @@ type
     function Write(m: TWasmModule; adst: TStream): Boolean;
   end;
 
-function WriteModule(m: TWasmModule; dst: TStream): Boolean;
+function WriteModule(m: TWasmModule; dst: TStream;
+  awriteLEB128: Boolean = false;
+  awriteReloc: Boolean = false): Boolean;
 
 type
   TLocalsInfo = record
@@ -119,15 +123,15 @@ begin
   SetLength(loc, j);
 end;
 
-function WriteModule(m: TWasmModule; dst: TStream): Boolean;
+function WriteModule(m: TWasmModule; dst: TStream;
+  awriteLEB128, awriteReloc: Boolean): Boolean;
 var
   bw : TBinWriter;
 begin
   bw := TBinWriter.Create;
   try
-    bw.keepLeb128:=true;
-    bw.writeReloc:=true;
-    Normalize(m);
+    bw.keepLeb128:=awriteLEB128;
+    bw.writeReloc:=awriteReloc;
     Result := bw.Write(m, dst);
   finally
     bw.Free;
@@ -241,6 +245,7 @@ begin
   end;
 
   if writeReloc then begin
+    PrepareLinkSym(m);
     WriteLinkingSect;
     WriteRelocSect;
   end;
@@ -508,6 +513,49 @@ begin
   inherited Destroy;
 end;
 
+function isFuncLinkSym(const l: TLinkInfo): boolean;
+begin
+  Result:=(l.Binding<>lbUndefined)
+    or l.isHidden
+    or l.isUndefined
+    or l.NoStrip;
+end;
+
+procedure LinkInfoToBin(const src: TLinkInfo; var dst: TSymInfo; ASymTab: byte; aofs: longword);
+begin
+  dst.kind := ASymTab;
+  dst.flags := 0;
+  case src.Binding of
+    lbWeak: dst.flags := dst.flags or WASM_SYM_BINDING_WEAK;
+    lbLocal: dst.flags := dst.flags or WASM_SYM_BINDING_LOCAL;
+    lbForHost: dst.flags := dst.flags or WASM_SYM_EXPORTED;
+  end;
+  if src.isHidden then dst.flags := dst.flags or WASM_SYM_VISIBILITY_HIDDEN;
+  if src.isUndefined then dst.flags := dst.flags or  WASM_SYM_UNDEFINED;
+  if src.NoStrip then dst.flags := dst.flags or WASM_SYM_NO_STRIP;
+  dst.symindex := aofs;
+  dst.hasSymIndex := ASymTab<>SYMTAB_DATA;
+  dst.hasSymName := src.Name<>'';
+  if (dst.hasSymName) then begin
+    dst.flags := dst.flags or WASM_SYM_EXPLICIT_NAME;
+    dst.symname := src.Name;
+  end;
+end;
+
+procedure TBinWriter.PrepareLinkSym(m: TWasmModule);
+var
+  i   : integer;
+  f   : TWasmFunc;
+  so  : TSymbolObject;
+begin
+  for i:=0 to m.FuncCount-1 do begin
+    f := m.GetFunc(i);
+    if isFuncLinkSym(f.LinkInfo) then begin
+      so:=AddSymbolObject;
+      LinkInfoToBin(f.linkInfo, so.syminfo, SYMTAB_FUNCTION, i);
+    end;
+  end;
+end;
 
 end.
 

+ 11 - 9
utils/wasmbin/watparser.pas

@@ -321,6 +321,7 @@ procedure ParseModuleInt(sc: TWatScanner; dst: TWasmModule);
 var
   tk : TWatToken;
   symlist : TAsmSymList;
+  f : TWasmFunc;
 begin
   if not ConsumeOpenToken(sc, weModule) then
     ErrorExpectButFound(sc, 'module');
@@ -334,7 +335,9 @@ begin
         weAsmSymbol:
           ConsumeAsmSym(sc, symlist);
         weFunc: begin
-          ParseFunc(sc, dst.AddFunc);
+          f:=dst.AddFunc;
+          symlist.ToLinkInfo(f.LinkInfo);
+          ParseFunc(sc, f);
           symlist.Clear;
         end;
         weExport:
@@ -434,22 +437,21 @@ var
   i : integer;
 begin
   for i:=0 to count-1 do begin
-    if syms[i].name = '.name' then
+    if syms[i].name = 'name' then
       AInfo.Name := syms[i].value
-    else if syms[i].name = '.weak' then
+    else if syms[i].name = 'weak' then
       AInfo.Binding := lbWeak
-    else if syms[i].name = '.local' then
+    else if syms[i].name = 'local' then
       AInfo.Binding := lbLocal
-    else if syms[i].name = '.hidden' then
+    else if syms[i].name = 'hidden' then
       Ainfo.isHidden := true
-    else if syms[i].name = '.undef' then
+    else if syms[i].name = 'undef' then
       AInfo.isUndefined := true
-    else if syms[i].name = '.strong' then
+    else if syms[i].name = 'nostrip'  then
       AInfo.NoStrip := true
-    else if syms[i].name = '.forhost' then
+    else if syms[i].name = 'forhost' then
       AInfo.Binding := lbForHost;
   end;
-
 end;
 
 { EParserError }